Ir al contenido

API

En esta página

Códigos de error

Gestiona los fallos de la Merchant API con códigos estables legibles por máquina, detalle de validación por campo y vías de recuperación documentadas.

Catálogo de códigos

Identificadores estables y legibles por máquina que se devuelven en code (y por campo en errors[].code). Esta es la lista real: cada código lo emite al menos un handler, un validador o un middleware de la API en funcionamiento, no es un superconjunto teórico. Los códigos existentes nunca cambian de significado y se añaden códigos nuevos cuando aparecen escenarios nuevos. Un código se renombra solo en casos raros, y cada cambio de nombre se anuncia en el changelog.

Usa code para la lógica programática. detail llega únicamente en inglés y está pensado para los registros o para una interfaz de reserva; localiza en el cliente a partir de code.

Códigos por campo

Los emite la validación de la petición. Cada código de abajo pone en field el nombre del campo problemático en snake_case. Cuando fallan varios campos a la vez, el code de nivel superior es validation_failed y cada fallo por campo aparece en errors[].

Code Cuándo Qué hacer
validation_failed El code de nivel superior cuando fallan varios campos a la vez. Cada fallo por campo lleva su propio code y field dentro de errors[]. Revisa errors[] y corrige cada field de la lista.
field_required Un campo obligatorio está vacío, es null o solo contiene espacios. Envía un valor para ese field.
field_too_long El campo supera la longitud máxima permitida. Recórtalo al límite documentado para ese endpoint.
field_out_of_range Valor numérico fuera del rango permitido. Ajusta el valor al rango documentado.
field_invalid_enum El valor no es uno de los admitidos por la enumeración (por ejemplo, currency o network desconocidos, o un token que el proyecto no tiene activado). Consulta la referencia de valores admitidos; con los tokens, comprueba que el proyecto tenga activada la pareja token + red.
field_invalid_format El valor no tiene la forma que espera el campo: un ID que no se puede interpretar (por ejemplo, invoice_id sin el prefijo inv_…) o un amount que no es una cadena decimal simple como "10.00". Envía el campo en el formato documentado y usa tal cual los IDs que devuelve la API.
entity_id_empty Un ID enviado es un GUID vacío o todo a ceros (00000000-0000-…). field indica cuál es — por ejemplo, invoice_id o withdrawal_id. Envía tal cual el ID que devuelve la API; nunca un ID vacío o a ceros.
field_must_be_positive El decimal o entero debe ser mayor que 0. Envía un valor positivo.
field_percentage_out_of_range El porcentaje debe estar entre 0 y 100, ambos incluidos. Ajusta el valor a [0, 100].
query_parameter_unknown Una petición de listado incluye un parámetro de consulta que el endpoint no admite. Quita el parámetro o usa su nombre documentado en snake_case.
pagination_cursor_invalid El cursor está mal formado, ha vencido, ha sido manipulado, pertenece a otro recurso o se combina con filtros distintos. Reinicia la paginación sin cursor y luego mantén los mismos filtros mientras sigues next_cursor.
amount_too_many_decimals En facturas con flujo fiat, amount tiene más decimales que la unidad mínima de la moneda (por ejemplo, 23.345 en USD o 23.01 en JPY). Redondea a la unidad mínima de la moneda.
amount_too_large El amount al crear una factura o un retiro queda fuera del rango admitido: por encima del tope de 20 dígitos enteros que guarda la API. Envía un importe dentro del rango admitido.

Alternativas genéricas por estado HTTP

Se devuelven cuando el fallo no lleva asociado un código de negocio concreto. Cada uno es la alternativa de un estado HTTP: la petición falló, pero ningún código más específico describía la causa.

Code HTTP Cuándo Qué hacer
forbidden 403 La petición está autenticada, pero esta credencial no puede realizar la operación: su alcance (capacidad) o su entorno no lo permiten; por ejemplo, una clave de Sandbox llamando a un endpoint que solo existe en producción. Llama con una credencial cuya capacidad y entorno encajen con la operación. La pertenencia nunca da un 403: un recurso de otro comercio devuelve not_found (404), no forbidden.
payment_key_required 403 El endpoint necesita una clave Payment (pk_), pero la petición usó una Payout (rk_) — por ejemplo, al listar facturas. Llámalo con una clave Payment.
payout_key_required 403 El endpoint necesita una clave Payout (rk_), pero la petición usó una Payment (pk_) — por ejemplo, al leer saldos. Llámalo con una clave Payout. Ten en cuenta que la clave Payout además necesita una lista blanca de IP para funcionar.
internal_error 500 Un error inesperado o un fallo de nuestro lado. Reinténtalo una vez. Si sigue fallando, escribe al soporte e indica la hora de la respuesta.
validation_failed 400 La petición no pasó la validación, pero no aplicaba ningún código a nivel de campo. Lee el campo detail: dice qué se rechazó.

