Skip to content

Decrypted Token

This guide describes how to create a payment with a Google Pay™ token that you decrypt yourself. Use it only when you have your own Google Pay integration with your own keys and need the decrypted payment data in your systems.

Prerequisites

  1. An Armaghast requestor with Google Pay enabled, its requestor ID and Bearer token. Decrypted tokens are accepted only on terminals whose acquirer supports them; ask your account manager to confirm this for your requestor.
  2. Your own Google Pay integration with the tokenization type DIRECT and your own keys to decrypt the token, see Payment data cryptography.
  3. Decryption on your backend that verifies the signature and messageExpiration, for example with Tink.

Implementation Process

  1. Receive the encrypted token from paymentMethodData.tokenizationData.token.
  2. Decrypt it on your backend and verify it.
  3. Put the decrypted JSON, unchanged, into the googlePayToken message extension under the key decryptedTokenJson. The value is a string with the JSON inside.
  4. Send a sale or auth request with paymentMethod: GOOGLE_PAY_TOKEN. Do not send the googlePayToken field: when it is present, Armaghast decrypts it itself and rejects the message extension.

Decrypted token

This is the decrypted token as Google defines it. Send it as is; do not rename or reformat its fields.

{
"messageExpiration": "1780000000000",
"messageId": "AH2EjtcgJh0...",
"paymentMethod": "CARD",
"paymentMethodDetails": {
"authMethod": "CRYPTOGRAM_3DS",
"pan": "4895370012003478",
"expirationMonth": 12,
"expirationYear": 2030,
"cryptogram": "AgAAAAAABk4DWZ4C28yUQAAAAAA=",
"eciIndicator": "05"
}
}
FieldRequiredNote
paymentMethodYesCARD
paymentMethodDetails.authMethodYesPAN_ONLY or CRYPTOGRAM_3DS
paymentMethodDetails.panYes12–19 digits
paymentMethodDetails.expirationMonthYesNumber, 1–12
paymentMethodDetails.expirationYearYesNumber, four digits
paymentMethodDetails.cryptogramFor CRYPTOGRAM_3DS
paymentMethodDetails.eciIndicatorIf Google returns itSend it as Google returned it

A PAN_ONLY token carries no cryptogram:

{
"paymentMethod": "CARD",
"paymentMethodDetails": {
"authMethod": "PAN_ONLY",
"pan": "4111111111111111",
"expirationMonth": 1,
"expirationYear": 2029
}
}

Sale/Auth example

{
"order": {
"orderMerchantId": "123",
"orderDescription": "Order description",
"orderAmount": "10.00",
"orderCurrencyCode": "EUR"
},
"browser": {
"ipAddress": "123.123.123.123"
},
"urls": {
"resultUrl": "https://merchant.example/result"
},
"paymentMethod": "GOOGLE_PAY_TOKEN",
"messageExtensions": [
{
"name": "googlePayToken",
"keyValues": {
"decryptedTokenJson": "{\"messageExpiration\":\"1780000000000\",\"messageId\":\"AH2EjtcgJh0...\",\"paymentMethod\":\"CARD\",\"paymentMethodDetails\":{\"authMethod\":\"CRYPTOGRAM_3DS\",\"pan\":\"4895370012003478\",\"expirationMonth\":12,\"expirationYear\":2030,\"cryptogram\":\"AgAAAAAABk4DWZ4C28yUQAAAAAA=\",\"eciIndicator\":\"05\"}}"
}
}
]
}

Important: decryptedTokenJson is a string. Serialize the decrypted JSON once and put the resulting string there; do not nest it as an object.

Troubleshooting

  1. Message extension rejected (-44): you sent googlePayToken together with the message extension. In the decrypted flow, send only the message extension.
  2. Missing fields: check that the decrypted JSON has paymentMethodDetails with pan, expirationMonth and expirationYear, and cryptogram for CRYPTOGRAM_3DS.
  3. Expired token: decrypt and send the token right away; do not send a token past its messageExpiration.
  4. Payment declined as not supported: the acquirer of your terminal does not accept decrypted Google Pay tokens. Contact Armaghast support.