moneyflydocs

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 recurso

2. 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

RotaExige Idempotency-Key
POST /v1/pix/qrcode✅ sim
POST /v1/pix/payout✅ sim
GET /v1/balancenão
GET /v1/transactions/:idnã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();
}