here is the class that is handling the purchase:
`package
{
import com.distriqt.extension.core.Core;
import com.distriqt.extension.inappbilling.BillingService;
import com.distriqt.extension.inappbilling.ErrorCodes;
import com.distriqt.extension.inappbilling.InAppBilling;
import com.distriqt.extension.inappbilling.InAppBillingServiceTypes;
import com.distriqt.extension.inappbilling.Product;
import com.distriqt.extension.inappbilling.Purchase;
import com.distriqt.extension.inappbilling.PurchaseRequest;
import com.distriqt.extension.inappbilling.events.InAppBillingEvent;
import com.distriqt.extension.inappbilling.events.PurchaseEvent;
import flash.display.Sprite;
import flash.events.ErrorEvent;
import flash.events.Event;
//https://docs.airnativeextensions.com/asdocs/inappbilling/com/distriqt/extension/inappbilling/InAppBilling.html
//https://github.com/distriqt/ANE-InAppBilling
public class InAppAndroid extends Sprite implements InAppPurchaseInterface
{
//[Event(name="complete", type="flash.events.Event.COMPLETE")]
[Event(name="activate", type="flash.events.Event.ACTIVATE")]
//[Event(name="error", type="flash.events.ErrorEvent)]
public var bookPrice:Array;
public var bookWasBought:Array;
private var isAndroidIABtSuported:Boolean = false;
private var FolderName:Array = ["completetalmud","Brachos","Peah","Demai","Kilayim","Sheviit","Trumot","Maasrot","Maaser_Sheni","Challah","Orlah","Bikkurim","Shabbos","Eruvin","Psachim","Shkalim","Yuma","Suka","Beiza","Rosh_Hashana","Tanit","Megila","Moed_Katan","Chagiga","Yebamot","Ktubot","Nedarim","Nazir","Sota","Gitin","Kidushin","Baba_Kama","Baba_Mezia","Baba_Batra","Sanhedrin","Makot","Shvuot","Eduyot","Avoda_Zara","Avot","Horaiot","Zvachim","Menachot","Chulin","Bechorot","Arachin","Tmura","Kritut","Meila","Tamid","Midot","Kanim","Kelim","Oholot","Negaim","Parah","Taharoth","Mikvaot","Nida","Machshirin","Zavim","Tvul_Yom","Yadayim","Oktzin"];
private var SeriesName:String = "com.company.MainProductName.";
public var isReady:Boolean = false;
private var ListOfRestoredBooks:String = "";
public var Globals:Object;
public function InAppAndroid(G:Object)
{
Core.init();
bookPrice = new Array();
bookWasBought = new Array();
var i:int = 0;
for (i=0;i<FolderName.length;i++)
{
bookPrice[i] = "*";
bookWasBought[i] = "0";
}
Globals = G;
if (InAppBilling.isSupported)
{
if (InAppBilling.service.isServiceSupported(InAppBillingServiceTypes.GOOGLE_PLAY_INAPP_BILLING))
{
InAppBilling.service.addEventListener( InAppBillingEvent.SETUP_SUCCESS, setup_successHandler );
InAppBilling.service.addEventListener( InAppBillingEvent.SETUP_FAILURE, setup_failureHandler );
InAppBilling.service.setup(
new BillingService().setGooglePlayPublicKey( "MIIBIj... ...wIDAQAB" )
);
}
else
{
Globals.debug += "\n Google Play in app billing not supported";
}
}
else
{
Globals.debug += "\n Billing ane not supported";
}
}
private function setup_successHandler( event:InAppBillingEvent ):void
{
InAppBilling.service.addEventListener( InAppBillingEvent.PRODUCTS_LOADED, onProductsLoaded );
InAppBilling.service.addEventListener( InAppBillingEvent.PRODUCTS_FAILED, onProductsFailed );
InAppBilling.service.addEventListener( InAppBillingEvent.INVALID_PRODUCT, onProductsFailed );
InAppBilling.service.addEventListener( PurchaseEvent.PURCHASES_UPDATED, purchases_updatedHandler );
InAppBilling.service.addEventListener( PurchaseEvent.PURCHASE_FAILED, purchase_failedHandler );
InAppBilling.service.addEventListener( InAppBillingEvent.FINISH_SUCCESS, finishPurchase_successHandler );
InAppBilling.service.addEventListener( InAppBillingEvent.FINISH_FAILED, finishPurchase_failedHandler );
InAppBilling.service.addEventListener( InAppBillingEvent.RESTORE_PURCHASES_SUCCESS, restorePurchases_successHandler );
InAppBilling.service.addEventListener( InAppBillingEvent.RESTORE_PURCHASES_FAILED, restorePurchases_failedHandler );
isReady = true;
GetProducts();
}
private function setup_failureHandler( event:InAppBillingEvent ):void
{
//Globals.debug += "\n"+event.errorCode;
trace("sorry, in app billing won't work on this phone!");
}
//-------the interface functions------
public function setNewBookList(BookList:Array):void
{
FolderName = BookList;
}
public function GetProducts():void
{
var productIdList:Array = new Array();
var i:int = 1;
for (i = 0;i<FolderName.length; i++)
{
productIdList.push(SeriesName+FolderName[i].toLowerCase());
}
// Retrieve the product list
InAppBilling.service.getProducts( productIdList);
}
public function RestorePurchases():void
{
ListOfRestoredBooks = ": ";
// Start the restore process
InAppBilling.service.restorePurchases();
}
private var purchasedItemID:String;
public function purchase(choice:int):void
{
var request:PurchaseRequest = new PurchaseRequest();
purchasedItemID = request.productId = SeriesName+FolderName[choice].toLowerCase();
request.quantity = 1;
var success:Boolean = InAppBilling.service.makePurchase( request );
}
//-------end of interface functions------
private function onProductsLoaded( event:InAppBillingEvent ):void
{
if (event.data.length!=0)
{
for each(var item:Product in event.data)
{
//Globals.debug += "--price--"+item.price;
var j:int = Id2Num(item.id);
if (j)
bookPrice[j] = item.price;
/*
trace("item id:"+item.itemId);
trace("title:"+item.title);
trace("description:"+item.description);
trace("price:"+item.price);
*/
}
}
isReady = true;
// event.data will be an Array of Product instances for each product and subscription successfully loaded
for each (var product:Product in event.data)
{
trace( product.toString() );
}
}
private function onProductsFailed(event:InAppBillingEvent):void
{
SendErrorMsg("Error#Loading details Failed "+event.errorCode);
trace("Something went wrong loading details: "+event.errorCode);
}
//-----------------------------
function purchases_updatedHandler( event:PurchaseEvent ):void
{
for each (var purchase:Purchase in event.data)
{
var massege:String = "";
massege += "\nProduct ID: "+purchase.productId;
massege += "\nTransaction Date: "+purchase.transactionDate;
massege += "\nError: "+purchase.error;
massege += "\nError Code: "+purchase.errorCode;
massege += "\nTransaction Id: "+purchase.transactionId;
massege += "\nTransaction State: "+purchase.transactionState;
switch (purchase.transactionState)
{
// These transactions are in progress, so don't finish them unless you don't want them to complete
case Purchase.STATE_PURCHASING:
SendErrorMsg("PURCHASING!#"+massege);
break;
case Purchase.STATE_DEFERRED:
SendErrorMsg("DEFERRED!#"+massege);
break;;
// The purchased state should finished after you have delivered the product if applicable
case Purchase.STATE_PURCHASED:
{
trace( "purchase success" );
//
// If you wish you can add the purchase to your inventory
// and finish the purchase here
addPurchaseToInventory( purchase );
InAppBilling.service.finishPurchase( purchase );
SendErrorMsg("Purchase Succeeded!#You can now view all pages of the Masechet you have purchased.");
//
// Alternatively hold onto this purchase so we can call
// finish when you've delivered the product
//
// You would do this if you are validating the purchase on a server or
// other operation that is required to complete before the product is delivered
//_purchases.push( purchase );
break;
}
case Purchase.STATE_RESTORED:
// The originalPurchase property will contain all the
// information on the original transaction allowing
// you to restore the user's product
addPurchaseToInventory( purchase.originalPurchase );
InAppBilling.service.finishPurchase( purchase );
SendErrorMsg("Restore Succeeded!#Restore Previous Purchases has succeeded, you can now view all pages of the books you have previously purchased"+ListOfRestoredBooks);
// Again you could hold on to this purchase and check it against
// your application server before calling finishPurchase
break;
// For all other states you should handle appropriately and call finish purchase
case Purchase.STATE_FAILED:
SendErrorMsg("FAILED!#"+massege);
break;
case Purchase.STATE_REFUNDED:
SendErrorMsg("REFUNDED!#"+massege);
break;
case Purchase.STATE_RESTORED:
SendErrorMsg("RESTORED!#"+massege);
break;
case Purchase.STATE_REMOVED:
SendErrorMsg("REMOVED!#"+massege);
break
case Purchase.STATE_CANCELLED:
SendErrorMsg("CANCELLED!#"+massege);
break;
case Purchase.STATE_NOTALLOWED:
InAppBilling.service.finishPurchase( purchase );
SendErrorMsg("NOTALLOWED!#"+massege);
break;
}
}
}
function purchase_failedHandler( event:PurchaseEvent ):void
{
// This transaction failed so you should notify your user and finish the purchase
var s:String = "purchase failed [" + event.errorCode + "] :: "+ event.message;
if (event.data && event.data.length > 0)
{
//s += "Item id: "+event.data[0].productId+"\n";
InAppBilling.service.finishPurchase( event.data[0] );
}
switch (event.errorCode)
{
// Other error codes...
case ErrorCodes.ITEM_ALREADY_OWNED:
{
s += " Item Already Owned! Click on Restore Previous Purchases";
// You should use getPurchases() to retrieve the users purchases
// and then add them as missing from their current inventory
InAppBilling.service.getPurchases();
break;
}
case ErrorCodes.RESPONSE_CANCELLED:
case ErrorCodes.USER_CANCELLED:
s += " Purchase Cancelled!";
break;
}
SendErrorMsg("Error#" + s);
}
function finishPurchase_successHandler( event:InAppBillingEvent ):void
{
SendErrorMsg("Purchase Succeeded!#You can now view all pages of the Masechet you have purchased.");
}
function finishPurchase_failedHandler( event:InAppBillingEvent ):void
{
SendErrorMsg("Purchase Failed!#"+event.errorCode);
}
//-----------------------------
private function addPurchaseToInventory(purchase:Purchase):void
{
var A:Array = purchase.productId.split(".");
var idName:String = A[A.length-1];
ListOfRestoredBooks += " "+ Globals.CapitalizeFirstLetter(idName)+",";
for (var i:int = 0;i<FolderName.length; i++)
{
if (FolderName[i].toLowerCase() == idName)
{
bookWasBought[i] = "2";
break;
}
}
var eventObject:Event = new Event("activate");
dispatchEvent(eventObject);
}
function restorePurchases_successHandler( event:InAppBillingEvent ):void
{
SendErrorMsg("Restore Succeeded!#Restore Previous Purchases has succeeded, you can now view all pages of the books you have previously purchased"+ListOfRestoredBooks);
}
function restorePurchases_failedHandler( event:InAppBillingEvent ):void
{
SendErrorMsg("Error#Loading inventory Failed "+event.errorCode);
}
private function Id2Num(name:String):int
{
var A:Array = name.split(".");
var idName:String = A[A.length-1];
for (var j:int=0;j<FolderName.length;j++)
{
if (idName==FolderName[j].toLowerCase())
return j;
}
return 0;
}
private function SendErrorMsg(s:String):void
{
var errorEvent:ErrorEvent = new ErrorEvent(ErrorEvent.ERROR, true);
errorEvent.text = s;
dispatchEvent(errorEvent);
}
}
}`