Autenticación

Se devuelven solo en respuestas 401 Unauthorized del handler de autenticación HMAC. Cada código identifica un punto de fallo concreto para que el cliente muestre un mensaje accionable en lugar de un genérico «auth failed».

Code HTTP Cuándo Qué hacer
unauthorized 401 Código de reserva cuando no se aplicó ninguno de los códigos siguientes: normalmente, una petición a un endpoint con autenticación obligatoria sin cabecera Authorization (o con un esquema de autenticación desconocido). Envía una cabecera Authorization HMAC válida y revisa todo el flujo de firma de principio a fin.
authorization_missing 401 El valor de la cabecera Authorization está vacío (se envía, pero en blanco). Envía la cabecera completa Authorization: HMAC-SHA256 {apiKeyId}:{base64signature}.
authorization_malformed 401 La cabecera está presente pero mal formada: el esquema se interpreta bien, pero a la parte de credenciales le faltan los dos puntos, el ID de la clave de API no se puede interpretar o la firma está vacía. Vuelve a construir la cabecera según Autenticación; la causa más habitual es una errata en el ID de la clave de API.
timestamp_missing 401 Falta la cabecera X-Request-Timestamp o no se interpreta como un entero positivo. Ponla con la marca de tiempo Unix actual en segundos.
timestamp_expired 401 La marca de tiempo queda fuera de la ventana permitida de desfase de reloj (5 minutos por defecto). Sincroniza tu reloj por NTP y vuelve a firmar con una marca nueva.
invalid_credentials 401 La credencial no se puede usar: ID de clave desconocido, clave revocada, un prefijo de entorno o de tipo que no coincide con la clave guardada, o una firma que no verifica. Es un solo código para los cuatro casos a propósito: una respuesta distinguible confirmaría qué IDs de clave existen a quien no tiene el secreto. Comprueba que el ID de la clave de API es correcto y está activo, y que la firma se calcula con el secreto que le corresponde. La causa más habitual está en la firma: revisa cómo montas el string-to-sign ({ts}\n{METHOD}\n{path}\n{query}\n{bodyHash}) y que bodyHash esté vacío cuando no hay cuerpo (no calcules el hash de una cadena vacía).
ip_not_allowed 401 La clave Payout tiene configurada una lista blanca de IP y la IP que llama no está en ella. Solo las claves Payout llevan comprobación de IP; las claves Payment se pueden llamar desde cualquier IP. Se verifica después de validar la firma, así que una firma correcta desde la red equivocada también falla. Añade la IP que llama (o su bloque CIDR) a la lista blanca de la clave Payout en el panel.
payout_whitelist_required 401 Una clave Payout recién generada aún no tiene lista blanca de IP. Las claves Payout siguen inactivas hasta que el comercio añade al menos una IP autorizada; es un código distinto de ip_not_allowed para que el cliente pueda separar «falta configurarlo en el panel» de «la IP de origen no es la correcta». Abre el panel, ve a la página de claves de API y configura al menos una IP o un CIDR en la lista blanca de la clave Payout.

Límite de peticiones

Se devuelven en 429 Too Many Requests cuando una petición supera el límite por comercio. El recuento va por ventana de un segundo y suma todas tus claves de API: ninguna tiene cupo propio. Delante de la API actúa otro límite, por dirección IP; el que se describe aquí es el del comercio.

Code HTTP Cuándo Qué hacer
rate_limited 429 Se superó el límite por comercio. Se aplican dos: un tope global en todos los endpoints (30 peticiones/segundo por defecto) y otro más estricto en la creación de facturas, POST /v1/invoices (5 peticiones/segundo por defecto). La respuesta indica cuál saltó y con qué límite. Lee la cabecera Retry-After (la espera en segundos) y reinténtalo cuando pase; la mayoría de clientes HTTP con middleware de reintentos la respetan solos.

