I offer a subscription in my application, and after purchase I validate that transaction against the receipt to get its expiration date. I do this by loading the receipt from disk, sending it to Apple for validation/ decryption (I know this is bad practice), and then iterating over the latest_receipt_info
in the JSON response looking for a transaction matching the transactionIdentifier
of the SKPaymentTransction
object.
This works for most subscriptions, but not those offered with a free trial/ introductory offer. Please take a look at my example below:
transactionIdentifier
of 1000000506350685
and originalTransaction.transactionIdentifier
of null
. transaction_id
is 1000000506350686
and so is original_transaction_id
. Therefore I am unable to validate the purchase.
There are no problems when purchasing a subscription without a free trial/ introductory offer. There are no other objects in the returned receipt that matches the transaction id returned to my application.
This is in the sandbox environment, I am not sure about the behavior in production.
Has anyone had any similar experiences? What can I do to fix this?
I think this is probably due to the fact that you've already purchased that product before in Sandbox, and there's no device receipt in sandbox until you make a purchase (unlike production).
Either way, what you should be looking at is the latest product_id
and expiration_date
from the receipt to validate if the subscription is active. Transaction IDs can be keys for your transactions if you're saving them in a database, but shouldn't be used to validate a purchase.
Here is a really good blog post that goes over what your in-app purchase server should be doing to validate and keep subscription status up-to-date: iOS Subscriptions are Hard
I do this by loading the receipt from disk, sending it to Apple for validation/ decryption (I know this is bad practice).
This is actually the recommended approach by Apple.