Incluir Botón de Google Pay en mi sitio Web

Integración del SDK de Google Pay (Web)

Nota: Esta guía cubre la integración de Google Pay en sitios web usando la librería JavaScript de Google Pay. Para integrar Google Pay en apps móviles (Android e iOS), consulta la Integración Mobile.

Antes de comenzar, asegúrate de haber completado los Requisitos previos.

1. Cargar la librería de Google Pay

Agregar el script de Google Pay en el HTML del sitio:

<script async src="https://pay.google.com/gp/p/js/pay.js" onload="onGooglePayLoaded()"></script>

2. Configurar el PaymentDataRequest

2.1 Parámetros del Gateway (Conekta)

const tokenizationSpecification = {
  type: 'PAYMENT_GATEWAY',
  parameters: {
    gateway: 'conektagpay',
    gatewayMerchantId: 'conekta'
  }
};
ParámetroValorDescripción
gatewayconektagpayIdentificador de Conekta como procesador de pagos en Google Pay
gatewayMerchantIdconektaValor fijo, identificador de Conekta como gateway

2.2 Redes y métodos de autenticación

const allowedCardNetworks = ['VISA', 'MASTERCARD', 'AMEX'];
const allowedCardAuthMethods = ['CRYPTOGRAM_3DS'];

const baseCardPaymentMethod = {
  type: 'CARD',
  parameters: {
    allowedAuthMethods: allowedCardAuthMethods,
    allowedCardNeGtworks: allowedCardNetworks,
    assuranceDetailsRequired: true
  }
};

const cardPaymentMethod = {
  ...baseCardPaymentMethod,
  tokenizationSpecification: tokenizationSpecification
};

2.3 Request completo

const paymentDataRequest = {
  apiVersion: 2,
  apiVersionMinor: 0,
  allowedPaymentMethods: [cardPaymentMethod],
  callbackIntents: ['PAYMENT_AUTHORIZATION'],
  emailRequired: true,
  shippingAddressRequired: true,
  shippingAddressParameters: {
    phoneNumberRequired: true
  },
  transactionInfo: {
    totalPriceStatus: 'FINAL',
    totalPrice: '100.00',        // Monto del cobro
    totalPriceLabel: 'Total',
    currencyCode: 'MXN',         // Moneda
    countryCode: 'MX'            // País
  },
  merchantInfo: {
    merchantId: '<GOOGLE_MERCHANT_ID>',   // ID de Google Pay & Wallet Console (producción)
    merchantName: 'Nombre del Merchant'
  }
};

Nota: En ambiente de pruebas (TEST), merchantId puede omitirse o usar cualquier valor. En producción se requiere el ID obtenido de la Google Pay & Wallet Console.

3. Inicializar el cliente y mostrar el botón

let paymentsClient;

function onGooglePayLoaded() {
  paymentsClient = new google.payments.api.PaymentsClient({
    environment: 'TEST', // Cambiar a 'PRODUCTION' en producción
    paymentDataCallbacks: {
      onPaymentAuthorized: function(paymentData) {
        return { transactionState: 'SUCCESS' };
      }
    }
  });

  // Verificar si Google Pay está disponible
  paymentsClient.isReadyToPay({
    apiVersion: 2,
    apiVersionMinor: 0,
    allowedPaymentMethods: [baseCardPaymentMethod]
  })
    .then(function(response) {
      if (response.result) {
        addGooglePayButton();
      }
    });
}

function addGooglePayButton() {
  const button = paymentsClient.createButton({
    onClick: onGooglePayClicked,
    buttonColor: 'black',
    buttonType: 'pay'
  });
  document.getElementById('google-pay-container').appendChild(button);
}

4. Capturar el PaymentData

Cuando el usuario hace clic en el botón, invoca Google Pay con loadPaymentData. El callback onPaymentAuthorized(configurado en el paso 3) recibe el paymentData cuando el pago es autorizado:

function onGooglePayClicked() {
  paymentsClient.loadPaymentData(paymentDataRequest)
    .then(function(paymentData) {
      // paymentData contiene el token encriptado y la info de la tarjeta
      processGooglePayPayment(paymentData);
    })
    .catch(function(err) {
      console.error('Error en Google Pay:', err);
    });
}

Estructura del PaymentData retornado por Google

{
  "apiVersion": 2,
  "apiVersionMinor": 0,
  "paymentMethodData": {
    "type": "CARD",
    "description": "Visa •••• 1234",
    "info": {
      "cardNetwork": "VISA",
      "cardDetails": "1234",
      "cardFundingSource": "CREDIT"
    },
    "tokenizationData": {
      "type": "PAYMENT_GATEWAY",
      "token": "<TOKEN_ENCRIPTADO_BASE64>"
    }
  }
}

5. Enviar al backend del Merchant

Extrae los datos de paymentData y envíalos a tu backend:

function processGooglePayPayment(paymentData) {
  const pmd = paymentData.paymentMethodData;

  // IMPORTANTE: El token debe codificarse en base64 antes de enviarlo a Conekta
  const conektaPayload = {
    token: btoa(pmd.tokenizationData.token),
    card_network: pmd.info.cardNetwork,
    card_details: pmd.info.cardDetails,
    card_funding_source: (pmd.info.cardFundingSource || 'CREDIT').toLowerCase(),
    description: pmd.description
  };

  // Enviar al backend del merchant
  fetch('/api/create-charge', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(conektaPayload)
  });
}

6. Procesar en el backend con API Conekta POST /orders

En tu backend, recibe el payload del frontend y construye una Order para enviarla al API de Conekta.

La estructura de payment_method para Google Pay es específica de este flujo y debe incluir el envoltorio type: "google" con un objeto google_payment que contenga tokenization_data, info y description:

{
  "currency": "MXN",
  "customer_info": {
    "name": "Cliente Google Pay",
    "email": "[email protected]",
    "phone": "5555555555"
  },
  "line_items": [
    {
      "name": "Producto",
      "unit_price": 10000,
      "quantity": 1
    }
  ],
  "charges": [
    {
      "amount": 10000,
      "payment_method": {
        "type": "google",
        "google_payment": {
          "tokenization_data": {
            "token": "<TOKEN_EN_BASE64_RECIBIDO_DEL_FRONTEND>"
          },
          "info": {
            "card_network": "VISA",
            "card_details": "1234",
            "card_funding_source": "credit"
          },
          "description": "Visa •••• 1234"
        }
      }
    }
  ]
}

Para más detalles del payload esperado por POST /orders, consulta la referencia completa de API de Conekta.