Search code examples
iosobjective-cin-app-purchasein-app

How to handle not finished iOS in-app purchase of consumable?


I check & process IAP receipts (of consumables) on server side, and only call [[SKPaymentQueue defaultQueue] finishTransaction:transaction] on the app when it gets an okay back.

When the server does not return this okay (for whatever reason), the app correctly won't finish the transaction.

My question now is: Is there anything the app needs to do to receive the receipt again for a retry, or does iOS take care of this by invoking - (void)paymentQueue:(SKPaymentQueue*)queue updatedTransactions:(NSArray*)transactions`? When I reran my app, the item was re-submitted; but a user should not need to restart the app.

Related question: When I tried to buy a still pending item again (on the sandbox), I got an iOS alert saying that I bought it earlier but was not downloaded. Why is this? I would expect (and have actually seen) this for non-consumables. I could buy another consumable, with this previous one still pending.


Solution

  • Once you finish the transaction of CONSUMABLE IN-APP the following method will fire there add this statement "[[SKPaymentQueue defaultQueue] finishTransaction:transaction]" to remove the purchased product.Using this statement you can avoid the alert message(I bought it earlier but was not downloaded).

    -(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
    {
     for (SKPaymentTransaction *transaction in transactions)
     {        
        switch (transaction.transactionState) {
            case SKPaymentTransactionStatePurchased:
                if (transaction.downloads)
                {
                    [[SKPaymentQueue defaultQueue]
                     startDownloads:transaction.downloads];
                } else {
                    //Add the following line to remove purchased observer
                    [[SKPaymentQueue defaultQueue] finishTransaction:transaction];                    
                }
                break;
    
            case SKPaymentTransactionStateFailed:
                [[SKPaymentQueue defaultQueue]
                 finishTransaction:transaction];
    
                break;
    
        }
    }
    }