Google Pay con payload desencriptado
Si cuentas con certificación PCI DSS y configuras tu botón de Google Pay para que el token se cifre con tu propia llave, desencríptalo de tu lado y envía a Conekta el payload ya desencriptado.
En la integración estándar, tu botón de Google Pay declara tokenizationSpecification.type: "PAYMENT_GATEWAY" con gateway: "conektagpay". Google cifra el token con la llave de Conekta, tu backend nos lo envía como lo devuelve Google y Conekta lo desencripta.
Esta guía cubre el flujo alterno: configuras tu botón con tokenizationSpecification.type: "DIRECT" y tu propia llave pública, así que Google cifra el token para ti, tú lo desencriptas y envías el contenido ya desencriptado.
Requiere habilitación y certificación PCI DSSEste flujo está disponible solo para comercios con PCI DSS vigente y se habilita por cuenta.
DIRECTno es lo mismo que "Direct API"
DIRECTes uno de los dos valores detokenizationSpecification.typeen la librería de Google Pay, y define a qué llave se cifra el token.
1. Cuándo usar este flujo
Se recomienda si necesitas que el token de Google Pay no quede atado a un solo procesador.
| Flujo estándar | Payload desencriptado | |
|---|---|---|
tokenizationSpecification.type | PAYMENT_GATEWAY (gateway de Conekta) | DIRECT (tu llave pública) |
| Quién desencripta | Conekta | Tu backend |
| PCI DSS | No requerido | Requerido |
| Qué envías | google_payment.tokenization_data.token | google_payment.decrypted_payment_data.data (Base64) |
source | Omitido | merchant_decrypted |
2. Métodos de autenticación soportados
Se aceptan los dos métodos de Google Pay, y cada uno se procesa distinto:
authMethod | Qué trae el payload | Cómo se procesa |
|---|---|---|
CRYPTOGRAM_3DS | DPAN, expiración y criptograma. | Como network token. La autenticación viaja en el criptograma. |
PAN_ONLY | FPAN y expiración de la tarjeta guardada en la cuenta de Google. | Como tarjeta. El step-up depende de lo que envíes, no de la configuración de tu cuenta: con three_ds_mode: strict o not_strict siempre se dispara el 3DS y la orden regresa en pending_payment con next_action.redirect_to_url. Con smart, solo se dispara si el antifraude no aprueba. |
Sinthree_ds_mode, unPAN_ONLYno traslada la responsabilidadSi no envías
three_ds_mode, el cargoPAN_ONLYviaja al banco sin autenticar, como una tarjeta digitada: sin criptograma y sin indicador de wallet. No se rechaza, pero tampoco hay traslado de responsabilidad al emisor.CRYPTOGRAM_3DSno tiene este problema: la autenticación ya viaja dentro del criptograma.
Con 3DS, elreturn_urlva a nivel ordenSi usas
three_ds_modeconPAN_ONLY, envíareturn_urlcomo atributo de la orden. No usescheckout.success_url: Conekta lo interpreta como un checkout hosteado.
3. Construye el payload desencriptado
Toma el mensaje que obtuviste al desencriptar el token de Google, serialízalo y codifícalo en Base64 estándar, con un máximo de 8,192 bytes.
// message = JSON obtenido al desencriptar el token de Google Pay
const data = Buffer.from(JSON.stringify(message)).toString('base64');El JSON conserva el formato de Google. Conekta valida lo siguiente, y rechaza la petición si falta o viene mal formado:
| Campo | Descripción | Tipo |
|---|---|---|
| messageExpiration | Vigencia del mensaje en milisegundos UTC. Debe estar en el futuro al momento del cobro. | string | number |
| paymentMethodDetails.pan | Número de tarjeta: DPAN en CRYPTOGRAM_3DS, FPAN en PAN_ONLY. De 12 a 19 dígitos. | string |
| paymentMethodDetails.expirationMonth | Mes de expiración, de 1 a 12. | number |
| paymentMethodDetails.expirationYear | Año de expiración, 4 dígitos. | number |
| paymentMethodDetails.authMethod | CRYPTOGRAM_3DS o PAN_ONLY. | string |
| paymentMethodDetails.cryptogram | Criptograma de la transacción. Solo en CRYPTOGRAM_3DS. | string |
El mensaje vencido se rechazaGoogle pide a los integradores descartar cualquier mensaje cuyo
messageExpirationya pasó, y Conekta aplica la misma regla. Calcula la vigencia al momento de cobrar, no al construir el payload.
4. Crea el cargo
Envía el payload dentro de google_payment.decrypted_payment_data e incluye "source": "merchant_decrypted". Todos los parámetros de la tabla son obligatorios.
| Parámetro | Descripción | Tipo |
|---|---|---|
| source | Debe ser merchant_decrypted para activar este flujo. | string |
| google_payment.decrypted_payment_data.data | Mensaje desencriptado, serializado y codificado en Base64. | string |
| google_payment.info.card_network | Red de la tarjeta, por ejemplo VISA. | string |
| google_payment.info.card_details | Últimos dígitos que Google muestra al cliente. | string |
| google_payment.info.card_funding_source | Origen de los fondos, por ejemplo CREDIT. | string |
| google_payment.description | Descripción de la tarjeta que entrega Google. | string |
curl --location 'https://api.conekta.io/orders' \
--header 'Accept: application/vnd.conekta-v2.3.0+json' \
--header 'Content-type: application/json' \
--header 'Authorization: Bearer key_YOUR_PRIVATE_API_KEY' \
--data '{
"currency": "MXN",
"customer_info": { "customer_id": "cus_xxxxxxxxxxxx" },
"line_items": [{ "name": "Vasija de Cerámica", "unit_price": 20000, "quantity": 1 }],
"charges": [{
"payment_method": {
"type": "google",
"source": "merchant_decrypted",
"google_payment": {
"decrypted_payment_data": { "data": "eyJtZXNzYWdlRXhwaXJhdGlvbiI6IjE3OTAwMDAwMDAwMDAi..." },
"info": { "card_network": "VISA", "card_details": "2346", "card_funding_source": "CREDIT" },
"description": "Visa •••• 2346"
}
}
}]
}'La orden pagada regresa payment_status: "paid" y el cargo indica "product_type": "google_pay":
{
"livemode": false,
"amount": 20000,
"currency": "MXN",
"payment_status": "paid",
"object": "order",
"id": "ord_31wKoGLYa9BpeDc4e",
"charges": {
"object": "list",
"has_more": false,
"total": 1,
"data": [
{
"id": "68a5e90679fcdd001abab412",
"livemode": false,
"created_at": 1761004800,
"currency": "MXN",
"payment_method": {
"auth_code": "249606",
"object": "card_payment",
"type": "credit",
"last4": "2346",
"brand": "visa",
"country": "MX",
"fraud_indicators": [],
"three_ds_flow_required": false,
"product_type": "google_pay"
},
"object": "charge",
"description": "Payment from order",
"status": "paid",
"amount": 20000,
"paid_at": 1761004800,
"fee": 2785,
"customer_id": "cus_xxxxxxxxxxxx",
"order_id": "ord_31wKoGLYa9BpeDc4e"
}
]
}
}El cargo guarda payment_method.source como merchant_decrypted y el auth_method utilizado, para que puedas distinguirlos en tus reportes. El number solo conserva los últimos 4 dígitos.
5. Errores
Si el payload es inválido, la respuesta nombra el campo que falla pero nunca su valor.
| Error | Causa |
|---|---|
source.merchant_decrypted_disabled | Tu cuenta no tiene habilitado el flujo desencriptado. |
google_payment.decrypted_payment_data.conflicts_with_payment_data | Enviaste tokenization_data.token y decrypted_payment_data juntos. |
google_payment.decrypted_payment_data.not_allowed_for_source | Enviaste decrypted_payment_data con un source distinto de merchant_decrypted. |
google_pay_merchant_decrypted_invalid | El payload no decodifica, no es JSON, excede el tamaño, venció su messageExpiration, le falta un campo obligatorio, trae formato inválido o el authMethod no está soportado. |
Updated 1 day ago

