Saltar al contenido principal

Cómo usar

Agrega el header X-Sandbox-Scenario: <escenario> a cualquier llamada de cash-in o cash-out. Sin el header, el sandbox usa el escenario success por defecto.
curl -X POST https://sandbox.mx.ntxpay.com/api/spei/cash-out \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Sandbox-Scenario: error:insufficient-funds" \
  -H "Content-Type: application/json" \
  -d '{
    "amountCentavos": 15000,
    "destinationClabe": "012180001234567890",
    "beneficiaryName": "Maria Lopez",
    "externalId": "test-error-001"
  }'
El header solo controla el webhook asíncrono. La respuesta HTTP siempre es 201 Created con status: PENDING, sin importar el escenario. El resultado final (CONFIRMED, FAILED o EXPIRED) llega en el webhook ~1 segundo después.

Escenarios disponibles

Escenarios de éxito

Header ValueComportamiento síncronoWebhook
success (default)201 PENDINGCONFIRMED en ~1s
(sin header)201 PENDINGCONFIRMED en ~1s

Escenarios de error

Header ValueComportamiento síncronoWebhook
error:insufficient-funds201 PENDINGFAILED con errorCode: INSUFFICIENT_FUNDS
error:invalid-clabe201 PENDINGFAILED con errorCode: INVALID_CLABE
error:account-not-found201 PENDINGFAILED con errorCode: ACCOUNT_NOT_FOUND
error:account-blocked201 PENDINGFAILED con errorCode: ACCOUNT_BLOCKED
error:duplicate-external-id201 PENDINGFAILED con errorCode: DUPLICATE_EXTERNAL_ID
error:bank-rejected201 PENDINGFAILED con errorCode: BANK_REJECTED

Escenarios de atraso

Header ValueComportamiento síncronoWebhook
delayed:5s201 PENDINGCONFIRMED tras +5s
delayed:30s201 PENDINGCONFIRMED tras +30s
delayed:60s201 PENDINGCONFIRMED tras +60s
El delay máximo permitido es de 120 segundos — valores mayores se truncan automáticamente.

Ejemplo: webhook de éxito

{
  "event": "cash_out",
  "deliveryId": "8e2c5b6f-3a12-4b9c-9a18-77a2b3c4d5e6",
  "createdAt": "2026-03-26T10:00:00.000Z",
  "transaction": {
    "id": 12345,
    "externalId": "test-success-001",
    "paymentMethod": "SPEI",
    "direction": "out",
    "type": "cash_out",
    "status": "CONFIRMED",
    "provider": "sandbox",
    "amountCentavos": 15000,
    "clabe": "012180001234567890",
    "referenceNumerical": "9876543",
    "createdAt": "2026-03-26T09:59:59.000Z",
    "confirmedAt": "2026-03-26T10:00:00.000Z",
    "counterpart": {
      "name": "Maria Lopez",
      "taxId": null,
      "bank": {}
    }
  },
  "errorCode": null,
  "errorMessage": null,
  "metadata": {}
}

Ejemplo: webhook de falla

{
  "event": "cash_out",
  "deliveryId": "1a3f9e8d-2c47-4b9c-aa18-77a2b3c4d5e6",
  "createdAt": "2026-03-26T10:01:00.000Z",
  "transaction": {
    "id": 12346,
    "externalId": "test-error-001",
    "paymentMethod": "SPEI",
    "direction": "out",
    "type": "cash_out",
    "status": "FAILED",
    "provider": "sandbox",
    "amountCentavos": 15000,
    "clabe": "012180001234567890",
    "referenceNumerical": null,
    "confirmedAt": null
  },
  "errorCode": "INSUFFICIENT_FUNDS",
  "errorMessage": "Cuenta sin saldo suficiente",
  "metadata": {}
}
Notas:
  • En status: FAILED, referenceNumerical y confirmedAt son null — la red SPEI nunca confirmó la transacción.
  • errorCode y errorMessage describen el motivo de la falla.

Restricciones

  • El header X-Sandbox-Scenario funciona exclusivamente en cuentas sandbox.
  • Las cuentas de producción que envíen el header reciben:
{
  "statusCode": 400,
  "message": "X-Sandbox-Scenario header is only supported in sandbox mode."
}

Buenas prácticas

  1. Prueba todos los escenarios antes de ir a producción — implementa el manejo de CONFIRMED, PENDING, FAILED y EXPIRED.
  2. Valida los campos de error — usa errorCode para decisiones automáticas; reserva errorMessage para logs/usuarios.
  3. Prueba con delay — verifica que tu sistema maneja bien la entrega lenta del webhook.
  4. Idempotencia — usa transaction.id como clave de idempotencia; el mismo webhook puede ser re-entregado.