docs

Test mode

Test keys, MockAcquirerAdapter e cartões 4929 (BIN brasileiro) — como simular sucesso, decline, 3DS, chargeback e PIX/boleto sem tocar adquirente real.

Test mode é first-class na Zhex. Cada par de chaves (zk_test_* / zsk_test_*) opera num espaço isolado do ambiente de produção: dados de teste não vazam para reports financeiros, webhooks usam whsec_test_* separado, e a smart routing roteia tudo para o MockAcquirerAdapter em vez de adquirente real.

A regra mental é: test mode toca o mesmo Postgres que live, mas com livemode: false em todas as entidades. Você lista, retrieve, refunde, faz tudo igual — só não há dinheiro real movendo.

Test keys

No dashboard, Developers → API keys mostra os pares:

PrefixoOnde usar
zk_test_*Publishable, frontend (zhex.js em test)
zsk_test_*Secret, server-side em test
whsec_test_*Webhook signing em test (gerado por endpoint criado em test mode)

A Zhex rejeita uso cruzado: chave de um modo tentando acessar entidades do outro retorna 404 (genérico — não confirma existência cross-mode, evita leak).

Cartões de teste

A Zhex implementa o conjunto Stripe de PANs de teste — qualquer dev acostumado já reconhece. CVV pode ser qualquer 3 dígitos (4 para Amex), validade qualquer mês/ano no futuro.

Sucessos

PANComportamento
4929 9999 9999 9991Visa, sucesso direto
5151 5151 5151 5155Mastercard, sucesso

Declines

PANdecline_code
4929 0000 0000 0000card_declined (genérico)
4929 0000 0000 0091insufficient_funds
4929 0000 0000 0083lost_card
4929 0000 0000 0075stolen_card
4929 0000 0000 0067expired_card
4929 0000 0000 0059incorrect_cvc
4929 0000 0000 0042processing_error (retryable)

3DS

PANComportamento
4929 0000 0000 3004Força requires_action (3DS challenge)

Chargeback

PANComportamento
4929 0000 0000 2501Sucesso + simula charge.dispute.created
4929 0000 0000 1909Sucesso + simula chargeback product_not_received

Chargebacks de teste seguem o mesmo modelo de produção: reembolso compulsório, sem direito de resposta. Use para validar seu handler de charge.dispute.created (registro contábil, email para o cliente, revogação de acesso).

PIX em test mode

Não há QR real para escanear — você dispara o pagamento via test helper:

import { randomUUID } from 'node:crypto';

// 1. crie um intent PIX normalmente (com customer já existente)
const intent = await zhex.paymentIntents.create({
  amount: 4990,
  currency: 'brl',
  customer: 'cus_…',
  payment_method_types: ['pix'],
});

// 2. simule pagamento bem-sucedido
await fetch(
  `https://prometheus.zhex.io/v1/test_helpers/payment_intents/${intent.id}/succeed`,
  {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${process.env.ZHEX_TEST_KEY}`,
      'Idempotency-Key': randomUUID(),
    },
  },
);
// dispara webhook payment_intent.succeeded com livemode: false

Outras transições disponíveis em /v1/test_helpers/payment_intents/:id/:

EndpointResultado
succeedpayment_intent.succeeded
failpayment_intent.payment_failed com decline_code: insufficient_funds
expirepayment_intent.canceled (timeout PIX/boleto)

Test helpers só aceitam zsk_test_*/zrk_test_*. Chaves live retornam 403 test_mode_only.

Boleto em test mode

// 1. customer com document + endereço
const intent = await zhex.paymentIntents.create({
  amount: 4990,
  currency: 'brl',
  customer: 'cus_…',
  payment_method_types: ['boleto'],
});

// 2. simular pagamento via test helper
await fetch(
  `https://prometheus.zhex.io/v1/test_helpers/payment_intents/${intent.id}/succeed`,
  {
    method: 'POST',
    headers: { Authorization: `Bearer ${process.env.ZHEX_TEST_KEY}` },
  },
);

PDFs reais não são gerados em test mode hoje — a renderização do boleto é função do checkout hosted, e em test mode ele exibe placeholders. O fluxo de webhook (payment_intent.succeeded) é o que importa para validar a integração.

Webhooks em test mode

Endpoints criados via Integrações → Webhooks com a chave zsk_test_* recebem eventos livemode: false. Boa prática:

  • Endpoint A (live): https://api.meusite.com/webhooks/zhexwhsec_live_*
  • Endpoint B (test): https://abc123.ngrok-free.app/webhooks/zhexwhsec_test_*

Ambos recebem o mesmo formato de evento. O campo livemode: false no payload permite seu handler decidir se aciona side effects reais (envio de email com nota fiscal, integração com SAP) ou apenas log.

if (!event.livemode) {
  console.log('[test] event:', event.type);
  return res.status(200).end();
}
// fluxo real de produção

Mode toggle no dashboard

O canto superior do dashboard mostra um toggle TEST / LIVE com banner amarelo no topo da tela em test. Listings (Transações, Customers, Produtos) filtram automaticamente pelo modo selecionado.

Limpeza de dados de teste

Test data nunca expira automaticamente (decisão deliberada — facilita debug de bug intermitente que aconteceu há 2 meses). Para limpar:

  • Manual no dashboard: Developers → Test data → Wipe. Confirma com WIPE digitado.
  • API: roadmap. Quando entrar, vai ficar em POST /v1/test_helpers/wipe com exclusão assíncrona.

Checklist antes de virar live

Antes de trocar zsk_test_* por zsk_live_* em produção:

Endpoints de webhook configurados em ambos os modos

Não esqueça do live. É erro clássico criar só o endpoint de test e mandar produção sem nenhum.

Fluxo 3DS testado

Use 4929 0000 0000 3004 para forçar requires_action e garantir que seu fluxo de retorno (via webhook payment_intent.succeeded) funciona.

Idempotency keys batem com sua estratégia de retry

Reuse a mesma Idempotency-Key em retries — sem isso, network flake duplica cobrança.

Erros declinados são tratados

Cliente vê mensagem útil em PT-BR, não card_declined cru.

Eventos críticos têm logs e alertas

payment_intent.succeeded, payment_intent.payment_failed, charge.dispute.created no mínimo.

Próximos passos

Esta página foi útil?

Atualizado em

Nesta página