FITALAPI

Errores

Cada código, su causa, su solución y si se reintenta.

Los errores de la API llegan con una sola forma, salvo las dos excepciones de abajo. Lee code para decidir, muestra message y guarda request_id.

Forma del error

{
  "error": {
    "code": "invalid_request",
    "message": "Petición inválida",
    "request_id": "0123456789abcdef0123456789abcdef",
    "details": { "fields": { "amount": "Monto decimal inválido" } },
    "retryable": false,
    "docs_url": "https://merchants.fital.xyz/docs/errores/#invalid_request"
  }
}

details.fields trae los errores por campo. retryable dice si repetir la misma petición más tarde puede servir, y es el dato de cada respuesta el que manda. Las tablas de abajo dan el valor habitual de cada código: un rechazo ya registrado siempre llega con false, se repite tal cual con esa clave y necesita una nueva. Ver Qué hacer con la clave tras un rechazo. Tu código debe tolerar códigos nuevos.

Excepciones

RespuestaFormaQué hacer
503 de GET /v1/health{"status": "down", "api_version": "v1"}, sin errorDecide por status. Es el único error de la API sin esta forma
404 del simulador público, cuando un escenario no aplica a la operaciónapplication/problem+jsonSólo ocurre ahí. Ver Ambientes

Un error fuera de la lista de arriba también puede ser de tu proxy o de tu red, no de FITAL: si no trae error.code, trátalo como un timeout.

Códigos

idempotency_key_invalid

HTTPretryable¿Reintentar?
400falseNo

Causa. La clave no mide entre 8 y 200 caracteres, o viene duplicada.

Solución. Envía una sola cabecera con una clave de largo válido.

idempotency_key_required

HTTPretryable¿Reintentar?
400falseNo

Causa. Falta Idempotency-Key en una operación que la exige.

Solución. Envía una clave derivada de tu identificador interno.

invalid_request

HTTPretryable¿Reintentar?
400falseNo

Causa. Algún campo no cumple el esquema, el cuerpo no es JSON válido o supera el tamaño máximo. El detalle por campo llega en details.fields.

Solución. Corrige los campos indicados antes de repetir. Un cuerpo demasiado grande llega con HTTP 413 y este mismo código: ver Límites.

invalid_api_key

HTTPretryable¿Reintentar?
401falseNo

Causa. Llave mal formada, vencida o revocada, o empresa suspendida.

Solución. Revisa la llave en tu gestor de secretos o crea otra en el panel.

invalid_signature

HTTPretryable¿Reintentar?
401falseNo, hasta corregir la firma

Causa. Falta la firma de la petición, es inválida o tiene más de 5 minutos.

Solución. Revisa la cadena firmada en Autenticación y el reloj de tu servidor.

wrong_environment

HTTPretryable¿Reintentar?
401falseNo

Causa. Llave de otro ambiente: sk_test_ en producción, o sk_live_ en un simulador.

Solución. Usa la base y la llave del mismo ambiente. Ver Ambientes.

account_not_active

HTTPretryable¿Reintentar?
403falseNo

Causa. La cuenta no está activa. No dice si un pago previo ocurrió.

Solución. Consulta el pay_ o escribe a soporte.

account_restricted

HTTPretryable¿Reintentar?
403falseNo

Causa. Tu cuenta tiene una restricción.

Solución. Contacta a tu ejecutivo FITAL. No reintentes en bucle.

forbidden_scope

HTTPretryable¿Reintentar?
403falseNo

Causa. La llave no tiene el scope de esta operación.

Solución. Crea en el panel una llave con el scope necesario.

ip_not_allowed

HTTPretryable¿Reintentar?
403falseNo, hasta registrar la IP

Causa. La IP de origen no está en la lista de esa llave.

Solución. Regístrala en el panel. Ver IP permitidas.

kyb_required

HTTPretryable¿Reintentar?
403falseNo

Causa. La empresa no tiene KYB aprobado o aún no está inscrita.

Solución. Completa el KYB en empresa.fital.xyz. Si ya está aprobado, pide la inscripción a FITAL.

live_not_enabled

HTTPretryable¿Reintentar?
403falseNo, hasta la inscripción

Causa. Tu empresa aún no está habilitada para producción: tiene KYB aprobado pero falta la inscripción de FITAL. Lo responde el panel al crear una llave sk_live_fital_…; la cuenta de prueba sigue disponible.

