问题
I have requested a refund on my own app’s monthly subscription. Apple gave me the refund. But my subscription is still active and I can use the premium features.
My app is checking the validity of the receipt every time I use it, this proves that the receipt's expiry date has remained valid.
This is how I check for it. Although it is in Python on my server, I hope the code is clear enough for anyone to understand:
def verify_receipt(receipt):
r = requests.post(config.APPLE_STORE_URL, json=Subscription.produce_receipt_with_credentials(receipt))
now = datetime.utcnow()
if 'latest_receipt_info' in r.json():
for item in r.json()['latest_receipt_info']:
dt, tz = item['expires_date'].rsplit(maxsplit=1)
expires_date = datetime.strptime(dt, '%Y-%m-%d %H:%M:%S').replace(tzinfo=pytz.timezone(tz))
expires_date = expires_date.astimezone(pytz.utc)
expires_date = expires_date.replace(tzinfo=None)
if expires_date > now:
return True, expires_date, r.json()['latest_receipt'], item
else:
current_app.logger.info('latest_receipt_info not found: %s', r.json())
return False, None, None, None
Essentially I'm checking within the collection of ‘latest_receipt_info’ for each receipt's ‘expires_date’. If at least one of them is set in the future, then the premium check is valid.
But in my case even though that Apple has refunded the subscription, they left it active until the next renewal.
So what is the point of checking the receipt regularly then? If we can't catch early cancellation?
Wouldn’t be more efficient and faster for the existing users to just save the expiry date in UserDefaults and check locally when the expiry date has expired and then check for the validity of the next receipt?
SWIFT:
UserDefaults.standard.set(expiryDate, forKey: Constants.expiryDate)
UPDATE:
So based on the answer I have received, I suppose the cancellation_reason
and cancellation_date
will be next to these fields in the latest receipt?
"latest_receipt_info": [
{
"quantity": "1",
"product_id": "com.x.sub.weekly",
"transaction_id": "100000053x",
"original_transaction_id": "100000053x",
"purchase_date": "2019-06-03 19:52:05 Etc/GMT",
"purchase_date_ms": "1559591525000",
"purchase_date_pst": "2019-06-03 12:52:05 America/Los_Angeles",
"original_purchase_date": "2019-06-03 19:52:06 Etc/GMT",
"original_purchase_date_ms": "1559591526000",
"original_purchase_date_pst": "2019-06-03 12:52:06 America/Los_Angeles",
"expires_date": "2019-06-03 19:55:05 Etc/GMT",
"expires_date_ms": "1559591705000",
"expires_date_pst": "2019-06-03 12:55:05 America/Los_Angeles",
"web_order_line_item_id": "10000000x",
"is_trial_period": "false",
"is_in_intro_offer_period": "false"
"cancellation_reason": "0",
"cancellation_date" "2019-06-03 21:55:05 Etc/GMT"
},
I wished there was a way to emulate this. How can I code against this based on the docs and go to production without being really able to test it?
回答1:
For refunds you need to check the cancellation_reason
field which will indicate that customer support refunded the user. There will also be a cancellation_date
that will indicate when the cancellation occurred.
If that field is present then your premium check should be invalid:
Treat a canceled receipt the same as if no purchase had ever been made.
来源:https://stackoverflow.com/questions/56440302/how-to-check-if-a-subscription-has-been-cancelled