I've setup a monthly subscription with a 1-month free trial and I've also set my Play Store email as a tester.
When I purchase a subscription, the Android "popup" correctly says that it's a test and that I have a 1-month free trial, so, I keep the "Test card always approve" setting and accept.
Now, the purchase info returned by Montemagno's InAppPurchase plugin (and I've also checked this directly by calling the IInAppBillinService API myself) returns the subscription with a PaymentPending status (a code 0 in the IInAppBillinService return json).
I've also tried a test subscription WITHOUT free trial, which gives the same response.
After every test renew iteration, calling GetPurchases verifies the subscription still says PaymentPending.
I'm at a loss.
How can I verify the subscription is within the free trial period? Does the status ever change to Purchased (1 in the return json) and jow can I test that?
Related
I am working on shifting my existing iOS 10+ app to offer auto-renewing subscriptions.
While "normal" subscriptions (no introductory offer) work fine both within my app and on my server (receipt validation and user account handling) I am having a hard time to understand how a free trial period can be offered.
Setting up the free trial period in App Store Connect is no problem, but I do not understand how to implement it in my app and on my server.
Problem 1 : Understanding eligibility
From the Apple docs:
You can make introductory offers to customers who haven’t previously
received an introductory offer for the given product, or for any
products in the same subscription group (...)
Before offering introductory price, you must first determine if the
user is eligible to receive it (...)
To determine if a user is eligible for an introductory offer, check their receipt...
Assume I have setup a subscription with a 7 day free trial. A user purchases this subscriptions, uses the free trial and continues the paid subscriptions for a while before the subscription is canceled. Some time later the wants to continue the subscriptions
What happens if the user purchases the same subscription product again?
Will fail because he has already used the free trial? ("... who haven’t previously received an introductory offer...")
Will it start with another free trial period? (== Store does not check the eligibility at all)
Will it start with no free trial but directly with a payed period
In other words:
Is checking the eligibility only necessary to show the right UI (= grant offer yes/no is checked by store) or to make sure the user does not benefits from the same offer (= grant offer yes/no is checked by app)?
Problem 2 : How to check eligibility?
As described in the apple docs the best way to check the eligibility is to validate the app receipt and to check whether an introductory offer has been received or not. This should be done as early as possible, at app start at best.
Fine, but as far as I know the receipt is not guaranteed to be available. If no receipt can be found the user has to first provide his app store credentials to download the receipt...
It would be quite annoying if the first thing the app does on the the first start would be to ask the user to login to the store.
Is this really the intended implementation?
Problem 3 : How to handle eligibility?
Assume that I have successfully check whether the user is eligible to receive an offer or not: How to provide the offer?
Do I have to setup two different subscription products in App Store Connect (one with free trial and one without) to let the user purchase the one or the other?
Or the eligibility check only necessary to display the correct UI ("Purchase now with free trial" vs "Purchase now") while I can use the same product in both cases?
Problem 1 : Understanding eligibility
He will be charged for the subscription immediately. Free-trial can be availed only once
Problem 3 : How to handle eligibility?
Do I have to setup two different subscription products in App Store Connect (one with free trial and one without) to let the user
purchase the one or the other?
No. You only need to setup one product and add Introductory offer (free trial or intro offer)
Or the eligibility check only necessary to display the correct UI ("Purchase now with free trial" vs "Purchase now") while I can use the same product in both cases?
It is only for showing correct CTA and messaging. At the end of the day, Store(Apple) is the one who is taking the decision if user will get free-trial or not
To check eligibility of the user you need to pass the receipt to your server. Your server can then query Apple for the decoded receipt (/verifyReceipt endpoint). In decoded receipt, check all the txn in latest_renewal_info list. if you find is_in_free_trial field to be true for any product in same subscription group then you can safely assume that user has used free trial before and show right messaging to the user.
Also, user can get free trial only once per subscription group even if all the products under that have free trial enabled.
I agree that Apple would have provided eligibility in the app itself while querying the product. But trust me none of the App stores provide this information including Google.
As far as login is concerned, the receipt is always present at a sandbox location and can be retrieved from there. (Also, do consider that user anyway can't buy the subscription if he is not logged in)
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.
I've been implementing auto-renewing In App Purchases and, using the info found here, have had little trouble the purchasing, renewing, & restoring transaction flows.
The problem I am having is finding a way to test when a user renews (after, presumably, canceling some time in the past) from their account page in either iTunes or the App Store app (Detailed here). I'm assuming, since those exist outside of the sandbox and when you log into one of them using a sandbox account that account is invalidated as a test account, there is no way to actually test this use case so I'm just looking for more information on the expected behavior to try and account for it.
I know that keeping a copy of the receipt around to validate will give the latest receipt as part of the JSON payload, I'm more curious for information on how StoreKit will handle this renewal. Will paymentQueue: updatedTransaction: fire with a new SKPaymentTransaction as soon as I add a TransactionObserver or will it stay silent until calling restoreCompletedTransactions and then the new SKPaymentTransaction will be part of that?
Yes, you are correct; paymentQueue:updatedTransactions: will fire, just as if you were making the initial subscription purchase.
You can actually test this since renewals within the sandbox kick in at a much faster pace (up to six times a day) as explained here (scroll down to the bottom under "The Test Environment").
Also when you verify the transaction with Apple's verification service right after you made a test subscription purchase, look for the expires_date field in the response, it will tell you when the next renewal will be triggered.
I've been reading the various threads on in-app purchases auto-renewal subscriptions, and I think I've pieced together most of the information I need, but there are a few missing pieces. I'm hoping someone can help me.
The situation:
I have various subscription packages the user can subscribe to (e.g., package A for £1 a month, package B for £2 a month, etc.). I store the user's subscription information in my database. When the user logs in, I check which package he's on and if it's expired or not. My website, android and iOS all use the same database, hence this approach seems to make sense.
Subscribing users via in-app purchase seems straight forward enough. I check paymentQueue and once the payment is cleared, I can update my database.
My questions:
1) My understanding is the user can use iTunes to manage their subscription. Say, they go in to iTunes and cancel their subscription, how can I be notified so I can update my database? Do I need a daemon that checks expired subscriptions to see if the user renewed?
2) If the user wants to upgrade their subscription from Package A to Package B, how do I handle the pricing? Say on Jan 1st, they buy Package A, I charge them £1.00 and set the expiry date to Jan. 31st. On Jan. 15th, they want to upgrade to package B via in-app purchase. Ideally, I would charge them £2 for Package B minus £0.50 of credit they have for Package A and set the new expiry date to feb 14th. However, Apple forces me to associate each package with a tier price. How can I handle this? I don't want the user to wait until the end of the month to put them on a higher tier package...if they upgraded mid-month, it means they want the new content package B will deliver to them immediately.
Any help appreciated!
Thanks!
1) Yes you'll have to reverify your receipt check out the Receipt Validation Programming Guide in the documentation. They mention some important keys:
status - 0 if receipt is valid, or an error code
receipt - JSON response of the receipt
latest_receipt (auto-renewable only) - base 64 encoded receipt for the most recent renewal
latest_receipt_info - JSON version of latest_receipt
With this information, when a purchase is made, send the receipt to your backend for validation, the backend will keep the receipt in the DB and verify with status = 0 that it's a valid receipt. From there, every x days you can validate that receipt with a chron job, daemon, etc. and reverify. The response back each time will have latest_receipt_info that you now need to save to your DB so you have an up-to-date receipt for the next check in x days. This way you will always have the latest receipt. There is no instant notification for telling when a user cancels a subscription, but with this you'll know every x days if they have the subscription still.
2) Pricing like this unfortunately can't be handled. It was not intended for a user to "upgrade" with subscriptions - each subscription is access to it's own exclusive content as of this writing. However, if a customer emails in and complains about it, you could ask for their user name and figure out in your DB if this user has indeed upgraded mid-month and reimburse them appropriately. Very old-school and not feasible for a big user base, but hopefully you won't have that many and can keep them happy.
EDITED
For the second question, Apple's auto-renewable subscription system does not technically offer upgradeable plans between different products.
Every subscription is a stand alone product and it's up to the user to turn on/off subscriptions manually using the Subscription Manager in the iTunes Store.
However if package A and package B offer the exact same content only different duration than what ajay_nasa said is correct, you can create an single auto-subscription product with different duration options. If the user is on 1 month subscription and then the user tries to change to 2-months subscription they will get the following error message asking them go to the App Store's subscriptions manager
So basically the ONLY place the user can actually change the subscription's length is in the App Store. Whether Apple decide to pro-rate the amount left on the old subscription or just append it to the current one is really up to Apple. You need to make sure the user have access to the subscription as long as it's active by reading the Original Purchase Date and Subscription Expiration Date field from each receipt entry and determining the start and end dates of the subscription.
Answering question 1, you can verify subscription receipts in the same way as other IAP, but you'll need to check it periodically to see if the subscription has expired (the verification will tell you if it's expired).
There is more info on the Apple docs here:
http://developer.apple.com/library/mac/#documentation/NetworkingInternet/Conceptual/StoreKitGuide/RenewableSubscriptions/RenewableSubscriptions.html
Actually, Apple's auto-renewable subscription system does offer upgradeable plans.
To achieve this we simply should add duration in existing Auto-Renewable Subscription. Every Auto-Renewable Subscription could be family of Subscriptions so whenever developer wants to achieve upgradation in subscription he should add duration in existing Auto-Renewable Subscription with different productID.
Whenever, user upgrade his plan in between the month then his upgrade plan will be automatically works from next month.
Answering to your question #1
Recently Apple launched a feature to enable server notification whenever the subscription is renewed. However, the subscription should be in-app.
See the links given below for your reference:
https://help.apple.com/itunes-connect/developer/#/dev0067a330b
&
https://itunespartner.apple.com/en/apps/news/45333106?sc_cid=ITC-AP-ENREC
We Need to Check Cancellation-Date provided in Receipt.
I am looking to build a ios application that will use an auto-renewable subscription on a monthly biases. We will be using some VOIP features that we will be charged monthly for. My question is, how can we be notified when a user cancels a subscription in IOS, so that we can cancel the users VOIP telephone number with our provider.
You will need to verify the receipt the same way you do for regular In App Purchases, but obviously you will do this every time the subscription period expires. Check out the documentation on this, Verifying an Auto-renewable Subscription Receipt
So based on this, it appears you will need to setup your server to check for a valid subscription every month (cron job?). This will allow you to cancel the VOIP number in your system if the subscription is no longer valid. Your app would be responsible for verifying a subscription is still valid when it is opened or the user attempts to access features that require a subscription.
Updated For Comment
The sandbox is supposed to return expiration dates in the following scheme.
This is from page 164 of the iTunes Connect Developer Guide
If it is not working this way you may want to file a bug report.
Also, please not the following from Apples IAP doc:
Additionally, a sandbox subscription will only autorenew a maximum of 6 times. After the subscription has auto-renewed 6 times, it will no longer renew in the sandbox.