iOS In App Purchase Non Renewing Subscription Receipt Validation - ios

I am trying to understand if it is possible (or not), from within an app targeted at iOS7, to check if a Non Renewing Subscription receipt has been cancelled by Apple?
I thought there was a way to check for a Cancellation Date in the receipt, however, I can't see how you can re-request a Non Renewing Subscription receipt?
Any advice greatly appreciated.

For information, I have found that if a receipt is verified against the AppStore servers there is a field cancellation_date within the formatted data from the receipt that is returned.
So, if you post the receipt from your main bundle up to Apple to verify, the returned data will show any cancellation date. If this date is present Apple state to treat the transaction as never having occurred. See here for more details https://developer.apple.com/library/ios/releasenotes/General/ValidateAppStoreReceipt/Chapters/ReceiptFields.html#//apple_ref/doc/uid/TP40010573-CH106-SW1

Related

StoreKit Subscription with free trial not present in receipt after purchase (tx id off by 1)

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:
I purchase a subscription that is returned to my application with a transactionIdentifier of 1000000506350685 and originalTransaction.transactionIdentifier of null.
I get the latest JSON receipt from Apple whose latest entry is one matching my product identifier and timestamp, but the 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.

how to detect the renewal status in apple auto subscription development?

there is a way if the server verify the receipt the apple will return the latest_receipt_info which contains the expires_date of auto subscription.But what time and what way to do this check? everyday the server to do this check or the app to do this when it's opened,should I always take the first buy receipt to post http://buy.itunes.apple.com/veriryreceipt for get the latest_receipt_info?
https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/StoreKitGuide/Chapters/Subscriptions.html
is there a good way to check the renewal status?

iOS - how should i make sure the IAP receipt is valid

I want to offer a renewable subscription in my iOS application. The user subscribed and the receipt is stored. Now i wonder how i need to make sure that the receipt is valid and not cancelled:
If the user cancels the subscription and it is not renewed, how would i know it? If the subscription is renewed, when a new receipt will be created?
If the user cancels the subscription through apple support (because, for example, he bought it my mistake), how can i know it? The receipt on the device will be valid. Should i refresh the receipt every time the user logs in?
EDIT:
I forgot to mention it, but the receipt is checked in the client side.
Generally you need to check the expiration date of the subscription. To do that you need to get the receipt list and find the most recent record. It could be done using several ways (iOS Restore in App purchases with receipts)
If user cancels the subscription, I believe it means that receipt list simply will updated and you can find this by reading the 'cancellation date' field. To get track the expiration date I'd recommend to use UILocalNotification. If user continues to use subscription and you doubt whether he prolonged it or not, you should update the receipt list and send request to Apple [[SKPaymentQueue defaultQueue] restoreCompletedTransactions]
If user cancel the subscription through apple support , you can find the corresponding record (aka "Cancellation Date") in the receipt data. Please read (https://developer.apple.com/library/ios/releasenotes/General/ValidateAppStoreReceipt/Chapters/ReceiptFields.html).
I'd recommend to check the receipt from time to time or use a notification mechanism.

How do I know if a user cancels an auto renewing subscription with In-App Purchases on iOS?

I have been testing out Apple's In-App Purchases (sandbox mode) which is great for testing what happens when a user subscribes, but how do I tell if the user is still paying? How do I know if the subscription has been canceled? Apple doesn't appear to let me test that out?
I see that there is something about verifying receipts? How can I do this?
When you subscribe a auto-renewable subscription from app, you will get a receipt. Send that receipt to your server and your sever can use that receipt to verify if your purchase is valid from iTune store (check their doc)
You will get a JSON response and some field inside can show you the expired date.
As to user's cancel, sorry, you cannot know that until current period expire (actually you will know that 24 hours before expiration due to apple store's mechanism)
Hope this helps.
[Updated # 2017/11/5]
Now Auto-renewable subscription is allowed to notify your sever when new period begins. Please check latest document.

How does Apple notify iOS apps of refunds of in-app purchases (IAP)?

I have Apple iOS IAP successfully implemented in my app and tested in the sandbox. Works great.
I'm concerned that users could buy something with IAP, download it into my app, then complain to Apple and get a refund. There's no obvious way that refunds are reported to my app. Are they simply left out of the list of products I receive during a "restore" operation? Is there some undocumented transaction type that will asynchronously show up in my SKPaymentTransactionObserver when a refund occurs?
Right now I'm operating on the assumption that I need to delete the user's IAP transactions before doing a restore, and that anything refunded will just not be in the list of restored transactions. Is this the right way to do it? Is there any way to test this in the sandbox?
Has anyone seen refunds in a production environment and can explain how they work?
Update June 24, 2020:
At WWDC 2020, a new notification was introduced that informs you of refunds: https://developer.apple.com/documentation/storekit/in-app_purchase/handling_refund_notifications
Original answer:
I received a response from Apple Developer Relations today (Dec 6, 2018):
Hello Johannes,
In response to your question, unfortunately, there is no supported means to detect that the user has contacted Apple Care and received a refund for the In-App Purchase of a consumable item. The only option which I can refer you to is to submit an API enhancement request for an API to be made available for an app to detect that a refund was provided to a user of an In-App Purchase. Currently, this support is realistically only available to apps which offer auto-renewable subscription In-App Purchase.
You can submit the enhancement request using the Apple Developer Bug Report web page - http//bugreport.apple.com
As this is an enhancement request type issue, I'm going to arrange for this incident to be unbilled from your account for use on a future issue.
So there we have it.
The in-app purchasing guide discusses the concept of "cancellation" of subscriptions. This is the only place I've seen discussing the subject.
Further details about the cancellation date field can also be found in the App Store receipt validation documentation.
cancellation_date
After decoding a receipt, you can get the cancellation date which will tell you the following:
For a transaction that was canceled by Apple customer support, the time and date of the cancellation.
The strategy is:
You save the latest_receipt ("MIIUJgYJKoZIhvc..." base64) field in your DB, associated with the user account.
Every day you query apple to validate all the receipts, by sending them the base64 receipt from saved latest_receipt field.
In the receipt you check if there is a cancellation_date field. If you find it, treat it according to documentation:
Treat a canceled receipt the same as if no purchase had ever been made.
Same way you also checking subscription renewals (check expires_date_ms field).
Refunds are given, but your app gets no notification of them at all. Whether it's an In-App Purchase, an app download or any other iTunes content, the user can still use the content even if they have asked for a refund.
In iOS 14 a new method is added to the SKPaymentTransactionObserver protocol that is called when the user is no longer entitled to one or more in-app purchases ๐Ÿ‘‰ https://developer.apple.com/documentation/storekit/skpaymenttransactionobserver/3564804-paymentqueue
Although the documentation doesnโ€™t tell in which situation this method is called, Apple does tell this in this WWDC2020 video at 26:55 ๐Ÿ‘‰ https://developer.apple.com/videos/play/wwdc2020/10661/
According to latest documentation, server to server notification with type CANCEL is now handling cancel scenario by Apple customer support.
Starting October 21, 2021, App Store Server Notification Version 2 became available and the notificationType in the notification payload will be returned with REFUND when the App Store refund process is completed.
See below for more information.
https://developer.apple.com/documentation/appstoreservernotifications/app_store_server_notifications_v2

Resources