Reputation: 2085
I want to validate my iap receipts (both non-consumable and auto-renewable subscriptions) for both iOS 6 and iOS 7.
Since I'm using a server to follow best practices for iOS 6, I want to use it for iOS 7 too (mostly for the subscriptions). It's a newsstand magazine app, so I keep receipt on my server and I want to check which receipts contain valid subscriptions so that I can send push notifications to those users to background download the next issue. For iOS 6 everything is ok, but in iOS 7 there is much confusion.
In the receipt validation documentation it says that to validate an auto-renewable subscription receipt we send the JSON object with the shared secret and we get a response with a specific status.
Does that apply to iOS 7? It's not very clear to me.
The status of an iOS 7 receipt refers to the app receipt itself (not to a specific in app purchase). So then if I have to check each iap entry in the app receipt (eg. to compare the iap expiration date to the current date) will I have to implement app receipt parsing on my server?
Also is there a way to notify which specific purchase I want to check? I'm guessing no.
Will I have to use my server for iOS 6 and on-device validation for iOS 7? And if yes, how? :S
Upvotes: 3
Views: 5732
Reputation: 1530
For iOS7, instead of sending an SKPaymentTransaction
's transactionReceipt
to your server, you would send the app receipt (after base64 encoding it like you would the transactionReceipt
).
You can try running the implementation in this answer to see how to send it and to see the structure of the JSON response you get back from the App Store.
The JSON response has a latest_receipt_info
field with a list of in-app purchases the user has made and info about their expiration, such as:
"latest_receipt_info":({
"quantity":"1",
"product_id":"com.example.subscription_30",
"transaction_id":"1000000097606958",
"original_transaction_id":"1000000097606821",
"purchase_date":"2014-01-01 13:22:25 Etc/GMT",
"purchase_date_ms":"1388582545000",
"purchase_date_pst":"2014-01-01 05:22:25 America/Los_Angeles",
"original_purchase_date":"2014-01-01 11:10:40 Etc/GMT",
"original_purchase_date_ms":"1388574640000",
"original_purchase_date_pst":"2014-01-01 03:10:40 America/Los_Angeles",
"expires_date":"2014-01-01 11:14:35 Etc/GMT",
"expires_date_ms":"1388574875000",
"expires_date_pst":"2014-01-01 03:14:35 America/Los_Angeles",
"web_order_line_item_id":"1000000027707568"},
...)
The JSON response also includes a latest_receipt
field which contains the receipt (base64 encoded) that you can store on your server and send to Apple's verification server just like you do with your stored iOS6 receipt.
It does look like you will need to calculate manually whether there is any active subscription. Maybe something like this (untested):
$desired_product_identifier = <identifier of your in-app purchase>;
$response = <JSON response you get from Apple verification server>;
$receipt = json_decode($response);
$latest_expiration_interval_since_1970 = 0;
for ($receipt_info in $receipt['latest_receipt_info']) {
if ($receipt_info['product_id'] != $desired_product_identifier)
continue;
$expiration_interval_since_1970 = intval(doubleval($receipt_info['expires_date_ms']) / 1000.0);
if ($expiration_interval_since_1970 > $latest_expiration_interval_since_1970) {
$latest_expiration_interval_since_1970 = $expiration_interval_since_1970;
}
}
$is_subscription_active = ($latest_expiration_interval_since_1970 > time());
If this doesn't work and you need to perform local app receipt validation for iOS7 you can check out my github library for autorenewable subscriptions or RMStore. Hope this helps!
Upvotes: 13