I'm implementing google in-app billing on my app. Normally, when a subscription reaches expire time, it will be automatically renewed. A new purchase is made (with the purchase token remain the same)
So, should my app acknowledge this new purchase or can I safely ignore it?
after rereading the google play in app billing documentation (https://developer.android.com/google/play/billing/billing_library_releases_notes#2_0_acknowledge)
"For subscriptions, you must acknowledge any purchase that has a new purchase token. This means that all initial purchases, plan changes, and re-signups need to be acknowledged, but you do not need to acknowledge subsequent renewals. To determine if a purchase needs acknowledgment, you can check the acknowledgement field in the purchase."
so basically, if the subscription is renewed, i don't have to acknowledge it.
i share the answer here for anyone interested in the same topic.
You simply periodically call billingClient.queryPurchases() if you use the billing libray, or mService.getPurchases() if using the AIDL
If the user has renewed the subscription, it will return that the user owns the item, if he decides not to renew it, after the grace period, if any, it will return that he does not own the item.
Related
I am providing levels in app (easy(unlocked),fun,crazy,hard)
want the users to buy only once and when they return they should have subscription.
I achieved it by saving in room database
But if I don't consume purchase it gets refunded. If I consume purchase when user comes back he has to buy again (the restore does not works)
What could be the solution?
If we use Subscriptions they are for specific period of time and user has to pay again for renewal but I want them permanent stick with that user.
For non-consumed purchases you need to acknowledge them or they will be automatically refunded in a couple days.
From the docs:
Note: If you do not acknowledge a purchase within three days, the user automatically receives a refund, and Google Play revokes the purchase.
In the Android Developer Console, I saw this message
Resubscribe isn't currently available for your users because your app
does not use Billing Library 2.0 in all active APKs
But, I was puzzled. Currently, we are using Billing Library 1.2.2.
This is how we decide, whether to show subscription button to user or not.
During queryPurchases, We will perform List<Purchase> purchases = PurchasesResult.getPurchasesList(). If the subscription's SKU is not found in purchases, we will show the subscription button. If not, we will hide the subscription button.
If this is a new subscriber, there will be no SKU in his purchases. Hence, he will see the subscription button, and allowed to subscribe again.
If this is a previous subscribed, and already cancelled user, we assume there will be no SKU in his purchases too!!! Hence, he will see the subscription button, and allowed to subscribe to the same sku again.
As you can see, even with old Billing Library 1.2.2, we are still allow user to resubscribe to same SKU again, to his previous cancelled subscription.
If that is so, why there is a special feature called "Resubscribe" (https://developer.android.com/google/play/billing/subs#resubscribe) in Billing Library 2.0? How does it different from our current Billing Library 1.2.2 flow?
To be perfectly honest, there isn't any enormous difference between resubscribing to the same sku with old and new approach using the resubscribe feature. Why? (None of these are solidly tested by the way, this is a logical explanation.)
In both cases, the subscription elements will stay the same and they will both return in queryPurchases method as long as the subscription is active.
This relates to the queryPurchases method, I haven't tested this yet, but it is possible that, in the old way, multiple purchases with the same sku might return, which may create a confusion. After resubscribing while canceled subscription is still active, the queryPurchases method will return only 1 subscription, causing queryPurchaseHistoryAsync method to return nothing. In the old way, if queryPurchases method returns only 1 purchase after getting a subscription over a canceled subscription with same sku, queryPurchaseHistoryAsync might actually return the old subscription that was canceled for, even if it was still active in a canceled state.
On Google Play Developer API side, there is a method that links a purchase token to the older one. For this, the Purchase.getLinkedPurchaseToken() function might return different values after subscribing to same sku, between the old way and new way. I presume, resubscribing to an active canceled subscription with the old way will generate a new purchase token, and getLinkedPurchaseToken(). This does not affect the BillingClient itself since there is no getLinkedPurchaseToken() method but logically this should be the result.
Bottom line: The only difference I can say is that resubscribing with the new way might reduce confusions, while on the old way there might be unnecessary data that you want to avoid from. As long as you have a subscription that's returned from queryPurchases where it matches your sku, you can consider that the user has an active subscription.
https://developer.android.com/google/play/billing/subs#resubscribe
Users can resubscribe in a number of different scenarios:
Before the subscription has expired, users can repurchase the same subscription in your app. This generates a new subscription and
purchase token.
Before the subscription has expired, users can restore the subscription in the Google Play subscriptions center. This keeps the
same subscription and purchase token.
After the subscription has expired, users can also repurchase the same SKU up to 1 year after expiration through the Google Play
subscriptions center. This generates a new subscription and purchase
token.
More details are provided in the release notes of 2.0 here: https://developer.android.com/google/play/billing/release-notes
I think the API is for subscriptions made outside your app (for example, from Google Play Subscriptions Center (mentioned in bullet point 3), or at a physical store).
Based on your question, it seems that you already handle the other scenarios regarding a user not having a subscription or having cancelled their subscription - but these flows apply to within the app, not outside. To gracefully handle purchases made outside the app you must use 2.x or higher.
The ability to process subscriptions outside the app, such as Google Play subscription Center or a physical store is not available in 1.x. It is available from 2.x+
Presuming you don't confuse the flow of subscriptions , that will remain as it is. Additional features have been added to Google play billing . As we talk , Google play billing 3.0 is up and ready. Follow this link
https://developer.android.com/google/play/billing/release-notes#3-0-0-summary-changes
Resubscribe feature will make restoring subscriptions easier.
There are scenarios where managing subscription should be made easy .
Subscription Restore and Resubscribe
Lets assume a user for some reason cancels the subscription renewals and before the subscription is expired and wants to subscribe it again. Now if user wants to resume it again. This newly feature will allow to resume the subscription as if they were never cancelled. For this the condition is that the subscription must not have expired . If it has expired , then here it is . Users will have to resubscribe instead. To resume any paused subscription users will need to resubscribe , you will have to treat this as you have been treating it.
Account hold feature
A user subscribes and sometimes users are unable to pay their subscription, whether due to financial woes or an expired credit card. In these cases, developers can initiate an Account Hold instead of cancelling it . This will allow users to manage the subscriptions until they fix the payment at their end.
Developers with existing apps will need to integrate Account Hold and Subscription Restore by November 1st. Unless they opt out, they’ll also need to integrate Subscription Pause and Resubscribe. If they fail to do so by the deadline, future updates may be rejected, thus delaying the launch of new features, bug fixes and metadata.
I'm working on a subscription renewal feature, in test mode, with testing payment methods. Problem is that we receive cancelation subscription webhook, GooglePlay makes subscription revoke.
From params:
"cancelReason": "1"
Status code from the docs,
Subscription was canceled by the system, for example, because of a
billing problem.
Also from the docs
Revoking a subscription instantly removes access to the subscription
and is usually done when you or Google suspects fraud.
Usually, it sends cancelation webhook immediately after renewal, even when it was successful, so there are cases when I got two e-mails, about renewal success and cancelation. In my case renewal called after 5 minutes (doc)
Have someone idea, what could be the reason? Is it some "Google anti-fraud system". Because for testing purpose we have short subscription period but the big price. But probably anti-fraud should not be executed when we do testing, with testing payment methods, when there is no real transaction.
The problem was, that we didn't acknowledge new subscriptions.
From the docs:
If you use the Google Play Billing Library version 2.0 or newer, you
must acknowledge all purchases within three days. Failure to properly
acknowledge purchases results in those purchases being refunded.
Regarding subscriptions:
For subscriptions, you must acknowledge any purchase that contains a
new purchase token. This means that all initial purchases, plan
changes, and re-signups need to be acknowledged, but you do not need
to acknowledge subsequent renewals.
Test acknowledging purchase with license testers:
For purchases made by license testers, the acknowledgment window is
shorter. Instead of three days, purchases are refunded and revoked if
they are not acknowledged within five minutes.
UPDATE
changes in documentation
You should also verify that purchases are properly acknowledged as
described in processing purchases. For purchases from license testers, a > purchase will be refunded after 3 minutes if your app does not
acknowledge the purchase and you will receive an email about the
cancellation. You can also check the Orders tab in the Google Play
Console to see if an order was refunded after 3 minutes.
In my android app using in-app subscription monthly plan. I have purchased a subscription product with test account. After one hour I cancelled it manually from my phone.
After I query using inventory.getPurchase(monthlyplan), I always get purchase state is 0.
I waited more than one day; still getting response of purchase state is 0. Can any one help me on this?
You may want to check this document - Subscription Cancellation:
Users can view the status of all of their subscriptions and cancel them if necessary from the My Apps screen in the Play Store app. Currently, the In-app Billing API does not provide support for programatically canceling subscriptions from inside the purchasing app.
When the user cancels a subscription, Google Play does not offer a refund for the current billing cycle. Instead, it allows the user to have access to the canceled subscription until the end of the current billing cycle, at which time it terminates the subscription. For example, if a user purchases a monthly subscription and cancels it on the 15th day of the cycle, Google Play will consider the subscription valid until the end of the 30th day (or other day, depending on the month).
Important: In all cases, you must continue to offer the content that your subscribers have purchased through their subscriptions, as long any user is able to access it. That is, you must not remove any content while any user still has an active subscription to it, even if that subscription will terminate at the end of the current billing cycle. Alternatively, you can use the refund and revoke API to revoke each subscriber's subscription (one by one) and refund their subscription payments. Removing content that any subscriber is entitled to access will result in penalties. Please see the policies document for more information.
There are some good insights regarding the following (also found in the same document):
App uninstallation
Refunding and revoking subscriptions
Here is a related SO question that also talk about cancelling subscription in-app.
Let's say I have saved the token from when a user has purchased an automatically renewing subscription via Google Play. When that subscription is automatically renewed, can I still use that older, initial token to get the current status of that subscription (via Purchases.subscriptions: get)?
Yes, you can. That token does not change. You will pass this token in your request to find out if the subscription has renewed or not.
Make sure you do not lose that token otherwise it will be a nightmare to figure out if the user has renewed or not.
The purchase token changes when user cancels the auto-renewal and restarts the subscription before the current period ends ( turns the auto-renew back on from play store), does upgrades/downgrades, purchases new subscription after an old subscription lapsed + for SOME cases when the order is on hold and the subscription is recovered. Almost sure Purchases.subscriptions: get response will not contain the new receipt when using the old token in this cases.
Resignup refers to when a user subscribes, cancels their subscription, and then re-subscribes before the original subscription has expired. Although they have not lost entitlement and the new subscription will be the same as the previous one, they will go through another purchase flow as they are committing to future payments. They will receive a new purchase token and the linkedPurchaseToken field will be set, as in the case of an upgrade or downgrade.
You can read more at Medium post here.