Formato de Resposta de Erro
Todos os erros da API seguem um formato consistente:
{
"success": false,
"error": "Human-readable error message",
"details": [
{
"field": "amount",
"message": "Must be a positive number"
}
]
}Códigos de Estado HTTP
200OKPedido bem-sucedido
201CreatedRecurso criado com sucesso
400Bad RequestDados do pedido inválidos ou erro de validação
401UnauthorizedAutenticação em falta ou inválida
403ForbiddenSem autorização para aceder a este recurso
404Not FoundRecurso não encontrado
429Too Many RequestsLimite de taxa excedido
500Internal ErrorErro do servidor. Por favor contacte o suporte
| Código | Estado | Descrição |
|---|---|---|
200 | OK | Pedido bem-sucedido |
201 | Created | Recurso criado com sucesso |
400 | Bad Request | Dados do pedido inválidos ou erro de validação |
401 | Unauthorized | Autenticação em falta ou inválida |
403 | Forbidden | Sem autorização para aceder a este recurso |
404 | Not Found | Recurso não encontrado |
429 | Too Many Requests | Limite de taxa excedido |
500 | Internal Error | Erro do servidor. Por favor contacte o suporte |
Erros Comuns
Erros de Validação (400)
Dados de entrada inválidosO corpo do pedido não corresponde ao esquema esperado. Verifique o array para erros de campos específicos.details
{
"success": false,
"error": "Invalid input data",
"details": [
{"path": ["amount"], "message": "Expected number, received string"},
{"path": ["token"], "message": "Invalid enum value. Expected 'USDC' | 'EURC'"}
]
}Montante inválidoO montante deve estar entre 0,01 e 1.000.000.
Endereço do comerciante inválidoO não corresponde ao endereço da wallet do comerciante.toAddress
Erros de Autenticação (401/403)
Nenhum token fornecidoO endpoint protegido requer autenticação. Inclua o cabeçalho ou .AuthorizationX-API-Key
Token inválido ou expiradoO token JWT expirou (tempo de vida de 15 min) ou está malformado. Reautentique-se para obter um novo token.
API key inválidaAPI key não encontrada ou foi revogada. Verifique que está a utilizar a chave correta.
Erros de Recurso (404)
Comerciante não encontradoNão existe nenhum comerciante com o ID fornecido. Verifique o seu .merchantId
Pagamento não encontradoNão existe nenhum pagamento com o ID fornecido. Verifique se o ID do pagamento está correto.
Pagamento já existeJá existe um pagamento com este . A API devolve com os dados do pagamento existente. Isto previne ataques de gasto duplo.txHash200
Códigos de Erro da API
Quando ocorre um erro, a resposta inclui um campo legível por máquina que pode utilizar para tratamento programático de erros:code
{
"success": false,
"error": "Human-readable message",
"code": "RATE_LIMIT_EXCEEDED",
"retryAfter": 60
}Códigos de Erro Gerais
RATE_LIMIT_EXCEEDED429Limite de taxa excedido para este endpoint
INVALID_UUID_FORMAT400O parâmetro ID não é um UUID válido
MISSING_PARAMETER400Falta um parâmetro obrigatório
2FA_REQUIRED403A operação requer que o 2FA esteja ativado
2FA_CODE_REQUIRED400O código 2FA não foi fornecido
2FA_INVALID401O código 2FA está incorreto ou expirado
SELF_TRANSFER_NOT_ALLOWED400Não é possível levantar para a sua própria wallet Fivo
INVALID_MERCHANT_ID400O formato do Merchant ID é inválido
WEBHOOK_LIMIT_REACHED400Número máximo de webhooks por comerciante atingido
REFUND_WINDOW_EXPIRED400A janela de reembolso (180 dias) expirou
REFUND_EXCEEDS_REMAINING400O montante excede o saldo reembolsável
PAYMENT_NOT_COMPLETED400O pagamento não está no estado concluído
NO_SOURCE_ADDRESS400O pagamento não tem endereço de origem
REFUND_NOT_CANCELABLE400O reembolso não está no estado pendente
| Código | HTTP | Descrição |
|---|---|---|
RATE_LIMIT_EXCEEDED | 429 | Limite de taxa excedido para este endpoint |
INVALID_UUID_FORMAT | 400 | O parâmetro ID não é um UUID válido |
MISSING_PARAMETER | 400 | Falta um parâmetro obrigatório |
2FA_REQUIRED | 403 | A operação requer que o 2FA esteja ativado |
2FA_CODE_REQUIRED | 400 | O código 2FA não foi fornecido |
2FA_INVALID | 401 | O código 2FA está incorreto ou expirado |
SELF_TRANSFER_NOT_ALLOWED | 400 | Não é possível levantar para a sua própria wallet Fivo |
INVALID_MERCHANT_ID | 400 | O formato do Merchant ID é inválido |
WEBHOOK_LIMIT_REACHED | 400 | Número máximo de webhooks por comerciante atingido |
REFUND_WINDOW_EXPIRED | 400 | A janela de reembolso (180 dias) expirou |
REFUND_EXCEEDS_REMAINING | 400 | O montante excede o saldo reembolsável |
PAYMENT_NOT_COMPLETED | 400 | O pagamento não está no estado concluído |
NO_SOURCE_ADDRESS | 400 | O pagamento não tem endereço de origem |
REFUND_NOT_CANCELABLE | 400 | O reembolso não está no estado pendente |
Códigos de Erro da Blockchain
Estes códigos aparecem no campo de pagamentos falhados:failure_reason
E001Fundos insuficientes na wallet do remetente
E002Transação revertida na cadeia
E003Tempo limite de rede durante a transação
E004Endereço de wallet inválido
E005Estimativa de gas falhou
E006O utilizador cancelou a transação
E007Atestação CCTP falhou
E999Erro de blockchain desconhecido
| Código | Descrição |
|---|---|
E001 | Fundos insuficientes na wallet do remetente |
E002 | Transação revertida na cadeia |
E003 | Tempo limite de rede durante a transação |
E004 | Endereço de wallet inválido |
E005 | Estimativa de gas falhou |
E006 | O utilizador cancelou a transação |
E007 | Atestação CCTP falhou |
E999 | Erro de blockchain desconhecido |
Limitação de Taxa
Quando excede os limites de taxa, recebe uma resposta 429 com cabeçalhos adicionais:
HTTP/1.1 429 Too Many Requests
Retry-After: 60
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1705312800
{
"success": false,
"error": "Rate limit exceeded",
"message": "Too many requests. Please retry after 1 minute.",
"code": "RATE_LIMIT_EXCEEDED",
"retryAfter": 60,
"context": "general"
}Cabeçalhos de Limite de Taxa
| Cabeçalho | Descrição |
|---|---|
Retry-After | Segundos a aguardar antes de tentar novamente |
X-RateLimit-Limit | Máximo de pedidos permitidos na janela |
X-RateLimit-Remaining | Pedidos restantes na janela atual |
X-RateLimit-Reset | Timestamp Unix de quando o limite é reposto |
Limites de Taxa por Endpoint
Endpoints de API Key
200 req / 1 minute
Per: API Key
API Geral
100 req / 1 minute
Per: IP
Criação de pagamento (widget)
20 req / 1 minute
Per: IP
Início de sessão
5 req / 5 minutes
Per: IP + email
Registo
3 req / 15 minutes
Per: IP
Recuperação de Palavra-passe
3 req / 15 minutes
Per: IP + email
Verificação 2FA
5 req / 5 minutes
Per: IP
Levantamentos
10 req / 10 minutes
Per: IP
Formulário de contacto
3 req / 15 minutes
Per: IP
| Endpoint | Limite | Janela | Por |
|---|---|---|---|
| Endpoints de API Key | 200 req | 1 minute | API Key |
| API Geral | 100 req | 1 minute | IP |
| Criação de pagamento (widget) | 20 req | 1 minute | IP |
| Início de sessão | 5 req | 5 minutes | IP + email |
| Registo | 3 req | 15 minutes | IP |
| Recuperação de Palavra-passe | 3 req | 15 minutes | IP + email |
| Verificação 2FA | 5 req | 5 minutes | IP |
| Levantamentos | 10 req | 10 minutes | IP |
| Formulário de contacto | 3 req | 15 minutes | IP |
Boa Prática
Retry-AfterErros Entre Cadeias
Os pagamentos entre cadeias são tratados do lado do cliente pelo Bridge Kit no widget. Se o bridge falhar (ex.: tempo limite de atestação, falha na emissão), o widget mostra o erro diretamente ao cliente. Estes erros não chegam à API do backend.
Se um pagamento entre cadeias falhar após a transação de queima, o cliente pode contactar o suporte com o hash da sua transação. Pagamentos falhados armazenam o erro no campo , acessível através da API de estado do pagamento.failure_reason
Deteção de Fraude
O Fivo inclui deteção de fraude integrada. Estes erros indicam potenciais ataques:
Verificação do montante do pagamento falhouO montante declarado não corresponde ao montante real da transação na blockchain. Isto pode indicar uma tentativa de manipulação dos registos de pagamento.
Segurança
Exemplo de Tratamento de Erros
Veja como tratar erros da API corretamente no seu código:
async function createCheckoutSession(data) {
try {
const response = await fetch('https://api.fivo.finance/checkout/sessions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': process.env.FIVO_API_KEY
},
body: JSON.stringify(data)
});
const result = await response.json();
if (!response.ok) {
// Handle specific error codes
switch (response.status) {
case 400:
console.error('Validation error:', result.details);
throw new Error('Invalid session data');
case 401:
console.error('Authentication failed');
throw new Error('Please check your API key');
case 429:
const retryAfter = response.headers.get('Retry-After');
console.log(`Rate limited. Retry after ${retryAfter}s`);
throw new Error('Too many requests');
default:
throw new Error(result.error || 'Unknown error');
}
}
return result.data;
} catch (error) {
console.error('Checkout session failed:', error.message);
throw error;
}
}Ainda com Problemas?
Se encontrar um erro não listado aqui, por favor contacte o suporte com:
- A resposta de erro completa
- Detalhes do pedido (endpoint, método, corpo)
- ID de Pagamento ou hash da transação (se aplicável)
- Timestamp de quando o erro ocorreu