Differences

This shows you the differences between the selected revision and the current
version of the page.


wmelite:iap_guide 2011/07/30 16:44 wmelite:iap_guide 2013/05/15 19:34 current
Line 1: Line 1:
-====== In app purchases guide ======+====== In app purchases guide (iOS only) ======
Starting with iOS 3.0, the users can purchase "products" directly from applications. This technology is called "in app purchases". These products can be of three types: Starting with iOS 3.0, the users can purchase "products" directly from applications. This technology is called "in app purchases". These products can be of three types:
Line 40: Line 40:
} }
</code> </code>
 +
Line 70: Line 71:
on "ProductsValidated" on "ProductsValidated"
{ {
- // products are now validated, display purchase GUI+  // products are now validated, display purchase GUI
} }
Line 102: Line 103:
 +
 +
 +===== Purchasing =====
 +Once you are sure that the store is available and the products are valid, you can allow the user to purchase them. It is done using the Store.Purchase() method:
 +
 +<code script>
 +Store.Purchase("org.deadcode.wmelite.unlock");
 +</code>
 +
 +Once again, this method is asynchronous. You trigger the purchase and then you need to wait for a transaction event (see below). Again, you may want to display some waiting animation and a cancel button while the purchase is in progress.
 +
 +
 +
 +
 +===== Transactions =====
 +Purchases (and purchase attempts) will cause App Store to generate transactions. App Store is then sending the transaction notifications to the application and awaits confirmation.
 +
 +First, the application must allow reception of transaction events:
 +
 +<code script>
 +Store.EnableEvents();
 +</code>
 +
 +The important concept here is, that the script that called this method will receive the transaction events. If multiple scripts called it, the last one wins. If the script no longer exists, WME Lite will route the event to Game object.
 +
 +Since in iOS the application can be terminated at any moment (incoming call etc.), there may be pending transactions (App Store initiated the transaction but the application didn't have a chance to confirm it). App Store will re-send any pending transactions immediately after the application calls Store.EnableEvents(). For that reason you should call it immediately when the game starts, in game.script, and this script should be able to handle transactions. That way even if the game quits before confirming a transaction, the purchase will be finalized immediately after the user restars the game.
 +
 +Whenever App Store sends a transaction for confirmation, a "TransactionsUpdated" event is triggered in the script that last called Store.EnableEvents(). The game can then access all pending transactions like this:
 +
 +
 +<code script>
 +// list all pending transactions
 +on "TransactionsUpdated"
 +{
 +  for (var i = 0; i < Store.NumTransactions; i = i + 1)
 +  {
 +    var trans = Store.GetTransaction(i);
 +    Game.Msg("ID: " + trans.Id + "  Product ID: " + trans.ProductId + "  State: " + trans.State);
 +  }
 +}
 +</code>
 +
 +As you can see, each transaction has a unique ID, an ID of the purchased product, and a state. Use the state to decide what to do about the transaction. The state can be one of the following strings:
 +
 +  * **purchased** - the transaction was successful and the product was purchased
 +  * **cancelled** - the user cancelled the transaction
 +  * **failed** - the transaction failed
 +  * **restored** - it is a previously handled transaction requested by Store.RestoreTransactions() (see below)
 +
 +You MUST confirm all pending transactions once you processed them, using the Store.FinishTransaction() method. If you fail to do so, App Store will re-send the transaction.
 +
 +
 +So the actual transaction handling code should look like this:
 +
 +<code script>
 +// handle all pending transactions
 +on "TransactionsUpdated"
 +{
 +  for (var i = 0; i < Store.NumTransactions; i = i + 1)
 +  {
 +    var trans = Store.GetTransaction(i);
 +   
 +    if (trans.State == "purchased" || trans.State == "restored")
 +    {
 +      // do something with the purchased product Id
 +      UnlockPurchasedProduct(trans.ProductId);
 +    }
 +    else if (trans.State == "failed")
 +    {
 +      // perhaps notify the user?
 +    }
 +    else if (trans.State == "cancelled")
 +    {
 +      // perhaps notify the user?
 +    }
 +   
 +    // but in any case tell the App Store that you handled the transaction!
 +    Store.FinishTransaction(trans.Id);
 +  }
 +}
 +</code>
 +
 +
 +
 +
 +===== Restoring transactions =====
 +Since the users can uninstall and reinstall games, or buy new devices, they must be able to restore previous purchases. Use the Store.RestoreTransactions() method to ask App Store to re-send all previously completed transactions. These transactions (if any) will be added to the list of transactions with the "restored" state (see above).
 +
 +Just like the other communication methods, this one is anynchronous. You request the restored transactions and then you wait for events. In this case, the script which called Store.RestoreTransactions() will receive either the "TransactionsRestoreFinished" event or the "TransactionsRestoreFailed" event.
 +
 +
 +<code script>
 +// display waiting animation
 +// and a "cancel" button
 +// ...
 +
 +// request restored transactions
 +Store.RestoreTransactions();
 +
 +
 +on "TransactionsRestoreFinished"
 +{
 +  // it went well
 +}
 +
 +on "TransactionsRestoreFailed"
 +{
 +  // it went wrong
 +}
 +</code>
 +
 +
 +
 +
 +===== Unlocking functionality =====
 +Once the product is purchased, you should store this information somewhere locally (it would be impractical to connect to App Store all the time). WME Lite provides two convenience methods: Store.UnlockProduct() and Store.IsProductUnlocked(). Both accept a product ID as a parameter.
 +
 +When you are handling the "purchased" or "restored" transaction, you can call Store.UnlockProduct() to save the information about the purchase. In your game, just use the Store.IsProductUnlocked() to check if the user has purchased some functionality. If yes, let them continue playing, if not, display some purchase GUI and offer them to buy the functionality.
 +
 +Note that you don't have to use these two methods. You could as well store the information yourself, for example using Game.RegWriteNumber().
 +Also note, that this information is lost if the user uninstalls the game. That's why you always must provide means of restoring previous transactions (see above).
 
wmelite/iap_guide.1312037043.txt.gz · Last modified: 2011/07/30 16:44 by Mnemonic
Recent changes RSS feed Creative Commons License Driven by DokuWiki