Idempotência e Reenvio Seguro

Use o header HTTP Idempotency-Key para repetir uma operação de pagamento com segurança quando houver timeout, queda de conexão ou dúvida sobre o resultado de uma requisição.

O que é idempotência?

Imagine que seu sistema envia uma requisição para criar uma Venda. O Gateway conclui a operação, mas a conexão é interrompida antes de devolver a resposta. Sem uma identificação da tentativa original, um novo envio poderia criar outra Venda.

Com a chave de idempotência, você pode reenviar a mesma requisição com a mesma chave. Se a operação já tiver sido concluída, o Gateway identifica a tentativa anterior e responde sem executar novamente a criação ou o pagamento.

⚠️

A chave identifica uma intenção de operação, não uma nova tentativa de pagamento. Se você não recebeu resposta, reutilize a chave original ao tentar novamente. Não crie uma chave diferente apenas porque houve timeout.

Como utilizar

Envie o header Idempotency-Key com um UUID válido, além dos headers exigidos pela operação:

api_key: <sua-api-key>
Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000
RegraComportamento
ObrigatoriedadeO header é opcional. Ausente ou contendo apenas espaços, a requisição segue o comportamento normal, sem controle de idempotência.
FormatoDeve conter um UUID válido. Formatos equivalentes são normalizados para a representação canônica em minúsculas.
Primeira tentativaUse uma chave nova para identificar a operação.
Reenvio da mesma operaçãoRepita a mesma chave e o mesmo payload.
Nova intenção de operaçãoGere outra chave, mesmo que esteja utilizando o mesmo endpoint.
Prazo de validadeA chave não expira.

A identificação da tentativa considera a empresa autenticada, a operação, o recurso de destino e a chave. Por isso, uma mesma chave pode existir em operações ou recursos diferentes; ainda assim, recomendamos gerar um UUID exclusivo para cada nova intenção, evitando confusões na integração.

Operações compatíveis

O suporte descrito atualmente está disponível nas operações abaixo:

OperaçãoEndpointSucesso na primeira chamada ou no reenvio concluído
Criar VendaPOST /v1/charges201 Created com o JSON atual da Venda.
Pagar VendaPOST /v1/charges/:uuid/pay200 OK com o JSON atual da Venda.
Pagar TransaçãoPOST /v1/transactions/:uuid/pay204 No Content, sem corpo de resposta.
📘

Escopo do recurso: não presuma que o header funciona em todos os endpoints de escrita. Utilize idempotência apenas nas operações que documentam suporte a esse mecanismo.

O que acontece quando uma requisição é reenviada?

Na primeira tentativa com uma chave nova, o Gateway registra o processamento, executa a operação e vincula a chave ao recurso resultante. Quando recebe novamente a mesma chave, avalia o resultado da tentativa anterior:

Condição encontradaHTTPResultado
Operação concluída e mesmo payload201, 200 ou 204Retorna o recurso atual ou a confirmação correspondente, sem repetir a operação.
Operação ainda em execução e mesmo payload409idempotency_key.processing. Aguarde antes de tentar novamente.
Operação anterior falhou e mesmo payload409idempotency_key.failed. A chave não pode ser utilizada para executar a operação outra vez.
Mesma chave e payload diferente409idempotency_key.payload_mismatch.
Operação concluída, mas resultado não disponível409idempotency_key.result_not_found.

Atenção: o reenvio não é uma cópia da primeira resposta

Nas operações sobre Vendas, o Gateway consulta o recurso novamente e devolve seu estado atual. Portanto, a resposta de um reenvio não é necessariamente idêntica à resposta original. Dados disponíveis somente na primeira resposta, como determinados conteúdos de 3DS ou SmartForm, não são reconstruídos.

Em POST /v1/transactions/:uuid/pay, o reenvio confirma a existência da Transação na empresa e retorna 204 No Content, sem repetir a operação de pagamento.

Exemplos práticos

Os exemplos usam a variável BASE_URL para representar a URL do ambiente em que sua empresa está integrando. Os arquivos JSON citados devem conter o corpo válido definido na referência de cada endpoint.

1. Criar uma Venda

curl --request POST "$BASE_URL/v1/charges" \
  --header 'api_key: <sua-api-key>' \
  --header 'Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000' \
  --header 'Content-Type: application/json' \
  --data-binary @criar-venda.json

