4

After calling restoreCompletedTransactions, for a non-consumable, the SKPaymentTransactions that are being returned seem to have nil in their originalTransaction.transactionReceipt property. This is where the documentation says we should find the original transactionReceipt:

https://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/StoreKitGuide/MakingaPurchase/MakingaPurchase.html#//apple_ref/doc/uid/TP40008267-CH3-SW2

Has anyone actually got this to be not nil - and if so, how?

In the returned SKPaymentTransactions, it looks like the actual correct transactionReceipt is in their transactionReceipt property (rather than their originalTransaction.transactionReceipt property).

delany
  • 3,371
  • 4
  • 23
  • 17

3 Answers3

3

It has happened to me as well.

It's weird, but even though Apple states in its documentation that the transactionReceipt is found in originalTransaction, I found the transactionReceipt in the original SKPaymentTransaction class.

So, I have set up a little check before choosing which transaction to pass onwards:

SKPaymentTransaction *passedTransaction = nil;
if (transaction.transactionReceipt) {
    passedTransaction = transaction;
} else if (transaction.originalTransaction.transactionReceipt) {
    passedTransaction = transaction.originalTransaction;
}
Alex
  • 7,432
  • 20
  • 75
  • 118
  • Thanks for this. Definitely seems like an error in the iOS SDK, but at least this allows us to verify the restored transactions. – Michael Jan 28 '14 at 04:50
  • Code is wrong. The type of 'transaction.transactionReceipt' is NSData*, not SKPaymentTransaction*. I'll leave it to you to rewrite, as there are two possible rewrites. – CuriousGeorge Jun 23 '16 at 20:54
2

I also ran into the same issue. It would seem that the transactionReceipt on the originalTransaction will always return nil when restoring purchases. From the Discussion in the apple docs for transactionReceipt:

Discussion
The contents of this property are undefined except when transactionState is set to SKPaymentTransactionStateRestored.

Since during a restore (of a consumable item) the transactionState is always set to SKPaymentTransactionStatePurchased, the originalTransaction.transactionReceipt property will always be nil.

Nhat Dinh
  • 3,378
  • 4
  • 35
  • 51
michaelFG
  • 21
  • 1
  • 1
    Documentation states: "except when `transactionState` is set to `SKPaymentTransactionStateRestored`" https://developer.apple.com/library/ios/documentation/StoreKit/Reference/SKPaymentTransaction_Class/Reference/Reference.html#//apple_ref/occ/instp/SKPaymentTransaction/originalTransaction Still have the same problem – Maciek Czarnik Oct 16 '13 at 11:43
  • Not only that, but originalTransaction is not identical to the original transaction! –  Jul 10 '14 at 04:02
  • @michaelFG Although NSLog states that transaction.originalTransaction.transactionReceipt is null, when I pass this value into a [NSUserDefaults standardUserDefaults] variable, the correct receipt is added. Twilight zone... – Charles Robertson Jan 22 '17 at 17:50
  • @michaelFG Forget that comment. I had another code snippet which I had forgotten about, which actually uses transaction.transactionReceipt, as a back-up, to populate the relevant [NSUserDefaults standardUserDefaults] receipt variables. So, yes, we should use transaction.transactionReceipt NOT originalTransaction.transactionReceipt for our restore purchases routine. – Charles Robertson Jan 22 '17 at 18:22
0

I've found that that transactionID for original transaction is random. For different transactions can be the same original and you shouldn't rely on original transaction if this is not restoring the purchases.

Example from sandbox https://file.io/ReprC88b2K8Q. Check transactionID for original transactions.

Nike Kov
  • 12,630
  • 8
  • 75
  • 122