Solución. Completa la inscripción con FITAL. Ver Ambientes.

not_enabled

HTTPretryable¿Reintentar?
403falseNo

Causa. Función sin activar para tu empresa, como PIX sin activación vigente o un método de cobro.

Solución. Consulta con tu ejecutivo FITAL.

rail_not_enabled

HTTPretryable¿Reintentar?
403falseNo

Causa. El riel de pago no está habilitado para esta cuenta. En la cuenta de prueba, cualquier riel que no sea SPEI.

Solución. Pide a FITAL habilitarlo o usa otro riel. En la cuenta de prueba usa mxn_spei.

not_found

HTTPretryable¿Reintentar?
404falseNo

Causa. El recurso no existe o es de otra empresa. La respuesta es la misma en ambos casos.

Solución. Revisa el identificador y el ambiente.

beneficiary_ref_conflict

HTTPretryable¿Reintentar?
409falseNo

Causa. El identificador del alta choca con un beneficiario que ya existe.

Solución. Consulta GET /v1/beneficiaries antes de repetir.

beneficiary_state_conflict

HTTPretryable¿Reintentar?
409falseNo

Causa. El estado actual del beneficiario no permite esta operación.

Solución. Consulta su estado con GET /v1/beneficiaries/{id}.

collection_not_ready

HTTPretryable¿Reintentar?
409falseNo

Causa. El cobro aún no está listo para esta operación.

Solución. Consulta el cobro con GET /v1/collections/{id}.

idempotency_in_progress

HTTPretryable¿Reintentar?
409trueSí, misma clave

Causa. Una petición anterior con esa clave sigue en curso.

Solución. Repite con la misma clave tras Retry-After.

not_cancellable

HTTPretryable¿Reintentar?
409falseNo

Causa. El pago ya no se puede cancelar. Es la respuesta normal cuando ya avanzó.

Solución. Sigue el pago con GET /v1/payments/{id}.

payment_in_flight

HTTPretryable¿Reintentar?
409trueSí, misma clave, tras resolverse

Causa. Otra salida de dinero de tu empresa sigue en curso.

Solución. Repite con la misma clave cuando se resuelva.

quote_changed

HTTPretryable¿Reintentar?
409falseTras recotizar, con clave nueva

Causa. El débito superaría max_source_amount o lo cotizado. No se creó ningún pago. También aplica en la cuenta de prueba.

Solución. Pide otra cotización y usa una clave nueva.

quote_expired

HTTPretryable¿Reintentar?
409falseTras recotizar, con clave nueva

Causa. La cotización quote_id venció antes de crear el pago.

Solución. Pide otra cotización y usa una clave nueva.

receipt_not_available

HTTPretryable¿Reintentar?
409falseCuando el movimiento sea terminal

Causa. El movimiento aún no llega a un estado terminal, o no tiene recibo.

Solución. Consulta el movimiento y pide el recibo cuando sea terminal.

receiving_account_in_progress

HTTPretryable¿Reintentar?
409trueSí, con espera

Causa. Otra alta de esa moneda sigue en curso.

Solución. Espera unos segundos y reintenta con la misma clave.

sandbox_invalid_transition

HTTPretryable¿Reintentar?
409falseNo

Causa. Sólo cuenta de prueba: advance pidió un cambio que un pago real no puede hacer, como llevar a returned un pago que no está completed.

Solución. Consulta el estado del pago y pide una transición válida. Ver Avanzar un pago.

amount_below_minimum

HTTPretryable¿Reintentar?
422falseCon otro monto, con clave nueva

Causa. El monto está por debajo del mínimo aplicable.

Solución. Aumenta el monto y usa una clave nueva.

amount_out_of_range

HTTPretryable¿Reintentar?
422falseCon otro monto

Causa. El monto está fuera del rango del método.

Solución. Consulta min_amount y max_amount en GET /v1/collection-methods.

beneficiary_not_approved

HTTPretryable¿Reintentar?
422trueTras aprobar en el panel, misma clave

Causa. Beneficiario propio sin aprobar. Uno ajeno o inexistente da not_found.

Solución. Apruébalo en el panel y repite con la misma clave.

collection_rejected

HTTPretryable¿Reintentar?
422falseNo

Causa. El cobro fue rechazado.

Solución. Revisa los datos y conserva el request_id.

currency_not_supported

HTTPretryable¿Reintentar?
422falseNo

Causa. La moneda no aplica a este beneficiario o riel.

