Auto-Renewable subscription for in-app purchase - ios

After buying a product from in-app purchase (Auto-renewable), I hit API on server to give buying information.
How to know that product is re-new for hitting API ?
When user cancel that subscription, how to known that ?

Swift 3: In order for you to detect when the user has cancelled the subscription you need to do the following;
Download the app receipt
Validate the receipt so you can get the json back containing all the in-app purchases and subscriptions dictionaries
Now inside each receipt there is a field in the dictionary called cancellation_date if this is subscription purchase and otherwise not available for other in-app purchases. If this is nil then there's no cancellation occurred, but if this has a value which contains the cancellation date then a cancellation did occurred and according to apple:
Cancellation Date
For a transaction that was canceled by Apple customer support, the time and date of the cancellation.
Treat a canceled receipt the same as if no purchase had ever been made.
then link below explains all the fields you can use inside the receipts;
https://developer.apple.com/library/ios/releasenotes/General/ValidateAppStoreReceipt/Chapters/ReceiptFields.html
Code Example:
// Create receipt request
let receiptRefreshRequest = SKReceiptRefreshRequest()
// Get the receiptUrl from the main bundle
let receiptUrl = Bundle.main().appStoreReceiptURL
//If the receipt file exist on local device
if (receiptUrl as NSURL?)?.checkResourceIsReachableAndReturnError(nil) == true{
// Get the file as data
let receipt: Data = try! Data(contentsOf: receiptUrl!)
}
now you send the receipt to apple server to validate it using your server as apple recommend. After you get callback from the validation you check the cancellation date.

Apple does not provide anything built into iOS or a REST API that gives you simple subscription details, nor are there any callbacks that you can listen for and respond to in regards to renewal or cancellation. Apple does have an API that, when given a user's local receipt and a “shared secret” generated in iTunes Connect, returns a JSON object of the user's purchase history for your app, including their current subscription information.
More Information check this link

Related

auto-renewable subscription renew?

