Idempotência
A Mises API implementa idempotência para garantir que operações críticas (como saques) não sejam duplicadas acidentalmente.
O que é Idempotência?
Idempotência é a propriedade que garante que uma operação pode ser executada múltiplas vezes sem alterar o resultado além da primeira execução.
Exemplo prático:
- Você envia uma requisição de saque de R$ 100,00
- A requisição falha por timeout de rede
- Você reenvia a mesma requisição com a mesma chave
- A API reconhece que já processou essa operação e retorna o resultado original
- Resultado: Apenas 1 saque é criado, não 2
Header Idempotency-Key
Para operações idempotentes, você deve incluir o header Idempotency-Key:
POST /v1/withdrawals HTTP/1.1
Host: api.misespay.com
Authorization: Bearer {token}
Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000
Content-Type: application/jsonFormato Aceito
- UUID v4 (recomendado):
550e8400-e29b-41d4-a716-446655440000 - Alfanumérico com hífens/underscores:
my-unique-key-123 - Tamanho: 1 a 255 caracteres
- Caracteres permitidos: Letras, números, hífens (
-) e underscores (_)
IMPORTANTE
Cada tentativa de operação única deve ter uma Idempotency-Key diferente. Use a mesma chave apenas para retry da mesma operação.
Endpoints que Requerem Idempotência
| Endpoint | Requer Idempotency-Key | Descrição |
|---|---|---|
POST /v1/withdrawals | ✅ Sim (obrigatório) | Criar saque |
POST /v1/sales | ❌ Não | Criar venda |
GET /v1/balance | ❌ Não | Consultar saldo |
Como Funciona
Primeira Requisição (201 Created)
curl -X POST https://api.misespay.com/v1/withdrawals \
-H "Authorization: Bearer {token}" \
-H "Idempotency-Key: abc-123-xyz" \
-H "Content-Type: application/json" \
-d '{"amount": 10.00, "authorize": true}'Response:
{
"success": true,
"message": "Saque solicitado com sucesso",
"data": {
"withdrawal_id": "881c686a-9e53-4809-a63c-c2730b924ea7",
"amount": "R$ 10,00",
"status": "processing"
}
}Requisição Duplicada (200 OK)
# Mesma Idempotency-Key
curl -X POST https://api.misespay.com/v1/withdrawals \
-H "Authorization: Bearer {token}" \
-H "Idempotency-Key: abc-123-xyz" \
-H "Content-Type: application/json" \
-d '{"amount": 10.00, "authorize": true}'Response:
{
"success": true,
"message": "Saque já processado anteriormente",
"data": {
"withdrawal_id": "881c686a-9e53-4809-a63c-c2730b924ea7",
"amount": "R$ 10,00",
"status": "processing"
},
"idempotent": true
}Diferenças:
- Status HTTP:
200 OK(ao invés de201 Created) - Campo adicional:
"idempotent": true - Mesmos dados do saque original
Boas Práticas
✅ Faça
- Gere uma chave única para cada nova operação
- Reutilize a mesma chave apenas para retry da mesma operação
- Use UUID v4 para garantir unicidade global
- Armazene a chave junto com a requisição para possíveis retries
- Implemente retry automático em caso de timeout/erro de rede
❌ Não Faça
- Não reutilize chaves entre operações diferentes
- Não use valores sequenciais (1, 2, 3...)
- Não use timestamps como chave única
- Não omita o header em endpoints que requerem
Erros Relacionados
400 - Idempotency-Key Ausente
{
"success": false,
"message": "Header Idempotency-Key é obrigatório"
}Solução: Adicione o header Idempotency-Key à requisição.
400 - Idempotency-Key Inválido
{
"success": false,
"message": "Idempotency-Key inválido. Use apenas letras, números, hífens e underscores (máximo 255 caracteres)"
}Solução: Use apenas caracteres permitidos (a-z, A-Z, 0-9, -, _).
409 - Conflito de Idempotência
Se você enviar a mesma Idempotency-Key com dados diferentes, a API pode retornar erro:
{
"success": false,
"message": "Conflito: Idempotency-Key já usada com dados diferentes"
}Solução: Gere uma nova Idempotency-Key para a nova operação.
Casos de Uso
1. Timeout de Rede
// Primeira tentativa - timeout
try {
await createWithdrawal(idempotencyKey, 100);
} catch (error) {
// Retry com a MESMA chave
await createWithdrawal(idempotencyKey, 100); // ✅ Seguro
}2. Erro 500 do Servidor
// Primeira tentativa - erro 500
const response = await createWithdrawal(idempotencyKey, 100);
if (response.status === 500) {
// Retry com a MESMA chave
await createWithdrawal(idempotencyKey, 100); // ✅ Seguro
}3. Múltiplas Operações
// Operação 1
const key1 = uuidv4();
await createWithdrawal(key1, 100);
// Operação 2 - NOVA chave
const key2 = uuidv4();
await createWithdrawal(key2, 50); // ✅ CorretoPróximos Passos
- Withdrawals - Criar saques com idempotência
