iOS Server Side Validation - receipt types
Asked Answered
C

1

27

I'm getting 2 kinds of receipt formats from Apple when i try to verify purchases on the server.

Any idea what's the difference ?

1)

  content: {
    status: 0,
    receipt: {
      item_id: "662554154",
      original_purchase_date: "2012-10-12 08:32:12 Etc/GMT",
      purchase_date_pst: "2012-10-12 01:32:12 America/Los_Angeles",
      purchase_date: "2012-10-12 08:32:12 Etc/GMT",
      product_id: "com.example.mygame.tool1",
      bid: "com.example.mygame",
      version_external_identifier: "5647854",
      bvrs: "1.0",
      quantity: "1",
      transaction_id: "8844567822225544",
      app_item_id: "659563252",
      original_purchase_date_ms: "1350030732000",
      original_transaction_id: "8844567822225544",
      purchase_date_ms: "1350030732000",
      original_purchase_date_pst: "2012-10-12 01:32:12 America/Los_Angeles"
    }
  }

2)

content: {
  receipt: {
    in_app: [
      {
        is_trial_period: "false",
        original_purchase_date_pst: "2013-10-09 20:55:27 America/Los_Angeles",
        original_purchase_date_ms: "1386571707000",
        original_purchase_date: "2013-10-09 04:55:27 Etc/GMT",
        purchase_date_pst: "2013-10-09 20:55:27 America/Los_Angeles",
        purchase_date_ms: "1386571707000",
        purchase_date: "2013-10-09 04:55:27 Etc/GMT",
        original_transaction_id: "654888452251325",
        transaction_id: "654888452251325",
        product_id: "com.example.mygame.tool1",
        quantity: "1"
      }
    ],
    original_application_version: "1.0",
    original_purchase_date_pst: "2013-10-09 20:55:27 America/Los_Angeles",
    original_purchase_date_ms: "1386569706000",
    original_purchase_date: "2013-10-09 04:55:27 Etc/GMT",
    request_date_pst: "2013-10-09 20:55:27 America/Los_Angeles",
    request_date_ms: "1386571710087",
    request_date: "2013-10-09 04:55:27 Etc/GMT",
    download_id: 215425636588954,
    application_version: "1.0",
    bundle_id: "com.example.mygame",
    adam_id: 654225311,
    receipt_type: "Sandbox"
  },
  environment: "Sandbox",
  status: 0
}
Collyrium answered 9/12, 2013 at 8:55 Comment(3)
Question I have... the _ms timestamps are not unix timestamps are they? When converting 1386571707000 you get Wed, 16 Sep 45908 15:30:00 GMT How the hell does apple want us to validate purchased timeframe?Hagio
@Hagio The timestamp is in ms, you have to divide it by 1000Endymion
developer.apple.com/library/archive/releasenotes/General/…Uropod
R
30

In iOS 6 each IAP (in-app purchase) transaction would have its own receipt (SKPaymentTransaction.transactionReceipt in the StoreKit API). When you send this receipt data over to their validation API, you get the former response.

In iOS 7, Apple has started using something they call the “Grand Unified Receipt”. This means that apps have one receipt that contains information about the purchase of the app itself, as well as IAPs. You use the -[NSBundle appStoreReceiptURL] API to load this receipt data from disk (and possibly SKReceiptRefreshRequest to get it if it doesn't seem to exist). When you send this receipt data over to their validation API, you get the latter response.

The main difference is that the former receipt format represents one IAP transaction, while the latter represents an array of them (as well as the purchase of the application itself).

See more info in the “Using Receipts to Protect Your Digital Sales” WWDC 2013 session.

Rembrandt answered 9/12, 2013 at 15:28 Comment(9)
These receipts are returned from Apple's validation service. Does it return a receipt according to the iOS version on the device?Collyrium
The receipt itself originates from the device — iOS 6 devices get it from SKPaymentTransaction and iOS 7 devices by reading the contents of the file located at -[NSBundle appStoreReceiptURL]. The device then sends the receipt to a server that performs the validation by forwarding the receipt to Apple's validation service, which responds with either of the two examples in the original question (depending on whether the receipt is a "classic" iOS 6 receipt, or an iOS 7+ "Grand Unified Receipt").Rembrandt
Ok. Thanks. But why don't i get an 'environment' indication ?Collyrium
Does anyone know what means field is_trial_period: "false", why it always false ?Prosser
The field is_trial_period is for subscriptions. It will be set to true during the trial period (either 1 week or 1 month) which is applied at the beginning if this option is used. See the options for subscription IAPs in iTunes Connect.Fanatical
@Collyrium In sandbox test account auto-renewable subscription successfully excuted ( initial transaction and + 5 renews after it ) but after that i can not get latest_expired_receipt_info so how I can validate that auto-renewable subscription is expired In Response I get status,environment,receipt,latest_receipt,latest_receipt_info I did not get latest_expired_receipt_infoArmallas
@SimonTillson In sandbox test account auto-renewable subscription successfully excuted ( initial transaction and + 5 renews after it ) but after that i can not get latest_expired_receipt_info so how I can validate that auto-renewable subscription is expired In Response I get status,environment,receipt,latest_receipt,latest_receipt_info I did not get latest_expired_receipt_infoArmallas
@AnkurPatel I'm not sure, mate. Maybe you should ask a new question and provide as much detail as possible so that others may help you. Good luck.Fanatical
@Rembrandt so then how do we validate the most current purchase if it keeps the users entire purchase history?!Huffy

© 2022 - 2024 — McMap. All rights reserved.