After adding a subscription product to your app in Google Play Console and implementing the in-app purchase code, you will find yourself looking at a purchase receipt that needs to be verified. Verification cannot be done from within the app, it has to be done from server to server. I will outline how to set up the project, account and permissions to do this.
First, you will need to create a Google Cloud Platform project, and I believe that you should create this project using the same Google account that you have logged into the Play Console. I haven’t tested out NOT using the same user, and I’ve read a number of people saying that you must use the same user, but I’m not sure if that’s actually true. As with all things related to permissions, it’s likely best that you just use the same user.
Inside the Google Cloud project, go into “APIs and Services”, click the “+” to add a new API, and then add the API named “Google Play Android Developer API”.
Still inside the Google Cloud project, go into IAM and create a Service Account. Give it the Viewer role. Create a new key for this service account and save it as a JSON file named service-account.json
Copy the email address for the Service Account.
Within Google Play Console, from the “All Apps” home screen, click on “Users and Permissions”, and then “Invite New Users”. Paste the email address for the Service Account and then grant it the following permissions:
- View app information and download bulk reports (read-only)
- View financial data, orders, and cancellation survey responses
- Manage orders and subscriptions
The above step is critically important. Without it, you will run into 401 permission errors if you try to run code that queries the androidpublisher API.
From within your app code, ensure that you are printing the purchase receipt details, because you will need to copy them from the console later.
Your app should be published to the Google Play Store under the test track “Internal Testing”. Remember to add your testing user as a “License Tester” so that all your purchases are fake and they don’t actually charge your credit card. Invite your test user to test the app and then install the Internal Testing version of the app on your device.
You should already have a subscription product created and published in your app, but if not then go publish one now. Make a subscription purchase. Using adb
you can then look at the device logs. Grab a copy of the purchase details, it will look something like this:
{
"orderId":"GPA.3378-6966-0708-62563",
"packageName":"com.example.game",
"productId":"com.example.game.subscribe",
"purchaseTime":1741899145093,
"purchaseState":0,
"purchaseToken":"kljbpdhecfjbihmpmnclhncbJ1OzSGctAk_39kqPo",
"quantity":1,
"autoRenewing":true,
"acknowledged":false
}
On your server (or wherever you want to try out the code below) install the python modules googleapiclient and google-auth. Edit the following code and paste in your own values for the three variables:
import sys
import json
from googleapiclient.discovery import build
from google.oauth2 import service_account
def main(argv):
credentials = service_account.Credentials.from_service_account_file(
"service-account.json",
scopes=["https://www.googleapis.com/auth/androidpublisher"]
)
print(f"Using service account: {credentials.service_account_email}\n")
# Hard coded values for testing
appPackage="com.example.game"
subscriptionProductID="com.example.game.subscribe"
purchaseToken="kljbpdhecfjbihmpmnclhncbJ1OzSGctAk_39kqPo"
#Build the service interface to the API
service = build("androidpublisher", "v3", credentials=credentials)
#Use the token to verify the purchase
result = service.purchases().subscriptions().get(packageName=appPackage, subscriptionId=subscriptionProductID, token=purchaseToken).execute()
print(json.dumps(result, indent=2))
if __name__ == "__main__":
main(sys.argv)
This Python script must be in the same directory as the service-account.json file you saved above. Once you run the code, it should print something like this:
Using service account: test1@testproj-12345.iam.gserviceaccount.com
{
"startTimeMillis": "1741899145093",
"expiryTimeMillis": "1741901245093",
"autoRenewing": false,
"priceCurrencyCode": "USD",
"priceAmountMicros": "1390000",
"countryCode": "US",
"developerPayload": "",
"cancelReason": 0,
"userCancellationTimeMillis": "1741900993593",
"orderId": "GPA.3378-6966-0708-62563..5",
"purchaseType": 0,
"acknowledgementState": 1,
"kind": "androidpublisher#subscriptionPurchase"
}
That’s it for now. You have everything in place as far as accounts and authorizations in order to verify purchase receipts.
This example was with a subscription product, however you can also verify receipts for non-subscription products by changing the code above (the .subscriptions()
call needs to be replaced).