I have a game created in Unity wherein we have subscriptions enabled for various prized packs. We are storing the details of this subscription in a DB in the backend. I wanted to check if it's possible to cancel the subscriptions through the backend itself - if a particular API exists for Google and Apple stores to do the same for all users belonging to a particular prized pack. Changing the status in our DB for the subscriptions is straightforward, but how do we stop the Google and Apple stores from charging these players on a monthly basis? Or does there exist some way to mark a particular subscription pack as obsolete?
On Google, you have an API to cancel a subscription
On Apple, such API doesn't exist and the only thing you can do for now, is explaining to your users the different steps to cancel their subscriptions. You can help them with this deeplink: https://apps.apple.com/account/subscriptions
Opening this URL launches iTunes or iTunes Store and displays the Manage Subscriptions page where the user can upgrade, downgrade, or cancel their subscription by disabling auto-renew
Related
As the documentation says:
queryPurchaseHistoryAsync():
Returns the most recent purchase made by the user for each SKU, even if that purchase is expired, canceled, or consumed.
So lets say I would like to make an IAP for the user to remove Ads forever from my app.
How do I decide with a fresh install if that user already purchased that IAP if this function also returns the "canceled" IAPS?
I would like to query the actually purchased IAPS, not everything. Becuase that way a user could unlock the Ad free version with a cancelled IAP.
To make it worse, the Purchase class doesn't have status like "cancelled" or "consumed" I cannot decide the state of the user's purchased IAPS.
Am I missing something here?
Thanks in advance
The billing client documentation states it checks for the user.
Then we have the question: Who is the user
If you look at the steps taken for the billing api on https://developer.android.com/google/play/billing/billing_library_overview then you see that a connection to google play is needed.
What happens then is that the current user on android, the account they are signed in with on google play and their mobile device is determined to be the user.
So if they purchased it via google play in app, it will always be assigned to that user on google play and that is what's being queried by this. No matter on which device they are logged in, Their tablet, smartwatch, phone, television, etc...
How to get a list of actually bought products
Instead of using async that gives you everything included abandoned shopping carts I suggest you use https://developer.android.com/reference/com/android/billingclient/api/BillingClient#querypurchases
That way Get purchases details for all the items actually bought and paid within your app. This method uses a cache of Google Play Store app without initiating a network request.
Note: It's recommended for security purposes to go through purchases
verification on your backend (if you have one) by calling the
following API:
https://developers.google.com/android-publisher/api-ref/purchases/products/get
If you read that API link it's easy to check with the online cache if the purchase was valid with a simple GET request.
Personally I would build in a check if the phone is suspect to be rooted before doing the manual background check with the purchases API that sends a request to the store.
Phones that are not rooted have a higher trust level, as the user are probaly not very tech savvy and will not have a shimmer of a clue how to circumvent such checks, and the google play cache will be updated regularly, reflecting trustworthy data.
When a phone is suspect to be rooted(you can read protected directories/write to them), then perform the check online if they bought the stuff each time you deem it neccesary.
I'm researching method to implement auto renew subscription in app billing with google play. I read https://developer.android.com/google/play/billing/billing_subscriptions.html and see
Billing continues indefinitely at the interval and price specified for the subscription. At each subscription renewal, Google Play charges the user account automatically, then notifies the user of the charges afterward by email. For monthly and annual subscriptions, billing cycles will always match subscription cycles, based on the purchase date. (Seasonal subscriptions are charged annually, on the first day of the season.)
When the subscription payment is approved, Google Play provides a purchase token back to the purchasing app through the In-app Billing API. Your apps can store the token locally or pass it to your backend servers, which can then use it to validate or cancel the subscription remotely using the Google Play Developer API.
So have any method to my server know when user's subscription was renewed? Instead of google play send new bill subscription to android app after that android app send this new bill to my server just for validate.
Can google play send a notify to my server when user's subscription renewed such as notify the user by email ? I want to google play send me a notify that user's subscription was renewed automatically so that my backend will update expire their subscription in app increase. Don't need android app have to check bill each time user open store to check have new bill from goole play charge automation or not. Do it implement?
My workfollow
Google charge a new cycle subscription and notify to my server { body such as bundId, bill, product_id or subscription package name, expire date...), also sent mail to user about their subscription automation renewed.
My server determine change subscription of the user and validate in app purchase by google play api and change expire package subscription in your app if validate is valid.
Store newest bill in my db
Is that possible?
[Update] Recommend from goolge play api doc
Recommendation: Include business logic in your app to notify your
backend servers of subscription purchases, tokens, and any billing
errors that may occur. Your backend servers can use the server-side
API to query and update your records and follow up with customers
directly, if needed.
How to implement recommend from google api, any doc or tutorials ?
I have currently exactly the same problem. The concept of Google is not well-conceived. There is a possibility to notify your backend server about financial transactions (see here), but I would not recommend this. You rely your business transactions on a lot of Google services and your server uptime. If anything goes wrong or is down or something, you will not be informed and your backend business logic does not work anymore.
This recommendation of Google you mentioned sucks as well. What happens if there is an auto-renawal (which delivers a new purchaseToken to your app) and the user never opens your app. Then the new subscription data will never be transferred to your server. And if you never got a new token, how can you check, if the user is still a subscriber, since this limited Google Play Developer API stupidly needs a purchaseToken as parameter (see here) that you never get as long as the user does not open your app at least once after an auto-renewal (to submit it to your server).
I think about implementing this in this way:
1.) I continuously check the purchase records by cron job. A purchase record is a database entry which contains all data from the initial subscription (orderId, purchaseToken, and so on, all that is needed for the security validation process on the server). Every purchase record is connected to a user's account (some UserID) in my backend system. As long as the autoRenewing attribute of the purchaseRecord is not false, the subscription is valid. Even if the expiryTimeMillis is exceeded, this one user could still have a valid subscription, because of the use case I described above: Subscription will be auto-renewed by Google, but the user never opens the app, so no transfer token is sent to your server and you are still not informed about the subscription update.
2.) If the use cancels his subscription any when, the autoRenewing would be false at any time. That means that the subscription will indeed end at the expiryTimeMillis.
3.) When the user opens your app and transfers the new purchaseToken to your backend, you will get a new purchase record which is again connected to the user account with his User ID. The user will probably have 2 purchase records now. The old one and the new one. If so, you could delete the old one, and the same process repeats with the new purchase record at step 1.
I didn't have implemented the concept so far, so I don't know if this really works like this. Maybe this could work in a different manner, but maybe it's a step into the right direction.
I don't think, relying upon daily basis cronjob is a feasible way to go about this problem, It is messy and you have to also consider the case when your application is handling too many requests, you have a limit of transactions that made using android developer's api. The better way to implement it would be to use google's recommendation. Which stats:
...
Note: Due to quota restrictions, it is not recommended to check state by polling the Google Play Developer API at regular intervals instead of leveraging Real-time developer notifications.
...
Here, You can follow the following url
How to get expiry date for Subscription with client side in Android? and to implement the auto-renewal subscription.
I want to share In-App purchased product identifiers from one app(say "App1") to another app(say "App2"). Both run on iOS 7 devices. And more importantly since "App2" was released long time back, both the apps have different Team IDs. When the user clicks on a "Restore purchase from App1" button I want "App2" to unlock certain features based on the purchases the user has made in "App1". What is the best way to achieve this?
I dont want to use UIDocumentInteractionController or UIActivityViewController because that would require unnecessary user interaction.
Key chain items or iCloud key-value storage cannot be shared because both the apps have different Team IDs.
Can't use an exclusive server through which the two apps can communicate.
You cannot do this by using the IAP API. You could store the information on your server and unlock it for a user, however, this is against the App Store Review Guidelines:
Apps utilizing a system other than the In-App Purchase API (IAP) to purchase content, functionality, or services in an App will be rejected.
And technically you would not be using the API if you checked against your own server and provided the content through that.
Now this looks possible for subscriptions with App Bundles: https://developer.apple.com/documentation/storekit/in-app_purchase/offering_a_subscription_across_multiple_apps
You can offer customers auto-renewable subscription services that are accessible through multiple apps across one or more operating systems.
In order to offer this functionality, your server must grant access to the subscription content across all apps, despite the user having purchased the subscription within a specific app. You can use a unified account management database along with server-side receipt validation to validate a user's purchase and ensure in-app transactions are handled. By entitling subscription access from your server, you can provide users the ability to access your subscription across multiple apps.
It's Possible using Authentication API
step 1: When purchased product successfully to store status inside API
step 2: Then call API every time of didFinishLaunching to check purchase status and use multiple APP
Another benefit is make payment without any payment gateway...
I have an app that sells Virtual Phone Numbers. When an user subscribes, we deliver a new virtual number and the user can manage this number within the app. After that, the user can receive calls but not necesarily through the app. I mean, after the initial purchase the user does not need to open the app to use the service but I need a way to check the subscription status monthly. My question is, can I set up a cron in the server to check the next receipts even the user wont open the app anymore?
Is it possible to sell a subscription service that is not delivered through the app? Thanks.
Take a look at this service that manages IAP and push notifications..
http://urbanairship.com/
IF your service is eligible for auto-renewable subscriptions you can use that ( this is tricky because they reject this if the app dosen't give content. see more here: http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/StoreKitGuide/RenewableSubscriptions/RenewableSubscriptions.html )
I've not done this myself, but the gist I get from the store docs is that you will verify the receipt and get an updated transaction if the subscription has been renewed. So presumably on your server you have some indication of when the original subscription was purchased and the time, so you would check before it expires and get the new transition.
I'd suggest maybe using push notification if this were to fail, to engage the user to update/renew.
You can use the Auto-renewable subscription from apple to serve your users.
When user buy the subscription first time store the receipt in the server.
Maintain the expiry date of the subscription per user in the server DB.
Run the cron job and check for the "Active Status" of the subscription via apple APIs http://tinyurl.com/ay2labm
Depending on the status you can extend the service to your users.
http://tinyurl.com/aeh9f84
I have an Iphone application in which i am trying to implement non renewable subscription.I had done it a manner that after the purchase i am adding that details to user account information.so he can get it on all the devices.I have a login at the start of my application.And after associating the reciept data with the user account i was finding out the expiry date in my server from the purchase date in the reciept data, by using that information i was showing the buy button again to my user.But the apple is rejecting it for the reasons
11.6: Content subscriptions using IAP must last a minimum of 7 days and be available to the user from all of their iOS devices
17.2: Apps that require users to share personal information, such as email address and date of birth, in order to function will be rejected
Can anybody know the exact mechanism to implement nonrenewable subscriptions ?
From your description it sounds like your login when they start your app is mandatory. Apple forbids this. They insist that the login be optional, but it must still be available to everyone who wants to use it (when using non-renewing subscriptions).
What I did on my app was, next to where I show the user's purchased subscription level, I have a button that says Save your account.... And when they click it it describes to them how, if they create an e-mail and password than they can share their subscription across all their devices and they can restore their account if their iPhone gets lost or stolen. You want to incentivize the user to do this because a better experience for them means a better experience for you. You could even offer them a perk, like 2-weeks free if they create an account. And since you're using non-renewing subscriptions, you have the power to do this since you're calculating your own expiration date, instead of letting the app store do it for you.