Erros Comuns de Integração
Quick Reference
1. Usar credenciais de produção no sandbox
Sintoma: 401 Unauthorized em todas as requisições para sandbox.api.a55.tech.
Correção: Sandbox e produção usam pools Cognito separados. Use client_id/client_secret do sandbox com a URL de autenticação do sandbox, e credenciais de produção com a URL de autenticação de produção.
2. Não tratar o redirecionamento 3DS
Sintoma: Cobranças com cartões registrados no 3DS ficam em awaiting_3ds para sempre.
Correção: Quando a resposta da cobrança inclui uma redirect_url, redirecione o portador do cartão para essa URL. Após a autenticação, o usuário retorna para sua callback_url e você deve consultar o status da cobrança.
3. Hardcoding de tokens da API
Sintoma: Tokens expiram após 1 hora, e todas as requisições falham com 401.
Correção: Nunca faça hardcode de tokens. Implemente um gerenciador de tokens que chama o endpoint OAuth2 antes da expiração:
import time
class TokenManager:
def __init__(self):
self._token = None
self._expires_at = 0
def get_token(self):
if time.time() > self._expires_at - 60:
self._refresh()
return self._token
def _refresh(self):
# Call OAuth2 token endpoint
self._token = response["access_token"]
self._expires_at = time.time() + response["expires_in"]
4. Não verificar assinaturas de webhook
Sintoma: Seu sistema processa payloads de webhook forjados, levando a atualizações incorretas do status do pedido.
Correção: Sempre verifique a assinatura HMAC-SHA256 antes de processar:
import hmac
import hashlib
def verify_webhook(payload: bytes, signature: str, secret: str) -> bool:
expected = hmac.new(secret.encode(), payload, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, signature)
5. Chaves de idempotência ausentes em retentativas
Sintoma: O cliente é cobrado duas vezes porque um timeout disparou uma retentativa sem a mesma Idempotency-Key.
Correção: Gere um UUID v4 uma única vez por operação de negócio e envie em todas as tentativas:
import uuid
idempotency_key = str(uuid.uuid4()) # Generate ONCE
# Use the same key on retries
headers = {"Idempotency-Key": idempotency_key}
6. Formato incorreto do valor
Sintoma: 422 Unprocessable Entity com erro de validação no campo amount.
Correção: O formato do valor depende das casas decimais da moeda:
| Moeda | Decimais | Correto | Errado |
|---|---|---|---|
| BRL, MXN, USD, EUR, PEN, ARS | 2 | 150.00 | 150, "150", 150.0 |
| CLP, COP | 0 | 50000 | 50000.00, 50000.50 |
Peso Chileno e Peso Colombiano não possuem unidades fracionárias. O backend arredonda os valores para inteiros nessas moedas. Enviar 50000.50 para CLP resulta em 50000. Sempre envie números inteiros para CLP e COP para evitar truncamento inesperado.
7. Campos obrigatórios do pagador ausentes
Sintoma: Erro 422 listando campos ausentes como payer.document ou payer.email.
Correção: Toda cobrança requer, no mínimo:
{
"payer": {
"name": "Customer Name",
"email": "customer@example.com",
"document": "12345678909",
"document_type": "CPF"
}
}
Os requisitos de documento variam por país (CPF para Brasil, RFC para México).
8. Não implementar retry com backoff exponencial
Sintoma: Seu sistema bombardeia a API após um erro 500, é limitado por rate limit e piora a indisponibilidade.
Correção: Implemente backoff exponencial com jitter:
import time
import random
for attempt in range(4):
response = make_request()
if response.status_code < 500:
break
delay = (2 ** attempt) + random.uniform(0, 1)
time.sleep(delay)
9. Ignorar rate limits
Sintoma: Respostas 429 Too Many Requests repentinas durante picos de tráfego.
Correção: Leia os headers de rate limit (X-RateLimit-Remaining, X-RateLimit-Reset) e reduza a taxa proativamente. Consulte o guia de rate limiting.
10. Não verificar o status da cobrança após a criação
Sintoma: Pedido marcado como pago imediatamente após a criação da cobrança, mas a cobrança estava na verdade como pending ou declined.
Correção: Após criar uma cobrança, verifique o campo status na resposta. Para métodos assíncronos (PIX, Boleto), configure webhooks para receber atualizações de status — não assuma que a cobrança foi confirmada.
11. webhook_url ausente na criação da cobrança
Sintoma: Nenhuma notificação de webhook chega, mesmo que seu endpoint funcione.
Correção: Inclua webhook_url no corpo da requisição de criação da cobrança, ou configure uma URL de webhook padrão nas configurações do merchant.
12. Moeda incorreta para o país
Sintoma: Erro 422 ou taxas de conversão inesperadas.
Correção: Use a moeda correta para cada país:
| País | Moeda | Decimais | Tipo de documento | Exemplo de valor |
|---|---|---|---|---|
| Brasil | BRL | 2 | CPF / CNPJ | 150.00 |
| México | MXN | 2 | RFC / CURP | 2500.00 |
| Chile | CLP | 0 | RUT | 50000 |
| Colômbia | COP | 0 | CC (Cédula) | 200000 |
| Peru | PEN | 2 | DNI | 350.00 |
| Argentina | ARS | 2 | DNI / CUIT | 85000.00 |
13. Não tratar capturas parciais corretamente
Sintoma: O valor autorizado é capturado integralmente quando apenas um envio parcial foi realizado.
Correção: Ao capturar menos que o valor autorizado, defina explicitamente o valor da captura:
{
"amount": "75.00"
}
O valor autorizado restante é liberado automaticamente.
14. Tratamento de erros ausente no código
Sintoma: Exceções não tratadas derrubam sua aplicação quando a API retorna respostas inesperadas.
Correção: Envolva cada chamada de API em try/catch e trate todos os códigos de status HTTP possíveis. Registre o request_id para cada requisição que falhar.
15. Não testar todos os cenários de recusa de cartão
Sintoma: A aplicação trava ou mostra erro genérico quando um cartão é recusado.
Correção: Teste com todos os cartões de teste de recusa e verifique se sua interface mostra mensagens apropriadas:
| Cartão de Teste | Cenário |
|---|---|
4000 0000 0000 0002 | Cartão recusado |
4000 0000 0000 0069 | Erro de processamento |
4000 0000 0000 0119 | Saldo insuficiente |