Picture of a mobile phone with the Google Pay app open next to a Mac.
Photo by Matthew Kwong on Unsplash

How to decrypt Google Pay tokens using Python

Delena Malan
Yoyo Engineering
Published in
2 min readAug 17, 2021

--

Google Pay provides a secure way for users to make payments using saved cards on Android phones. If you want to support Google Pay payments in your Android app, you would most likely want to use Google Pay’s Gateway Integration to process payments through a Payment Service Provider (PSP).

However, if your business is Payments Card Industry (PCI) Data Security Standard (DSS) Level 1 compliant, you might want to use the Direct Integration which will allow you to decrypt Google Pay tokens in your backend.

The Google Pay documentation describes the process of verifying and decrypting tokens. Google also developed a Java library, Tink, which can be used to decrypt these tokens. We used the documentation and Tink to implement a Python package: google-pay-token-decryption. In the rest of this article, we will describe how to use this package.

1. Install the google-pay-token-decryption package

You would need Python 3.8+ and pip to install the package:

pip install google-pay-token-decryption

2. Create an instance of GooglePayTokenDecryptor

To decrypt a token, you first need to set up a new instance of GooglePayTokenDecryptor:

from google_pay_token_decryption import GooglePayTokenDecryptordecryptor = GooglePayTokenDecryptor(
root_signing_keys,
recipient_id,
private_key
)
  • root_signing_keys is a list of Google’s root signing keys. Test keys can be fetched here and production keys can be fetched here.
  • recipient_id is your Google merchant ID from the Google Pay business console in the format “merchant:<your merchant ID>”. In Google’s test environment, it will always be “merchant:12345678901234567890”.
  • private_key is your base64-encoded private key in PKCS #8 format which can be generated by following these steps in the Google Pay documentation.

3. Decrypt the token

Now that you have an instance of GooglePayTokenDecryptor , you can decrypt a token using its decrypt_token method:

decrypted_token = decryptor.decrypt_token(encrypted_token)

encrypted_token is a Dict version of the encrypted JSON token you’ve received from your Android app. An example would look like this:

encrypted_token = {
"signature": "MEYCIQCbtFh9UIf1Ty3NKZ2z0ZmL0SHwR30u...",
"intermediateSigningKey": {
"signedKey": "{\"keyValue\":\"MFkwEwYHKoZIzj0CAQYIIzj0D...\",\"keyExpiration\":\"1879409613939\"}",
"signatures": [
"MEQCIFBle+JsfsovRBeoFEYKWFAeBYFAhq0S+Gtu..."
]
},
"protocolVersion": "ECv2",
"signedMessage": "{\"encryptedMessage\":\"PeYi+ZnJs1Gei1dSOkItd...",\"ephemeralPublicKey\":\"BD6pQKpy7yDebAX4q...",\"tag\":\"8gFteCvCuamX1RmL7OR..."}"
}

Google provides a test environment in which you can generate test tokens to test your implementation.

--

--