Google Pay via direct API

This guide covers how to integrate Google Pay directly with DEUNA's API. Direct integration gives you full control over the payment flow, making it ideal for merchants who need custom implementations or have existing payment systems. This integration supports one-time payments.

📘

Google Pay via API is only supported in Purchase V2. Purchase V1 is not supported.

Google Pay with DEUNA

The following is the standard process for a Google Pay purchase with DEUNA:

  1. Get the payment methods
  2. Initialize the Google Pay Web SDK
  3. Purchase with Google Pay

1. Get the payment methods

Retrieve the Google Pay credential ID and SDK configuration parameters.

See Get Payment Methods API reference

Response

{
  "data": [
    {
      "allow_installments_plan": true,
      "credentials": {
        "external_merchant_id": "merchant.test.io.deuna.pay"
      },
      "enabled": true,
      "extra_params": {
        "allowed_auth_methods": [
          "PAN_ONLY",
          "CRYPTOGRAM_3DS"
        ],
        "allowed_card_networks": [
          "VISA",
          "MASTERCARD",
          "AMEX"
        ],
        "merchant_name": "Test DEUNA"
      },
      "id": "ef2319fe-f88d-4d8d-b4d1-e4fa08f18651",
      "method_type": "card_wallet",
      "payment_provider": "google_pay",
      "processor_name": "google_pay"
    }
  ]
}

2. Initialize the Google Pay Web SDK

Refer to the following Google Pay documentation for the full reference:

📘

The snippet below shows the complete Google Pay SDK flow. If you're already familiar with the Google Pay Web SDK, you can skip to step 3 in the code comments (loadPaymentData) — that's where the DEUNA-specific integration happens.

Import the Google Pay JS SDK

Add the following script to your page:

<script src="https://pay.google.com/gp/p/js/pay.js"></script>

Complete integration example

// 1. Check availability
const paymentsClient = new google.payments.api.PaymentsClient({
  environment: 'PRODUCTION' // or 'TEST' for sandbox
});

const isReadyToPayRequest = {
  apiVersion: 2,
  apiVersionMinor: 0,
  allowedPaymentMethods: [
    {
      type: 'CARD',
      parameters: {
        allowedAuthMethods: ['PAN_ONLY', 'CRYPTOGRAM_3DS'], // from extra_params.allowed_auth_methods
        allowedCardNetworks: ['VISA', 'MASTERCARD', 'AMEX'] // from extra_params.allowed_card_networks
      }
    }
  ]
};

paymentsClient.isReadyToPay(isReadyToPayRequest).then((response) => {
  if (!response.result) {
    // Google Pay not available — hide the button or show a fallback
  }
});

// 2. Build the payment data request (use values from Get Payment Methods endpoint)
const paymentDataRequest = {
  apiVersion: 2,
  apiVersionMinor: 0,
  allowedPaymentMethods: [
    {
      type: 'CARD',
      parameters: {
        allowedAuthMethods: ['PAN_ONLY', 'CRYPTOGRAM_3DS'],
        allowedCardNetworks: ['VISA', 'MASTERCARD', 'AMEX']
      },
      tokenizationSpecification: {
        type: 'PAYMENT_GATEWAY',
        parameters: {
          gateway: 'deuna',
          gatewayMerchantId: '{external_merchant_id}' // from credentials.external_merchant_id
        }
      }
    }
  ],
  merchantInfo: {
    merchantId: '{google-merchant-id}',
    merchantName: 'Test DEUNA' // from extra_params.merchant_name
  },
  transactionInfo: {
    countryCode: 'MX',
    currencyCode: 'MXN',
    totalPrice: '1.00',
    totalPriceStatus: 'FINAL'
  }
};

// 3. Load payment data on button click (must be inside a user gesture)
// The credential-id comes from the `id` field in the Get Payment Methods response
paymentsClient.loadPaymentData(paymentDataRequest).then((paymentData) => {
  // 4. Handle payment authorization
  // Extract the raw token string — send it as-is to DEUNA, without parsing or re-serializing
  const googlePayToken = paymentData.paymentMethodData.tokenizationData.token;

  // Use googlePayToken in step 3 — Create Card or Purchase V2
}).catch((err) => {
  console.error('Google Pay error:', err);
});
⚠️

