Copy of Google Pay via Widget
This guide walks you through integrating Google Pay using the DEUNA Web‑SDK (@deuna/web-sdk v1.6). It covers the two integration paths the SDK exposes:
| Payment Widget | Payment Vault | |
|---|---|---|
| What it does** | Handles the full checkout: UI, payment processing, and confirmation | Tokenizes the card only — returns a card_id for you to use |
| Who processes the purchase | DEUNA (internally) | You (via the Purchase API from your backend) |
| Apple Pay button | Rendered inside DEUNA's iframe | Rendered by you, in your own UI |
| SDK method | initPaymentWidget | initElements({ types: ['GOOGLE_PAY'] }) |
| Use when | You want a drop-in checkout experience | You need control over the payment flow or want to store the card for later |
| Full integration reference | Payment Widget — Web SDK | Payment Vault - Web SDK |
1. Prerequisites
Before you start, make sure the following are in place:
| Requirement | Notes |
|---|---|
| DEUNA account | Active merchant account in the DEUNA Dashboard. |
publicApiKey | Public API key issued by DEUNA. Required for DeunaSDK.initialize. |
orderToken | Generated on your backend via the DEUNA Orders API. Required to start a payment. |
userToken (optional) | Required only when you want to tokenize the card against a known DEUNA user. |
| HTTPS domain | Google Pay requires the page to be served over HTTPS. localhost is allowed only for development. |
| Browser runtime | Chrome, Edge, Firefox, Safari (any evergreen browser). User must be signed into a Google account with a saved card. |
| Web‑SDK bundle | Loaded from the DEUNA CDN — not from npm. |
Loading the SDK from the CDN
Add the SDK script to your HTML (ideally in <head> so it's ready before checkout renders):
<script src="https://cdn.deuna.io/web-sdk/v1.6/index.js"></script>Once loaded, the SDK exposes a global DeunaSDK object on window:
const DeunaSDK = window.DeunaSDK;If you need to wait for the script to load before using it (e.g. when injecting it dynamically), listen for the load event:
const script = document.createElement("script");
script.src = "https://cdn.deuna.io/web-sdk/v1.6/index.js";
script.onload = () => {
// window.DeunaSDK is now available
};
document.head.appendChild(script);The SDK dynamically loads Google's
pay.jslibrary (https://pay.google.com/gp/p/js/pay.js) the first time Google Pay is initialized. You don't need to add it manually.
2. What needs to be pre‑configured for Google Pay
Unlike Apple Pay, Google Pay does not require hosting a verification file on your domain. Instead, the setup has two parts: credentials and, for production, domain registration inside the Google Pay Business Console.
2.1 Credentials (handled by DEUNA)
DEUNA resolves Google Pay credentials from your merchant configuration. The fields involved are:
| Field | Meaning | Where it comes from |
|---|---|---|
merchantId | Your Google Pay Merchant ID (e.g. 12345678901234567890). | Google Pay Business Console, stored in DEUNA Dashboard. |
merchantName | Label shown on the Google Pay sheet. | DEUNA Dashboard. |
gateway | Payment gateway identifier (e.g. "deuna", "adyen"). Used with PAYMENT_GATEWAY tokenization. | DEUNA Dashboard. |
gatewayMerchantId | Merchant identifier within the gateway. | DEUNA Dashboard. |
tokenizationType | "PAYMENT_GATEWAY" (default) or "DIRECT". | Merchant choice. |
publicKey (DIRECT only) | Base64‑encoded public key used for DIRECT tokenization. | DEUNA Dashboard. |
protocolVersion (DIRECT only) | Defaults to "ECv2". | DEUNA Dashboard. |
allowedCardNetworks | Subset of VISA, MASTERCARD, AMEX, DISCOVER, INTERAC, JCB. | Optional — defaults provided. |
allowedCardAuthMethods | PAN_ONLY, CRYPTOGRAM_3DS. | Optional — defaults provided. |
Most integrations will use PAYMENT_GATEWAY tokenization with DEUNA as the gateway. DIRECT is reserved for merchants that decrypt the Google Pay token themselves.
What you need to provide/confirm in the DEUNA Dashboard:
- Google Pay credential enabled for your merchant.
- Merchant ID and merchant name.
- Gateway and gateway merchant ID (for PAYMENT_GATEWAY).
- Allowed networks and auth methods (optional).
2.2 Domain registration (production only)
Google Pay requires that every production domain be registered in the Google Pay Business Console before it can take live payments:
- Go to Google Pay & Wallet Console → Integration → Business information.
- Register the domain(s) that will load the Web‑SDK (e.g.
checkout.mystore.com). - Submit your integration for approval (screenshots of the checkout flow are required).
No file needs to be hosted on your domain. Test/sandbox environments work out of the box — only production requires the console registration.
The SDK automatically switches Google Pay to
TESTmode for anyenvother than"production", so you can develop and QA without console registration.
3. Path A — Payment Widget
Use this when: you want DEUNA to handle the full checkout experience. Google Pay appears inside DEUNA's iframe alongside other payment methods. You do not call the Purchase API.
// DeunaSDK is the global injected by https://cdn.deuna.io/web-sdk/v1.6/index.js
const { DeunaSDK } = window;
// 1) Initialize the SDK once (e.g. at app bootstrap).
await DeunaSDK.initialize({
env: "staging", // "production" | "staging" | "develop" | "sandbox"
publicApiKey: "<YOUR_PUBLIC_API_KEY>",
});
// 2) Open the Payment Widget with an order. Google Pay is enabled automatically
// when the merchant has it configured in the DEUNA Dashboard.
await DeunaSDK.initPaymentWidget({
mode: "modal", // or "embedded" with a `target`
orderToken: "<ORDER_TOKEN>",
userToken: "<USER_TOKEN>", // optional
language: "es",
callbacks: {
onSuccess: (payload) => {
console.log("Payment success", payload);
DeunaSDK.close();
},
onError: (err) => console.error("Error", err),
onClosed: (action) => console.log("Closed by", action),
onPaymentProcessing:() => console.log("Processing..."),
onEventDispatch: (type, d) => console.log("Event", type, d),
},
});Notes:
- The widget renders the Google Pay button when the browser/device supports it and the merchant has Google Pay enabled.
- All Google Pay configuration (
merchantId,merchantName,gateway,gatewayMerchantId, tokenization, networks) is resolved by the widget via the DEUNA SSR endpoint. No extra params are needed on the client. - The SDK automatically calls
isReadyToPayunder the hood and hides the button on unsupported devices.
4. What the commerce must do for Google Pay
This is the checklist the merchant (commerce) owns:
- Serve the checkout over HTTPS. Google Pay refuses to run on
http://exceptlocalhost. - Register all production domains in the Google Pay Business Console (see §2.2). Staging/dev hosts don't need registration because the SDK runs Google Pay in
TESTmode there. - Complete the Google Pay brand‑compliance review. Upload screenshots of the full checkout (button on cart, payment sheet, confirmation) in the Business Console.
- Do not modify the Google Pay token. The SDK forwards
paymentMethodDataunchanged toonPaymentAuthorized/onSuccess. Re‑serializing it will break tokenization. - Respect the user gesture. When using
initElements, the button click must reachloadPaymentData()without a longawaitin between, or Chrome will block the sheet.
5. Initialize Google Pay using only initElements
initElementsUse this path when you want to render a native Google Pay button inside your own UI (no DEUNA iframe). Common in custom/headless checkouts.
5.1 SSR‑resolved configuration (recommended)
Let the SDK resolve Google Pay credentials from the DEUNA backend using your publicApiKey and (optionally) an orderToken.
// 1) Initialize the SDK
await DeunaSDK.initialize({
env: "staging",
publicApiKey: "<YOUR_PUBLIC_API_KEY>",
});
// 2) Check availability + warm up the Google Pay provider
const available = await DeunaSDK.getWalletsAvailable();
if (!available.includes("GOOGLE_PAY")) {
console.warn("Google Pay is not available on this device/merchant.");
return;
}
// 3) Mount the Google Pay button via initElements
await DeunaSDK.initElements({
types: [{ name: "GOOGLE_PAY", target: "#google-pay-container" }],
orderToken: "<ORDER_TOKEN>",
userInfo: {
email: "[email protected]",
firstName: "John",
lastName: "Doe",
},
callbacks: {
onSuccess: (payload) => console.log("Google Pay success", payload),
onError: (err) => console.error("Google Pay error", err),
onClosed: (action) => console.log("Sheet closed:", action),
},
});5.2 What the SDK does for you
When the user taps the Google Pay button, the SDK:
- Uses Google's
PaymentsClient(already loaded frompay.js) configured withTESTorPRODUCTIONbased onenv. - Builds the
paymentDataRequestby merging parentwalletConfigwith any iframe‑supplied params (parent wins). - Calls
client.loadPaymentData(paymentDataRequest)to open the Google Pay sheet. - Forwards the (unmodified)
paymentMethodDatathroughonPaymentAuthorizedand thenonSuccess. - Translates Google's
statusCode: "CANCELED"intoonClosed("userAction").
5.3 Gotchas
| Gotcha | Fix |
|---|---|
| Button does not render | Check getWalletsAvailable() result. isReadyToPay may be rejecting the device — verify you're signed into Google and have a saved card. |
| Works locally, fails in production | Domain is not registered in the Google Pay Business Console. |
DEVELOPER_ERROR in the sheet | merchantId, gateway, or gatewayMerchantId is wrong or missing. Double‑check the walletConfig. |
| Sheet opens but no payment methods | Card networks in allowedCardNetworks don't match any saved card on the Google account. |
| Token decryption fails on your backend | You're in DIRECT mode with a mismatched publicKey / protocolVersion. Prefer PAYMENT_GATEWAY unless you need raw card data. |
Quick reference
| API | Purpose |
|---|---|
DeunaSDK.initialize({ env, publicApiKey }) | One‑time SDK bootstrap. |
DeunaSDK.initPaymentWidget({ orderToken, callbacks, ... }) | Open DEUNA's full Payment Widget (Google Pay included). |
DeunaSDK.getWalletsAvailable() | Check which wallets are usable + warm up providers. |
DeunaSDK.initElements({ types, orderToken?, walletConfig?, callbacks }) | Mount native wallet buttons in your own UI. |
| Google Pay Business Console | Where production domains must be registered. No file to host on your server. |
Updated about 3 hours ago