🚀 Lanzamiento v2.3: Activa y desactiva métodos de pago para tu Conekta Checkout desde el Panel, sin tocar tu código. Ver documentación →

Apple Pay con payload desencriptado

Si cuentas con certificación PCI DSS y controlas la llave privada de tu Apple Pay Payment Processing Certificate, desencripta el token de Apple Pay de tu lado y envía a Conekta el payload ya desencriptado.

En la integración estándar de Apple Pay por Direct API, tu backend envía a Conekta el objeto pk_payment como lo devuelve Apple, con el token de pago encriptado, y Conekta lo desencripta con su certificado. Esta guía cubre el flujo alterno: tú desencriptas el token con tu propio certificado y nos mandas el contenido ya desencriptado.

🚧

Requiere habilitación y certificación PCI DSS

Este flujo está disponible solo para comercios con PCI DSS vigente y se habilita por cuenta. Contacta a tu ejecutivo de Conekta para activarlo.

1. Cuándo usar este flujo

Úsalo si necesitas que el token de Apple Pay no quede atado a un solo procesador.

Flujo estándarPayload desencriptado
Quién desencriptaConektaTu backend
Quién tiene la llave que descifraConekta (su Payment Processing Certificate)Tuyo (Payment Processing Certificate)
Quién firma la sesión de AppleConektaTu servidor
PCI DSSNo requeridoRequerido
Qué envíaspk_payment.paymentData (encriptado)pk_payment.decryptedPaymentData.data (Base64)
sourceexternal si Conekta descifra con el certificado de su PSP; omitido si descifra con el tuyomerchant_decrypted

2. Requisitos previos

  • Certificación PCI DSS vigente y el flujo habilitado en tu cuenta por Conekta.
  • Tu propio Apple Pay Payment Processing Certificate, con su llave privada bajo tu control.
  • Tu propio Apple Pay Merchant Identity Certificate y tu merchantIdentifier, con tu dominio verificado bajo ese merchant id.
🚧

El merchant validation sí cambia

El markup del botón es el mismo, pero la sesión de Apple Pay debe crearla tu servidor, contra Apple, con tu propio Merchant Identity Certificate. No uses el endpoint de sesión de Conekta ni envíes "source": "external": esa sesión se firma con la identidad del PSP de Conekta, y entonces Apple cifra el token al Payment Processing Certificate del PSP — cuya llave privada no tienes, así que no podrías descifrarlo. Sigue la Opción B, certificado propio de la guía de integración.

📘

Los dos certificados de Apple Pay hacen cosas distintas

El Payment Processing Certificate es al que Apple cifra el token: su llave privada es la que descifra. El Merchant Identity Certificate autentica tu servidor ante Apple al crear la sesión de pago (mTLS) y no participa en el descifrado. Para este flujo necesitas los dos.

3. Construye el payload desencriptado

Después de que Apple te devuelve el pk_payment, desencripta paymentData con tu certificado y toma el JSON. Posteriormente se debe serializar y codificar en Base64 estándar, con un máximo de 8,192 bytes.

// payload = JSON obtenido al desencriptar pk_payment.paymentData
const data = Buffer.from(JSON.stringify(payload)).toString('base64');
🚧

Manda el JSON completo, no lo recortes

Conekta solo rechaza la petición si falta alguno de los campos de la primera tabla, pero lee otros que vienen en el mismo JSON. Quitarlos no da error de validación: degrada o tumba el cargo más adelante.

El JSON desencriptado conserva el formato de Apple. Estos campos son obligatorios y, si falta cualquiera, la petición se rechaza:

CampoDescripciónTipo
applicationPrimaryAccountNumberDPAN.string
applicationExpirationDateExpiración en formato YYMMDD.string
paymentDataTypeCampo de Apple que indica el formato del dato de pago, no un flujo de autenticación. Conekta exige que venga presente pero no interpreta su valor: mándalo tal cual.string
paymentDataObjeto que contiene los datos criptográficos.object
paymentData.onlinePaymentCryptogramCriptograma de la transacción.string

Estos no se validan, pero sí se usan:

CampoDescripciónSi no viene
paymentData.eciIndicatorECI que viaja al adquirente junto con el criptograma.Conekta solo tiene valor por defecto para Mastercard y American Express. En cualquier otra marca — Visa y Carnet incluidas — el cargo falla.
deviceManufacturerIdentifierIdentificador del dispositivo que generó el token.Llega vacío al adquirente. No tumba el cargo.

4. Crea el cargo

Envía el payload dentro de pk_payment.decryptedPaymentData e incluye "source": "merchant_decrypted" en payment_method. Todos los parámetros de la tabla son obligatorios.

ParámetroDescripciónTipo
sourceDebe ser merchant_decrypted para activar este flujo.string
pk_payment.decryptedPaymentData.dataJSON desencriptado, serializado y codificado en Base64.string
pk_payment.transactionIdentifierIdentificador de la transacción que devolvió Apple.string
pk_payment.paymentMethod.displayNameNombre que Apple muestra para la tarjeta (Visa 0121)string
pk_payment.paymentMethod.networkRed de la tarjeta (Visa)string
pk_payment.paymentMethod.typeTipo de tarjeta (credit)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": "apple",
            "source": "merchant_decrypted",
            "pk_payment": {
                "decryptedPaymentData": { "data": "eyJhcHBsaWNhdGlvblByaW1hcnlBY2NvdW50TnVtYmVyIjoi..." },
                "paymentMethod": { "displayName": "Visa 0121", "network": "Visa", "type": "credit" },
                "transactionIdentifier": "610c88f19c8d43e289fd1f15bee320d5440c3bd450fcb8431d3a8d4be73f2f01"
            }
        }
    }]
}'

La respuesta es idéntica a la de cualquier cargo de Apple Pay: payment_status es paid y el cargo indica "product_type": "apple_pay".

{
    "livemode": false,
    "amount": 20000,
    "currency": "MXN",
    "payment_status": "paid",
    "object": "order",
    "id": "ord_2yYE5xyYQaJ8YRAG9",
    "charges": {
        "object": "list",
        "has_more": false,
        "total": 1,
        "data": [
            {
                "id": "68a5e90679fcdd001abab388",
                "livemode": false,
                "created_at": 1755703558,
                "currency": "MXN",
                "payment_method": {
                    "auth_code": "976866",
                    "object": "card_payment",
                    "type": "credit",
                    "last4": "0121",
                    "brand": "visa",
                    "country": "MX",
                    "fraud_indicators": [],
                    "three_ds_flow_required": false,
                    "product_type": "apple_pay"
                },
                "object": "charge",
                "description": "Payment from order",
                "status": "paid",
                "amount": 20000,
                "paid_at": 1755703558,
                "fee": 2785,
                "customer_id": "cus_2yYDbYkcDCB5queoa",
                "order_id": "ord_2yYE5xyYQaJ8YRAG9"
            }
        ]
    }
}

El cargo guarda payment_method.source como merchant_decrypted para que puedas distinguirlo en tus reportes.

5. Errores

Si el payload es inválido, la respuesta nombra el campo que falla pero nunca su valor.

ErrorCausa
source.merchant_decrypted_disabledTu cuenta no tiene habilitado el flujo desencriptado.
pk_payment.decrypted_payment_data.conflicts_with_payment_dataEnviaste paymentData y decryptedPaymentData en la misma petición.
pk_payment.decrypted_payment_data.not_allowed_for_sourceEnviaste decryptedPaymentData con un source distinto de merchant_decrypted.
Campo faltante o data inválidoEl Base64 no decodifica, no es JSON, excede 8,192 bytes o falta un campo obligatorio.

Did this page help you?