Applying In-App Purchases in your application can be a little mind-boggling and tedious process. Integrating it with Corona requires calling the store module:
store = require("store")
The store module is already incorporated to the Corona API, similar to Facebook and Game Network. You can find more information on Corona's store module at http://docs.coronalabs.com/daily/guide/monetization/IAP/index.html.
The store.init()
function must be called when handling store transactions to your app. It activates In-App Purchases and allows you to receive callbacks with the listener function you specify:
store.init( listener )
The only parameter here is listener
. It's a function that handles transaction callback events.
The following blocks determine the transaction states that can occur during an In-App Purchase. The four different states are purchased, restored, cancelled, and failed:
function transactionCallback( event ) local transaction = event.transaction if transaction.state == "purchased" then print("Transaction successful!") print("productIdentifier", transaction.productIdentifier) print("receipt", transaction.receipt) print("transactionIdentifier", transaction.identifier) print("date", transaction.date) elseif transaction.state == "restored" then print("Transaction restored (from previous session)") print("productIdentifier", transaction.productIdentifier) print("receipt", transaction.receipt) print("transactionIdentifier", transaction.identifier) print("date", transaction.date) print("originalReceipt", transaction.originalReceipt) print("originalTransactionIdentifier", transaction.originalIdentifier) print("originalDate", transaction.originalDate) elseif transaction.state == "cancelled" then print("User cancelled transaction") elseif transaction.state == "failed" then print("Transaction failed, type:", transaction.errorType, transaction.errorString) else print("unknown event") end -- Once we are done with a transaction, call this to tell the store -- we are done with the transaction. -- If you are providing downloadable content, wait to call this until -- after the download completes. store.finishTransaction( transaction ) end store.init( "apple", transactionCallback )
The event.transaction
object contains the transaction.
The transaction object supports the following read-only properties:
"state"
: This is a string containing the state of the transaction. Valid values are "purchased"
, "restored"
, "cancelled"
, and "failed"
."productIdentifier"
: This is the product identifier associated with the transaction."receipt"
: This is a unique receipt returned from the App Store. It is returned as a hexadecimal string."signature"
: This is a string used to verify the purchase. For Google Play, it is returned by "inapp_signature"
. In iOS, it returns nil
."identifier"
: This is a unique transaction identifier returned from the App Store. It is a string."date"
: This is the date the transaction occurred."originalReceipt"
: This is a unique receipt returned from the App Store from the original purchase attempt. It is mostly relevant in the case of a restore. It is returned as a hexadecimal string."originalIdentifier"
: This is a unique transaction identifier returned from the Store from the original purchase attempt. This is mostly relevant in the case of a restore. It is a string."originalDate"
: This is the date of the original transaction. It is mostly relevant in the case of a restore."errorType"
: This is the type of error that occurred when the state is "failed"
(a string)."errorString"
: This is a descriptive error message of what went wrong in the "failed"
case.The store.loadProducts()
function retrieves information about items available for sale. This includes the price of each item, a name, and a description:
store.loadProducts( arrayOfProductIdentifiers, listener )
Its parameters are as follows:
The following block displays the list of products that are available in the app. Information about the product can be retrieved from the loadProductsCallback()
function and determines whether it is valid or invalid:
-- Contains your Product ID's set in iTunes Connect local listOfProducts = { "com.mycompany.InAppPurchaseExample.Consumable", "com.mycompany.InAppPurchaseExample.NonConsumable", "com.mycompany.InAppPurchaseExample.Subscription", } function loadProductsCallback ( event ) print("showing valid products", #event.products) for i=1, #event.products do print(event.products[i].title) print(event.products[i].description) print(event.products[i].price) print(event.products[i].productIdentifier) end print("showing invalidProducts", #event.invalidProducts) for i=1, #event.invalidProducts do print(event.invalidProducts[i]) end end store.loadProducts( listOfProducts, loadProductsCallback )
When a requested list of products is returned by store.loadProducts()
, the array of product information can be accessed through the event.products
property.
Product information, such as title, description, price, and the product identifier, is contained in a table:
event.products
Each entry in the event.products
array supports the following fields:
title
: This is the localized name of the itemdescription
: This is the localized description of the itemprice
: This is the price of an item (as a number)productIdentifier
: This is the product identifierWhen store.loadProducts()
returns its requested list of products, any products you requested that are not available for sale will be returned in an array. You can access the array of invalid products through the event.invalidProducts
property.
This is a Lua array containing the product identifier string requested from store.loadProducts()
:
event.invalidProducts
The store.canMakePurchases
function returns true if purchases are allowed, and false otherwise. Corona's API can check whether purchasing is possible. iOS devices provide a setting that disables purchasing. This can be used to avoid purchasing apps accidentally.
if store.canMakePurchases then store.purchase( listOfProducts ) else print("Store purchases are not available") end
The store.purchase()
function initiates a purchase transaction on a provided list of products.
This function will send purchase requests to the store. The listener specified in store.init()
will be invoked when the store finishes processing the transaction:
store.purchase( arrayOfProducts )
Its only parameter is arrayOfProducts
, an array specifying the products you want to buy:
store.purchase{ "com.mycompany.InAppPurchaseExample.Consumable"}
This function notifies the App Store that a transaction is complete.
After you finish handling a transaction, you must call store.finishTransaction()
on the transaction object. If you don't do this, the App Store will think your transaction was interrupted and will attempt to resume it on the next application launch.
Syntax:
store.finishTransaction( transaction )
Parameters:
Transaction: The transaction
object belonging to the transaction you want to mark as finished.
Example:
store.finishTransaction( transaction )
Any previously purchased items that have been wiped clean from a device or upgraded to a new device can be restored on the user's account without paying for the product again. The store.restore()
API initiates this process. Transactions can be restored by the transactionCallback
listener, which is registered with store.init()
. The transaction state will be "restored"
and your app may then make use of the "originalReceipt"
, "originalIdentifier"
, and "originalDate"
fields of the transaction object:
store.restore()
The block will run through the transactionCallback()
function and determine whether a product has been previously purchased from the application. If the result is true, store.restore()
will initiate the process of retrieving the product without asking the user to pay for it again:
function transactionCallback( event ) local transaction = event.transaction if transaction.state == "purchased" then print("Transaction successful!") print("productIdentifier", transaction.productIdentifier) print("receipt", transaction.receipt) print("transactionIdentifier", transaction.identifier) print("date", transaction.date) elseif transaction.state == "restored" then print("Transaction restored (from previous session)") print("productIdentifier", transaction.productIdentifier) print("receipt", transaction.receipt) print("transactionIdentifier", transaction.identifier) print("date", transaction.date) print("originalReceipt", transaction.originalReceipt) print("originalTransactionIdentifier", transaction.originalIdentifier) print("originalDate", transaction.originalDate) elseif transaction.state == "cancelled" then print("User cancelled transaction") elseif transaction.state == "failed" then print("Transaction failed, type:", transaction.errorType, transaction.errorString) else print("unknown event") end -- Once we are done with a transaction, call this to tell the store -- we are done with the transaction. -- If you are providing downloadable content, wait to call this until -- after the download completes. store.finishTransaction( transaction ) end store.init( transactionCallback ) store.restore()