loadPaymentData() must be called synchronously within a user gesture (e.g. a button click). Calling it outside of one will throw an error.

⚠️

Send tokenizationData.token as the exact raw string received from Google. Do not JSON.parse() or JSON.stringify() the token before sending it to DEUNA.

3. Purchase with Google Pay

Once the customer authorizes the payment, loadPaymentData() resolves and delivers an encrypted ECv2 token via paymentData.paymentMethodData.tokenizationData.token. This token must be sent as-is, without any modification, to DEUNA.

You have three options depending on your use case:

3.1 Create Card

Use this option when you want to save the card for future purchases. The token from tokenizationData.token is sent to the Create Card endpoint, which returns a card_id that can be reused in subsequent purchases.

→ See Create Card API reference

{
  "google_pay": {
    "paymentData": {
      "token": {
        "protocolVersion": "ECv2",
        "signature": "MEQCIH6Q4OwQ0jAceFEkGF0JID6sJNXxOEi4r+mA7biHQS9nwiiNwOrr24RyPeHA0Q==",...
        "intermediateSigningKey": {
          "signedKey": "{\"keyExpiration\":\"1542323393147\",\"keyValue\":\"MFJeFRxyCw==\"}",...
          "signatures": [
            "MEYCIQCO2EIi48s8VTH+ilMEpoXLFfkxAwHjfPSCVED/QDSHmQWpeNmIP+z+tCQHQxP0v"...
          ]
        },
        "signedMessage": "{\"tag\":\"jpGz1F1BVrKbRU9K8+7cZs=\",\"en:\"mKOoXwi8OavZ...\"}"...
      }
    }
  },
  "credential_source": "google_pay"
}

3.2 Purchase with Card ID

Use this option when the card has already been saved via Create Card. This is a standard Purchase V2 request using the card_id returned by the Create Card endpoint — no Google Pay token needed.

→ See Purchase V2 API reference

{
  "order_token": "{order-token}",
  "order_type": "DEUNA_CHECKOUT",
  "payer_info": {
    "email": "[email protected]",
    "card_holder_dni": "12345678"
  },
  "payment_source": {
    "method_type": "credit_card",
    "card_info": {
      "card_id": "{deuna-card-id}"
    }
  }
}

3.3 Direct Purchase

Use this option for one-time payments where you don't need to save the card. The token from tokenizationData.token is sent directly in the purchase request.

→ See Purchase V2 API reference

{
  "order_token": "{order-token}",
  "order_type": "DEUNA_CHECKOUT",
  "payer_info": {
    "email": "[email protected]",
    "card_holder_dni": "12345678"
  },
  "payment_source": {
    "method_type": "credit_card"
  },
  "specific_fields": {
    "google_pay": {
      "paymentData": {
        "token": {
          "protocolVersion": "ECv2",
          "signature": "MEQCIH6Q4OwQ0jAceFEkGF0JID6sJNU/bdsrAOpZIsrHQS9nwiiNwOrr24RyPeHA0Q==",...
          "intermediateSigningKey": {
            "signedKey": "{\"keyExpiration\":\"1542323393147\",\"keyValue\":\"MFkwzFRxyCw==\"}"...,
            "signatures": [
              "MEYCIQCO2EIi48s8VTH+ilMEpoXLFfkxALJmrUlNAY8hDQRV/y1iKZGsWpeNmIP+z+tCQHQxP0v"...
            ]
          },
          "signedMessage": "{\"tag\":\"jpGz1F1Bcoi/U9=\",\"ege\":\"mKOoXwi8OavZ...\"}"...
        }
      }
    }
  }
}

Response:

{
  "order_type": "DEUNA_CHECKOUT",
  "order_token": "4598f493-de86-4fe0-b9fd-c4c6c9847e39",
  "order": {
    "order_id": "DEUNA_CHECKOUT_b6a5c0b6-3df9-4b3b-b778-7086c190062b",
    "currency": "MXN",
    "total_amount": 10000,
    "display_total_amount": "MXN 100,00",
    "status": "succedeed",
    "payment": {
      "data": {
        "status": "processed"
      }
    }
  }
}