transactionReceipt for in-app purchase is deprecated in iOS 7. What can I replace it with?

16,180

Solution 1

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.

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

Share:
16,180

Related videos on Youtube

user_Dennis_Mostajo
Author by

user_Dennis_Mostajo

Updated on June 04, 2022

Comments

  • user_Dennis_Mostajo
    user_Dennis_Mostajo almost 2 years

    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

    • Alexandr Kurilin
      Alexandr Kurilin over 10 years
      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.
  • Sagi Mann
    Sagi Mann over 10 years
    what if there is more than one transaction?
  • bmueller
    bmueller over 10 years
    Heads up - if you haven't yet completed a purchase with your test account with this app, the appStoreReceiptURL will return nil.
  • jhabbott
    jhabbott over 10 years
    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.
  • Protocole
    Protocole over 10 years
    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.
  • capikaw
    capikaw over 10 years
    Be aware that the method to decode [NSData dataWithContentsOfURL:[[NSBundle mainBundle] appStoreReceiptURL]] is different than that of transaction.transactionReceipt.
  • user102008
    user102008 over 10 years
    @capikaw: can you elaborate?
  • capikaw
    capikaw over 10 years
    @user102008 Check out my answer here. mluisbrown's video link would be a great place to get some quick n' easy info, too.
  • NachoSoto
    NachoSoto about 10 years
    The appStoreReceiptURL property is for the app itself, not for IAPs.
  • Dave Peck
    Dave Peck about 10 years
    What @jhabbott said -- appStoreReceiptURL is not what you're looking for.
  • Voxar
    Voxar over 9 years
    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. developer.apple.com/library/ios/releasenotes/General/…
  • gnasher729
    gnasher729 over 8 years
    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.
  • OmniBug
    OmniBug almost 7 years
    How could i get the receipt for the specific transaction from appStoreReceiptURL ?