IOS6 Transactions Validation

Non-consumables: Set aside the current receipts, perform a restore operation, and validate the new receipts.

To do this have a look on  restorePurchases function of InAppPurchaseManager class

Consumables: If you have saved the receipts, either on the device or on your server, revalidate the receipts after implementing your mitigation strategy. If you have not saved the receipts, you cannot validate these past transactions; you should not take any action.


When you got OnTransactionComplete action from the InAppPurchaseManager class, it contains IOSStoreKitResponse as event data. From  IOSStoreKitResponse, you can get transaction recipe, send it to your server and validate transaction there.


Note: Apple’s official recommendation to perform receipt validation is to connect to your own server, which then connects to Apple’s servers to validate the receipts.For a number of reasons, this is more secure than connecting to Apple directly.

If you do not want to use your server you can use apple server for transaction validation

After you got OnTransactionComplete action and the product state is Purchased call


you will get OnVerificationComplete action request is complete. Action contains IOSStoreKitVerificationResponse data, with information about transaction from apple server.

Warning: Use SANDBOX_VERIFICATION_SERVER url ( during app testing  and APPLE_VERIFICATION_SERVER url  ( on production.

So basically there is 2 scenarios how you can perform the validation for your game

1. Local Validation.

  • Item was Purchased
  • Use VerifyLastPurchase method
  • If Verifications result is success provide content to your player

You can find basic sample bellow:

IOSInAppPurchaseManager.OnTransactionComplete += OnTransactionComplete;
IOSInAppPurchaseManager.OnVerificationComplete += OnVerificationComplete;


private static void OnTransactionComplete (IOSStoreKitResponse result) {

        Debug.Log("OnTransactionComplete: " + result.ProductIdentifier);
        Debug.Log("OnTransactionComplete: state: " + result.State);

        switch(result.State) {
        case InAppPurchaseState.Purchased:

void OnVerificationComplete (IOSStoreKitVerificationResponse resp) {
	if(resp.status == 0) {
		Debug.Log("Transaction is valid");

The validation result is represented as the IOSStoreKitVerificationResponse object.

If the status field is 0 if the receipt is valid, or one of the error codes listed  bellow:

Status Code



The App Store could not read the JSON object you provided.


The data in the receipt-data property was malformed or missing.


The receipt could not be authenticated.


The shared secret you provided does not match the shared secret on file for your account.

Only returned for iOS 6 style transaction receipts for auto-renewable subscriptions.


The receipt server is not currently available.


This receipt is valid but the subscription has expired. When this status code is returned to your server, the receipt data is also decoded and returned as part of the response.

Only returned for iOS 6 style transaction receipts for auto-renewable subscriptions.


This receipt is from the test environment, but it was sent to the production environment for verification. Send it to the test environment instead.


This receipt is from the production environment, but it was sent to the test environment for verification. Send it to the production environment instead.


2. Validate on your own server

  • Item was Purchased
  • Send the purchase data to your own server
  • On your server contact Apple server and validate purchase data
  • Listen for reply from your server, and provide the content if validation succeeded

Learn more here