Restoring Purchases

Users restore transactions to maintain access to content they've already purchased. For example, when they upgrade to a new phone, they donât lose all of the items they purchased on the old phone. Include some mechanism in your app to let the user restore their purchases, such as a Restore Purchases button. Restoring purchases prompts for the userâs App Store credentials, which interrupts the flow of your app: because of this, donât automatically restore purchases, especially not every time your app is launched.

Restoring completed transactions creates a new transaction for every completed transaction the user made, essentially replaying history for your transaction queue observer. While transactions are being restored, your app maintains its own state to keep track of why it's restoring completed transactions and how it needs to handle them. Restoring multiple times creates multiple restored transactions for each completed transaction.

Generally,  this means, that after you will launch Restore Purchases flow, you will get transaction action for every item which was already purchased by the customer.

Before we will start  Restore Purchases flow, let's make sure that we are listening for OnTransactionComplete and OnRestoreComplete events.

The same as BuyProduct method, RestorePurchases should be used only after Store Kit is initialized successfully.

Note: As any other PaymentManager API can be used only after the initialization is complete (i. e. OnStoreKitInitComplete action fired). The initialization process is described at the Coding Guidelines article.

Note. OnRestoreComplete event will contain RestoreResult object inside as operation result.

Following code snippet will show how you can handle purchases restore in your application.

using SA.IOSNative.StoreKit;
...

PaymentManager.OnTransactionComplete += OnTransactionComplete;
PaymentManager.OnRestoreComplete += OnRestoreComplete;

PaymentManager.Instance.RestorePurchases();


void OnRestoreComplete (RestoreResult res) {
	if(res.IsSucceeded) {
		IOSNativePopUpManager.showMessage("Success", "Restore Compleated");
	} else {
		IOSNativePopUpManager.showMessage("Error: " + res.Error.Code, res.Error.Message);
	}
}

void OnTransactionComplete (PurchaseResult result) {

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

	switch(result.State) {
	case PurchaseState.Purchased:
	case PurchaseState.Restored:
		//Our product been succsesly purchased or restored
		//So we need to provide content to our user depends on productIdentifier
		UnlockProducts (result.ProductIdentifier);

		break;
	case PurchaseState.Deferred:
		//iOS 8 introduces Ask to Buy, which lets parents approve any purchases initiated by children
		//You should update your UI to reflect this deferred state, and expect another Transaction Complete  to be called again with a new transaction state 
		//reflecting the parent’s decision or after the transaction times out. Avoid blocking your UI or gameplay while waiting for the transaction to be updated.
		break;
	case PurchaseState.Failed:
		//Our purchase flow is failed.
		//We can unlock intrefase and repor user that the purchase is failed. 
		ISN_Logger.Log("Transaction failed with error, code: " + result.Error.Code);
		ISN_Logger.Log("Transaction failed with error, description: " + result.Error.Message);


		break;
	}

	if(result.State == PurchaseState.Failed) {
		IOSNativePopUpManager.showMessage("Transaction Failed", "Error code: " + result.Error.Code + "\n" + "Error description:" + result.Error.Message);
	} else {
		IOSNativePopUpManager.showMessage("Store Kit Response", "product " + result.ProductIdentifier + " state: " + result.State.ToString());
	}
}