Pular para o conteúdo principal

Guia de Idempotência

Quick Reference

WhatPrevina cobranças duplicadas com chaves de idempotência
WhyFalhas de rede e retentativas nunca devem resultar em cobrança dupla do cliente
Reading Time8 min
DifficultyIntermediate
PrerequisitesIntegração com a API funcional

No processamento de pagamentos, uma retentativa não idempotente é um erro financeiro:

  1. Seu servidor envia uma requisição de cobrança
  2. A cobrança é realizada com sucesso, mas a resposta é perdida devido a um timeout de rede
  3. Seu servidor retenta — sem uma chave de idempotência, a A55 cria uma segunda cobrança
  4. O cliente é cobrado duas vezes

Chaves de idempotência resolvem isso: se a A55 receber uma chave duplicada, ela retorna a resposta original em vez de criar uma nova cobrança. Isso torna as retentativas seguras — o cliente é cobrado exatamente uma vez, independentemente de quantas vezes você enviar a requisição.

Como Funciona

Envie um header Idempotency-Key em toda requisição POST:

POST /api/v1/bank/wallet/charge/ HTTP/1.1
Authorization: Bearer <token>
Content-Type: application/json
Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000

A A55 armazena a chave e sua resposta associada. Se a mesma chave for enviada novamente dentro da janela de expiração:

  • Mesmo payload → Retorna a resposta original (HTTP 200/201)
  • Payload diferente → Retorna HTTP 409 Conflict

Formato da Chave

Use UUID v4 para chaves de idempotência:

550e8400-e29b-41d4-a716-446655440000

Requisitos:

  • Única por operação de negócio (não por tentativa de retry)
  • Gerada uma única vez e reutilizada em todas as tentativas de retry da mesma operação
  • Mínimo de 16 caracteres, máximo de 128 caracteres

Endpoints Suportados

Todos os endpoints POST suportam idempotência:

EndpointCaso de Uso
POST /api/v1/bank/wallet/Criação de wallet
POST /api/v1/bank/wallet/charge/Criação de cobrança
POST /api/v1/bank/wallet/charge/refund/Reembolso
POST /api/v1/bank/wallet/charge/capture/Captura
POST /api/v1/bank/wallet/charge/cancel/Cancelamento

Requisições GET, PUT e DELETE são naturalmente idempotentes e não necessitam do header.

Comportamento de Requisições Duplicadas

CenárioResultado
Mesma chave + mesmo payloadRetorna a resposta original
Mesma chave + payload diferenteHTTP 409 Conflict
Mesma chave após expiração (24h)Tratada como nova requisição
Sem chave fornecidaCada requisição cria um novo recurso

Expiração da Chave

As chaves de idempotência expiram após 24 horas. Após a expiração, a mesma chave pode ser reutilizada para uma nova requisição. Projete sua estratégia de retry para concluir bem antes dessa janela.

Exemplos de Código

# Generate an idempotency key ONCE for this operation
IDEMPOTENCY_KEY=$(uuidgen)

# First attempt
curl -s -X POST "https://sandbox.api.a55.tech/api/v1/bank/wallet/charge/" \
-H "Authorization: Bearer ${A55_ACCESS_TOKEN}" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: ${IDEMPOTENCY_KEY}" \
-d '{
"amount": "100.00",
"currency": "BRL",
"type_charge": "credit_card",
"card": { "number": "4111111111111111", "holder_name": "TEST", "expiration_month": "12", "expiration_year": "2030", "cvv": "123" },
"payer": { "name": "Test", "email": "test@example.com", "document": "12345678909", "document_type": "CPF" }
}'

# Retry with SAME key — returns the same response, no duplicate charge
curl -s -X POST "https://sandbox.api.a55.tech/api/v1/bank/wallet/charge/" \
-H "Authorization: Bearer ${A55_ACCESS_TOKEN}" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: ${IDEMPOTENCY_KEY}" \
-d '{
"amount": "100.00",
"currency": "BRL",
"type_charge": "credit_card",
"card": { "number": "4111111111111111", "holder_name": "TEST", "expiration_month": "12", "expiration_year": "2030", "cvv": "123" },
"payer": { "name": "Test", "email": "test@example.com", "document": "12345678909", "document_type": "CPF" }
}'
Nunca gere uma nova chave por retentativa

A chave de idempotência deve ser gerada uma única vez por operação de negócio. Se você gerar uma nova chave para cada tentativa de retry, você perde completamente a proteção contra duplicatas.