We want to store when a google play purchase is refunded to a user for data analysis.
According to documentation, there are 3 ways for a user to request a refund for a subscription on google play:
https://support.google.com/googleplay/answer/2479637?hl=en
If the user requests the refund to the developer (us), we can keep track of it on our servers and manage it on our end, no problem. However, users can also ask google for a refund directly. Problem is that we can't find documentation on this kind of refunds.
Looking at the API documentation for subscriptions, it doesn't provide whether a purchase was refunded or not: https://developers.google.com/android-publisher/api-ref/purchases/subscriptions
Also tried looking into the realtime developer notifications system. Looks like it doesn't have an event for refunds.
https://developer.android.com/google/play/billing/realtime_developer_notifications#json_specification
Any idea what happens if google refunds a purchase on their end?
In my experience with the realtime events thus far, after a subscription is refunded two realtime-events get sent. First, a SUBSCRIPTION_CANCELED event is sent, followed by a SUBSCRIPTION_REVOKED event.
On my server, I treat the SUBSCRIPTION_CANCELED as a normal cancel, then if that event is followed by a SUBSCRIPTION_REVOKED event for the same subscription, I mark it as refunded.
Details can be found for these two specific events, as you also mentioned, at this link: https://developer.android.com/google/play/billing/realtime_developer_notifications.html#json_specification
Related
One of my Android apps has an in-app item that is essentially a token which people can buy and use at a later time.
I see that some people buy it and then refund it later. While implementing purchases I used the standard guide from Java section of the docs that Google provides on the topic, plus I do verify the purchases on my backend server.
All that said, I'm still not sure that it can't potentially lead to some kind of fraud. Generally speaking, is it possible for the user to buy this "token" use it and then refund it in a matter of few minutes? I didn't look into it yet, but it doesn't seem that Google would bother to send a refund callback to my backend..
Basically, how to handle these things correctly to prevent fraud?
Edit: to be more clear, I do the acknowledgePurchase() and I get valid sales that don't get refunded, not after a while, not ever. I just wonder how is it so happens that from time to time I see a purchase made, then after some time (which differs in length) it does become "refunded" (but not all of them, only some).
Please make sure after purchasing you did BillingClient.acknowledgePurchase() in your app. You can find details about this Here
If your code, when handling a purchase, does not call acknowledgePurchase() and neither call consumeAsync() then the purchase is refunded after a short time period
The only real way to verify the authenticity of a document is by verifying its signature, the same happens with in-app purchases.
A purchase token can be faked but a signature can not.
Look at this : https://stackoverflow.com/a/48531877/7690376
I'm trying to implement the backend of payment processor with google play in-app billing.
Google play billing api is tottally built for serveless scenario and is being a hell of a work to make it work for a normal world situation where apps have backends that need to validate and process payment logic.
i'm following this tutorial: https://developer.android.com/google/play/billing/getting-ready#configure-rtdn
but only after implementing the whole logic i read the small line
Real-time developer notifications (RTDN) is a mechanism to receive
notifications from Google whenever there is a change in a user's
entitlement within your app. RTDN leverages the use of Google Cloud
Pub/Sub, which allows you to receive data that is either pushed to a
URL that you set or is polled using a client library. These
notifications allow you to react immediately to subscription state
changes, avoiding the need to poll the Google Play Developer API. Note
that inefficient use of the Google Play Developer API can lead to API
quota restrictions.
so my logic integration is well done, the test message in play console works but google play billing is not sending the real notifications because my app deals with in-app products and not with subscriptions
then i read this tutorial https://developer.android.com/google/play/billing/rtdn-reference and it says
Note: A OneTimePurchaseNotification is sent only for some types of
one-time purchases. For more information, see Integrate.
but the link that was: https://developer.android.com/google/play/integrate goes to 404
does anyone know how to make google play console send notification for payment status on in-app purchases?
also how to get notifications for refunded purchases
OneTimeProductNotification was introduced in 2019-05-07 and its main purpose of handling cash purchases
https://developer.android.google.cn/google/play/billing/release-notes#release-2_0
As release notes says:
"This notification type is sent only for purchases associated with delayed forms of payment, such as cash"
+1 for your question becuase this is a weird scenario with lack of docs from google.
When I tested the notification from google play console by clicking "Send test notification" it works, but when I'm trying do so from my android app using testing client billing IT DOES NOT WORK!
but this screenshot says that
...for updates to your in-app products and subs...
In order to get refund purchases, you can try Voided Purchases API
The Google Play Voided Purchases API provides a list of orders that are associated with purchases that a user has voided. You can use information from this list to implement a revocation system that prevents the user from accessing products from those orders.
This API applies to one-time in-app orders and App Subscriptions.
A purchase can be voided in the following ways:
The user requests a refund for their order.
The user cancels their order.
An order is charged back.
Developer cancels or refunds order. Note: only revoked orders will be shown in the Voided Purchases API. If developer refunds without setting the revoke option, orders will not show up in the API.
Google cancels or refunds order.
Just copy and paste the below line of code to the permissions input box and then add this to the members.
google-play-developer-notifications#system.gserviceaccount.com
Next give permission to pub/sub publisher and you are good to go.
The mistake you would have done is you would have added a service account already present in your google cloud account which is not correct.
Above solution works perfectly fine for me!
I'm not specifically looking to have the option to refund a user for an in app purchase of a consumable, but just in the odd case that a user asks for a refund, either through google, or through the developer of an in app purchase of a consumable.
There does not seem any way of handling refunds through the In App Billing api V3. All documentation points to V2 of the api using broadcast receivers. This does not help me in least bit.
So how are refunds handled in the In App Billing v3 api? I'm assuming for a non consumable, the refund is processed, and then google handles the processing through their backend, and then when a getPurchaseState() is conducted, it would return a value of 2 (refunded). If so, this works great for a NON CONSUMABLE product.
When a getPurchaseState() call to a consumable purchase is made, it returns null. That's assuming if the purchase was previously successful, and that the item was consumed and provisioned. I figure I could store the purchase items locally within the app, but then there is still no way of receiving a refund notification for that product. I can check for purchase state, but again, it will return null, as long as it was consumed and provisioned already.
A slight workaround I can think of right now, is to not consume the purchase on provisioning. So that it remains "unconsumed" according to google, and remains in their database. Now, if a refund is requested, I am assuming a call to getPurchaseState() for that consumable will return refunded, thus the application logic can then subtract/deduct the provisioned consumable from user's inventory. If a user would want to repurchase that consumable again, then before the IAB api call is made for the purchase, get the purchaseState() and/or hasPurchase(), and if there is already a purchase there, consume that item without provisioning, this will let the user repurchase that consumable. Only issue with this workaround, is that if A user wants to re purchase the same consumable product, as soon as the select the option to repurchase, the item must be consumed regardless of whether they successfully repurchase the product or not. So if the user does not complete the purchase, the product is already consumed, and I end up back where I am now with inability to check for refund state on the consumable.
I can't think of any other way to do a refund for a consumable in app product, and that is what I ask here. Is the way I thought of sufficient, or is there a proper way to handle refunds using IAP v3 on consumables?
I was thinking I have 3 options:
Don't offer refunds for consumables, no/little exceptions, but the issue with this is if a user requests refund through google, and not through developer, leading to option 3 below)
Find a workaround (either properly through the api, or with my proposed workaround)
Offer refunds, but have no application logic to subtract/deduct the consumable. In this scenario, users could end up taking advantage of free purchases.
I know this is a super late response to this issue, but it took me quite some time to track down info on this issue, so hopefully it can help someone else out. There are a few ways of doing this... In the Google Play Developer console you can click on the left nav saying "Order Management" which will bring up a list of all recent orders though your app. If you need to refund one you can click on it, or multi select them and refund them in this view. Just a heads up... you will most likely need permissions from your account admin to see this view and refund users.
Your other option is though the API docs here. You will need to set up your API account though the Android console, which I will say is a massive pain and not clear. But once that's set up and your "Server Applications" is set up you will need to make sure it has proper permissions as well. Then you should be able to use a library such as this to do the heavy lifting for you, because from what I've read the JWT auth process though the google API is not super straightforward, and their docs are a mess. I hope this helps someone and comment if you have questions... I will do my best to answer.
This same API also can be used to find items that were purchased by users and then refunded, so you can remove these items from those users' apps. Also you can do server side purchase validation through this as well, which is highly recommended, because rooted phones can inject fake purchase requests making your app believe that it's hearing back from the google play store, but in reality it's not. You then send back to your server the purchase token and SKU of the item being purchased and then on your server you just run this. This will give you back a 400 error if it's invalid, and a 200 with a some JSON data if it's a successful purchase.
I am using google in-app billing v-3 to implement auto renewal subscription process of google in my android application.
In my application user can go for different types of subscriptions, like Subs-1 for 30MB of space, Subs-2 for 90MB and so on. Now if, user chooses initially Subs-1 and then upgrades it to Subs-2, as a result now there are two simultaneous subscriptions on user's account.
I want to cancel first subscription, when second is purchased. Is there any method for the same in android code, or do I have to go for server-side implementation of the same here.
Google docs are really confusing, and I didn't find any solution there.
Yes you could use the cancel method, detailed here https://developers.google.com/android-publisher/api-ref/purchases/subscriptions/cancel#request
All you would need is the subscription_id and token which you got when user purchased the subscription
I have gone through most of the links here on stackoverflow and i have some doubts regarding InApp Subscriptions and Google Wallet.
What i know:
InApp Subscriptions basically allows a user to be able to subscribe to an app, say for example if it offers one year trial period, then once thats over, Google automatically handles the subscriptions then after.
Google Wallet, its a method that can be used to perform the purchase. What i don't understand is, can i use this method in order to allow users to use the app for one year, and then make them pay for the next years?
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.)
This is what happens in my app:
1. A user logs in, and i get a date that probably keeps track of the billing cycle
2. If the sessions expired, the user is asked to pay using the inApp Billing serivce
3. Based on TrivailDriveApp Example, where we have the success log printed on subscription, we update the date of payment.
Some questions i have:
As per the quote from android, if the user is automatically subscribed to the service, and if a mail is sent to the user, does that mean that i would never be able to get a notification about the payment extension? How do i sync that with the server then?
Is my approach wrong in handling this kind of scenario? Or do i have to select a different method of handling app extensions?
P.S: There is no way of testing inapp subscriptions also. I wonder if i could do that without using real credit/debit card credentials.
EDIT:
I would also want to keep track of when the purchase or billing was done, if subscriptions are auto-renewed, then should i take up the purchase flow as an InApp Product instead of an InApp Subscription?
Please help.