Fairlight provides you with an easy way of manage consumables and non-consumables through different app stores (currently it supports: iOS, Google Play, Amazon and Windows Phone 8).
Configuration via INI
First you should create a new INI-File that looks like that:
#!ini [general] ouyaDeveloperId = foo ouyaApplicationKey = data/key.der parentalGate = 0 samsungItemGroupId = xfoobar [loadingImage] file = gfx/loader.png width = 56 height = 21 frames = 13 duration = 1000 [removeAds] type = non-consumable iosId = com.company.appid.removeads googlePlayId = com.company.appid.removeads amazonId = com.company.appid.removeads win8Id = com.company.appid.removeads ouyaId = ouyaItemId samsungItemId = someItemId [200coins] type = consumable iosId = com.company.appid.removeads.200coins googlePlayId = com.company.appid.removeads.200coins amazonId = com.company.appid.removeads.200coins win8Id = com.company.appid.removeads.200coins
The general section provides your app identifiers for the various stores. In loadingImage you provide an image file that will be showed while the payment processes (for example an animated progress bar). duration is in milliseconds.
Then for each product create one section with an internal id you want to use in your code. Provide as type either consumable or non-consumable. Then provide the product ids from the various stores.
Initialize the payment service
Now to initialize the payment service put the following code into your OnEnter-Method of your scene:
#!blitzmax Field paymentService:PaymentService Method OnEnter:Void() paymentService = PaymentService.Init("monkey://data/payment.ini") 'this is the path to your ini file paymentService.eventManager = GetSceneManager().eventManager 'your event manager paymentService.SetPaymentReceiver(Self) 'the class that should receive payments Add(paymentService) End
Now to purchase an product you can simply call:
It's the same for consumables and non-consumables products. The id is the internal id you set in your ini file (the name of the section, you never work with real inapp-ids in your code, it will be routed automatically to the ids you defined in the ini file).
Next you have to implement the PurchaseStateChanged interface. In our example we set our scene as payment receiver, so we have to implement it here (of course you can define your own class that handle payments):
#!blitzmax Class MyMenuScene Extends Scene Implements PurchaseStateChanged [.....] Method OnPurchaseStateChanged:Void(product:PaymentProduct) If (product.IsPurchased() And product.GetId() = "removeAds") DebugLog "Add your code here to disable the ads..." End If (PaymentProductConsumable(product) And (product.GetId() = "200coins" Or product.GetId() = "500coins")) Local quantity := PaymentProductConsumable(product).GetQuantity() Print "Quantity: " + quantity If (quantity > 0) If (PaymentProductConsumable(product).Consume(quantity)) Print "Consumed: " + quantity Print "Product consumed and saved!" End End End End
The code above shows the handling of an non-consumable item (removeAds) and one for consumables. The GetQuantity() method returns the number from your product identifier (for example if you internal id is 200coins it will return 200 by default). You can also define another quantity if you don't want to extract it from the product id.
That's it. We're done. Now just relax and wait for the money roll in...
Important notes for Windows Phone 8
If you get a linker error, you should add %(AdditionalDependencies) at "Settings -> Linker -> Input -> Additional Dependencies"
Make sure, that the publisher and product id in the Manifest file is correct and exists on the Microsoft servers else it's possible for the app to crash (a beta app is fine).
Sometimes if you initiate multiple purchases the app crashes when the debugger is attached. If you run the app without the debugger attached it seems to work fine (check this related post: http://social.msdn.microsoft.com/Forums/wpapps/en-US/7bee4c28-a123-41f3-a37d-48fe3ccc4dab/inapp-purchase-in-a-native-c-app)