How to handle auto renewable subscription resubscribe? - ios

I am implementing auto renewable subscription in my iOS application. Monthly subscription auto renews after 5 mins in sandbox mode. I have added transaction observer in appDelegate. So when app restarts updated transaction method gets called and i m getting following logs.
payment store product purchased il_pkg1_1month_2
payment storee product purchased transaction id Optional("1000000792969469")
payment store product purchased il_pkg1_1month_2
payment storee product purchased transaction id Optional("1000000792972183")
payment store product purchased il_pkg1_1month_2
payment storee product purchased transaction id Optional("1000000792976003")
payment store product purchased il_pkg1_1month_2
payment storee product purchased transaction id Optional("1000000792978690")
payment store product purchased il_pkg1_1month_2
payment storee product purchased transaction id Optional("1000000792982052")
My questions are
1)This method is not getting called when app is open and transaction is renewed. is this correct behaviour?
I am planning to implement verification of receipt when this Method is called (on server side). So Suppose when i open app and transaction is auto renewed multiple times.Do i need to implement verify receipt for each transactions or the latest one only? How to verify receipt if app is open and transaction is auto renewed?
3)I have 3 kind of plans in same subscription group. I am not able to upgrade/downgrade in sandbox mode, is it possible to test upgrade/downgrade in sandbox mode?
4)After subscription has expired, if i renew subscription from manage subscription page updated transaction method is called but i m getting same transaction as before renewal.Even transaction expiry date is same as before renewal. Is this correct behaviour, do i need to do any additional things.
Any help would be appreciated.

That is the expected behaviour, also note that with each of the subsequent purchases there is an original_transaction_id so you can tell what the original purchase was.
Whenever you call your server receipt verification, you send up the receipt data the app has currently, and Apple always returns the very latest receipt info. So you can call Apple whenever you like to verify a subscription is still active, or an any subsequent transition to verify a re-subscriptiuon happened. You can also store the data from the app receipt on the server to check from time to time only on the server side, to verify a subscription is still active and has not been cancelled.
I think you used to be able to upgrade/downgrade in sandbox, if not from the sandbox account editing page in device settings, then try by allowing a downgrade/upgrade purchase in your app. At the very least I believe it should work using Xcode 12 App Store configuration local StoreKit testing.
I am not sure if that behaviour you are seeing is normal, If you subscribe after a subscription has lapsed, it should behave like a new purchase - but would still have an original_transaction_id of the original subscription.

Related

Correct workflow to online validate non-consumable in-app purchase receipts on iOS?

What is the correct workflow to online validate the in-app purchase of non-consumable IAPs on iOS?
While I found a lot of information about in-app purchases in general I found no details on how to actually perform online validation.
Is the following workflow correct and complete or am I missing something?
General setup:
iOS app starts purchase by adding an SKPaymentQueue to the payment queue
iOS calls paymentQueue:updatedTransactions: with transaction.transactionState == SKPaymentTransactionStatePurchased when purchase is complete
At this time the app receipt has already been updated and the purchase of the non-consumable item was added.
The receipt data and transaction.transactionIdentifier are send via HTTP POST to my own web service
The web service POSTs the data to Apples /verifyReceipt endpoint
Apples server response with an error if the receipt is invalid or with detailed JSON data if receipt is valid
The JSON Data received from Apple includes information about all prior non-consumable and subscription purchases AND the current consumable purchase.
The information about the consumable purchase can be identified by the product_id field or by using the transaction.transactionIdentifier
The web service adds the purchase to the current user account and/or sends back an valid/invalid response to the iOS app.
If necessary (when the purchase is not stored/handled online) the iOS app can handle the purchase (add coins, or whatever)
The transaction is closed using [queue finishTransaction:transaction]
Additional Observations:
The receipt includes information about all prior non-consumable and subscription purchases AND the current/last consumable purchase.
The information about the current consumable purchase is available until the next purchase (no matter if consumable, non-consumable or subscription).
Restarting the app does not destroy the information about the current consumable purchase
When the app is deleted and re-installed the receipt is empty / does not exist. After restoring previous purchases the receipt only includes information about non-consumable and subscription purchases. No information about non-consumable purchases is restored (no surprise)
Conclusion:
If (for some reason) the receipt cannot send be to the web service (server down, no connection, etc.), this can be retry later. The purchase data will be available within the receipt until the next purchase.
To be able to access the receipt data even after the next purchase one has to implement a custom storage method (e.g. save receipt data to file).
This way the user can be informed about outstanding validations and a retry option can be offered.
Is this a complete and valid workflow to validate consumable in-app purchases online or am I missing some special cases?

