Google Pay
This guide covers the communication flow between a Headless Storefront, the Adyen Web library, and the VTEX Payment Provider Protocol (PPP) for Google Pay payments.
Because headless storefronts control their own UI, developers must manually orchestrate the data extraction from VTEX, the rendering of Adyen Components, and the API calls to the VTEX Connector backend.
The Google Pay payment method configured in Adyen must be the paywithgoogle variant. See the Google Pay configuration guide for the full setup.
Extracting Google Pay credentials
Inside the appPayload returned by the gateway callback (see Step 2), extract the Google Pay credentials:
const googlePaymentMethods = paymentMethods.paymentMethods.find(
payments => payments.type === 'paywithgoogle'
)
const googleMerchantName = googlePaymentMethods.configuration.gatewayMerchantId
const googleMerchantId = googlePaymentMethods.configuration.merchantId
Use these values in the paymentMethodsConfiguration object when initializing AdyenCheckout:
paymentMethodsConfiguration: {
googlepay: {
configuration: {
merchantName: merchantName,
merchantId: googleMerchantId,
gatewayMerchantId: googleMerchantName,
},
},
}
Step 1: Save Browser Information
At the beginning of the checkout process (before the user places the order), your frontend must send the shopper's browser information to the backend connector. This data is mandatory for 3D Secure (3DS) flows.
Because headless storefronts run on a different domain than the VTEX API (which blocks traditional cross-domain session cookies), you must explicitly pass the orderformId in the request body.
Endpoint: POST https://{your-vtex-account}.myvtex.com/api/io/_v3/api/save-checkout-info
Payload:
{
"browserInfo": {
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36",
"acceptHeader": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
"language": "pt-PT",
"colorDepth": 32,
"screenHeight": 748,
"screenWidth": 1707,
"timeZoneOffset": -3,
"javaEnabled": false
},
"origin": "https://www.your-headless-store.com",
"orderformId": "10928nr01927rb6basdb61"
}
Capture browser data dynamically using the browser's navigator and window.screen objects.
Step 2: Place Order and Extract appPayload
When the user clicks "Place Order", call the standard VTEX Place Order API, then call /api/checkout/pub/gatewayCallback/${orderGroupId} to retrieve the appPayload. This payload contains all configuration data generated by the connector to initialize Adyen components.
Example of parsed appPayload:
{
"authorization": {},
"merchantName": "Test",
"paymentType": "googlepay",
"environment": "test",
"action": false,
"lineItems": [
{
"quantity": "1",
"taxPercentage": "0",
"productUrl": "",
"imageUrl": "",
"amountIncludingTax": "25",
"id": "123",
"description": "test"
}
],
"paymentMethods": {}
}
Step 3: Handling Adyen Component Events
onSubmit
Triggered when the shopper submits the payment data.
Purpose: initiate payment authorization.
Endpoint: POST /api/io/_v/api/payment-authorization
Payload:
{
"paymentMethod": {},
"authorization": {}
}
Pass the API response to the component using component.handleAction(data) when required (e.g., 3DS, redirects).
onChange
Triggered when the component state changes and becomes valid. Used for payment methods that do not have an explicit submit button.
Endpoint: POST /api/io/_v/api/payment-authorization
Payload:
{
"paymentMethod": {},
"authorization": {}
}
Handle the response with component.handleAction(data).
onAdditionalDetails
Triggered when Adyen requires additional information (e.g., 3D Secure authentication).
Purpose: complete the payment authentication step.
Endpoint: POST /api/io/_v/api/payment-details
Payload:
{
...state.data,
...authorization
}
Based on the response, resolve the payment flow (success or failure).
Payment Status Polling
Call this endpoint at intervals (e.g., every 5 seconds) while the status is pending.
Endpoint: POST /api/io/_v/api/payment-status
Payload:
{
"paymentId": "payment identifier"
}
Treat the following statuses as successful:
AuthorisedReceivedPending(depending on your business logic)
Any other status should be treated as a failure or refusal.
Step 4: Handling 3DS and External Redirects
When a user undergoes a 3D Secure challenge or uses an external wallet, they are redirected away from your storefront. After authentication, the VTEX Payment Gateway issues a hardcoded 302 redirect to:
/checkout/orderPlaced/?og={orderGroup}
Your headless application must implement a route at /checkout/orderPlaced. This page should:
- Capture the
og(Order Group) parameter from the URL. - Fetch the order details using the VTEX Orders API (if needed).
- Display your custom "Order Confirmation" UI.
If you do not create this route, users returning from 3DS validations will encounter a 404 error on your headless storefront.