On this page
No Headings
Last updated: June 10, 2026
Use this guide to integrate the Google Pay payment handler for Google's Universal Commerce Protocol (UCP) with Braintree as your payment provider. This enables AI-powered checkout experiences through Google AI Mode (Gemini), where Google Pay returns a tokenized credential that Braintree can process, and your server uses it to process the payment.
In a standard Google Pay integration, tokenization happens client-side. With UCP, Google shifts this to the server side. The following table shows the key differences.
| Integration detail | Standard integration | UCP or AI mode integration |
|---|---|---|
| Client SDK | Required in your web or mobile client | Not used in your client |
| Tokenization | Performed client-side through SDK | Google handles tokenization on server side |
| Single-use token delivery | SDK returns to client | Google includes it in checkout-complete payload |
| Parsing | SDK parses automatically | Merchant parses androidPayCards JSON |
Using Google's UCP, AI agents can:
Transaction.sale or chargePaymentMethod GraphQL mutation.When registering your UCP profile with Google, you will define a full Google Pay payment handler specification. The following tokenizationSpecification block is the Braintree-specific section that belongs inside the allowed_payment_methods entry of that specification. For more information, see the Google Pay payment handler specification.
{
"payment_handlers": {
"com.google.pay": [
{
"id": "YOUR_HANDLER_UUID",
"name": "com.google.pay",
"version": "2026-01-23",
"config": {
"api_version": 2,
"api_version_minor": 0,
"environment": "PRODUCTION",
"merchant_info": {
"merchant_name": "YOUR_BUSINESS_NAME",
"merchant_id": "YOUR_GOOGLE_MERCHANT_ID",
"merchant_origin": "checkout.yourdomain.com"
},
"allowed_payment_methods": [
{
"type": "CARD",
"parameters": {
"allowed_auth_methods": ["PAN_ONLY"],
"allowed_card_networks": [
"AMEX",
"DISCOVER",
"MASTERCARD",
"VISA"
],
"billingAddressRequired": true,
"billingAddressParameters": {
"format": "FULL",
"phoneNumberRequired": false
}
},
"tokenizationSpecification": {
"type": "PAYMENT_GATEWAY",
"parameters": {
"gateway": "braintree",
"braintree:apiVersion": "v1",
"braintree:sdkVersion": "BRAINTREE_SDK_VERSION",
"braintree:merchantId": "YOUR_BRAINTREE_MERCHANT_ID",
"braintree:clientKey": "YOUR_BRAINTREE_TOKENIZATION_KEY"
}
}
}
]
}
}
]
}
}| Parameter | Description |
|---|---|
gateway | Set to braintree |
braintree:apiVersion | API version (v1) |
braintree:sdkVersion | Braintree-web SDK version string such as "3.136.0" |
braintree:merchantId | Your Braintree public merchant ID |
braintree:clientKey | Your Braintree tokenization key |
braintree:clientKeyrequires a tokenization key. See the Braintree tokenization key documentation for details. > -braintree:sdkVersionvalue comes from the merchant's pinned braintree-web dependency or npm. The system uses it for telemetry and observability only and doesn't affect tokenization or payment behavior.
When Google calls your /checkout-session/{id}/complete endpoint, the payment payload includes the Braintree single-use token in the credential.token field.
Expected payload structure
{
"payment": {
"instruments": [
{
"id": "pm_1234567890abc",
"handler_id": "8c9202bd-63cc-4241-8d24-d57ce69ea31c",
"type": "card",
"display": {
"brand": "visa",
"last_digits": "4242"
},
"billing_address": {
"street_address": "123 Main Street",
"extended_address": "Suite 400",
"address_locality": "Charleston",
"address_region": "SC",
"postal_code": "29401",
"address_country": "US",
"first_name": "Jane",
"last_name": "Smith"
},
"credential": {
"type": "PAYMENT_GATEWAY",
"token": "{\"androidPayCards\":[{\"\":\"bd4c9b33-6e1c-11d8-1f4b-c0117fad06f7\",\"description\":\"Android Pay\",\"details\":{\"bin\":\"411111\",\"cardType\":\"Visa\",\"lastFour\":\"4242\"}}]}"
}
}
]
},
"risk_signals": {}
}Parsing the single-use token
The credential.token contains a JSON string with the androidPayCards array. Parse it to extract the single-use token.
// Parse the token from Google's checkout complete payload
const tokenData = JSON.parse(payment.instruments[0].credential.token);
const nonce = tokenData.androidPayCards[0].nonce;
// Use the nonce with Braintree
console.log(nonce); // "bd4c9b33-6e1c-11d8-1f4b-c0117fad06f7"Use the extracted single-use token exactly as you would any other Braintree payment method.
Using Braintree SDK (Node.js)
const result = await gateway.transaction.sale({
amount: "10.00",
paymentMethodNonce: nonce,
options: {
submitForSettlement: true,
},
});
if (result.success) {
console.log("Transaction ID:", result.transaction.id);
} else {
console.error("Transaction failed:", result.message);
}Using GraphQL
mutation ChargePaymentMethod($input: ChargePaymentMethodInput!) {
chargePaymentMethod(input: $input) {
transaction {
id
status
amount {
value
currencyCode
}
}
}
}Variables
{
"input": {
"paymentMethodId": "bd4c9b33-6e1c-11d8-1f4b-c0117fad06f7",
"transaction": {
"amount": "10.00"
}
}
}Vaulting considerations
If you need to vault the Google Pay payment method for recurring transactions:
const result = await gateway.customer.create({
firstName: "Jane",
lastName: "Smith",
paymentMethodNonce: nonce,
});
if (result.success) {
const paymentMethodToken = result.customer.paymentMethods[0].token;
// Store this token for future transactions
}Review Google Pay's terms regarding vaulting network-tokenized cards and FPAN-based cards. Braintree treats the Google Pay-derived credential as a single-use payment method that may only be used once and expires after 3 hours if unused, so avoid flows that try to both charge and vault the same value.
Use the following information to diagnose and resolve common integration issues.
| Error | Cause | Solution |
|---|---|---|
Unknown or expired single-use payment method | Single-use token expired or wrong merchant ID |
|
Empty androidPayCards array | Tokenization failed | Verify tokenization key and merchant ID configuration. |
tokenizationSpecification section.