Idempotency
O problema que isso resolve
Sua chamada de rede pode falhar depois que o pagamento já foi processado do nosso lado — você não sabe se foi só a resposta que se perdeu. Sem uma chave de idempotência, um retry ingênuo arrisca cobrar duas vezes.
Como usar
Envie o header Idempotency-Key (qualquer string única sua — um id de pedido interno costuma
ser uma boa escolha) em qualquer POST/PATCH:
curl -X POST https://api.gateway.example/v1/payments \
-H "Authorization: Bearer sk_test_..." \
-H "Idempotency-Key: order-1042" \
-H "Content-Type: application/json" \
-d '{"amountInCents": 5000, "method": "pix", "payerDocument": "12345678900"}'
- Mesma chave + mesmo corpo → devolve a resposta já computada, sem reprocessar (nem cobrar de novo).
- Mesma chave + corpo diferente →
422 UNPROCESSABLE_ENTITY(nunca reprocessa silenciosamente algo diferente do que a chave já representa). - Sem o header → sempre executa (comportamento padrão).
O registro é durável (sobrevive a um restart do nosso lado) — não é uma otimização em memória, é uma garantia contratual.
Nos SDKs
@gateway/sdk (TypeScript) e o SDK PHP já geram uma Idempotency-Key automática (UUID) em
toda chamada mutável que você não informar explicitamente — um retry de rede feito pelo
próprio SDK nunca duplica um efeito financeiro. Pra usar a sua própria:
await gateway.payments.create(params, { idempotencyKey: 'order-1042' });
Paginação (cursor)
Todo endpoint de listagem (payment-links, receivables, settlements) devolve a mesma
forma:
{ "data": [ ... ], "nextCursor": "abc123==", "hasMore": true }
let cursor;
do {
const page = await gateway.receivables.list({ cursor, limit: 50 });
for (const r of page.data) {
/* ... */
}
cursor = page.nextCursor ?? undefined;
} while (cursor);
limit default é 20, máximo 100. cursor é opaco — nunca monte um você mesmo, sempre use o
nextCursor da página anterior.