Transporte y framework

Los devuelve el gestor de errores del framework cuando la petición nunca llegó a un handler normal.

Code HTTP Cuándo Qué hacer
malformed_request 400 El cuerpo de la petición no se pudo interpretar: JSON mal formado. Comprueba que el cuerpo sea JSON válido.
payload_too_large 413 El cuerpo de la petición supera el límite de 1 MiB. Envía un cuerpo más pequeño; reparte las cargas grandes en varias peticiones.
unsupported_media_type 415 El Content-Type no es application/json. Pon Content-Type: application/json.
method_not_allowed 405 La ruta existe, pero no para este método HTTP. Usa el método documentado para ese endpoint (por ejemplo, POST para crear).
route_not_found 404 Ningún endpoint coincide con la ruta de la petición. Revisa la URL contra la referencia de la API.

Facturas

Code HTTP Cuándo Qué hacer
invoice_not_found 404 El ID de factura no resuelve a nada, o apunta a una factura de otro comercio. Usa tal cual el ID que devuelve POST /v1/invoices.
project_not_found 404 El project_id de una petición de creación de factura no resuelve a nada visible para quien llama. Usa un ID de proyecto del panel (debe estar activo y pertenecer al mismo comercio que la clave de API).
invoice_terminal 410 Se llamó a confirm-payment sobre una factura expired o cancelled. (Una factura paid devuelve invoice_not_awaiting_client, 409, no este código.) Actualiza el estado de la factura; no hay nada más que hacer.
invoice_deadline_passed 410 Se llamó a confirm-payment después del plazo límite de la factura. Crea una factura nueva.
requested_amount_invalid 400 El amount de la factura falta, está mal formado, queda fuera del rango decimal admitido o no es positivo. Envía amount como cadena decimal positiva, junto con la currency elegida y la network opcional.
invoice_amount_below_minimum 400 El valor en USD calculado de la factura está por debajo del mínimo por token o por red del catálogo. Sube el importe por encima del mínimo que se indica para el token elegido.
deposit_amount_exceeds_limit 400 El valor en USD calculado del pago esperado supera el tope MaxDepositAmount por depósito de la política del comercio. Limita el importe cotizado en la confirmación, no lo que se recibe realmente on-chain. Baja el importe de la factura o escribe al soporte para subir el límite.
currency_not_enabled_for_project 400 La criptomoneda solicitada no está en la lista de tokens activados del proyecto (en ninguna red). Activa la moneda en el proyecto o elige una de las enabled_tokens del proyecto.
tokens_required 409 Creación de factura o confirmación de pago en un proyecto que no tiene ningún token activado. Activa al menos un token en el proyecto desde el panel.
acceptance_disabled 503 El token solicitado no se está aceptando ahora mismo. Usa otro token o vuelve a intentarlo más tarde.
exchange_rate_unavailable 503 El proveedor de tipos de cambio no tiene una cotización fresca para la pareja token / fiat. Reinténtalo; los tipos se refrescan en intervalos cortos.
network_unavailable 503 La confirmación automática no pudo usar la red elegida. Quita la confirmación automática y deja que el cliente elija el token en la página de pago.
payment_method_unavailable 503 El token o la red elegidos no pueden aceptar un pago en este momento. Sustituye a no_available_address, address_lease_failed y bridge_unavailable desde el 23-08-2026. Reinténtalo, o deja que el cliente elija otro token u otra red.
client_confirmation_failed 409 Se rechazó la confirmación del lado del cliente (elección de token, confirmación automática). El campo detail trae el motivo concreto. Mira detail; los casos habituales son que la factura ya pasó de awaiting_client o que el token no está permitido.
invoice_not_awaiting_client 409 Se llamó a confirm-payment sobre una factura que ya no está en awaiting_client. Actualiza el estado de la factura; el cliente ya pasó de la selección.
invoice_cannot_be_cancelled 409 La factura ya no está en awaiting_client: el cliente ya eligió token, o la factura está pagada o vencida. Cancelar de nuevo una factura ya cancelada devuelve 200, no este error. Mira el estado actual; la cancelación solo funciona en awaiting_client.
simulate_payment_failed 409 Se rechazó simulate_payment, disponible solo en sandbox. Mira detail; suele ser un estado incorrecto o un importe que no cuadra.
not_sandbox 403 Se llamó a simulate-payment (el simulador de sandbox) sobre una factura de producción. Solo se pueden simular facturas de sandbox: usa una factura de sandbox o mueve una factura real con un pago on-chain de verdad.

