# Set up Google Pay™ (API)

> Configure Google Pay on your VINR account and integrate directly with the Google Pay JavaScript API.

This page covers the direct API integration using the Google Pay JavaScript API in your own checkout UI. If you use a different integration path you may not need any of this code:

| Integration path     | What to read instead                                                                                                                      |
| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| VINR hosted checkout | [Google Pay in hosted checkout](/docs/payments/payment-methods/add-payment-methods/wallets/google-pay/hosted-checkout) — no code required |
| Payment links        | [Google Pay in payment links](/docs/payments/payment-methods/add-payment-methods/wallets/google-pay/payment-links) — no code required     |
| VINR Elements        | [Google Pay with Elements](/docs/payments/payment-methods/add-payment-methods/wallets/google-pay/elements) — minimal setup                |

> To use Google Pay, you **must** accept the [Google Pay API Terms of Service](https://payments.developers.google.com/terms/sellertos) and **must** comply with the [Google Pay API Acceptable Use Policy](https://payments.developers.google.com/terms/aup). See also the [Google Pay Web developer documentation](https://developers.google.com/pay/api/web/overview), [Web integration checklist](https://developers.google.com/pay/api/web/guides/test-and-deploy/integration-checklist), and [Web Brand Guidelines](https://developers.google.com/pay/api/web/guides/brand-guidelines).

## Enable Google Pay in the Dashboard

1. Go to **Settings → Payment methods** in the VINR Dashboard.
2. Toggle **Google Pay** to enabled.

The integration below identifies you with two VINR values in the Google Pay request — the gateway ID `vinrpay` and your VINR account ID (see [Tokenization specification](#tokenization-specification)). Your VINR secret key is needed only server-side, when you create the payment.

## Integration

### 1. Configure the payment request

Set `allowedAuthMethods` to the methods enabled on your VINR merchant account. Most accounts support both — see [Authentication methods](/docs/payments/payment-methods/add-payment-methods/wallets/google-pay/authentication-methods) for what each method means and how to request a configuration change.

VINR supports **Visa** and **Mastercard** for Google Pay. Set `allowedCardNetworks` to `['MASTERCARD', 'VISA']` — other networks are not supported and including them causes the token to be rejected at checkout.

```javascript
const googlePayClient = new google.payments.api.PaymentsClient({
  environment: 'PRODUCTION', // use 'TEST' in sandbox
});

const paymentDataRequest = {
  apiVersion: 2,
  apiVersionMinor: 0,
  allowedPaymentMethods: [{
    type: 'CARD',
    parameters: {
      allowedAuthMethods: ['CRYPTOGRAM_3DS', 'PAN_ONLY'], // match your merchant account config
      allowedCardNetworks: ['MASTERCARD', 'VISA'],         // match your enabled networks
    },
    tokenizationSpecification: {
      type: 'PAYMENT_GATEWAY',
      parameters: {
        gateway: 'vinrpay',                        // VINR's Google-registered gateway ID — constant
        gatewayMerchantId: 'YOUR_VINR_ACCOUNT_ID', // your VINR account ID — not your API key
      },
    },
  }],
  merchantInfo: {
    merchantName: 'Your Business Name',
  },
  transactionInfo: {
    totalPriceStatus: 'FINAL',
    totalPrice: '45.00',
    currencyCode: 'EUR',
    countryCode: 'BG',
  },
};
```

> The request above is the minimal configuration. To also collect the billing address and customer email — which VINR includes with the payment — add the parameters shown under [Billing address](#billing-address) below.

### Tokenization specification

The `tokenizationSpecification` object tells Google how to encrypt the payment token so that VINR can decrypt it. Set these values exactly:

| Field               | Value                | Description                                                                                                                                  |
| ------------------- | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| `type`              | `'PAYMENT_GATEWAY'`  | Google encrypts the token for VINR (your gateway) to decrypt. Do not use `'DIRECT'` — that requires merchant-side PCI DSS validation.        |
| `gateway`           | `'vinrpay'`          | VINR's gateway ID, registered with Google. This is a constant — use it verbatim.                                                             |
| `gatewayMerchantId` | your VINR account ID | Identifies which VINR merchant account receives the payment. Assigned by VINR and available in the Dashboard — **this is not your API key**. |

```javascript
tokenizationSpecification: {
  type: 'PAYMENT_GATEWAY',
  parameters: {
    gateway: 'vinrpay',
    gatewayMerchantId: 'YOUR_VINR_ACCOUNT_ID',
  },
}
```

> Do not confuse `gatewayMerchantId` with `merchantInfo.merchantId`. `gatewayMerchantId` is your VINR account ID (assigned by VINR). `merchantInfo.merchantId` is your Google-assigned merchant ID — VINR provisions this for you during onboarding and you'll find it in the VINR Dashboard; it is required only in the `PRODUCTION` environment. Mixing up these two values is the most common cause of `invalid_token` errors in production — see the [Go-live checklist](/docs/payments/payment-methods/add-payment-methods/wallets/google-pay/go-live-checklist).

### 2. Check readiness and render the button

Only render the button after `isReadyToPay` returns `true`. Call `loadPaymentData` synchronously in the click handler so the browser does not block the payment sheet as a pop-up.

```javascript
googlePayClient.isReadyToPay({
  apiVersion: 2,
  apiVersionMinor: 0,
  allowedPaymentMethods: paymentDataRequest.allowedPaymentMethods,
}).then(response => {
  if (response.result) {
    const button = googlePayClient.createButton({
      onClick: () => googlePayClient.loadPaymentData(paymentDataRequest)
        .then(paymentData => sendTokenToServer(paymentData))
        .catch(err => {
          if (err.statusCode !== 'CANCELED') {
            document.getElementById('error-message').textContent = err.message || 'Payment failed';
          }
        }),
    });
    document.getElementById('google-pay-button').appendChild(button);
  }
});
```

### 3. Send the token to your server

Extract the encrypted token from `paymentData.paymentMethodData.tokenizationData.token` and POST it to your backend. As Google's documentation states, if you are using gateway tokenization, **pass this token to your server without modification** — do not decode, re-encode, strip, or log it.

```javascript
async function sendTokenToServer(paymentData) {
  // paymentData → paymentMethodData → tokenizationData → token
  const token = paymentData.paymentMethodData.tokenizationData.token;

  const response = await fetch('/your-checkout-endpoint', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ googlePayToken: token, amount: 4500, currency: 'EUR' }),
  });

  if (!response.ok) {
    const { message } = await response.json();
    throw new Error(message || 'Payment failed');
  }

  return response.json();
}
```

### 4. Submit the token to VINR

From your backend, submit the Google Pay token to a VINR payment intent. This is a two-step, server-to-server flow: **create the intent**, then **process** it with the encrypted token. Your `X-Api-Key` is sent only from your server, never the browser.

> The base URL below is the **sandbox** API (`https://edge.dev.briklabs.io`). Switch to your VINR production API base when you go live. `amount` is in the currency's minor units (`4500` = €45.00).

```bash
# 1. Create a payment intent — returns its id
curl --request POST \
  --url https://edge.dev.briklabs.io/checkout/intent \
  --header 'X-Api-Key: YOUR_VINR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
    "amount": 4500,
    "currency": "EUR",
    "customer": { "customerId": "cust_123", "email": "jane@example.com", "name": "Jane Doe" },
    "configId": "YOUR_CHECKOUT_CONFIG_ID"
  }'
# → { "id": "INTENT_ID", "amount": 4500, "currency": "EUR", ... }
```

```bash
# 2. Process the intent with the Google Pay token — pass it unmodified
curl --request POST \
  --url https://edge.dev.briklabs.io/checkout/intent/INTENT_ID/process \
  --header 'X-Api-Key: YOUR_VINR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
    "paymentMethod": {
      "type": "googlePay",
      "googlePay": { "encryptedToken": "GOOGLE_PAY_TOKEN" }
    },
    "billingDetails": {
      "name": "Jane Doe",
      "email": "jane@example.com",
      "phone": "+35988123456",
      "address": {
        "line1": "1 Vitosha Blvd",
        "city": "Sofia",
        "postalCode": "1000",
        "country": "BG"
      }
    },
    "contactInfo": { "email": "jane@example.com" }
  }'
```

`GOOGLE_PAY_TOKEN` is the value of `paymentData.paymentMethodData.tokenizationData.token` from Step 3 — sent through unaltered. VINR decrypts it, identifies the credential type (`PAN_ONLY` or `CRYPTOGRAM_3DS`), and applies the appropriate risk and 3DS handling automatically.

### 5. Handle the 3D Secure challenge (if required)

If the process response contains `nextAction.type === "challenge"`, a 3D Secure step-up is required. This is expected for `PAN_ONLY` credentials — VINR routes them through its 3DS engine automatically (see [Authentication methods](/docs/payments/payment-methods/add-payment-methods/wallets/google-pay/authentication-methods)).

> When the shopper completes the challenge, the card issuer's ACS redirects their browser back to a VINR-hosted page — not a URL on your own domain. If you are integrating directly against the Google Pay API on your own checkout page (rather than using VINR's hosted checkout or Elements), you cannot currently host your own challenge-completion page or receive this redirect on your domain. Contact your VINR account manager before relying on this flow for a fully custom integration.

Once the challenge completes, confirm the payment with the `threeDSServerTransID` returned in `nextAction`:

```bash
curl --request POST \
  --url https://edge.dev.briklabs.io/checkout/intent/INTENT_ID/confirm \
  --header 'X-Api-Key: YOUR_VINR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{ "threeDSServerTransID": "VALUE_FROM_nextAction" }'
```

> Always confirm the final payment state from the `payment.completed` webhook on your server, not the client-side response — the customer's browser may close before the redirect returns.

## Billing address

VINR's hosted checkout requests a **full** billing address (with phone number) and the customer's email, and we recommend you do the same so you can supply complete billing details when you submit the payment. Set `billingAddressRequired: true` with `format: 'FULL'` on the card parameters, and `emailRequired: true` at the top level of the request. For more details, see Google's [`BillingAddressParameters` reference](https://developers.google.com/pay/api/web/reference/request-objects#BillingAddressParameters):

```javascript
const paymentDataRequest = {
  apiVersion: 2,
  apiVersionMinor: 0,
  emailRequired: true, // request the customer's email (top-level field)
  allowedPaymentMethods: [{
    type: 'CARD',
    parameters: {
      allowedAuthMethods: ['CRYPTOGRAM_3DS', 'PAN_ONLY'],
      allowedCardNetworks: ['MASTERCARD', 'VISA'],
      billingAddressRequired: true,
      billingAddressParameters: {
        format: 'FULL',          // 'FULL' (full street address) or 'MIN' (name, country, postal code)
        phoneNumberRequired: true,
      },
    },
    // tokenizationSpecification: { ... }  // see Tokenization specification above
  }],
  // merchantInfo, transactionInfo: { ... }
};
```

| Parameter                                      | Recommended | Description                                                                                                             |
| ---------------------------------------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------- |
| `billingAddressRequired`                       | `true`      | Request a billing address. VINR's checkout sets this to `true`.                                                         |
| `billingAddressParameters.format`              | `'FULL'`    | `'FULL'` returns the full street address; `'MIN'` returns only name, country code, and postal code. VINR uses `'FULL'`. |
| `billingAddressParameters.phoneNumberRequired` | `true`      | Also request the customer's phone number. VINR sets this to `true`.                                                     |
| `emailRequired`                                | `true`      | Request the customer's email. Set on the `PaymentDataRequest` itself — **not** inside `billingAddressParameters`.       |

When these are set, the billing address is returned on the Google Pay response at `paymentData.paymentMethodData.info.billingAddress` and the email at `paymentData.email`. Pass these along as the billing details when you submit the payment to VINR.

## Button guidelines

Google enforces brand guidelines for the payment button. Use only the approved button styles and do not modify the Google Pay logo. The `createButton` API returns a pre-styled, compliant button automatically. See [Button guidelines](/docs/payments/payment-methods/add-payment-methods/wallets/google-pay/button-guidelines) and the [Google Pay Web Brand Guidelines](https://developers.google.com/pay/api/web/guides/brand-guidelines).

## See also

[Authentication methods](/docs/payments/payment-methods/add-payment-methods/wallets/google-pay/authentication-methods) — CRYPTOGRAM\_3DS vs PAN\_ONLY: how VINR handles each and per-merchant configuration.

[Test & go live](/docs/payments/payment-methods/add-payment-methods/wallets/google-pay/test-and-go-live) — Test your integration and submit for production approval.

[Google Pay overview](/docs/payments/payment-methods/add-payment-methods/wallets/google-pay) — How Google Pay works with VINR.