Se houver timeout, envie novamente o mesmo arquivo JSON e a mesma chave. Se a Venda já tiver sido criada, o Gateway retornará 201 Created com os dados atuais dela, sem criar outra Venda.

2. Pagar uma Venda

curl --request POST "$BASE_URL/v1/charges/<uuid-da-venda>/pay" \
  --header 'api_key: <sua-api-key>' \
  --header 'Idempotency-Key: 743e72e4-c8bd-4f76-8134-ec1db58e049c' \
  --header 'Content-Type: application/json' \
  --data-binary @pagar-venda.json

Neste endpoint, o corpo corresponde ao array de solicitações de pagamento definido na referência da operação. Se a tentativa original tiver sido concluída, o reenvio com a mesma chave e o mesmo corpo retorna 200 OK com a Venda atual, sem cobrar novamente.

3. Pagar uma Transação

curl --request POST "$BASE_URL/v1/transactions/<uuid-da-transacao>/pay" \
  --header 'api_key: <sua-api-key>' \
  --header 'Idempotency-Key: a209b551-64a2-4e63-9fc3-bc587f058f08'

Esta operação não utiliza corpo de requisição. Uma tentativa concluída ou seu reenvio bem-sucedido retorna 204 No Content.

Erros de idempotência

O campo parameter permite identificar a condição retornada pela API. Consulte também Códigos de erros para entender o tratamento geral de erros.

HTTPparameterO que significaComo proceder
400idempotency_key.invalidO header foi informado, mas não contém um UUID válido.Corrija o formato e faça uma nova requisição.
400idempotency_key.create_errorNão foi possível registrar ou consultar a tentativa de idempotência.Registre o erro e verifique o resultado da operação antes de decidir por novo envio.
409idempotency_key.payload_mismatchA chave já foi usada para a mesma operação e recurso com outro payload.Recupere o payload original ou trate a requisição como uma nova intenção, com outra chave.
409idempotency_key.processingOutra tentativa com a mesma chave ainda está em andamento.Aguarde e consulte ou reenvie depois com a mesma chave.
409idempotency_key.failedA tentativa anterior falhou e a chave ficou indisponível para execução posterior.Verifique o resultado e utilize uma nova chave apenas quando uma nova tentativa for apropriada.
409idempotency_key.result_not_foundO processamento foi registrado como concluído, mas o recurso necessário para a resposta não foi encontrado.Verifique o recurso e investigue antes de iniciar outra operação.

Boas práticas de integração

  1. Gere um UUID para cada nova intenção. Salve-o junto do identificador interno da operação em seu sistema.
  2. Preserve a chave nas tentativas repetidas. Se o resultado for desconhecido após uma falha de rede, não substitua a chave automaticamente.
  3. Não altere o payload durante um reenvio. Mudanças no corpo da requisição podem produzir idempotency_key.payload_mismatch.
  4. Trate 409 processing como uma operação ainda não resolvida. Aguarde antes de consultar ou reenviar. O documento técnico não estabelece um intervalo fixo de espera.
  5. Diferencie falha de comunicação de falha de negócio. Uma operação registrada como failed exige outra chave para uma nova execução; primeiro confirme que não há uma operação anterior cujo resultado precise ser conciliado.
  6. Leia o estado atual do recurso. Não dependa de informações temporárias da resposta original para reconstruir um fluxo de 3DS ou SmartForm.

Perguntas frequentes

A idempotência funciona sem o header? Não. Sem uma chave válida informada, a rota mantém seu comportamento habitual.

Um erro de validação consome a chave? Nas operações de criação e pagamento de Venda, a validação do corpo é executada antes do registro da tentativa. Assim, erros dessa validação não consomem a chave.

Posso repetir a chave com outra Venda ou outra operação? O escopo técnico diferencia operação e recurso. Entretanto, para manter a rastreabilidade, prefira uma chave nova para cada intenção.

Por quanto tempo posso reutilizar a chave de uma operação concluída? A implementação descrita não possui expiração automática da chave.

Para orientações gerais sobre interpretação das respostas e diagnóstico de falhas, consulte Respostas e Convenções da API e Solução de Problemas e Boas Práticas.