Facturas del widget

Los devuelve POST /public/v1/sdk (creación de facturas con el Low-Code SDK).

Code HTTP Cuándo Qué hacer
widget_key_missing 401 La cabecera X-Sdk-Key falta o está vacía en un endpoint que exige autenticación de widget. Envía la clave pública del SDK en X-Sdk-Key.
widget_key_invalid 401 X-Sdk-Key está presente, pero no se interpreta como un ID de clave de API de Paymos. Copia la clave desde el panel; revisa espacios sobrantes, un prefijo equivocado o una codificación de URL accidental.
widget_key_not_found 401 La clave se interpreta, pero no corresponde a ninguna credencial activa: revocada, eliminada o de un tipo distinto de Payment (las claves Payout no pueden mover el widget). Usa una clave Payment en estado Active desde el panel.
widget_inactive 403 El widget del proyecto de destino está apagado, o nunca se inicializó. Activa el widget en los ajustes del proyecto.
terminal_not_enabled 403 La solicitud llegó con source=terminal, pero el método de integración del proyecto no es Terminal. Cree un proyecto de tipo Terminal o envíe source=embed desde un proyecto Low-Code.
embed_not_enabled 403 La solicitud llegó con source=embed, pero el método de integración del proyecto no es Low-Code. Use el método de integración del propio proyecto o cree un proyecto Low-Code.
origin_not_allowed 401 El Origin del navegador no coincide con ninguna política de orígenes permitidos. La comprobación ocurre dos veces —la capa de autenticación contrasta el origen con la unión de todos los proyectos de la clave que tienen widget activo, y después el handler lo contrasta con el proyecto de destino exacto—, y las dos responden el mismo 401, el mismo código y el mismo detalle. Es deliberado: un estado distinto en la segunda comprobación le diría a quien tiene la clave pk_ (pública y raspable) que el origen está registrado en otro proyecto del mismo comercio, y así se podrían enumerar hosts de staging y marcas sin lanzar, sonda a sonda. Añade el dominio a los orígenes permitidos del widget. Las peticiones del mismo origen —por ejemplo, un terminal POS servido desde el mismo host— se saltan la comprobación.

Canales de pago

Code HTTP Cuándo Qué hacer
payment_channels_disabled 503 Los canales de pago no están activados para tu cuenta en este entorno. Responden así todos los endpoints de canales y de depósitos, incluido el simulador de Sandbox. Escribe al soporte para que te lo activen. Reintentar no cambia la respuesta.
payment_channel_not_found 404 El id pc_ no resuelve a nada que esta credencial pueda ver: no existe, es de otro comercio, vive en el otro entorno o está en un proyecto fuera del alcance de la clave. Los cuatro casos son indistinguibles a propósito. Usa tal cual el id que devuelve POST /v1/payment-channels, firmando con una clave del mismo entorno y del mismo proyecto.
payment_channel_deposit_not_found 404 El id pcd_ no resuelve a nada que esta credencial pueda ver. Las mismas cuatro causas de arriba. Usa tal cual el id del contenido del webhook o del flujo de sondeo.
payment_channel_external_id_invalid 400 external_id está vacío, en blanco o supera los 128 caracteres, ya sea al crear o como filtro de la lista. Envía un identificador no vacío de 128 caracteres como mucho.
payment_channel_project_has_no_supported_tokens 409 El proyecto no activa ningún token que un canal de pago pueda cobrar, así que el canal se quedaría sin ninguna vía. Activa al menos un token admitido en el proyecto y crea el canal después.
payment_channel_simulation_sandbox_only 403 Se llamó a simulate-deposit sobre un canal de producción. La simulación existe solo para canales de Sandbox. Mueve un canal de producción con una transferencia de verdad.
payment_key_required 403 La petición se firmó con una clave Payout (rk_). El acceso a los canales va con la clave Payment, igual que los retiros van con la clave Payout. Firma con una clave pk_ del mismo entorno.
pagination_cursor_invalid 400 El cursor de una lista o de un flujo está mal formado, tiene más de 24 horas o está ligado a otros filtros; en el flujo, también a otro comercio, otro entorno u otro alcance de proyectos. Vuelve a empezar por la primera página. Descartar duplicados por pcd_ deja una resincronización completa en algo inofensivo.
currency_not_enabled_for_project 400 El token que se pasó a simulate-deposit no está en la lista de tokens activados del proyecto. Actívalo en el proyecto, o elige uno de los que el canal ya devuelve en sus networks[].tokens.
acceptance_disabled 503 El cobro del token solicitado está desactivado ahora mismo en toda la plataforma. Usa otro token o espera a que se vuelva a activar la aceptación.
amount_too_many_decimals 400 El importe simulado tiene más decimales de los que admite el token. El dinero de un comercio nunca se redondea en silencio hasta otro número. Redondea el importe a la precisión del token antes de enviarlo.

