Idempotencia
Chaves de idempotencia garantem que operacoes criticas sejam executadas apenas uma vez, mesmo em caso de retries ou falhas de rede.
O que e idempotencia?
Uma operacao e idempotente quando executa-la multiplas vezes produz o mesmo resultado que executa-la uma vez. Isso e crucial para operacoes financeiras onde duplicacoes podem causar prejuizos.
Importante
Como usar
Adicione o header Idempotency-Key com um valor unico para cada operacao:
POST /v1/payments HTTP/1.1
Host: api.axon.com
Authorization: Bearer axon_sk_...
Content-Type: application/json
Idempotency-Key: pay_order123_attempt1
{
"token_id": "tok_abc123",
"amount": 150.00
}Gerando chaves de idempotencia
// Opcao 1: UUID v4 (simples)
function generateIdempotencyKey() {
return crypto.randomUUID();
}
// Opcao 2: Baseado no contexto (recomendado)
function generateContextualKey(operation, resourceId, attempt = 1) {
// Permite retry com mesma chave
return `${operation}_${resourceId}_${attempt}`;
}
// Opcao 3: Hash de parametros
function generateDeterministicKey(params) {
const sorted = JSON.stringify(params, Object.keys(params).sort());
return crypto.createHash('sha256').update(sorted).digest('hex');
}
// Exemplos de uso
const key1 = generateIdempotencyKey();
// "f47ac10b-58cc-4372-a567-0e02b2c3d479"
const key2 = generateContextualKey('payment', 'order_123', 1);
// "payment_order_123_1"
const key3 = generateDeterministicKey({
token_id: 'tok_abc',
amount: 150.00,
order_id: 'order_123',
});
// "a1b2c3d4e5f6..."Comportamento da API
Primeira requisicao
A operacao e executada normalmente e a resposta e armazenada junto com a chave.
Requisicao duplicada (mesma chave, mesmos parametros)
Retorna a resposta armazenada sem executar novamente. Status 200.
Conflito (mesma chave, parametros diferentes)
Retorna erro 409 Conflict. Gere uma nova chave para a operacao diferente.
Tratando respostas
async function createPaymentSafely(tokenId, amount, orderId) {
const idempotencyKey = `payment_${orderId}`;
try {
const response = await fetch('https://api.axon.com/v1/payments', {
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json',
'Idempotency-Key': idempotencyKey,
},
body: JSON.stringify({
token_id: tokenId,
amount,
metadata: { order_id: orderId },
}),
});
const data = await response.json();
if (response.ok) {
// Checar se foi idempotente
if (response.headers.get('Idempotent-Replayed') === 'true') {
console.log('Resposta recuperada de requisicao anterior');
}
return data;
}
if (response.status === 409) {
// Conflito - parametros diferentes para mesma chave
throw new Error(`Idempotency conflict: ${data.error.message}`);
}
throw new Error(data.error.message);
} catch (error) {
// Em caso de timeout ou erro de rede, pode tentar novamente
// com a MESMA chave de idempotencia
if (error.name === 'TypeError' || error.code === 'ETIMEDOUT') {
console.log('Erro de rede, retentando com mesma chave...');
return createPaymentSafely(tokenId, amount, orderId);
}
throw error;
}
}Validade das chaves
Chaves de idempotencia sao armazenadas por 24 horas. Apos esse periodo, a mesma chave pode ser reutilizada para uma nova operacao.
| Servico | Validade |
|---|---|
| Vault | 24 horas |
| Payments | 24 horas |
| Chain | 7 dias |
Boas praticas
- ✓Use chaves baseadas no contexto do negocio (order_id, transaction_id)
- ✓Armazene a chave usada junto com o resultado da operacao
- ✓Use a mesma chave ao retentar apos erros de rede
- ✓Gere nova chave apenas para operacoes genuinamente diferentes
- ✓Limite o tamanho da chave a 255 caracteres