Idempotência
Como evitar cobrança duplicada com Idempotency-Key.
Idempotência
O header Idempotency-Key é opcional mas fortemente recomendado em rotas que criam recurso financeiro (POST /v1/pix/qrcode, POST /v1/pix/payout).
Sem ele, a request funciona normalmente — útil pra começar rápido. Mas se sua rede falhar e você refizer a mesma chamada, vai criar uma cobrança duplicada. Com a key, isso é impossível.
Por que isso importa
Imagina o cenário: seu servidor chama POST /v1/pix/qrcode, a request chega no Moneyfly, processamos, mas a resposta se perde na rede (timeout, 504 de um proxy, whatever). Seu servidor acha que falhou e refaz — você acaba de criar duas cobranças pro mesmo pedido.
O Idempotency-Key resolve isso: se você reenviar a mesma key, a gente devolve exatamente a mesma resposta da primeira, sem processar de novo.
Quando usar
- Sempre que possível em produção — qualquer integração séria de pagamento manda key.
- Pode pular em testes/protótipos — sandbox, scripts de exemplo, etc.
- Recomendamos passar mesmo na sandbox pra você acostumar o código com o padrão antes de ir pra produção.
Como usar
Gere um UUID (ou qualquer string única até 128 chars) por operação lógica e passe no header:
curl -X POST https://api.moneyflybr.com/v1/pix/qrcode \
-H "Idempotency-Key: 8f7a2d3e-9b1c-4f6e-8a0d-1b2c3d4e5f6a" \
...Formato aceito
- 8 a 128 caracteres
- Alfanuméricos,
_e- - Gere do seu lado (UUID v4, ULID, ou id do pedido no seu sistema)
TTL
Idempotency keys duram 24 horas. Passado esse período, a mesma key pode ser usada pra uma nova operação.
Regras
1. Mesma key = mesma resposta
# Chamada 1 — cria recurso, devolve 201
curl -X POST /v1/pix/qrcode -H "Idempotency-Key: abc123" -d '{"amount": 1000}'
# Chamada 2 (dentro de 24h) — MESMA key, MESMO body
curl -X POST /v1/pix/qrcode -H "Idempotency-Key: abc123" -d '{"amount": 1000}'
# → resposta idêntica, sem criar novo recurso2. Mesma key, body diferente = erro
Se você mandar a mesma key pra operações diferentes, retornamos 409:
{
"error": "Conflict",
"message": "Idempotency-Key reutilizada pra operação diferente."
}3. Escopo por conta
Keys são isoladas por merchant. Seu abc123 não conflita com o abc123 de outra conta.
Quais rotas exigem
| Rota | Exige Idempotency-Key |
|---|---|
POST /v1/pix/qrcode | ✅ sim |
POST /v1/pix/payout | ✅ sim |
GET /v1/balance | não |
GET /v1/transactions/:id | não |
Boas práticas
Uma key por operação lógica, não por tentativa HTTP. Se você vai criar uma cobrança pro pedido #1234, use o id do pedido ou um UUID gerado quando o pedido foi criado. Todas as tentativas de retry usam a mesma key.
Persista a key no seu banco. Salve antes de chamar o Moneyfly. Se seu servidor crashar no meio, ao reiniciar você busca o pedido e reusa a key.
Não reuse keys pra coisas diferentes. Se quiser criar outra cobrança pro mesmo pedido (primeira expirou), gere uma key nova.
Exemplo Node.js
import crypto from 'node:crypto';
import { savePedido, getPedido, updatePedido } from './db';
async function criarCobranca(pedidoId, valorCents) {
let pedido = await getPedido(pedidoId);
if (!pedido.idempotencyKey) {
pedido.idempotencyKey = crypto.randomUUID();
await updatePedido(pedidoId, { idempotencyKey: pedido.idempotencyKey });
}
const res = await fetch('https://api.moneyflybr.com/v1/pix/qrcode', {
method: 'POST',
headers: {
'client-id': process.env.MF_CLIENT_ID,
'client-secret': process.env.MF_CLIENT_SECRET,
'Idempotency-Key': pedido.idempotencyKey,
'Content-Type': 'application/json',
},
body: JSON.stringify({
amount: valorCents,
payer: { name: 'Cliente', document: '...' },
external_id: pedidoId,
}),
});
return res.json();
}