Retiros

Code HTTP Cuándo Qué hacer
withdrawal_not_found 404 El ID de retiro no resuelve a nada, o apunta a un retiro de otro comercio. Usa tal cual el ID que devuelve POST /v1/withdrawals.
insufficient_balance 409 El saldo disponible del comercio está por debajo de amount + fee. Ingresa más fondos o reduce el importe del retiro.
whitelist_required 403 La dirección de destino no está en la lista blanca de la red elegida. (La red admite listas blancas; esta dirección concreta aún no se ha añadido.) Añade la dirección a tu lista blanca y vuelve a intentarlo.
destination_address_invalid 400 La dirección no pasa la validación de formato o de suma de control de la red. Vuelve a comprobar la dirección contra la especificación de la red.
withdrawal_amount_below_minimum 400 El importe está por debajo del mínimo de la política para el token elegido. Sube el importe por encima del mínimo (viene en detail).
withdrawal_quota_exceeded 409 El número de retiros activos alcanzó el límite de la política del comercio. Espera a que se liquiden los retiros en curso o escribe al soporte para subir el límite.
withdrawal_amount_exceeds_limit 400 El equivalente en USD del principal del retiro supera el tope MaxWithdrawalAmount por transacción de la política del comercio. Reduce el importe o escribe al soporte para subir el límite.
exchange_rate_unavailable 503 El comercio tiene un tope MaxWithdrawalAmount configurado, pero no había una cotización token/USD fresca para contrastar el principal: el límite no se puede verificar, así que la petición se rechaza por seguridad. Reinténtalo; los tipos se refrescan en intervalos cortos.
withdrawal_not_enabled 400 Paymos no paga la pareja token/red que has pedido. detail nombra la pareja — por ejemplo, Withdrawals are not available for USDT on TRC20. Qué parejas se pueden pagar depende de nuestra configuración, no de la tuya. Retira el token en una red por la que Paymos sí paga, o pregunta al soporte por la pareja que necesitas.
withdrawal_cannot_be_cancelled 409 El retiro ya pasó del estado en el que se puede cancelar. Mira el estado actual. La ventana se cierra cuando arranca la ejecución, todavía dentro de created y antes de firmar nada.
withdrawal_simulation_failed 409 Se rechazó simulate_completion, disponible solo en sandbox. Mira detail.
merchant_suspended 403 La cuenta del comercio está suspendida para operaciones salientes, así que no se puede crear ningún retiro. Escribe al soporte para levantar la suspensión.
outbound_frozen 503 Las transferencias salientes están congeladas, ya sea en toda la plataforma o para la red y el token con los que retiras. Espera a que se levante la congelación, prueba con otra red o token, o escribe al soporte.
withdrawal_network_unavailable 503 Los retiros de este token en esta red no se pueden liquidar ahora mismo. Prueba con otra red de destino o vuelve a intentarlo más tarde.

Estado del proyecto

Se devuelven al crear una factura o confirmar un pago cuando el estado actual del proyecto no permite emitir facturas.

Code HTTP Cuándo Qué hacer
project_state_invalid 409 El proyecto no está Active: está Suspended o Archived. La respuesta no dice cuál de los dos. Mira el estado del proyecto en el panel: si está archivado, restáuralo; si está suspendido, actívalo. O envía la petición a un proyecto que ya esté activo.