Auto-renewal Subscription in App purchase - ios

I am working on a project for that I need auto-renewal subscription. I am done with back-end work but now my doubt is, "how to get status of subscription. If user cancels or turns off the auto-renewal before renew the subscription". Please help.

You need to parse the receipt of the in-app purchase to check the expiration date. You can parse it yourself from the NSBundle.mainBundle().appStoreReceiptURL or you can send it to apple and parse it from JSON response. See Receipt Validation guide

I have implemented a small library to simplify to work with In-App Receipt locally. You can easily fetch the object that represents the receipt (InAppReceipt) and retrieve an active purchase/all purchases.
Feel free to use. Github link
Here is an example of solving your problem:
import TPInAppReceipt
do {
let receipt = try InAppReceiptManager.shared.receipt()
//retrive active auto renewable subscription for a specific product and date
let purchase = receipt.activeAutoRenewableSubscriptionPurchases(ofProductIdentifier: "ProductName", forDate: Date())
//retrive all auto renewable subscription purchases for a specific product
let allAutoRenewableSubscriptionPurchases = receipt.purchases(ofProductIdentifier: "productName").filter({ return $0.isRenewableSubscription })
} catch {
print(error)
}

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

Non-renewing sbuscription in iOS

I want to implement InApp purchase in my iOS video streaming app to do that I need to implement Non-renewing subscription e.g 1 month,3 months, 6 months and 1 year.
I am using Objetive-C in my application.
Can you please tell me how to implement it because as per Apple, developer need to manage subscription expiration date and time.
How to validate receipt ??
How to manage user's subscription on multiple device or restore user's subscription if user login on other device ??
Please help me and let me know if anything is required in Non-renewing subscription.
Thanks,
You should go through the in-app purchase programming guide before starting the implementation.
https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/StoreKitGuide/Introduction.html
Store-kit won't send you any notification in case of subscription end for a non-renewable subscription. You need to calculate the duration on your own and revoke the user's access to your server after that duration.
To verify the receipt you can do the validation on user's device or on your server, but your server is preferably better and even recommended by apple also.
For restoring the purchase you can go through the following doc
https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/StoreKitGuide/Chapters/Restoring.html#//apple_ref/doc/uid/TP40008267-CH8-SW9
Non Renewing subscription
First of non renewing subscription is the consumable keys that means once it purchased it just purchased. Keep in mind Storekit doesnot restore consumable products so you have to manage yourself because StoreKit does not do it as it do in Auto-renewable subscriptions and Non-consumable .
More details about Non renewing subscription :
Does Non-Renewing subscription requires a restore button?
How to manage?
To manage your in-app purchase you have to use server DB. You have to store your all purchases in server DB by using post API.
Benefits:
You can easily maintain the end date of purchase.
You can get each paid account every time user logged in with any device.
Note: Maintain your DB according to your need.

Auto-Renewable subscription for in-app purchase

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

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