Pular para o conteúdo principal

O que é o Sandbox?

O sandbox é o ambiente público da NTX Pay México para integração e testes:
  • Base URL única: https://sandbox.ntxpay.com
  • Provedor bancário simulado — não toca Banxico nem a rede SPEI real
  • Saldo simulado — sem movimentação financeira real
  • Webhooks simulados disparados ~1 segundo após cada request
  • X-Sandbox-Scenario disponível para forçar diferentes resultados nos webhooks
Atualmente toda integração com a NTX Pay acontece pelo sandbox. Os endpoints, payloads e webhooks descritos nesta documentação são os definitivos — quando produção for liberada, o mesmo código funcionará apenas trocando as credenciais.

Visão Geral

  • O header X-Sandbox-Scenario controla o resultado do webhook assíncrono.
  • Sem o header, o sandbox devolve webhooks de sucesso por padrão.
  • Para cenários de erro, envie o header explicitamente na request.
  • A feature está disponível em todas as contas sandbox.

Como Funciona

O header não altera a resposta HTTP. A API sempre responde 201 Created com status: "PENDING". O cenário afeta exclusivamente o webhook assíncrono disparado ~1 segundo depois.
RequestHTTP ResponseWebhook (~1s depois)
Sem X-Sandbox-Scenario201 PENDINGCONFIRMED
X-Sandbox-Scenario: success201 PENDINGCONFIRMED
X-Sandbox-Scenario: error:insufficient-funds201 PENDINGFAILED com errorCode
X-Sandbox-Scenario: delayed:5s201 PENDINGCONFIRMED com +5s de delay

Como Usar

curl -X POST https://sandbox.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"
  }'

Cenários Disponíveis

Cenários de Erro

Header ValueDescriçãoWebhook Status
error:insufficient-fundsConta sem saldo suficienteFAILED
error:invalid-clabeCLABE de destino malformada ou inexistenteFAILED
error:account-not-foundConta destino não localizada na rede SPEIFAILED
error:account-blockedConta destino bloqueada ou encerradaFAILED
error:duplicate-external-idexternalId já usado em outra transaçãoFAILED
error:bank-rejectedBanco destino rejeitou a transferência (genérico)FAILED
error:oxxo-expiredCupom OXXO expirou sem pagamentoEXPIRED

Cenário de Sucesso

Header ValueDescriçãoWebhook Status
successForça sucesso (mesmo comportamento do default)CONFIRMED
(sem header)Comportamento default do sandboxCONFIRMED

Cenários de Delay

Header ValueDescriçãoWebhook Status
delayed:5sSucesso após 5 segundos extrasCONFIRMED
delayed:30sSucesso após 30 segundos extrasCONFIRMED
delayed:60sSucesso após 60 segundos extrasCONFIRMED
O delay máximo permitido é de 120 segundos — valores acima são truncados automaticamente.

Exemplos de Webhook Recebido

Webhook de Sucesso (default)

{
  "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": {}
}

Webhook de Erro (error:insufficient-funds)

{
  "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,
    "createdAt": "2026-03-26T10:00:59.000Z",
    "confirmedAt": null,
    "counterpart": {
      "name": null,
      "taxId": null,
      "bank": {}
    }
  },
  "errorCode": "INSUFFICIENT_FUNDS",
  "errorMessage": "Account without sufficient balance",
  "metadata": {}
}
Notas:
  • Em status: FAILED, referenceNumerical e confirmedAt são null (a rede SPEI nunca confirmou a transação).
  • errorCode e errorMessage descrevem o motivo da falha.

Endpoints Compatíveis

EndpointMétodoDescrição
/api/spei/cash-inPOSTGerar CLABE descartável de cobrança
/api/spei/cash-outPOSTEnviar SPEI por CLABE
/api/oxxo/cash-inPOSTGerar cupom OXXO

Comportamento

  • A API processa a request normalmente: retorna 201 Created com status: PENDING.
  • O header não altera a resposta imediata.
  • Após ~1 segundo (ou mais com delayed:), o webhook é enviado para a URL configurada.
  • Seu sistema recebe o webhook com status correspondente ao cenário (CONFIRMED ou FAILED).
O header controla apenas o webhook. A resposta HTTP é sempre 201 Created com status: PENDING, independentemente do cenário.

Boas Práticas

  1. Teste todos os cenários — implemente o tratamento de CONFIRMED, PENDING, FAILED e EXPIRED antes de ir ao ar.
  2. Valide os campos de erro — use errorCode e errorMessage para tomar a ação adequada (notificar usuário, retry, etc.).
  3. Teste com delay — verifique se seu sistema lida bem com entrega lenta do webhook.
  4. Idempotência — use transaction.id como chave de idempotência; o mesmo webhook pode ser reenviado.

Suporte

support@ntxpay.com