# ZWAY Docs — API de pagamentos API única: POST https://api.zwaybr.com/api/v1/payments para todas as moedas e métodos. Sem credenciais reais nos exemplos. ## Introdução https://docs.zwaybr.com/ API única de pagamentos da ZWAY: PIX, boleto e cartão no Brasil e métodos locais de outros países, todos em POST /payments. Uma API só para receber em qualquer moeda. Você muda a moeda e o método ; a rota, o formato da resposta e o webhook são os mesmos. POST Criar pagamento PIX, boleto, cartão, SPEI, OXXO… GET Buscar pagamento Status de qualquer cobrança EVENTO Webhooks Aviso de pago, recusado, vencido O essencial Endereço da API https://api.zwaybr.com/api/v1 Copiar Autenticação Authorization: Bearer $ZWAY_API_KEY ( como gerar ) Formato JSON em UTF-8. Valores sempre em centavos da moeda (inteiro): R$ 99,90 = 9990 ; MX$ 500,00 = 50000 . Moedas e métodos BRL PIX, BOLETO, CREDIT_CARD · MXN SPEI, OXXO — a lista da sua conta vem de Moedas e métodos . Em três passos Gere a chave secreta no painel ZWAY: Webhooks e chaves de API → Chaves de API . Cadastre a URL do seu servidor na aba Webhooks (tipo Recebimento). Crie pagamentos em Criar pagamento e acompanhe pelo webhook ou por Buscar pagamento . Baixar coleção do Postman OpenAPI ## Primeiro pagamento https://docs.zwaybr.com/integracao/primeira-requisicao/ Do zero a uma cobrança PIX: criar, acompanhar e receber o aviso. Um PIX de R$ 99,90 do começo ao fim. Troque currency e paymentMethod para qualquer outra moeda ou método. 1. Criar a cobrança Shell Copiar curl --request POST \ --url https://api.zwaybr.com/api/v1/payments \ --header "Authorization: Bearer $ZWAY_API_KEY" \ --header 'Content-Type: application/json' \ --header 'Idempotency-Key: pedido-0001-tentativa-1' \ --data '{ "currency" : "BRL" , "paymentMethod" : "PIX" , "amount" : 9990 , "name" : "Maria Souza" , "email" : "maria@exemplo.com.br" , "document" : { "type" : "cpf" , "number" : "12345678909" }, "phone" : "11999999999" , "items" : [ { "title" : "Plano Pro" , "unitPrice" : 9990 , "quantity" : 1 } ] }' A resposta traz o id do pagamento e, no PIX, o pix.qrCode (copia e cola) para mostrar ao comprador. 2. Acompanhar Shell Copiar curl --request GET \ --url https://api.zwaybr.com/api/v1/payments/zw_1760000000000_ab12cd34 \ --header "Authorization: Bearer $ZWAY_API_KEY" 3. Receber o aviso Quando o pagamento é aprovado, o webhook de Recebimento recebe transaction.approved . Valide a assinatura ( como ) e responda 2xx. Pagamento real Toda cobrança criada na API é real. Teste com valores baixos e só no seu servidor. ## Autenticação https://docs.zwaybr.com/integracao/autenticacao/ Chave secreta no header Authorization. Toda requisição leva a chave secreta no cabeçalho Authorization . Header Copiar Authorization: Bearer $ZWAY_API_KEY Gere a chave no painel: Webhooks e chaves de API → Chaves de API . Ela aparece uma vez só. Use a chave só no seu servidor: nunca no navegador, no app ou no jogo do cliente. Guarde em variável de ambiente (ex.: ZWAY_API_KEY ), fora do código versionado. Chave vazada: revogue no painel e gere outra. ## Idempotência https://docs.zwaybr.com/integracao/idempotencia/ Repetir um pedido nunca cobra duas vezes. Rede caiu? Repita o pedido com a mesma chave: a ZWAY devolve a resposta da primeira vez, sem cobrar de novo. Envie Idempotency-Key (8 a 120 caracteres: letras, números, . _ : - ) com um valor único por cobrança e estável nas repetições. Mesma chave e mesmo pedido: a resposta da primeira vez. Mesma chave com outro pedido: 422 IDEMPOTENCY_KEY_REUSED . Pedido ainda em andamento: 409 IDEMPOTENCY_IN_PROGRESS ; repita em instantes. Fora do Brasil a chave é obrigatória: sem o header, o externalId vale como chave. Timeout não é recusa Sem resposta (timeout, 502), consulte o pagamento ou repita com a MESMA chave antes de criar outro. ## Erros e limites https://docs.zwaybr.com/integracao/erros/ Formato único de erro, códigos e limite de requisições. Todo erro vem com o status HTTP e o corpo { error: true, code, message, details } . Nada é cobrado quando a resposta é um erro. HTTP code O que fazer 400 VALIDATION_ERROR Corpo ou parâmetro inválido. details traz o campo e o motivo. 401 AUTH_FAILED Chave ausente, inválida ou revogada. 403 METHOD_NOT_ENABLED Método ou moeda não liberados para a sua conta. 404 NOT_FOUND Pagamento inexistente ou de outra conta. 409 IDEMPOTENCY_IN_PROGRESS Outro pedido com a mesma chave ainda está em processamento. Repita em instantes. 422 CURRENCY_NOT_SUPPORTED Moeda não disponível. 422 METHOD_NOT_AVAILABLE Método não existe nesta moeda. 422 IDEMPOTENCY_KEY_REUSED A mesma chave foi usada com um pedido diferente. 422 FIELDS_REQUIRED / AMOUNT_OUT_OF_RANGE Campo exigido pelo método ausente, ou valor fora da faixa. 429 RATE_LIMIT_EXCEEDED Muitas requisições. Aguarde retryAfter segundos. 503 INTERNATIONAL_UNAVAILABLE Serviço temporariamente indisponível. Nada foi cobrado. Exemplo · 400 Copiar { "error" : true , "code" : "VALIDATION_ERROR" , "message" : "Dados inválidos" , "details" : [ { "field" : "email" , "message" : "Invalid email" } ], "timestamp" : "2026-10-12T15:00:00.000Z" } ## Integrar com IA https://docs.zwaybr.com/integracao/com-ia/ Prompt pronto para Claude Code, Codex e outros agentes de código. Cole no seu agente de código (Claude Code, Codex…). O prompt traz o contrato da API e as regras de segurança; a chave nunca vai no prompt. Prompt de integração Copiar Integre a API de pagamentos da ZWAY neste projeto. Base: https: //api.zwaybr.com/api/v1. Autenticação: header Authorization: Bearer (variável de ambiente; nunca no código, no navegador ou no app). Criar pagamento: POST /payments com JSON { currency, paymentMethod, amount (inteiro, em centavos da moeda), name, email, document { type, number }, items [{ title, unitPrice, quantity }], externalId, ... }. - BRL: paymentMethod PIX (exige phone e items), BOLETO (endereço opcional, expiresAt) ou CREDIT_CARD (cardToken + tokenOrigin gerados no navegador; nunca número/CVV). - Outras moedas (ex.: MXN): consulte GET /payments/methods?currency=MXN para saber os métodos e os campos exigidos (ex.: SPEI exige document rfc, birthDate, birthCountry) e envie returnUrl. - Sempre envie o header Idempotency-Key (um por cobrança, estável nas repetições). Consultar: GET /payments/{id}. Erros: { error: true, code, message, details }. Webhook: cadastre a URL no painel ZWAY (tipo Recebimento). Valide X-Webhook-Signature = 'sha256=' + HMAC-SHA256 do corpo BRUTO com o segredo do webhook (comparação em tempo constante) e use X-Webhook-Id para não processar duas vezes. Eventos: transaction.approved, transaction.pending, transaction.failed, transaction.cancelled, transaction.expired. Regras: Não execute cobranças reais durante o desenvolvimento. Não grave a chave em arquivos versionados nem em logs. Escreva testes com a API simulada. Revise o que a IA escrever Confira a validação da assinatura do webhook e a Idempotency-Key antes de publicar. ## Eventos e formato https://docs.zwaybr.com/webhooks/eventos/ Um webhook para todas as moedas: eventos, cabeçalhos e corpo. Todos os pagamentos, em qualquer moeda, chegam no mesmo webhook de Recebimento , no mesmo formato. Evento Quando Tipo de webhook transaction.approved Pagamento aprovado Recebimento transaction.pending Cobrança criada, aguardando pagamento Recebimento transaction.failed Pagamento com falha Recebimento transaction.rejected Pagamento recusado Recebimento transaction.cancelled Cobrança cancelada Recebimento transaction.expired Cobrança vencida Recebimento payment.refunded Estorno concluído Reembolso withdrawal.completed Saque concluído Saques withdrawal.failed Saque não concluído Saques Cabeçalhos X-Webhook-Event : o evento. X-Webhook-Id : o mesmo id em todas as tentativas e reenvios; use para não processar duas vezes. X-Webhook-Signature : sha256= + HMAC-SHA256 do corpo ( verificar ). X-Webhook-Timestamp : horário do envio. Corpo transaction.payment_method traz o método ( pix , credit_card , boleto , spei , oxxo …) e transaction.currency a moeda. transaction.approved Copiar { "event_type" : "transaction.approved" , "transaction" : { "id" : "zw_1760000000000_ab12cd34" , "external_id" : "pedido-0001" , "status" : "paid" , "payment_method" : "pix" , "currency" : "BRL" , "amount" : "99.90" , "amount_cents" : 9990 , "net_amount" : "97.90" , "net_amount_cents" : 9790 , "fee" : { "total_amount" : "2.00" , "total_amount_cents" : 200 , "percentage" : 2 }, "paid_at" : "2026-10-12T15:02:10.000Z" }, "customer" : { "name" : "Maria Souza" , "email" : "maria@exemplo.com.br" }, "items" : [ { "title" : "Plano Pro" , "unit_price" : "99.90" , "unit_price_cents" : 9990 , "quantity" : 1 , "total_amount_cents" : 9990 } ], "webhook" : { "event" : "transaction.approved" , "timestamp" : "2026-10-12T15:02:11.000Z" , "version" : "2.0" } } Responda rápido Responda 2xx logo que receber e processe depois. Sem 2xx, o evento é reenviado automaticamente, com intervalos crescentes. ## Assinatura https://docs.zwaybr.com/webhooks/assinatura/ Como verificar que o webhook veio da ZWAY. X-Webhook-Signature = sha256= + HMAC-SHA256 do corpo exato com o segredo do webhook. Recuse o evento quando não bater. Node.js Copiar import crypto from "node:crypto" ; // corpoBruto: o corpo EXATO recebido (Buffer), antes de qualquer JSON.parse. // segredo: o segredo do webhook, mostrado uma vez quando você o criou. export function assinaturaValida(corpoBruto, cabecalho, segredo) { if (!Buffer.isBuffer(corpoBruto)) return false ; const esperado = "sha256=" + crypto.createHmac( "sha256" , segredo).update(corpoBruto).digest( "hex" ); const a = Buffer. from (String(cabecalho || "" )); const b = Buffer. from (esperado); return a.length === b.length && crypto.timingSafeEqual(a, b); } Calcule sobre os bytes recebidos, antes de qualquer JSON.parse . Compare em tempo constante ( timingSafeEqual ). O segredo aparece uma vez, quando você cria o webhook no painel. ## Status do pagamento https://docs.zwaybr.com/referencia/status/ O campo status das respostas e da consulta. O campo status das respostas e da consulta. Status Significado PENDING Aguardando pagamento APPROVED Pago REJECTED Recusado ou falhou EXPIRED Venceu sem pagamento CANCELED Cancelado REFUNDED Estornado CHARGEBACK Contestado pelo pagador UNDER_REVIEW Em análise ## Criar pagamento https://docs.zwaybr.com/pagamentos/criar/ POST https://api.zwaybr.com/api/v1/payments Uma rota para todas as moedas e métodos: currency e paymentMethod decidem o fluxo. Os campos exigidos mudam conforme o método. ```bash curl --request POST \ --url https://api.zwaybr.com/api/v1/payments \ --header "Authorization: Bearer $ZWAY_API_KEY" \ --header 'Content-Type: application/json' \ --header 'Idempotency-Key: pedido-0001-tentativa-1' \ --data '{ "currency": "BRL", "paymentMethod": "PIX", "amount": 9990, "name": "Maria Souza", "email": "maria@exemplo.com.br", "document": { "type": "cpf", "number": "12345678909" }, "phone": "11999999999", "items": [ { "title": "Plano Pro", "unitPrice": 9990, "quantity": 1 } ] }' ``` ## Buscar pagamento https://docs.zwaybr.com/pagamentos/buscar/ GET https://api.zwaybr.com/api/v1/payments/{id} Consulta qualquer pagamento, em qualquer moeda. Pagamento de outra conta devolve o mesmo 404 de um id inexistente. ```bash curl --request GET \ --url https://api.zwaybr.com/api/v1/payments/zw_1760000000000_ab12cd34 \ --header "Authorization: Bearer $ZWAY_API_KEY" ``` ## Moedas e métodos https://docs.zwaybr.com/pagamentos/metodos/ GET https://api.zwaybr.com/api/v1/payments/methods Lista as moedas e os métodos liberados para a sua conta, com valor mínimo/máximo e os campos exigidos de cada método. ```bash curl --request GET \ --url https://api.zwaybr.com/api/v1/payments/methods \ --header "Authorization: Bearer $ZWAY_API_KEY" ``` ## Configuração do cartão https://docs.zwaybr.com/pagamentos/cartao/ GET https://api.zwaybr.com/api/v1/payments/card-configuration Script e chave pública para tokenizar o cartão no navegador do comprador. O número do cartão nunca passa pelo seu servidor: envie só o cardToken. ```bash curl --request GET \ --url https://api.zwaybr.com/api/v1/payments/card-configuration \ --header "Authorization: Bearer $ZWAY_API_KEY" ```