Android how to find purchase receipt
Android how to find purchase receipt
Android : inApp purchase receipt validation google play
I am using google wallet for my payment gateway, after purchasing the product google giving me a below response that
I am trying to make use of Receipt Validation that google play newly introduced.In Google Developer console I made certificate key by Service Account in the Permission. But I am confused how to make use of Receipt Validation after purchasing a Product from the Google Play-store.
So can anyone please help me how to do the Receipt validation of InApp Purchase.
5 Answers 5
Trending sort
Trending sort is based off of the default sorting method — by highest score — but it boosts votes that have happened recently, helping to surface more up-to-date answers.
It falls back to sorting by highest score if no posts are trending.
Switch to Trending sort
Google provides receipt validation through the Google Play Developer API, within the API are two endpoints you will be most interested in: Purchases.products: get and Purchases.subscriptions: get.
Purchases.products: get can be used to verify a non-auto-renewing product purchase, where Purchases.subscriptions: get is for verifying and re-verifying auto-renewing product subscriptions.
To get started with a service account first go to the Google play Developer console API access settings page and click the Create new project button:
You should now see a new Linked Project and a few new sections, in the the Service Account section, click the Create service account button.
You will be presented with an info box with instructions to create your service account. Click the link to Google Developers Console and a new tab will spawn.
Now click Create new Client ID, select Service account from the options and click Create Client ID.
A JSON file will download, this is your JSON Web Token you will use to exchange for an access_token so keep it safe.
Next, switch tabs back to the Google play Developer console and click Done in the info box. You should see your new service account in the list. Click on Grant access next to the service account email.
Next under the Choose a role for this user, select Finance and click Add user.
You have now set up your service account and it has all the necessary access to perform receipt validations. Next up is exchanging your JWT for an access_token.
The access_token expires after one hour of exchange you so need some server code to handle this and Google have provided several libraries in many languages to handle this (list not exhaustive):
Once you have the access_token you’re good to go (at least for the next hour at which point you will want to request a new one following the same process in the above paragraph).
To check the status of a consumable (non-auto-renewing) purchase make a http get request to: https://www.googleapis.com/androidpublisher/v2/applications/com.example.app/purchases/products/exampleSku/tokens/rojeslcdyyiapnqcynkjyyjh?access_token=your_access_token
If you get a 200 http response code, everything went as planed and your purchase was valid. A 404 will mean your token is invalid so the purchase was most likely a fraud attempt. A 401 will mean your access token is invalid and a 403 will mean your service account has insufficient access, check that you have enabled Finance for the access account in the Google Play Developer console.
The response from a 200 will look similar to this:
Subscriptions are similar however the endpoint looks like this:
And the response should contain these properties:
How to Find Paid Apps and In-app purchase History on Google Play
Do you let your children or other family members use your Android smartphone or tablet? Here are some quick tips to check up on your recent purchase history on Google Play to ensure they aren’t draining your credit card.
We’ve all heard nightmare stories about how children have spent 1,000s of dollars worth on in-app purchases without your consent. This guide will help you avoid that nightmare yourself. Below you’ll find information on how to find your paid apps and recent purchase history on Google Play, as well as how to make restrictions on app purchases.
How to Find Recent in-app Purchases & Paid Apps
If your child has a favorite app on your smartphone or tablet, you may need to be extra careful that they aren’t spending hundreds of dollars on in-app purchases without your consent. Sometimes your child may not even be aware that they are purchasing items with real money. For this reason it’s important not to get frustrated at them directly and instead solve the problem from the source and stop your child from being able to purchase in-app items whatsoever.
To begin with though, you may prefer to find out whether your child has spent any money on in-app purchases recently. You can find your recent in-app purchases by following the steps provided below.
On this page, you’ll be able to find your recent in-app purchase orders and recent paid app purchases. If you see a number of app orders that you aren’t aware of, chances are that another user of your device has purchased them. Take the image below for example. You’ll want to look out for any items you did not purchase yourself – in this example, £7.94 has been spent on Pokemon Go.
The order page doesn’t stop at in-app purchase history. If you’d like to see whether another user of your device has been purchasing apps, you can navigate the same order page. You can scroll down and view the entire history of that Google account.
If your device uses multiple accounts, make sure to follow the steps below to check the order page for each individual Google account.
As you can see from the image shown above, orders tied to a different account will only appear on that specific account.
How to Limit Purchases
If you’ve noticed that purchases are being made without your consent or you’re worried that this may happen, you can easily limit purchases so that you no longer need to worry about unexpected Google Play fees. Follow the steps below to limit your purchases.
Hopefully this guide has helped you to limit your purchases and check whether any unauthorized purchases have been made in the past.
How to verify purchase for android app in server side (google play in app billing v3)
I have a simple app (needs user login with account). I provide some premium features for paid users, like more news content.
I need to record if the user has bought this item in my server database. When I provide data content to user’s device, I can then check the user’s status, and provide different content for paid user.
I checked the official Trivialdrive sample provided by Google, it does not provide any sample code for server-side verification, here are my questions.
I am not sure what method I should take to verify the user’s purchase, and mark the user’s status in my database, maybe both?
And I am afraid there is a situation, if a user bought this item from google play, but for some reason, just in that time, when my app launched verification to my server, the network connection is down or my own server is down, user just paid the money in google play but I did not record the purchase in my server? What should I do, How can I deal with this situation.
8 Answers 8
Trending sort
Trending sort is based off of the default sorting method — by highest score — but it boosts votes that have happened recently, helping to surface more up-to-date answers.
It falls back to sorting by highest score if no posts are trending.
Switch to Trending sort
It sounds what you’re looking for is a way to check if the user has premium features enabled on their account, so this is where I would start;
Ensure there is a flag of some sort on your database indicating if the user has premium features and include that in the API response payload when requesting account info. This flag will be your primary authority for «premium features».
When a user makes an in-app purchase, cache the details (token, order id, and product id) locally on the client (i.e the app) then send it to your API.
Your API should then send the purchaseToken to the Google Play Developer API for validation.
A few things might happen from here:
In the case of 1. or 2. (2xx or 4xx status codes) your client clears the cache of purchase details because it doesn’t need it anymore because the API has indicated that it has been received.
Upon a successful validation (case 1.), you should set the premium flag to true for the user.
In the case of 3. (5xx status code) or a network timeout the client should keep trying until it receives a 2xx or 4xx status code from your API.
Depending on your requirements, you could make it wait a few seconds before sending again or just send the details to your API when ever the app is launched again or comes out of background if the purchase details are present on the app cache.
This approach should take care of network timeouts, servers being unavailable, etc.
There are now a few questions you need to consider:
What should happen immediately after a purchase? Should the app wait until validation is successful before providing premium content or should it tentatively grant access and take it away if the validation fails?
To put this in another way: Purchase is valid until proven fraudulent or; fraudulent until proven valid?
In order to identify if the user still has a valid subscription when their subscription period comes up for renewal, you will need to schedule a re-validation on the purchaseToken to run at the expiryTimeMillis that was returned in the result.
Lastly, to ensure the user has premium access (or not), your app should query your API for the users details on app launch or when it comes out of background.
Android how to find purchase receipt
How to find purchased apps on the Google Play Store
Keeping track of all our apps is almost impossible, especially when switching devices or performing a factory reset. Google makes it pretty painless to re-install all your apps on a new or reset device, but if you’re looking for a specific app that you may no longer remember the name of, things get a little complicated. Here’s how to find old purchased apps on the Google Play Store!
How to find old apps on the Play Store
Editor’s note: These steps are accurate for finding your apps on the most recent version of Google Play. We will update the list if anything changes.
Finding old apps
The Google Play Store homepage
The Settings menu within the Play Store
The Manage apps section of the Play Store
Before looking at purchased apps specifically, let’s take a quick look at how Google keeps track of your old apps for you. This method for finding apps isn’t actually beneficial when finding purchased apps unless you already know what you’re looking for.
The apps currently installed on your phone are found under the aptly named Installed tab. The Library lists all the apps you’ve ever installed on your Android devices past and present but aren’t on your phone anymore. The sorting options in the Library tab only include Recent and Alphabetical, while the Installed Tab adds Last Updated, Last Used, and Size.
Notably absent is any way to distinguish between free and purchased apps in both these sections. You’re also out of luck if you don’t know the name of what you’re looking for (and then you can search for it).
Finding your purchase history
Finding purchased apps, in particular, requires a few extra steps.
Budget & history is where you will find a list of any and all purchases you’ve made via Google Play. Unfortunately, this list also includes books, movies, TV shows, songs, and albums you may have bought via Google Play and all the in-app purchases you’ve ever made too.
Depending on your order history, it may take a lot of scrolling, but you should be able to find all the purchased apps you were looking for. There might be some surprises in there as well.
I had the OG Moto 360 smartwatch back in 2015 and had purchased a few watch faces. I didn’t keep the watch for long, and when I switched smartphones after that, I didn’t re-install any of those apps again. I got the Huawei Watch 2 a few years later but completely forgot about those watch faces. When I was looking at my order history, I was able to download and use them again.
The web app does it (slightly) better
You can find out order history by using the web app as well. Go to play.google.com on a web browser on your PC or Android device and head to the Apps section. Go to My apps in the menu on the left to see a full list of your Android apps. The web app shows you both free and paid apps, and you can sort your options in a few different ways. You can view your apps on each device or browse the entire list.
If you’re hoping to check on your books, movies, or TV shows, you’ll have to head to a different Google Play Store tab. There’s, unfortunately, no easy way to put all of your content in one place as of right now.
There’s an app for it
If you’ve ever grumbled about a missing software feature on your smartphone, you might have heard the phrase “There’s probably an app for it” in response. If you are looking for old purchased apps, there actually is an app for that. You can download the “Purchased Apps” app from the Google Play Store here.
Open the app, tap on your Google account, and your entire order history will show up. Opening the hamburger menu by tapping on the three horizontal lines at the top left corner shows you the different categories of purchased apps, as well as the total number of purchases and the amount you’ve spent. Just more information that isn’t directly available from the Google Play Store.
The app also has a leg up on the Google Play Store when it comes to the filters available. Tap on the three vertical dots at the top right corner of the app and tap on Filter. Here you will see options based on Installation Status (All, Installed only, or Uninstalled only) and Purchase Type (All, In-App only, No In-App). Select No In-App, and you will now be able to see a list of all of just your purchased apps.
Android : inApp purchase receipt validation google play
I am using google wallet for my payment gateway, after purchasing the product google giving me a below response that
I am trying to make use of Receipt Validation that google play newly introduced.In Google Developer console I made certificate key by Service Account in the Permission. But I am confused how to make use of Receipt Validation after purchasing a Product from the Google Play-store.
So can anyone please help me how to do the Receipt validation of InApp Purchase.
5 Answers 5
Google provides receipt validation through the Google Play Developer API, within the API are two endpoints you will be most interested in: Purchases.products: get and Purchases.subscriptions: get.
Purchases.products: get can be used to verify a non-auto-renewing product purchase, where Purchases.subscriptions: get is for verifying and re-verifying auto-renewing product subscriptions.
To get started with a service account first go to the Google play Developer console API access settings page and click the Create new project button:
You should now see a new Linked Project and a few new sections, in the the Service Account section, click the Create service account button.
You will be presented with an info box with instructions to create your service account. Click the link to Google Developers Console and a new tab will spawn.
Now click Create new Client ID, select Service account from the options and click Create Client ID.
A JSON file will download, this is your JSON Web Token you will use to exchange for an access_token so keep it safe.
Next, switch tabs back to the Google play Developer console and click Done in the info box. You should see your new service account in the list. Click on Grant access next to the service account email.
Next under the Choose a role for this user, select Finance and click Add user.
You have now set up your service account and it has all the necessary access to perform receipt validations. Next up is exchanging your JWT for an access_token.
The access_token expires after one hour of exchange you so need some server code to handle this and Google have provided several libraries in many languages to handle this (list not exhaustive):
Once you have the access_token you’re good to go (at least for the next hour at which point you will want to request a new one following the same process in the above paragraph).
To check the status of a consumable (non-auto-renewing) purchase make a http get request to: https://www.googleapis.com/androidpublisher/v2/applications/com.example.app/purchases/products/exampleSku/tokens/rojeslcdyyiapnqcynkjyyjh?access_token=your_access_token
If you get a 200 http response code, everything went as planed and your purchase was valid. A 404 will mean your token is invalid so the purchase was most likely a fraud attempt. A 401 will mean your access token is invalid and a 403 will mean your service account has insufficient access, check that you have enabled Finance for the access account in the Google Play Developer console.
The response from a 200 will look similar to this:
Subscriptions are similar however the endpoint looks like this:
And the response should contain these properties:
How to verify purchase for android app in server side (google play in app billing v3)
I have a simple app (needs user login with account). I provide some premium features for paid users, like more news content.
I need to record if the user has bought this item in my server database. When I provide data content to user’s device, I can then check the user’s status, and provide different content for paid user.
I checked the official Trivialdrive sample provided by Google, it does not provide any sample code for server-side verification, here are my questions.
I am not sure what method I should take to verify the user’s purchase, and mark the user’s status in my database, maybe both?
And I am afraid there is a situation, if a user bought this item from google play, but for some reason, just in that time, when my app launched verification to my server, the network connection is down or my own server is down, user just paid the money in google play but I did not record the purchase in my server? What should I do, How can I deal with this situation.
7 Answers 7
It sounds what you’re looking for is a way to check if the user has premium features enabled on their account, so this is where I would start;
Ensure there is a flag of some sort on your database indicating if the user has premium features and include that in the API response payload when requesting account info. This flag will be your primary authority for «premium features».
When a user makes an in-app purchase, cache the details (token, order id, and product id) locally on the client (i.e the app) then send it to your API.
Your API should then send the purchaseToken to the Google Play Developer API for validation.
A few things might happen from here:
In the case of 1. or 2. (2xx or 4xx status codes) your client clears the cache of purchase details because it doesn’t need it anymore because the API has indicated that it has been received.
Upon a successful validation (case 1.), you should set the premium flag to true for the user.
In the case of 3. (5xx status code) or a network timeout the client should keep trying until it receives a 2xx or 4xx status code from your API.
Depending on your requirements, you could make it wait a few seconds before sending again or just send the details to your API when ever the app is launched again or comes out of background if the purchase details are present on the app cache.
This approach should take care of network timeouts, servers being unavailable, etc.
There are now a few questions you need to consider:
What should happen immediately after a purchase? Should the app wait until validation is successful before providing premium content or should it tentatively grant access and take it away if the validation fails?
To put this in another way: Purchase is valid until proven fraudulent or; fraudulent until proven valid?
In order to identify if the user still has a valid subscription when their subscription period comes up for renewal, you will need to schedule a re-validation on the purchaseToken to run at the expiryTimeMillis that was returned in the result.
Lastly, to ensure the user has premium access (or not), your app should query your API for the users details on app launch or when it comes out of background.
Testing in-app purchases on Android
An addendum to the official documentation
Overview
Monetization is one of the most important aspects of distributing your product to the rest of the world. It can make or break a small freelance developer or an established startup.
Android, being so widespread, provides ways for users to purchase products from within your app: this is referred to as In-app Billing. Through this set of APIs, developers can offer two types of products:
The official documentation is very helpful when it comes to the first steps for adding in-app products to your application. In particular, the “Selling In-App Products” training is well structured and walks you through each required step:
Let’s focus on the third point.
Testing, according to the documentation
According to the documentation for testing, we have two ways of testing purchases:
Static responses
Using static responses sounds easy enough, right? You just use one on the following product IDs during a purchase operation:
and the Play Store will reply accordingly. The code looks roughly like this:
However, if you are testing subscriptions, you’re out of luck:
Note: If you’re testing subscription purchases, you must use the product ID of an actual subscription, not a reserved product ID. [Reference]
This means that we cannot rely on static responses to test subscriptions; instead, we need to resort to test purchases.
Test purchases
By using the so-called In-app Billing Sandbox, we can enable access to test purchases. These are the closest thing we have to actual purchases, with a few notable exceptions:
The last point is particularly interesting, because we have two ways of customizing the test purchase behavior.
The first method allows for fine control over the licensing behavior for all the testers: for example, by leaving it to RESPOND_NORMALLY we have a behavior similar to the real one.
The second method, on the other hand, allows for coarse control over the response of the fake credit card: you can decide whether the card will always approve the purchase or always decline it. Intuitively enough, this second method can be customized by each tester.
In order to be eligible for test purchases, there are a few steps to go through:
Sounds easy enough, right? The documentation is also very encouraging
It’s easy to set up test purchases [1]
…Sure, let’s see about that. 😒
Testing, according to real life
You religiously follow the documentation, wait 15 minutes (make it 30, just in case), you start testing and…an error occurs. What now?
It turns out that the documentation is fairly optimistic when explaining the required steps for testing in-app purchases. According to this StackOverflow answer, which in turn is a collection of various trial-and-errors by other users, plus my personal experience, there are actually 10+ conditions that you need to meet or account for before being able to properly use test products!
Let’s recap them here:
As you can see, the sandbox is far from straightforward when it comes to real usage, but at least now we have a few extra hints to start looking for a solution!
Bonus tip: faster testing for test subscriptions
We mentioned earlier that test subscriptions have a 1-day expiration period, regardless of their original duration. This means that, even if we cancel the subscription, it will still be considered active for that day. In turn, when the app retrieves the list of purchased products, it will receive the cancelled subscription and present it as an active subscription (because it technically still is). Your UI will then react accordingly and display premium features, instead of the purchase button: again, technically correct, but very inconvenient for us to do quick testing.
However, there’s a nice way of checking whether a subscription’s auto-renewal has been cancelled: the autoRenewing field inside the INAPP_PURCHASE_DATA JSON payload that comes from the billing service (see documentation). When checking the validity of a subscription in a debug environment, you can assume that when autoRenewing is false the subscription is cancelled and you can purchase another one.
⚠️ Be careful though! This check should only be done in debug/staging environments and not in production, so make sure you limit this “strict” check to debug/staging builds only. ⚠️
Update! 17/01/2018
While this post was still being drafted, Google announced that test subscriptions will no longer be renewed daily. Instead, the renewal period will vary from 5 to 30 minutes, depending on the original billing period.
In addition to this, they are limiting the amount of times a test subscription can be renewed to 6 (it is currently unlimited).
All these modifications will be applied starting February 20th 2018.
Conclusion
While far from perfect, the in-app billing support is critical for the Android ecosystem to grow and to being able to generate revenue.
When implementing purchases in your app, it’s worth paying attention to the checklist we reported before to avoid headaches, as well as provide a reliable sandbox environment for you to develop with and for your testers to test the app.
It’s also nice to see that Google is committed for the long run, as they just released the all new Play Billing Library (compared to the old 2013 version!).
A final shout out to the Android community, for being as open and as supportive as ever!
Go Foryt Blog
Recent Posts
Categories
Validating Android In-App Purchases With Laravel
Whoah! It’s been awhile since my last post. In that time SimpliFit launched the SimpliFit Weight Loss Coach for Android and iOS, the SimpliFit Coaching program, and, just last week, Magical, a texting-based picture calorie tracker. Yes, we’ve been quite busy! And it’s given me a lot more content for future blog posts.
Today, though, I’ll build on my previous post, Validating iOS In-App Purchases With Laravel, by covering Android in-app purchases (IAPs) in Laravel. The process was completed for a Laravel 4 app, but the code I’ll be showing can be used in Laravel 5 as well.
The workflows between iOS and Android are fairly similar, and just as working with iOS IAPs was frustrating due to lackluster documentation, working with Android IAPs is just as frustrating. If Apple and Google would take the best parts of each of their IAP systems, you would get quite a good system. As it stands, though, both systems make you wish your app didn’t have IAPs.
But if you’re reading this, then you probably have the unenviable task of adding IAP verification to your app. First, I’d recommend you get familiarized with Google’s In-app Billing documentation and skim the Google Play Developer API. Also, I’m assuming that you’ve already created your app in your Google Play Developer Console and added the in-app products you’ll be offering.
On the front-end, we are again using the Cordova Purchase Plugin to mediate between our app and Google Play via Google’s In-App Billing Service. Since the SimpliFit app only had a monthly subscription (we since made the app free), I’ll be discussing how to work with in-app auto-renewing subscriptions, however this guide can easily be applied to a one-time IAP.
Android IAP Workflow
Just as with iOS, we have three IAP stages: 1) Retrieve product information, 2) Request payment, and 3) Deliver the product.
Stage 3 was the most involved for Laravel for iOS IAPs, and for Android the steps increase. Take a look:
As you can see, steps 1-16 are identical to the iOS IAP workflow. However, to communicate with Google’s API server, your server must authenticate itself first using OAuth. Thankfully, Google has a PHP library we can pull into Laravel to simplify things. We’ll get to that shortly.
Retrieving Product Information and Requesting Payment
I don’t want to repeat myself, so please check my previous blog post for iOS on these two stages of the IAP process. I’m using the exact same models in Laravel as in the iOS workflow.
If you need guidance on setting up in-app products, check out Google’s documentation on Administering In-app Billing. We chose to make our product identifier for our subscription the same in Android and iOS to help us keep things more organized (i.e., com.example.app.productName).
And just as you can create test users in iOS to test your IAPs, Google allows you to grant gmail accounts test access in the Google Play Developer Console under Settings->Account details. Two things to note here, though:
Delivering Products
On a successful purchase, the Play Store will return a receipt to the Android app, which, through the Cordova Purchase Plugin, is sent via JSON in the following format:
NOTE: This receipt structure is specific to the Cordova Purchase Plugin. If your app uses a different method to access the Google In-App Billing Service API, the receipt structure may differ. Refer to Google’s In-App Billing API for more information on receipt data.
Before we start breaking this receipt down, note that the “receipt” sub-parameter is a JSON object in string format. I suspect this is just the way the Cordova Purchase Plugin processes the Play Store receipt.
Breaking down the receipt by parameter, here’s what we have:
Great, we have a receipt! Let’s move on to storing the data to create an audit trail. Before we do, let me remind you that I use Laracast’s commander pattern in Laravel 4. As such, all the code below is from my StoreTransactionCommandHandler class and sub-classes. If I were to do the same in Laravel 5, all the logic from the handler class would simply be added to the command class itself.
Store the receipt data
For Android receipts, the data that is of most interest to us is the “receipt” sub-parameter, which is a string of JSON data. So first, let’s get that into a format we can work with, then we store it:
Since my iOS guide, I’ve added a new error flow here, where I check to see if the purchaseToken parameter is present before sending it on to be saved into the database.
Note: At this point in the iOS workflow, we also set the URL endpoint to which we send receipt data for validation. For Android, however, Google does not offer a sandbox URL endpoint. If you want to test your IAPs, take a look at the Testing In-App Billing documentation.
Allow server access to the Google API
Before being able to validate a receipt with Google’s servers, we need the necessary data to authenticate with Google’s servers.
First, go to the Google Play Developer Console API Access Settings. Under “Linked Projects”, if you already have a project listed, select “Link” next to the existing project (if it isn’t already linked). If there are no existing projects, you’ll need to create a new project by clicking “Create new project”. This creates a new linked project titled “Google Play Android Developer”.
Next we need to create a service account to access the Google API. This service account is in effect a “user” that has permissions to access your Google Play Developer resources via the API. To create the service account, click the “Create Service Account” button at the bottom of the page. This will open a modal with instructions for setting up a service account. Go ahead and follow the instructions. When you’re on the step of creating the client ID, be sure to select “P12 Key” as the key type.
Once you click “Create Client ID” in the modal, the page will automatically download the P12 key file and will display the key file’s password. This key file will need to be accessed by your server to authenticate with Google but should not be accessible publicly. Once the modal closes, you’ll see the service account’s information. The only relevant piece we need (other than the downloaded key file) is the account’s email address.
We also need to enable the service account to use the Google Play Developer API. In the left-hand side menu, under “APIs & auth”, click “APIs” to view all the individual service APIs accessible via the Google Play Developer API.
Then under “Mobile APIs”, select “Google Play Developer API”. On the Google Play Developer API page, select “Enable API”.
Now the service account has access to the Google Play Developer API. If your server needs access to other APIs, find the appropriate APIs on the previous page and enable them.
Go back to the Google Play Developer Console and click “Done” in the open modal. The page will refresh and you should see your service account listed. Now just click “Grant Access”, and you’ll be asked to select the role and permissions for the service account. Since the server will only be getting information on existing IAPs, select only the “View financial reports” permission and click “Add User” (if you want your server to do more with the API, select the relevant permissions you’ll need).
Make the Request
Now that we have the necessary account details and permissions to access the Google API, we’re ready to make the request to Google. To help us with communicating with Google’s server, let’s pull in the Google PHP Client package to Laravel via the composer.json file:
As of this publication, the latest version of the Google PHP Client package is 1.1.4. According to the API Client Library for PHP, the Google PHP library is still in a beta state. This means that Google may introduce breaking changes into the library. The good news is that the API itself is in version 3, so that will likely remain stable for some time. For these reasons, I suggest stating the specific version of the client library you want to stick with.
With that package pulled in (after running composer update ), here’s my request code with comments to guide you through it:
As you can see, the only data needed from the receipt when making the request is the purchaseToken value (no need to build a JSON object as in the iOS process). The final line (the get on purchases_subscriptions) also includes the extra authentication step noted in the Android IAP Workflow section. If that authentication step fails, a Google_Auth_Exception is thrown. I wrapped the entire code in a try/catch so that if the call results in said exception, we throw our own exception. We then handle our exception at a higher level.
The mystery of the unnecessary P12 key file password
As a quick aside, you may have noticed that we didn’t pass in the key file’s password when creating the assertion credentials. In fact, we don’t need to use that password we received with the key file at all. If you take a look into the PHP client library on GitHub at line 57 of the AssertionaCredentials.php file, which contains the Google_Auth_AssertionCredentials class, you’ll see that the __construct function’s fourth argument is the key file’s password, and the default value is “notasecret”. As of this writing, all service account P12 key file passwords are “notasecret”. If that is no longer the case when you read this article, simply add the password as a fourth argument when creating the assertion credentials.
A valid subscription response will be in the form of:
An error response will look like:
If you’re validating a one-time product purchase receipt instead of a subscription, change the purchase_subscriptions get request to:
The valid product response contents are detailed in the Purchases.products resource documentation.
Validate the response
Awesome! We have a response from Google. Let’s see if the response indicates that the receipt we received from the app was valid:
The code above is specific to validating a subscription response. And since it is a subscription, we need to check if the subscription has already expired. This compares the current UTC time to the UTC time created from the subscription response. If you’re server’s default timezone is not set to UTC, then you will need to convert the expiration time to your timezone or convert the current time in your timezone to UTC time.
Store the validated receipt and start the subscription
Almost done! Knowing we have a valid subscription receipt, we store the transaction information in our database, add an active subscription for the user to the database, and then respond OK to the mobile app’s receipt validation request to indicate the user’s purchase completed properly and was indeed valid.
Closing Notes
Validating in-app purchases for Android or iOS is a lengthy process, and, as I mentioned, the documentation isn’t always clear and laid out in a logical step-by-step manner. Hopefully this guide helps you implement the process in your own app. This should also give you a good start to implement other features, such as canceling/refunding subscriptions via the app (rather than having to do this through the Google Wallet Merchant Center).
Regarding subscriptions specifically, unlike for iOS (at least in our case), an Android subscription does have a time length (for us it was one month) and will auto-renew. There are ways to set up webhooks through the Google Play Developer API Console, and perhaps you can set one specifically for listening if a user’s subscription doesn’t auto-renew or a user cancels it via the Play store. I found that the simpler solution was to just check with Google, at the subscription period’s expiration date and time, if the subscription is still active. You can use the same purchaseToken as in the original receipt (another reason to store that receipt) and follow the same process to make another call to the Purchases.subscriptions API resource. If the subscription was successfully renewed, then the expiration time in the response will again be in the future, meaning the user has been successfully charged for another subscription term. When this happens, the order number is slightly altered after each successful subscription renewal after the initial purchase:
This is detailed on the In-app Subscriptions page in the Subscription Order Numbers section. I keep track of the number of renewals via a counter column in my subscriptions table. And if I ever would have a need to get a specific recurrence of a subscription, I could construct that recurrence’s orderID from the renewal counter and the original order ID.
And a note on using the Google Play Developer Android Publisher API: Google lays out some best practices for using the API efficiently:
These are good practices to follow, as your developer account does have a request quota per day (200,000 API requests per day “as a courtesy”). Also, this helps decrease the number of HTTP requests between your server and Google, speeding up server responses to your mobile app.
And one more thing…
On Twitter, @dror3go asked about dealing with restoring a purchase if a user gets a new phone:
@pauly4it btw, how do you overcome the issue of users who made in-app purchase and then replace the phone?
It’s an interesting question, and there are three ways I can think of to deal with this:
My vote is for strategy #1. This offloads as much logic from the client onto the server. Theoretically, this means the client app will run faster, and if the server begins to use more resources, we can easily scale using AWS.
Источники информации:
- http://appuals.com/find-paid-apps-app-purchase-history-google-play/
- http://stackoverflow.com/questions/33850864/how-to-verify-purchase-for-android-app-in-server-side-google-play-in-app-billin
- http://deviceadvice.ru/android-how-to-find-purchase-receipt/
- http://blog.goforyt.com/validating-android-app-purchases-laravel/