Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When transaction ID is changing in iOS7 app receipt?

For iOS 6.1 or earlier, in-app purchase transaction ID received after purchase or restore is unique each time and original transaction id never change, even after restore.

However, for iOS7, transaction id and original transaction id is always same! I even tried to refresh receipt, delete app from device and put it back again. Both fields are always same.

Does anyone know in which cases transaction id will change? My server logic was relying on unique transaction ID from receipt itself, which currently doesn't work in case of iOS7.

Following is app receipt decrypted by Apple server. Same result if I decrypt it locally.

{
    environment = Sandbox;
    receipt =     {
        "adam_id" = 0;
        "application_version" = "1.0";
        "bundle_id" = "com.###";
        "download_id" = 0;
        "in_app" =         (
                        {
                "is_trial_period" = false;
                "original_purchase_date" = "2014-02-18 14:23:40 Etc/GMT";
                "original_purchase_date_ms" = 1392733420000;
                "original_purchase_date_pst" = "2014-02-18 06:23:40 America/Los_Angeles";
                "original_transaction_id" = 1000000101860870;
                "product_id" = "com.###";
                "purchase_date" = "2014-02-24 09:12:21 Etc/GMT";
                "purchase_date_ms" = 1393233141000;
                "purchase_date_pst" = "2014-02-24 01:12:21 America/Los_Angeles";
                quantity = 1;
                "transaction_id" = 1000000101860870;
            }
        );
        "original_application_version" = "1.0";
        "original_purchase_date" = "2013-08-01 07:00:00 Etc/GMT";
        "original_purchase_date_ms" = 1375340400000;
        "original_purchase_date_pst" = "2013-08-01 00:00:00 America/Los_Angeles";
        "receipt_type" = ProductionSandbox;
        "request_date" = "2014-02-24 09:12:56 Etc/GMT";
        "request_date_ms" = 1393233176903;
        "request_date_pst" = "2014-02-24 01:12:56 America/Los_Angeles";
    };
    status = 0;
}
like image 760
Pablo Avatar asked Feb 24 '14 09:02

Pablo


People also ask

Do transaction ID change?

The transaction ID is always unique, which means that there are no transaction IDs that are the same. This transaction key is usually generated after the system defines it as a successful one.

How to validate receipt in-app purchase?

To test receipt validation, you must run the app on a real device, as it won't work in the simulator. You'll need a Development Certificate and a sandbox account. When testing an app through XCode, the app won't have a receipt by default.

What is a transaction ID?

A transaction ID is a number generated from the electronic transfer of funds. It's a unique identifying number, meaning that no two transaction ID numbers are identical. These numbers can take many forms and are generated with every card transaction.

What is receipt validation in-app purchase?

The Receipt Verification Service (RVS) enables validation of purchases made by your app's users.


1 Answers

Transaction dates are updated correctly

We can make use of the observation that the transaction dates are updated correctly (even in the Sanbox environment and surely in Production):

"in_app":[{"quantity":"1", "product_id":"###",
    "transaction_id":"1000000122762089",
    "original_transaction_id":"1000000122762089",
    "purchase_date":"2014-09-07 16:15:13 Etc/GMT",
    "purchase_date_ms": "1410106513000",
    "purchase_date_pst":"2014-09-07 09:15:13 America/Los_Angeles",
    "original_purchase_date":"2014-09-07 05:35:16 Etc/GMT",
    "original_purchase_date_ms":"1410068116000",
    "original_purchase_date_pst":"2014-09-06 22:35:16 America/Los_Angeles",
    "is_trial_period":"false"}]

You can see that purchase_date_ms and original_purchase_date_ms differ.

Therefore: enforce uniqueness of the combination of transcation ID and date

Not only store the transaction ID but also the purchase date (not original purchase date) in your server database. The combination of those two values will not exist in your database for a legitimate restore transaction, but will collide with an existing record if the receipt is a replay.

Note that we are looking a response from the validation server, which means that clients won't be able to vary the date, just as they aren't able to vary the transaction ID without breaking the validity of the receipt.

like image 126
s.bandara Avatar answered Sep 28 '22 13:09

s.bandara