The solution is to not call
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
on the consumable purchase until it has been synced with the server. This way, the transaction will be delivered again to your observer every time it is set to observe the payment queue. You will need manage app side whether it's a purchase that has been delivered but not synced, or a new purchase.
Once you have synced the transaction with the server. You can call -finishTransaction:
. See the "Finishing The Transaction" in the docs here:
https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/StoreKitGuide/Chapters/DeliverProduct.html#//apple_ref/doc/uid/TP40008267-CH5-SW3
EDIT
So the user is charged by Apple, and Apple send you a SKPaymentTransaction
object that represents the transaction. If the transactionState property of that transaction is SKPaymentTransactionStatePurchased
, then it means Apple has processed the payment and the user has been charged.
Once you have received this SKPaymentTransaction
object from the paymentQueue, you deliver the content to the user, and sync the transaction with your server. Once both of those have been successfully completed, you call -finishTransaction
. Calling -finishTransaction
tells StoreKit
that you have successfully completed everything you need to do. -finishTransaction
is a synchronous call, you are handing responsibility back to StoreKit
, and you don't need to concern yourself with how that is communicated back to iTunes/Apple, StoreKit
handles it all for you.
You should not call -finishTransaction
until you have done everything you need to do. If something goes wrong (device battery dies, loss of internet connection, app crash), you will be delivered the same SKPaymentTransaction
from the payment queue next time your observer is registered with the queue, and can try to sync again with your server. This will keep happening until you call -finishTransaction
.
There is a scenario where the user is never able to sync with your server, never connects to internet again etc. That is out of your control, and at that point it is the responsibility of Apple to decide whether they charge the user.
It's also worth noting that the user can contact Apple and request a refund if they wish to.