there I am new to auto-renewable subscriptions.
I have implemented the subscription. My problem is if the user buys the subscription for the first time app will go premium. but in any case, his second payment is not happened because of any reason. how did I know that the payment was not successful and or successful? I followed the WWDC tutorial for in-app purchases. implemented with storekit 2.
func purchase(_ product: Product) async throws -> Transaction? {
//Begin a purchase.
let result = try await product.purchase()
switch result {
case .success(let verification):
let transaction = try checkVerified(verification)
print(transaction)
print(transaction.expirationDate as Any)
//Deliver content to the user.
await updatePurchasedIdentifiers(transaction)
if !purchasedIdentifiers.isEmpty{
IAP.premiumEndDate = transaction.expirationDate
}
//Always finish a transaction.
await transaction.finish()
return transaction
case .userCancelled, .pending:
return nil
default:
return nil
}
}
In IAP's apple generate a receipt against each transaction containing a lot of information like a digital signature to validate the purchase, history of transactions including successful and unsuccessful transaction, the current status of the subscription, expiry date, and much more.
You have to validate the receipt by fetching from the Apple server to get all this information. you can check this to know how to fetch receipt data.
for validation, we can go with 2 techniques
On-device validation(validation on the device locally if you're not using server in your app)
Server-side validation(Recommended)
you can read more about choosing receipt validation technique here.
When you fetch receipt it will give you a receiptData and you will convert it to base64EncodedString and hit API for receipt.
For SandBox use https://sandbox.itunes.apple.com/verifyReceipt and for production use https://buy.itunes.apple.com/verifyReceipt. pass it two parameters Receipt base64String and App-Specific Shared Secret you can find App-Specific Shared Secret on App store on the top right corner of your in-app purchases list.
You will receive a response containing all information about the subscription.
Check this video of title Engineering Subscriptions from WWDC 2018. This video is really helpful in understanding subscriptions.

iOS In app purchase: server side receipt validation with multiple purchases of consumable products

Regarding the receipt of IAP consumable products, in the Apple documentation I read: "Information about consumable products 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—e.g., the next time the user makes a purchase".
In a server to server receipt validation scenario, suppose the user buys the consumable product "A" and, due to a server outage, the purchase can't be immediately verified and the corresponding transaction is not finished. Then, suppose the user buys again another "A" product while the server is still not working.
From what I understand the IAP receipt is unique for all purchases and can be retrieved in this way:
let appStoreReceiptURL = Bundle.main.appStoreReceiptURL,
let receiptData = try Data(contentsOf: appStoreReceiptURL, options: .alwaysMapped);
let receiptString = receiptData.base64EncodedString(options: []);
Now, since the receipt is unique and the first transaction is not finished, is the second purchase appended to the first one in the receipt? When it comes the moment to validate the purchases should I send the same receipt to my server for both validation?
Thank you in advance

iOS: can receipts be reused to check for purchases?

is it possible to send an iOS receipt to the server and the server checks periodically with that same receipt if (new) purchases are made? Or are only in app purchases returned up to the point the receipt has been sent to the server?
For my use case I need to check "future" purchases with the same receipt as well, but while testing with sandbox it seems as if only purchases until the time of the receipt are returned from the App Store.
According to the documentation this varies based on the type of you in-app purchases. If your receipt containing auto-renewable subscriptions the response you will receive from apple will contain two additional fields "latest_receipt" and "latest_receipt_info", you can use these fields to determine whether the subscriptions are currently active or not. If your receipt doesn't containing auto-renewable subscriptions than you will only receive the "receipt" field which will be a JSON representation of the receipt that was sent for verification.

Notify server with IOS in-app purchase events (renewed,cancelled..etc)

I'm using auto recurring subscriptions in my app in my app,I need to change the subscription status if recurring fails from iOS.
I am following this documentation, but there are a few things that are still not clear to me:
What if my server missed the post data from iOS
How do I know if the subscription got renewed
How do I link my app user memberId (unique id) to the transaction
What is the difference between latest_receipt form iOS post data(server to server notification) and bundle receipt url after purchase.
Here are the steps I take the user to subscribe:
Ask the user to sign in. If they don't sign in they can't subscribe.
Send the app receipt to my server and store it there. If this fails they can't subscribe. This need this to validate get the latest_receipt info from the server at any time.
The user subscribes through iTunes.
Validate their receipt with the app store and check the latest_receipt to make sure they are subscribed. (This is done server side)
Repeat step 4 periodically to make sure they are still subscribed
So to answer your questions:
What if my server missed the post data from iOS?
Since I get the app receipt from the user before they subscribe I can check the with itunes directly from my sever any time and get the status of their subscription.
How do I know if the subscription got renewed?
Since you have the user receipt on your server, you can use it to get the latest receipt from apple and check the current status of the subscription. Here is how you do it Validating Receipts With the App Store
How do I link my app user memberId (unique id) to the transaction?
You could use the "Original Transaction Identifier" from the receipt as a unique id. This value is the same for all receipts that have been generated for a specific subscription
What is the difference between latest_receipt form iOS post
data(server to server notification) and bundle receipt url after
purchase?
When you send a receipt to the app store to be validated, it will return a JSON representation of the receipt that was send, this can be found in the "receipt" field. If your receipt contains subscriptions you will get "latest_receipt" and "latest_receipt_info" fields. These fields are useful when checking whether an auto-renewable subscription is currently active. If the bundle receipt is up to date then the "receipt" and "latest_receipt" will be the same.

How to manage the InAppPurchase subscriptions

I am doing one application.In that i implemented In App Purchase with Auto renewal subscription.First i subscribed for one month and got the receipt from apple.And when i try to send the receipt to server,due to some problem i am unable to send a receipt to my server.And i didn't store the receipt in my local DB also.Whenever next time i will try to open my application,my server giving the alert like "Please subscribe".So if i try to subscribe once again,apple will again deduct the money or not.Can i get the receipt from the apple.
Every user can only have one subscription at one time. Apple give him an alert that he already has this subscription.
You have to implement subscription restoring option for users. Here is a nice guide in the Apple Docs

Resources