Solución. Revisa la moneda de la operación.

deposit_address_rejected

HTTPretryable¿Reintentar?
422falseNo

Causa. La dirección de depósito fue rechazada.

Solución. Revisa chain y currency.

idempotency_key_reused

HTTPretryable¿Reintentar?
422falseNo

Causa. La misma clave se usó con otro cuerpo, también si pasaron más de 7 días. Es un error de programación.

Solución. Corrige tu integración: una clave identifica una sola operación.

in_review

HTTPretryable¿Reintentar?
422trueSegún retryable: misma clave con true, clave nueva con false

Causa. Operación frenada por revisión. No confundir con el estado in_review de un pago que ya existe. Con retryable: true se frenó antes de ejecutar: no se creó nada y no hay pay_. Con retryable: false quedó registrada al ejecutar: el pago queda failed, con failure_code: in_review.

Solución. Espera la revisión. Con retryable: true, repite con la misma clave. Con retryable: false, esa clave repite el rechazo: usa una nueva.

insufficient_funds

HTTPretryable¿Reintentar?
422falseTras fondear, con clave nueva

Causa. Saldo insuficiente.

Solución. Fondea la cuenta y repite con una clave nueva: la misma clave repite este rechazo.

invalid_beneficiary

HTTPretryable¿Reintentar?
422falseNo

Causa. El destino es inválido. En un alta latam, los datos no cumplen lo que pide el país.

Solución. Revisa los datos de la cuenta destino. En latam, compáralos con GET /v1/latam/countries. Usa una clave nueva: la misma repite el rechazo.

limit_exceeded

HTTPretryable¿Reintentar?
422falseCon otro monto o más tarde, con clave nueva

Causa. Se rebasó el tope acumulado de la empresa o un límite del riel: ver Límites. En la cuenta de prueba, un tope del ambiente: ver Cuenta de prueba.

Solución. Ajusta el monto o el momento. Usa una clave nueva: la misma repite este rechazo.

method_unavailable

HTTPretryable¿Reintentar?
422falseNo

Causa. El método de cobro no está disponible.

Solución. Consulta GET /v1/collection-methods.

pair_not_supported

HTTPretryable¿Reintentar?
422falseNo

Causa. El par de monedas no está disponible.

Solución. Elige otro par de monedas.

payment_rejected

HTTPretryable¿Reintentar?
422falseNo con la misma clave

Causa. El pago fue rechazado sin un motivo más específico.

Solución. Conserva el request_id y escribe a soporte si persiste. La misma clave repite este rechazo.

rail_unavailable

HTTPretryable¿Reintentar?
422trueSí, misma clave, más tarde

Causa. El riel no está disponible por ahora.

Solución. Repite más tarde con la misma clave.

receiving_account_rejected

HTTPretryable¿Reintentar?
422falseNo

Causa. La cuenta para recibir no se pudo abrir.

Solución. Contacta a tu ejecutivo FITAL y conserva el request_id.

sandbox_real_account_rejected

HTTPretryable¿Reintentar?
422falseCon datos ficticios

Causa. Sólo cuenta de prueba: la CLABE no empieza con 999 o el titular no incluye la palabra FICTICIO.

Solución. Usa una CLABE 999 y un titular con FICTICIO. Ningún dato real entra a este ambiente.

rate_limited

HTTPretryable¿Reintentar?
429trueSí, tras Retry-After

Causa. Superaste un límite de peticiones.

Solución. Espera lo que indique Retry-After.

sandbox_limit

HTTPretryable¿Reintentar?
429falseAl día siguiente

Causa. Sólo cuenta de prueba: alcanzaste el tope diario de pagos y cobros, o de reinicios de datos.

Solución. Repite al día siguiente. El tope de pagos y cobros se puede liberar reiniciando los datos desde el panel.

internal_error

HTTPretryable¿Reintentar?
500trueSí, misma clave

Causa. Fallo nuestro.

Solución. Repite con la misma clave. Si persiste, escribe a soporte con el request_id.

service_unavailable

HTTPretryable¿Reintentar?
503trueSí, misma clave

Causa. El servicio no está disponible por ahora.

Solución. Repite con la misma clave y espera exponencial.

Errores comunes

  • Decidir por el texto de message. Puede cambiar; code no.
  • Reintentar un error con retryable: false sin corregir la causa.

Qué sigue

Reintentos.

Ver esta página en Markdown

En esta página