Chaves e segredos
- A API Key está em variável de ambiente ou num gerenciador de segredos, nunca no código nem em repositório.
- A chave nunca vai para frontend, app mobile, URL ou log.
- Cada serviço tem a sua chave, com só as permissões de que precisa (
payments:write,transactions:read,balance:read,transfers:write). -
transfers:writeestá numa chave isolada, usada só pelo serviço de saques. - Você sabe rotacionar sem derrubar a integração: criar a segunda chave, trocar, depois revogar a antiga.
- O segredo de assinatura do webhook também está no cofre.
- Uma chave usada só nos testes foi revogada.
Idempotência
- Toda criação de cobrança e transferência envia
Idempotency-KeyouexternalId. - A chave vem do identificador do negócio mais a tentativa (
PEDIDO-1042-t1), não de um UUID novo a cada requisição. - A chave é gravada no seu banco antes de chamar a API.
- Em timeout, erro de rede ou
5xx, o retry usa exatamente a mesma chave e o mesmo corpo. - Para refazer uma cobrança depois que ela terminou (expirada, falha), você usa uma chave nova.
- O tratamento de
409 idempotency_conflictconsulta a operação original, em vez de trocar a chave.
Webhook
- A URL é HTTPS, na porta 443, sem redirecionamento e acessível publicamente.
- O receptor valida
X-NyxPag-Signaturecom o segredo do webhook, em tempo constante. - A validação usa o corpo bruto, sem parse e reserialização.
- O timestamp
té checado numa janela (por exemplo, 5 minutos). - O evento é gravado de forma durável antes de responder
2xx. - O processamento pesado roda depois, fora do request. A resposta sai em poucos segundos (o limite da NyxPag é 8).
- A deduplicação usa o
iddo evento emtransaction.*e oX-NyxPag-Deliveryemmed.*. - Há testes: assinatura inválida, corpo alterado, timestamp velho, evento repetido. Veja Ambientes.
- O receptor lida com eventos fora de ordem.
Estados e valores
- Um pedido só é liberado com
status: "approved", nunca por201ou202. -
202é tratado como “pendente”, e a decisão final vem do webhook ou da consulta. -
200e201são tratados como sucesso. - Uma cobrança expirada (
cancelledcomexpired: true) gera um novo Pix com chave nova, em vez de travar o pedido. - O Pix mostra o valor que o pagador paga (
amountda resposta), e o seu pedido guarda o valor original. - O valor é lido como reais decimais, nunca como centavos.
- Só há um saque
pendingpor vez na conta: o seu serviço de saques enfileira (WITHDRAWAL_IN_PROGRESS). - O CPF do pagador é validado no seu lado antes de enviar.
Erros e limites
- A decisão usa
error.code, não o texto deerror.message. -
400,401,403,404e422não são repetidos às cegas. - No
429, o cliente espera oRetry-Aftere adiciona jitter. - O número de tentativas tem teto (por exemplo, 5).
- O cliente lê
RateLimit-Remaininge desacelera antes do limite. - Nenhum fluxo usa
refresh=trueem polling. A cota é de 100 requisições por 60 segundos por chave.
Reconciliação
- Um job periódico percorre
GET /transactionse compara com o seu sistema. - Ele cobre webhook perdido, já que após 8 tentativas a NyxPag desiste.
- Ele cobre estados sem webhook, como
refunded. - Há um job para
GET /meds?status=pendingse você acompanha contestações. - Divergências geram alerta, não correção silenciosa.
Observabilidade e dados pessoais
- Todo
requestIdé registrado, em sucesso e erro. - A API Key e o segredo do webhook nunca aparecem em log, nem mascarados.
- CPF, e-mail e o Copia e Cola do pagador são removidos ou anonimizados antes de ir para log.
- Falha de webhook, timeout e
5xxgeram alerta com contexto suficiente.
Quando pedir ajuda
Escreva para [email protected] com:- o
requestIdda resposta; - o horário exato, com fuso;
- o endpoint e o método;
- o que você esperava e o que aconteceu.
Webhooks
Configuração, regras da URL e retentativas.
Idempotência
A regra mais importante de uma integração financeira.