ios auto-renewable-subscriptions - simulate cancel operation

I'd like to test CANCEL events...
My understanding is that when users switch between two items within the same group (down/up grades) - the old one is CANCELed and a new one PURCHASEd.
How would I simulate that in a sandbox?
The iTunes SUBSCRIPTION manager doesn't seem to be available on the device when I'm logged into a sandbox account. I'd also like to change subscription status from there also.
You cannot manage subscriptions in the sandbox, but there is nothing special about the upgrade/downgrade process. You just check the in_app field of the receipt as per usual.
For a downgrade, you will receive a purchase event/updated receipt containing the new, lower, subscription product at the end of the current period. If you validate the receipt then you will also see the new product in the auto_renew_product_id that indicates the product that will renew at the end of the current period
For an upgrade, you will receive a purchase event and updated receipt immediately.

IAP Receipt Validation for Consumable Products

I have implemented the IAP for Consumable Products in my app. I have couple of queries regarding validating the receipt. I am going to use my own server which will communicate with apple server.
1.) Does the below url will contain the most recent receipt or all the receipts (even the old ones)?
NSBundle.mainBundle().appStoreReceiptURL
2.) If the above url stores all the receipts then do i need to verify all the receipts whenever user purchase a new product?
3.) Does the user will have access to these receipts if he chooses to reinstall the application?
Refer: In-App Purchase Programming Guide
https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/StoreKitGuide/Chapters/DeliverProduct.html#//apple_ref/doc/uid/TP40008267-CH5-SW16
Information about consumable products and non-renewing subscriptions
is added to the receipt when they’re paid for and remains in the
receipt until you finish the transaction. After you finish the
transaction, this information is removed the next time the receipt is
updated—for example, the next time the user makes a purchase.
Information about all other kinds of purchases is added to the receipt
when they’re paid for and remains in the receipt indefinitely.

How Do I know that auto Renewalbe subscription is cancelled or not?

I am implementing In App purchases in my app ,with auto renewable subscription , Now i am confusing that how i know that when the user is cancelled auto-renewable subscription or not
When user purchase any subscription using in app purchase, apple provide a Receipt for each purchase or transaction. Now you can anytime verify the subscription of user using this receipt. When you will pass this receipt to apple server it will provide you with the user current subscription (if available) along with the current receipt also.
For learning more about receipt validation go through this apple link. May be it will solve your issue.
You need to track the expiration date of the current subscription. If you don't get a new subscription transaction at the start of the next period you can assume that the renewal has been cancelled.
From the In-App Purchase Programming Guide -
After a subscription is successfully renewed, Store Kit adds a
transaction for the renewal to the transaction queue. Your app checks
the transaction queue on launch and handles the renewal the same way
as any other transaction. Note that if your app is already running
when the subscription renews, the transaction observer is not called;
your app finds out about the renewal the next time it’s launched.

How to update a subscription with StoreKit?

I'm trying to work out the best mechanism to handle the auto renewing part so that it handles the continuation of the subscription into the next period.
What the best way of handling this?
Should I have an NSTimer set to check if the current expires_date has been reached .. and then try send a purchase request?
Apple iOS in-app purchases provides the product "Auto-renewable subscription". This product will be renewed automatically by Apple.
When you use this type of product, your app has to verify if the auto-renewable subscription is still valid, since the user might have cancelled the subscription. When an user cancel a subscription, the subscription remains valid until the end of the subscription period.
To validate an auto-renewable subscription, you have to use the purchase receipt and the shared secret generated for your app in-app purchases in iTunes Connect. You have to post this two things to the App Store. This will return a JSON and you have to get from this data the "
subscription's latest purchase date". From that date you have to calculate the expiration date and validate or invalidate the subscription.
You can do all this validation after application launch and/or when the model is updated.
Additional information
You can find information about auto-renewable subscription in Apple documentation. Also, you can check about MKStoreKit, which is a framework that reduces the amount of code that you have to write for the use of StoreKit, and supports Auto-renewable subscriptions.

Resources