Fiatside

Developers

Catálogo de errores

Cada error lleva un código estable y legible por máquina y un estado HTTP coherente. El código es en lo que su integración debe basarse: el texto puede evolucionar, el código no.

01

Forma de un error

La forma actual es deliberadamente mínima. Es estable, y eso es lo que importa: un código, y nada que filtre un detalle interno.

Forma actual — respuesta realjson
{ "error": "rate_stale" }
Con un motivo legible por humanos — respuesta realjson
{
  "error": "rail_not_open",
  "reason": {
    "fr": "La retenue TDS de 1 % et l’enregistrement FIU-IND exigent une entite locale…",
    "en": "The 1% TDS withholding and FIU-IND registration require a local entity…"
  }
}

Algunos errores llevan un objeto de motivo bilingüe, destinado a mostrarse tal cual al usuario. Un canal cerrado es uno de ellos: el motivo explica una restricción regulatoria con nombre, no una interrupción, y mostrarlo ahorra una solicitud de soporte. La API versionada añadirá un id de solicitud a este sobre, para que pueda señalarnos una línea precisa en nuestros registros.

02

Códigos en vigor

Estos códigos se devuelven hoy por el endpoint de cotización.

Códigos en vigor
codeHTTPQué significaQué hacer
invalid_request400El cuerpo de la solicitud no supera la validación del esquema: campo faltante, tipo incorrecto, valor fuera de los límites permitidos.Compruebe que el importe es una cadena y no un número, y que la dirección es exactamente «sell» o «receive».
invalid_amount400El importe no se puede analizar o lleva más decimales de los que acepta el activo o la moneda.Trunque a la precisión de la unidad: 6 decimales para USDT, 8 para BTC, 2 para el euro, 0 para el franco CFA.
unknown_asset_or_rail404El identificador de activo o de vía no existe en el catálogo.Los identificadores son estables y nunca se reasignan. Recargue el catálogo en lugar de adivinarlos.
rail_not_open409La vía existe pero no está abierta. La respuesta lleva el motivo exacto, en ambos idiomas.Muestre el motivo tal cual: explica una restricción normativa, no una interrupción. Ofrezca una vía abierta en el mismo país.
asset_not_offered409El activo está en el catálogo pero no se ofrece: el caso de los activos de anonimato mejorado.No lo ofrezca en su selector. El catálogo lo devuelve con su motivo para que pueda explicarlo.
rate_stale503El último precio conocido supera la antigüedad máxima tolerada. El motor se niega a cotizar en lugar de servir un precio obsoleto como firme.Reintente después de unos segundos. No almacene en caché la última cotización correcta para cubrir el hueco: eso sería exactamente el error que este código previene.
rate_unavailable503No hay precio disponible para este par de activo / moneda.Desactive el par en su interfaz en lugar de mostrar una estimación. Una estimación mostrada se convierte en una expectativa.
quote_failed500Error inesperado durante el cálculo. No se devuelve ninguna cotización.Reintente una vez; si el error persiste, escríbanos con la marca de tiempo exacta de la llamada.
03

Códigos del contrato publicado

Estos códigos acompañan a endpoints que aún no están abiertos. Se publican para que su manejo de errores se escriba una sola vez.

Códigos en vigor
codeHTTPQué significaQué hacer
unauthorized401Clave faltante, revocada o utilizada en el entorno equivocado.Una clave sk_test_ no funciona en producción, y tampoco lo contrario: eso es deliberado.
idempotency_conflict409La misma clave de idempotencia ya se ha utilizado con un cuerpo de solicitud diferente.Una clave pertenece a una intención. Si el contenido cambia, la clave cambia; de lo contrario, no hay forma de saber cuál de las dos órdenes reproducir.
quote_expired409La cotización ha superado su ventana de bloqueo.Vuelva a cotizar y haga que se acepte el nuevo importe. Nunca recalculamos el precio en silencio contra el cliente.
beneficiary_rejected422Los datos del beneficiario no superan la validación del canal: suma de verificación no válida, formato no conforme o un nombre que no coincide con la identidad verificada.La respuesta indica el campo infractor. El nombre del beneficiario debe ser la identidad verificada: no es posible ningún pago a terceros.
country_not_served451El país de destino no está disponible: sanciones, medidas restrictivas o ausencia de un marco local.El código 451 se elige deliberadamente en lugar de un 404: cuando rechazamos, decimos que es un rechazo y por qué.
rate_limited429Demasiadas llamadas dentro de la ventana deslizante.Respete el encabezado Retry-After. Las cotizaciones son baratas de poner en cola, caras de golpear.
not_found404El recurso no existe o no pertenece a su clave.Ambos casos devuelven el mismo código: una respuesta que los distinguiera permitiría a cualquiera enumerar las referencias de otros.
04

Qué no es un error

Un importe fuera de los límites del canal devuelve una cotización válida, con un objeto limitError. No es un fallo: es información que su interfaz debe mostrar.

Extracto de la respuestajson
"limitError": { "code": "below_min", "limit": "20.00" }

Tratar este caso como un error HTTP le privaría del importe calculado y, por tanto, de la capacidad de decir al usuario «le faltan 16,53 EUR para el mínimo de este método de pago». El límite se aplica al importe neto, el que recibe el beneficiario.

05

Reintentar, o no

Tres familias, tres comportamientos. Reintentar un error de validación en un bucle solo llena sus registros.

No reintentar nunca

invalid_request, invalid_amount, unknown_asset_or_rail, asset_not_offered, unauthorized. La solicitud es la culpable: reintentarla sin cambios da el mismo resultado. Corríjala o muestre el motivo.

Reintentar con retroceso

rate_stale, rate_unavailable, quote_failed, y cualquier limitación de velocidad. Espere unos segundos, con un intervalo creciente entre intentos. No llene el intervalo con una cotización en caché.

Pedir una decisión

rail_not_open, quote_expired, beneficiary_rejected, country_not_served. La situación requiere una elección humana: ofrezca otro canal, una cotización nueva, datos corregidos.