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 as 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.

Basically this mean, that after you will launch Restore Purchases flow, you will get transaction action for every item with 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 buy method restorePurchases should be used only after store is initialized successfully.

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

OSXInAppPurchaseManager.instance.OnTransactionComplete += OnTransactionComplete;
OSXInAppPurchaseManager.instance.OnRestoreComplete += OnRestoreComplete;

private static void OnRestoreComplete (OSXStoreKitRestoreResponce res) {
	if(res.IsSucceeded) {
		OSXMessage.Create("Success", "Restore Compleated");
	} else {
		OSXMessage.Create("Error: " + res.error.code, res.error.description);

private static void OnTransactionComplete (OSXStoreKitResponse response) {

	Debug.Log("OnTransactionComplete: " + response.productIdentifier);
	Debug.Log("OnTransactionComplete: state: " + response.state);

	switch(response.state) {
	case OSXInAppPurchaseState.Purchased:
	case OSXInAppPurchaseState.Restored:
		//Our product been succsesly purchased or restored
		//So we need to provide content to our user depends on productIdentifier
	case OSXInAppPurchaseState.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.
	case OSXInAppPurchaseState.Failed:
		//Our purchase flow is failed.
		//We can unlock intrefase and repor user that the purchase is failed. 
		Debug.Log("Transaction failed with error, code: " + response.error.code);
		Debug.Log("Transaction failed with error, description: " + response.error.description);


	if(response.state == InAppPurchaseState.Failed) {
		OSXMessage.Create("Transaction Failed", "Error code: " + response.error.code + "\n" + "Error description:" + response.error.description);
	} else {
		OSXMessage.Create("Store Kit Response", "product " + response.productIdentifier + " state: " + response.state.ToString());



Script References


public class OSXStoreKitRestoreResponce : ISN_Result {
	public bool IsSucceeded {get;}
	public bool IsFailed {get;}
	public OSXStoreKitError Error {get;}


public class OSXStoreKitResponse  {
	public string productIdentifier{get;}
	public OSXInAppPurchaseState state{get;}
	public string receipt{get;}
	public string transactionIdentifier{get;}
	public OSXStoreKitError error{get;}


public class OSXStoreKitError  {
	public string description{get;}
	public OSXTransactionErrorCode code{get;}


public enum OSXInAppPurchaseState {


public enum OSXTransactionErrorCode  {
	SKErrorUnknown = 0,
	SKErrorClientInvalid = 1,               // client is not allowed to issue the request, etc.
	SKErrorPaymentCancelled = 2,            // user cancelled the request, etc.
	SKErrorPaymentInvalid = 3,              // purchase identifier was invalid, etc.
	SKErrorPaymentNotAllowed = 4,           // this device is not allowed to make the payment
	SKErrorStoreProductNotAvailable = 5,    // Product is not available in the current storefront
	SKErrorPaymentNoPurchasesToRestore = 6,  // No purchases to restore"
	SKErrorPaymentServiceNotInitialized = 7  //StoreKit initialization required