25

In iOS 7, on the SKPaymentTransaction class, the property transactionReceipt:

// Only valid if state is SKPaymentTransactionStatePurchased.

 @property(nonatomic, readonly) NSData *transactionReceipt

…is deprecated. But, in my code, I created a InAppPurchase class, and in my method for controlling how is the method buying, I'm using the delegate method in my code and it's like:

- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions {

for (SKPaymentTransaction *transaction in transactions) {

    switch (transaction.transactionState) {

        case SKPaymentTransactionStatePurchasing:

                       // code and bla bla bla    
                          [self initPurchase];  
                          NSLog(@"PASO 1");          

            break;

        case SKPaymentTransactionStatePurchased:

                      // this is successfully purchased!
                            purchased = TRUE;
                            NSLog(@"PASO 2");
                           [self isPurchased];

                 NSLog(@"purchased %s", purchased? "true" : "false");

                     //  and return the transaction data

  if ([delegate respondsToSelector:@selector(successfulPurchase:restored:identifier:receipt:)])
  [delegate successfulPurchase:self restored:NO identifier:transaction.payment.productIdentifier receipt:transaction.transactionReceipt];

                     // and more code bla bla bla 

            break;

        case SKPaymentTransactionStateRestored:

                    // and more code bla bla bla 

                          [self restorePurchase];
                          NSLog(@"PASO 3");

            break;

        case SKPaymentTransactionStateFailed:

                    // and more code bla bla bla 

                           [self failedNotification];
                           NSLog(@"PASO 4");

            break;

                    //------------------------------------------//
                    //               THANKS GUYS                //
                    //          GRETTINGS FROM BOLIVIA          //
                    //             ROCK ON!!!! n_n'             //
                    //------------------------------------------//

    }
   }
  }

enter image description here

Pang
  • 9,564
  • 146
  • 81
  • 122
user_Dennis_Mostajo
  • 2,279
  • 4
  • 28
  • 38
  • 2
    Very valuable question. The documentation specific to this very area of StoreKit was changed the same day this question was posted, so it's possible it's still work in progress and Apple will clarify the flow. In the meantime someone looking into this would be very helpful. – Alexandr Kurilin Sep 20 '13 at 00:43

2 Answers2

27

You can get the receipt as the contents of the mainBundle's appStoreReceiptURL. You can find references: developer.apple.com

This is untested code, but off the top of my head, I'd say something along the lines of:

[NSData dataWithContentsOfURL:[[NSBundle mainBundle] appStoreReceiptURL]]

should get you the same result that transactionReceipt used to return.

Pang
  • 9,564
  • 146
  • 81
  • 122
lodlock
  • 3,638
  • 1
  • 19
  • 15
  • 9
    what if there is more than one transaction? – Sagi Mann Oct 09 '13 at 12:17
  • Heads up - if you haven't yet completed a purchase with your test account with this app, the `appStoreReceiptURL` will return nil. – bmueller Oct 30 '13 at 05:14
  • 34
    I can't find any documentation to verify this. The documentation for `appStoreReceiptURL` clearly states that this is for the bundle's App Store receipt (not for in-app-purchase receipts). Also, this doesn't make any sense for in-app-purchase receipts because you might have multiple subscriptions, for example you might subscribe separately to the news, sports and movies channels in a video streaming app. – jhabbott Nov 08 '13 at 05:10
  • 14
    I got different data between `[NSData dataWithContentsOfURL:[[NSBundle mainBundle] appStoreReceiptURL]]` and `transactionReceipt`. For verifying receipt in sandbox, the data of `appStoreReceiptURL` results as an invalid receipt with `"status":21002` but the deprecated `transactionReceipt` is valid with `"status":0`. – Protocole Nov 13 '13 at 07:15
  • Be aware that the method to decode [NSData dataWithContentsOfURL:[[NSBundle mainBundle] appStoreReceiptURL]] is different than that of transaction.transactionReceipt. – capikaw Dec 18 '13 at 17:51
  • 1
    @capikaw: can you elaborate? – user102008 Dec 30 '13 at 21:38
  • @user102008 Check out [my answer here](http://stackoverflow.com/questions/19955352/invalid-transaction-receipt-returned-by-appstorereceipturl-nsdata-in-ios-7?answertab=votes#tab-top). mluisbrown's video link would be a great place to get some quick n' easy info, too. – capikaw Jan 07 '14 at 23:26
  • The appStoreReceiptURL property is for the app itself, not for IAPs. – NachoSoto Mar 04 '14 at 20:21
  • What @jhabbott said -- `appStoreReceiptURL` is not what you're looking for. – Dave Peck Mar 07 '14 at 22:09
  • While the data returned from `transactionReceipt` contains only the receipt for the specific transaction, the data found at `appStoreReceiptURL` is a key-value container format encapsulating a wider range of information. In addition to IAP receipts it also contains the receipt for the app itself as well as the certificate chain and signatures. https://developer.apple.com/library/ios/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateLocally.html – Voxar Dec 16 '14 at 08:34
  • 4
    There's a lot of confusion and a very simple explanation: The receipt that you get from appStoreReceiptURL contains information about _all_ transactions for your application, except that consumables and non-renewable subscriptions are only included once (I believe when the consumable or non-renewable subscription is in your transaction queue). That addresses the confusion about what happens if the user made two purchases: You get two different transactions, but the receipt will contain both of them. – gnasher729 Oct 02 '15 at 10:49
  • How could i get the receipt for the specific transaction from appStoreReceiptURL ? – OmniBug Jun 30 '17 at 08:00
2

In case anyone maybe also confused about this problem (Maybe You also read an a little outdated tutorial like me...)

Please checkout WWDC 2014 Session 305 Preventing Unauthorized Purchases with Receipts. It covers both iOS & OS X, clear and comprehensive.

hewigovens
  • 1,190
  • 11
  • 9