La External API de Avirato Payments permite a integradores externos (ERPs, plataformas de e-commerce, sistemas de gestion, etc.) procesar pagos online y pagos POS de forma segura, sin necesidad de conocer la infraestructura interna del sistema.
Con una sola integracion puedes:
Crear sesiones de pago online y redirigir al cliente a una pagina de pago segura
Procesar pagos POS enviando un cobro directamente a un terminal fisico
Modificar pagos: reembolsos totales y parciales, capturas de preautorizacion, cancelaciones y extensiones de preautorizacion
Consultar pagos: obtener detalles de una sesion, listar sesiones con filtros y paginacion, listar modificaciones
Pagos recurrentes: cobrar periodicamente con la tarjeta guardada del cliente y gestionar su ciclo de vida (pausar, reactivar, cambiar tarjeta, cancelar)
Entornos: Live y Test
La External API ofrece dos entornos completamente independientes:
Live
Test
Proposito
Procesar pagos reales
Integrar y probar sin dinero real
URL base
https://aviratopayments.com/external/v1/
https://aviratopayments.com/external/v1/test/
API keys
Keys de entorno Live
Keys de entorno Test
Pagos online
Procesador real
Simulacion con tarjetas ficticias
Pagos POS
Terminal fisico real
Simulacion inmediata (magic amounts)
Pagos recurrentes
Cobros reales en su fecha
Cobros simulados (en su fecha o con simuladores)
Webhooks
Enviados por el procesador real
Generados automaticamente por el backend
Dinero real
Si
No
Recomendacion: Integra primero en el entorno Test para verificar que tu sistema funciona correctamente. Una vez validado, cambia a Live simplemente usando tu API key de produccion y eliminando /test/ de las URLs.
Todos los endpoints de esta documentacion muestran la URL completa del entorno Live. Para usar el entorno Test, inserta /test/ despues de /v1/. Por ejemplo:
Live: POST https://aviratopayments.com/external/v1/payment/session
Test: POST https://aviratopayments.com/external/v1/test/payment/session
Autenticacion rapida
Todas las peticiones requieren una API key en la cabecera X-API-KEY:
bash
X-API-KEY: tu_api_key_aqui
Las API keys se gestionan desde el dashboard de Avirato Payments (seccion Integraciones > Configuracion > API keys). Cada key esta vinculada a un webcode (identificador de negocio) y un entorno (Live o Test).
Ademas, todas las peticiones POST aceptan opcionalmente la cabecera Idempotency-Key para evitar operaciones duplicadas. Recomendamos usarla siempre en produccion. Reutilizar la misma clave con un body distinto u otro endpoint devuelve 409 Conflict (ver Autenticacion y Manejo de errores).
Las modificaciones (refund, capture, cancel, extend) son asincronas. La API acepta la peticion inmediatamente (HTTP 202) pero la operacion se procesa en background. El estado inicial es pending (refunds) o received (capture, cancel, extend) y evoluciona a success o failed conforme el procesador confirma.
Los pagos POS son sincronos: la peticion espera a que el terminal responda.
En entorno Test: Las modificaciones se resuelven de forma casi inmediata (el backend simula la respuesta del procesador). Recibiras el webhook de confirmacion en segundos.
Flujo tipico de integracion
1. Pago online
2. Pago POS
3. Pago recurrente
Nota: Estos flujos funcionan de forma identica en el entorno Test, sustituyendo /external/v1/ por /external/v1/test/. La unica diferencia es que en Test el pago online se completa con tarjetas ficticias y el pago POS se simula con magic amounts (sin terminal real).
Diferencias clave entre Test y Live
Aspecto
Live
Test
Pago online
El cliente paga con tarjeta real en el formulario de pago
El cliente usa tarjetas ficticias en formulario simulado
Pago POS
El terminal fisico procesa el cobro
El resultado se simula inmediatamente segun el importe
Pago recurrente
Primer pago en pagina segura real y cobros periodicos reales
Pagina simulada (el titular decide el resultado) y simuladores de renovacion y fin. No aparece en el panel
Webhooks
Enviados por el procesador real cuando confirma la operacion
Generados automaticamente por el backend al completar la simulacion
Modificaciones
Procesadas por el procesador real (puede tardar segundos/minutos)
La External API dispone de dos entornos independientes: Live y Test. Cada entorno tiene sus propias API keys, su propio client secret y sus propios datos (completamente aislados entre si).
Live
Test
Proposito
Pagos reales en produccion
Desarrollo e integracion sin dinero real
Rutas
/external/v1/...
/external/v1/test/...
API key
Key de entorno Live
Key de entorno Test
Client Secret
Secret del entorno Live
Secret del entorno Test
Datos
Datos de produccion
Datos aislados de test
API keys de Live
Las API keys de Live procesan pagos reales contra el procesador. Solo usa keys de Live cuando tu integracion este completamente validada.
API keys de Test
Las API keys de Test permiten probar toda la integracion sin mover dinero real. Los pagos se simulan, los webhooks se generan automaticamente, y los datos se almacenan de forma completamente aislada.
Flujo de integracion recomendado: Empieza siempre con una API key de Test. Desarrolla y valida toda tu integracion. Cuando todo funcione correctamente, crea una API key de Live y cambia las URLs (anade o quita /test/).
Restriccion por IP
Las API keys pueden tener restricciones de IP configuradas desde el dashboard. Si tu IP no esta en la lista permitida, recibiras un error 403 Forbidden.
Recomendacion: Configura restricciones de IP en produccion para mayor seguridad. En el entorno Test, puedes dejar las IPs sin restriccion para facilitar el desarrollo.
Restriccion por webcode
Cada API key esta vinculada a un webcode especifico (identificador de tu negocio en Avirato Payments). Solo puedes operar con el webcode asociado a tu key.
El campo webcode es obligatorio en todas las peticiones y debe coincidir con el webcode de tu API key. En POST/PATCH va en el body; en GET, como parametro de query (?webcode=SHOP01).
En pagos recurrentes solo ves y modificas los de tu webcode y del mismo entorno de la key. Uno de otro webcode o del otro entorno responde 404, como si no existiera.
Scopes
Las API keys tienen un scope que determina a que endpoints pueden acceder:
Entorno
Scope
Rutas accesibles
Live
external_api_live
/external/v1/...
Test
external_api_test
/external/v1/test/...
Una key de Live no puede acceder a rutas de Test, y viceversa.
Idempotencia
Los endpoints de escritura (crear sesion, modificaciones, pago POS y todos los POST/PATCH de pagos recurrentes) soportan la cabecera Idempotency-Key. Si envias la misma Idempotency-Key con los mismos parametros:
La primera peticion se procesa normalmente
Las siguientes peticiones con la misma key devuelven la misma respuesta sin ejecutar la operacion de nuevo
La idempotencia funciona de forma identica en ambos entornos (Live y Test). Los registros de idempotencia de cada entorno estan aislados entre si.
Conflictos de idempotencia (409)
Si reutilizas una Idempotency-Key de forma incorrecta, la API responde con 409 Conflict para evitar comportamientos inconsistentes:
Caso
Mensaje (literal)
Misma Idempotency-Key con body distinto en el mismo endpoint
Idempotency key reused with a different request body.
Misma Idempotency-Key en otro endpoint
Idempotency key already used for a different endpoint.
Recomendacion: usa Idempotency-Key siempre en produccion para evitar cobros duplicados, pero asocia una clave unica por intento logico (por ejemplo, derivada del orderId + retry). Si necesitas modificar el body, usa una clave nueva.
bash
# Primera llamada: crea el pago
curl -X POST .../payment/session \
-H "Idempotency-Key: order-12345-payment" \
-d '{ "webcode": "SHOP01", "amount": { "value": 10000, "currency": "EUR" }, ... }'
# Segunda llamada con la misma key y mismo body: devuelve la misma respuesta sin crear otro pago
curl -X POST .../payment/session \
-H "Idempotency-Key: order-12345-payment" \
-d '{ "webcode": "SHOP01", "amount": { "value": 10000, "currency": "EUR" }, ... }'
# Tercera llamada con la misma key pero distinto body: 409 Conflict
curl -X POST .../payment/session \
-H "Idempotency-Key: order-12345-payment" \
-d '{ "webcode": "SHOP01", "amount": { "value": 99999, "currency": "EUR" }, ... }'
Client Secret
Cada entorno tiene su propio client secret. El client secret se usa para descifrar los datos cifrados que llegan en el redirect post-pago (parametro data en la urlOk).
Client secret de Live: se genera al crear la primera API key de Live.
Client secret de Test: se genera al crear la primera API key de Test.
El client secret solo se muestra una vez al momento de crear la primera key del entorno. Si lo pierdes, puedes rotarlo desde el dashboard (seccion Integraciones > Configuracion > API keys > Rotar Secret).
Importante: Los client secrets de Live y Test son diferentes. Asegurate de usar el secret correcto para descifrar los datos del redirect en cada entorno.
Gestion de API keys
Las API keys se gestionan desde el Dashboard de Avirato Payments (seccion Integraciones > Configuracion > API keys):
Accion
Descripcion
Crear
Genera una nueva key para el entorno seleccionado (Live o Test). Si es la primera key de ese entorno, tambien genera el client secret
Listar
Ver todas las keys activas con su configuracion y entorno
Editar IPs
Modificar restricciones de IP
Revocar
Desactiva permanentemente una key
Regenerar
Genera un nuevo valor de key (mantiene la configuracion)
Rotar secret
Genera un nuevo client secret para un entorno
Pagos online
Concepto clave: Sesion vs pago
Es fundamental entender que en la External API existen dos conceptos distintos: la sesion y el pago. Aunque estan relacionados, representan cosas diferentes y tienen ciclos de vida independientes.
La sesion (sessionId)
La sesion es lo que tu sistema crea al llamar a POST /payment/session. Representa la intencion de cobro: el importe, la divisa, las URLs de retorno, la descripcion, etc. Cuando la creas, recibes un sessionId y una paymentUrl para redirigir al cliente.
Cuando el cliente completa el pago con exito, la sesion pasa a estado completed y se cierra.
La sesion no se modifica una vez completada. Su trabajo ha terminado: sirvio para que el cliente pagara.
El pago (paymentReference)
El pago es la transaccion real que se crea cuando el cliente completa satisfactoriamente el formulario de pago. Es el objeto que el procesador de pagos reconoce y sobre el que se pueden hacer operaciones.
El paymentReference (referencia del pago autorizado) aparece dentro de la sesion una vez completada, en el campo paymentReference y tambien en el array de attempts.
El pago es lo que importa para operaciones posteriores. Reembolsos, capturas, cancelaciones y extensiones se hacen sobre el paymentReference, no sobre el sessionId.
Relacion visual
En resumen
Concepto
Que es
Se crea cuando
Se usa para
Sesion (sessionId)
Intencion de cobro
Tu sistema llama a POST .../payment/session
Redirigir al cliente, consultar estado
Pago (paymentReference)
Transaccion autorizada
El cliente completa el pago con exito
Reembolsos, capturas, cancelaciones, conciliacion
Regla practica: Usa sessionId para consultar el estado y obtener el paymentReference. Usa paymentReference para modificar el pago (refund, capture, cancel, extend).
Flujo completo de un pago online
Antes de entrar en los endpoints, es importante entender el flujo completo. Un pago online implica tres participantes y tres redireccionamientos:
Paso a paso
Tu sistema crea la sesion llamando a POST /payment/session con el importe, la divisa, y dos URLs de retorno: urlOk y urlKo
Recibes un sessionId y una paymentUrl. La paymentUrl es un enlace a la pagina de pago segura de Avirato Payments
Redirige al cliente a la paymentUrl. Puedes hacer un redirect HTTP 302 o abrir en una nueva pestana, segun tu caso de uso
El cliente ve la pagina de pago. Ahi introduce su tarjeta, completa 3D Secure si es necesario, y confirma el pago. Tu sistema no interviene en este paso
Avirato Payments redirige automaticamente al cliente a una de las dos URLs que proporcionaste:
urlOk si el pago se completo con exito
urlKo si el pago fallo, fue cancelado por el cliente, o expiro
El cliente llega a tu pagina. En la urlOk puedes mostrar un mensaje de confirmacion. En la urlKo puedes informar del problema y, si tiene sentido, crear una nueva sesion de pago para ofrecer otro intento
Tu sistema confirma el pago usando las herramientas que te proporcionamos: los datos cifrados que llegan en el parametro data de la urlOk (descifrables con tu client secret), el webhook que recibiras automaticamente unos segundos despues, y opcionalmente la consultaGET /payment/session/{id} para verificacion adicional
Entorno Test: El flujo es identico. La unica diferencia es que en el paso 4, la pagina de pago es un formulario simulado (no conecta con ningun procesador real). El cliente introduce tarjetas ficticias y el resultado se determina segun el nombre del titular (ver Tarjetas de prueba).
La importancia de urlOk y urlKo
Estas dos URLs son el puente de vuelta entre nuestra pagina de pago y tu sistema. Son obligatorias y determinan la experiencia del cliente despues de pagar:
urlOk: Donde aterrizara el cliente cuando el pago sea exitoso. Debe ser una pagina de tu sistema que muestre una confirmacion (ej: "Gracias, tu pago se ha completado"). La URL recibira un parametro data con informacion cifrada del pago (descifrable con tu client secret)
urlKo: Donde aterrizara el cliente si algo falla (tarjeta rechazada, timeout, cancelacion). Debe ser una pagina que informe del problema. Si quieres ofrecer otro intento, crea una nueva sesion de pago desde tu backend y redirige al cliente a la nueva paymentUrl
Recomendacion practica: Usa el campo customReference al crear la sesion para incluir tu referencia interna (ej: numero de pedido, ID de operacion). Este valor se incluye en los datos cifrados del redirect y en los webhooks, lo que te permite asociar automaticamente el resultado con la operacion original en tu sistema.
No confies solo en la URL de retorno: verifica el estado con GET /payment/session/{sessionId} y, sobre todo, con los webhooks. En Live el estado definitivo de un pago puede evolucionar despues del redirect o de una consulta anterior (por ejemplo, un chargeback notificado por el procesador). Trata los webhooks como la referencia de negocio para cambios tardios y vuelve a consultar la API si necesitas el estado persistido (ver Webhooks).
Crear sesion de pago
Crea una sesion de pago y obtiene una URL donde redirigir al cliente para completar el pago.
Live: POST https://aviratopayments.com/external/v1/payment/session
Test: POST https://aviratopayments.com/external/v1/test/payment/session
Parametros del body
Campo
Tipo
Requerido
Descripcion
webcode
string
Si
Identificador de tu negocio
amount.value
integer
Si
Importe en centimos (ej: 10000 = 100.00 EUR)
amount.currency
string
Si
Codigo ISO 4217 de 3 letras en mayusculas. Valores aceptados: EUR, GBP, USD
urlOk
string
Si
URL donde redirigir al cliente cuando el pago se completa con exito. Debe ser una URL valida de tu sistema
urlKo
string
Si
URL donde redirigir al cliente cuando el pago falla, se cancela o expira. Debe ser una URL valida de tu sistema
countryCode
string
No
Codigo ISO 3166-1 alpha-2 (por defecto: ES)
shopperLocale
string
No
Idioma de la pagina de pago, formato BCP-47 (por defecto: es-ES). Max 10 caracteres
deliverAt
string
No
Fecha del servicio en formato ISO 8601 (ej: 2026-07-15T14:00:00Z)
description
string
No
Descripcion del pago. Max 255 caracteres
customReference
string
No
Tu referencia interna para conciliacion. Max 100 caracteres. Se incluye en los datos cifrados del redirect
isPreAuth
boolean
No
true para preautorizacion (no captura inmediata). Por defecto: false
Formato de sessionId: En Live el formato es {webcode}-EXT-{timestamp}. En Test el formato es {webcode}-EXTT-{timestamp}. Esto te permite identificar a simple vista de que entorno proviene una sesion.
paymentUrl en Test: La URL apunta a una pagina de pago simulada (no conecta con la pasarela real). El formulario acepta tarjetas ficticias y el resultado se determina por el nombre del titular. Ver Tarjetas de prueba.
Que hacer con la respuesta
Guarda el sessionId en tu sistema, asociado a la operacion (pedido, servicio, etc.). Lo necesitaras para consultar el estado y obtener el paymentReference cuando se complete
Redirige al cliente a paymentUrl inmediatamente. Ahi vera la pagina de pago segura con los metodos de pago disponibles
Prepara tus paginas de retorno (urlOk y urlKo). El cliente llegara a una de ellas despues de pagar
Tiempo limite para pagar
Una vez que el cliente abre la paymentUrl, dispone de 5 minutos (300 segundos) para completar el pago. Pasado ese tiempo, la pagina de pago expira automaticamente y el cliente es redirigido a urlKo.
La sesion en si no tiene un tiempo de expiracion fijo desde el servidor: lo que expira es la pagina de pago en el navegador del cliente. Si el cliente no abre la paymentUrl, la sesion permanece en estado pending indefinidamente.
La pagina de pago muestra un reloj con la cuenta atras visible para el cliente, asi que no necesitas informarle por tu parte.
Ciclo de vida de la sesion
La sesion (no el pago) pasa por estos estados:
Estado
Descripcion
pending
Sesion creada, esperando que el cliente pague. Puede haber intentos fallidos en curso
completed
Un intento de pago fue autorizado. La sesion se cierra y el paymentReference esta disponible
failed
Todos los intentos han fallado sin que ninguno sea autorizado
expired
La sesion ha expirado sin completarse
cancelled
Cancelada antes de completarse
Importante: Una sesion completed no cambiara de estado. A partir de ese momento, lo relevante es el pago (paymentReference), que es el que puedes reembolsar, capturar, etc.
Si el pago falla
Si el pago falla (tarjeta rechazada, 3DS cancelado, timeout), el cliente es redirigido a tu urlKo. Para ofrecer otro intento, crea una nueva sesion y redirige al cliente a la nueva paymentUrl.
URLs de prueba: Las URLs urlOk y urlKo del ejemplo apuntan a paginas de prueba del dashboard, pensadas para que puedas analizar el mensaje de respuesta y verificar el descifrado con tu client secret. Puedes sustituirlas por las URLs de tu propio sistema.
Redirect post-pago: lo que ocurre cuando el cliente termina
Una vez que el cliente completa el formulario de pago (o lo abandona/falla), Avirato Payments le redirige automaticamente a la URL correspondiente:
Pago exitoso -> el cliente es redirigido a tu urlOk
Pago fallido, cancelado o expirado -> el cliente es redirigido a tu urlKo
La redireccion es automatica: el cliente ve brevemente un mensaje "Redirigiendo..." y aterriza en tu pagina sin necesidad de hacer clic en ningun boton.
El parametro data en urlOk
Cuando el cliente llega a tu urlOk, la URL incluye un parametro data con un JWT que contiene informacion cifrada del pago:
El payload descifrado contiene los datos del pago: referencia, importe, estado, etc.
urlKo no incluye el parametro data, ya que no hay pago exitoso del que informar. En urlKo muestra un mensaje apropiado al cliente.
Entorno Test: El parametro data en urlOk funciona exactamente igual que en Live. Se cifra con el client secret del entorno Test, y lo descifras con ese mismo secret. El contenido tiene la misma estructura.
Validacion de los datos del redirect
Cuando recibas al cliente en urlOk con el parametro data, valida la informacion cifrada contra los datos en abierto:
Decodifica el JWT con tu client secret
Compara los datos del payload (importe, referencia, estado) con lo que esperas segun tu logica de negocio
Si los datos no coinciden, trata la operacion como sospechosa
Esto protege contra manipulaciones: un usuario podria cambiar la URL manualmente, pero no puede falsificar el JWT sin tu client secret.
Que pasa si el cliente cierra el navegador
Si el cliente completa el pago pero cierra el navegador antes de ser redirigido, el pago se ha completado igualmente.
En este caso, el cliente nunca llega a tu urlOk. Para cubrir este escenario:
Recibiras un webhook unos segundos despues de que el pago se complete (ver Webhooks)
Como alternativa, puedes hacer polling periodico con GET /payment/session/{sessionId} para detectar sesiones que pasaron a completed sin que el cliente volviera
Recomendacion: No dependas exclusivamente de la redireccion a urlOk para confirmar pagos. Usa los webhooks como fuente principal de confirmacion y la redireccion como mejora de experiencia de usuario.
Tarjetas de prueba (entorno Test)
En el entorno Test, la pagina de pago es un formulario simulado. No se conecta con ningun procesador real. El resultado del pago se determina por el nombre del titular de la tarjeta (holderName):
Pago exitoso
Usa cualquier nombre que no sea uno de los valores especiales de la tabla siguiente. Ejemplo: Juan Garcia, Test User, Maria Lopez.
Simular fallos
Nombre del titular (case-insensitive)
Resultado
Motivo
DECLINED
Pago rechazado
Generic decline
CARD_EXPIRED
Pago rechazado
Expired card
INVALID_CARD
Pago rechazado
Invalid card number
NOT_ENOUGH_BALANCE
Pago rechazado
Not enough balance
CVC_DECLINED
Pago rechazado
CVC declined
FRAUD
Pago rechazado
Fraud detected
ERROR
Error del procesador
Acquirer error
Datos de la tarjeta
El formulario simulado valida el formato de la tarjeta de forma realista:
Numero: Debe tener 13-19 digitos y pasar la validacion Luhn. Ejemplo: 4111 1111 1111 1111 (Visa)
Mes de expiracion: Formato MM (01-12), no puede estar expirada
Ano de expiracion: Formato YY (2 digitos), no puede estar expirado
CVC: 3 digitos (Visa/Mastercard) o 4 digitos (Amex)
Nombre del titular: Minimo 3 caracteres
Tip: Para probar un flujo exitoso rapido, usa 4111 1111 1111 1111, expiracion 12/30, CVC 737, nombre Test User.
Preautorizaciones
Si necesitas reservar un importe sin capturarlo inmediatamente (ej: deposito de garantia), usa isPreAuth: true.
Con una preautorizacion puedes despues:
Capturar el importe total o parcial: POST /payment/capture
Cancelar la preautorizacion: POST /payment/cancel
Extender el plazo antes de que expire: POST /payment/extend
Actualmente la External API acepta las siguientes divisas:
Codigo
Divisa
EUR
Euro
GBP
Libra esterlina
USD
Dolar estadounidense
Si envias un codigo de divisa no soportado, recibiras un error 400 Bad Request.
Errores comunes
Codigo
HTTP
Causa
12001
400
Campo requerido faltante o valor invalido (incluye divisa no soportada)
12002
400
Fecha deliverAt en formato incorrecto (debe ser ISO 8601)
12006
400
Formato de countryCode invalido
12009
400
Pais no soportado
11008
403
API key sin permisos o webcode no coincide
Pagos POS (terminal fisico)
Los pagos POS permiten enviar un cobro directamente a un terminal fisico (TPV) conectado. El flujo es sincrono: la respuesta llega cuando el terminal procesa el pago (o expira por timeout).
Listar terminales
Antes de enviar un pago POS, necesitas conocer el identificador del terminal (poiId).
Live: GET https://aviratopayments.com/external/v1/pos/terminals?webcode={webcode}
Test: GET https://aviratopayments.com/external/v1/test/pos/terminals?webcode={webcode}
Parametros de query
Parametro
Tipo
Requerido
Descripcion
webcode
string
Si
Identificador de tu negocio
syncFromProvider
boolean
No
true para forzar sincronizacion con el proveedor. Por defecto: false
Ejemplo
bash
curl -X GET "https://aviratopayments.com/external/v1/pos/terminals?webcode=SHOP01" \
-H "X-API-KEY: tu_api_key_live"
Solo se devuelven terminales con estado boarded (activos y operativos).
Con syncFromProvider=false (por defecto): devuelve todos los terminales registrados como boarded.
Con syncFromProvider=true: solo devuelve los terminales que ademas estan actualmente conectados (online). Util para saber que terminales estan operativos en tiempo real.
Entorno Test: Se devuelven 3 terminales simulados, todos con estado boarded:
poiId
Nombre
Modelo
Conectividad
V400m-TEST-000001
Terminal Test 1 - Mostrador
V400m
Online
S1F2-TEST-000002
Terminal Test 2 - Terraza
S1F2
Online
P400Plus-TEST-000003
Terminal Test 3 - Almacen
P400Plus
Offline
Con syncFromProvider=true, solo se devuelven los 2 terminales online. El terminal offline (P400Plus-TEST-000003) permite probar el error DeviceError (502, code 13004) al intentar cobrar en un terminal no conectado.
Solo se aceptan los poiId de esta lista para enviar pagos POS en Test. Usar un poiId no listado devolvera error 400.
Crear pago POS
Envia un cobro a un terminal fisico. La peticion espera a que el terminal procese el pago.
Live: POST https://aviratopayments.com/external/v1/pos/payment
Test: POST https://aviratopayments.com/external/v1/test/pos/payment
Parametros del body
Campo
Tipo
Requerido
Descripcion
webcode
string
Si
Identificador de tu negocio
poiId
string
Si
Identificador del terminal (obtenido de /pos/terminals)
Formato de posPaymentId: En Live el formato es {webcode}-POSX-{timestamp}. En Test el formato es {webcode}-POSXT-{timestamp}.
Timeout recomendado: Configura un timeout de al menos 240 segundos tanto en tu cliente HTTP como en tu servidor (por ejemplo, max_execution_time en PHP, proxy_read_timeout en Nginx, o el equivalente en tu stack). La peticion espera a que el cliente interactue con el terminal (insertar tarjeta, introducir PIN, etc.), lo cual puede tardar. Si tu servidor corta la conexion antes de recibir la respuesta, no recibiras el resultado directo — aunque el pago puede completarse igualmente en segundo plano.
Estados del pago POS
Estado
Descripcion
pending
Pago enviado al terminal, esperando resultado
success
Pago completado con exito
failed
El pago ha fallado (rechazado, error del terminal)
timeout
El terminal no respondio a tiempo
Manejo de timeouts
Si el terminal no responde dentro del tiempo limite, la respuesta tendra status: "timeout". En este caso:
No reintentes inmediatamente: el pago podria estar en proceso
Usa Idempotency-Key: si reenvias la peticion con la misma key, recibiras la respuesta almacenada
Consulta el estado: usa GET /pos/payments para verificar si el pago llego a completarse
El webhook llega igualmente: Si el pago se completa despues del timeout, recibiras un webhook de confirmacion (AUTHORISATION) con el resultado final. Implementa webhooks como red de seguridad para no perder pagos completados que no pudiste capturar en la respuesta sincrona.
Errores especificos de POS
Codigo
HTTP
Causa
13005
409
Terminal ocupado (DeviceBusy): hay otro pago en proceso
13004
502
Error del terminal (DeviceError): problema de comunicacion
Todos los errores de POS siguen el formato estandar de error:
json
{
"success": false,
"error": {
"message": "Terminal is busy processing another payment",
"code": 13005,
"statusCode": 409,
"traceId": "abc123def456..."
}
}
Simulacion POS en entorno Test
En el entorno Test, los pagos POS no se envian a un terminal real. El sistema valida el poiId contra la lista de terminales simulados y determina el resultado.
Terminales simulados
Solo se aceptan los poiId devueltos por GET /test/pos/terminals. Si envias un poiId que no esta en la lista, recibiras error 400.
Si envias un pago al terminal offline (P400Plus-TEST-000003), se simula el error real que devuelve el procesador cuando un terminal no esta conectado:
Para los terminales online (V400m-TEST-000001, S1F2-TEST-000002), el resultado se determina por los ultimos dos digitos del importe (amount.value):
Magic amounts (ultimos 2 digitos del importe)
Terminacion
Resultado
Descripcion
77
failed
Pago rechazado (tarjeta declinada)
99
timeout
Timeout del terminal
55
Error 409
Terminal ocupado
Cualquier otra
success
Pago exitoso
Ejemplos
Importe (`amount.value`)
Ultimos 2 digitos
Resultado
5000 (50.00 EUR)
00
Exito
10077 (100.77 EUR)
77
Rechazado
2599 (25.99 EUR)
99
Timeout
1055 (10.55 EUR)
55
Terminal ocupado (error 409)
15001 (150.01 EUR)
01
Exito
Importante: En Test, la respuesta incluye un pequeno delay simulado (2-3 segundos) para emular el tiempo de comunicacion con el terminal.
Webhooks en Test: Cuando un pago POS se completa (exito o fallo) en entorno Test, se genera automaticamente un webhook simulado que se envia a tu URL de webhook, igual que ocurriria en Live cuando el procesador confirma la operacion.
Listar pagos POS
Consulta el historial de pagos POS con filtros y paginacion basada en cursor.
Live: GET https://aviratopayments.com/external/v1/pos/payments?webcode={webcode}
Test: GET https://aviratopayments.com/external/v1/test/pos/payments?webcode={webcode}
Parametros de query
Parametro
Tipo
Requerido
Descripcion
webcode
string
Si
Identificador de tu negocio
status
string
No
Filtrar por estado: pending, success, failed, timeout
created_at_start
string
No
Fecha inicio (filtro)
created_at_end
string
No
Fecha fin (filtro)
cursor
string
No
Cursor de paginacion (obtenido de la respuesta anterior)
take
integer
No
Numero de resultados por pagina (1-100, por defecto: 20)
order
string
No
Orden de resultados: asc o desc (por defecto: asc)
Ejemplo
bash
curl -X GET "https://aviratopayments.com/external/v1/pos/payments?webcode=SHOP01&status=success&take=10" \
-H "X-API-KEY: tu_api_key_live"
La paginacion usa cursores en lugar de numeros de pagina:
La primera peticion se hace sin cursor
Si meta.hasMore es true, usa el valor de meta.cursor como parametro cursor en la siguiente peticion
Repite hasta que meta.hasMore sea false
bash
# Pagina 1
curl ".../pos/payments?webcode=SHOP01&take=20"
# Pagina 2 (usando el cursor de la respuesta anterior)
curl ".../pos/payments?webcode=SHOP01&take=20&cursor=eyJpZCI6NDJ9"
Cobra a tus clientes de forma periodica (mensual, semanal, cada N dias, anual, un dia concreto de cada mes, con o sin fecha de fin) y gestiona todo el ciclo de vida desde tu sistema: alta, consulta, cambios, pausa, reactivacion, cambio de tarjeta y cancelacion.
Nombre tecnico: en la API cada pago recurrente es un recurso subscription (rutas /subscriptions, ids WEBCODE-SB-xxxxxxxx). En el panel aparecen en Transacciones > Pagos Recurrentes.
Live
Test
URL base
/external/v1/subscriptions
/external/v1/test/subscriptions
API key
Key Live
Key Test
Pago inicial
Pagina segura real (/pay/...)
Pagina simulada (/pay-subscription-test/...)
Cobros recurrentes
Reales, en su fecha
Simulados (en su fecha o al momento con simulate-renewal)
Webhooks
URL Live
URL Test (con environment: "test")
Visible en el panel
Si (Pagos Recurrentes)
No
Reglas generales
webcode obligatorio: en el body en POST/PATCH y en la query en GET. Debe coincidir con el de tu API key.
Solo veras y modificaras los pagos recurrentes de tu webcode y de ese entorno. Cualquier recurso ajeno o del otro entorno responde 404.
Importes siempre en centimos (2990 = 29,90 EUR). Monedas: EUR, USD, GBP.
Idempotency-Key recomendada en todos los POST y PATCH (ver Autenticacion).
Flujo
POST /subscriptions crea un link de pago recurrente y devuelve paymentUrl.
Rediriges a tu cliente a paymentUrl. Paga el primer importe y se guarda su tarjeta.
Se crea el pago recurrente (subscriptionId) y recibes SUBSCRIPTION_CREATED. Tambien puedes consultarlo en GET /subscriptions/links/{linkId} (campo subscriptionId).
Avirato cobra cada periodo. Si un cobro falla se reintenta 3 veces (5 h, 8 h y 11 h despues); si sigue fallando el pago recurrente queda pausado (SUBSCRIPTION_ERROR).
Si el primer pago se rechaza
Se crea igualmente el pago recurrente en estado error (statusReason: initial_payment_failed) y recibes SUBSCRIPTION_FAILED. El link sigue pending y tu cliente puede reintentar con el mismo paymentUrl: cada intento crea un pago recurrente nuevo. El anterior queda en error, nunca se cobra y puedes ignorarlo. El valido es el del webhook SUBSCRIPTION_CREATED, que es tambien el que devuelve el detalle del link. El motivo del rechazo esta en refusalReason de GET /subscriptions/{id}/payments. Igual en Live y en Test.
Intervalos
Quieres
intervalUnit
intervalCount
Extra
Mensual
month
1
—
Cada 15 dias
day
15
—
Cada 2 semanas
week
2
—
Trimestral
month
3
—
Anual
year
1
—
El dia 5 de cada mes
month
1
billingDay: 5
Mensual hasta el 31/12/2027
month
1
endAt: "2027-12-31"
intervalCount minimo 1.
billingDay (1-31) solo con month. En meses mas cortos se cobra el ultimo dia del mes.
endAt futura (Y-m-d o Y-m-d H:i:s): el dia de fin ya no se cobra; esa noche el pago recurrente se cancela (statusReason: end_date_reached).
initialAmount: primer pago distinto al recurrente (puede ser 0 para solo guardar la tarjeta).
Al terminar el pago el cliente vuelve a returnUrl con ?linkId=...&subscriptionId=...&status=success|refused|error. No te fies solo del redirect: confirma con el webhook o consultando el link.
Endpoints
Consultas
Metodo
Ruta
Descripcion
GET
/subscriptions?webcode=
Listado. Filtros: status, plan_code, customer_internal_id, customer_internal_folder, created_at_start, created_at_end. Paginacion: take (1-100, def. 20), cursor, order
GET
/subscriptions/{id}?webcode=
Detalle. Incluye paymentRetryInfo si hay reintentos en curso y failedPaymentInfo si se pauso por cobro fallido
GET
/subscriptions/{id}/payments?webcode=
Historial de pagos (inicial, cambios de tarjeta y recurrentes) con refusalReason si fallaron
GET
/subscriptions/{id}/charges?webcode=&status=
Cola de cobros: pendientes, realizados, fallidos, reintentos
GET
/subscriptions/links?webcode=&status=
Links de pago recurrente (pending, redeemed, expired, cancelled)
GET
/subscriptions/links/{linkId}?webcode=
Detalle del link (tras el pago incluye subscriptionId)
Fallo el primer pago o el pago con la nueva tarjeta
Reactivar, cambiar tarjeta, cancelar
pendingNewCard
Esperando a que el cliente pague con su nueva tarjeta
Generar otro link (update-card), cancelar
cancelled
Cancelado por ti o fin por endAt (end_date_reached)
Nada (definitivo)
Entorno Test
Todo funciona igual que en Live pero sin dinero real. Los pagos recurrentes de test no aparecen en el panel; consultalos con la API.
Pago inicial: abre paymentUrl (/pay-subscription-test/...) y usa cualquier tarjeta valida (p. ej. 4111 1111 1111 1111, fecha futura en formato MM/AA, CVC 737). El titular decide el resultado:
Completa el pago inicial (o el de cambio de tarjeta) sin abrir la pagina
POST
/test/subscriptions/{id}/simulate-renewal
Ejecuta ya el siguiente cobro con ese resultado (reintentos, pausa tras 3 fallos, siguiente ciclo y webhooks como en Live)
POST
/test/subscriptions/{id}/simulate-end
Da de baja el pago recurrente como si hubiera llegado su endAt
Webhooks
Eventos SUBSCRIPTION_CREATED, SUBSCRIPTION_RENEWED, SUBSCRIPTION_FAILED, SUBSCRIPTION_ERROR, SUBSCRIPTION_PAUSED, SUBSCRIPTION_REACTIVATED, SUBSCRIPTION_CANCELLED y SUBSCRIPTION_CARD_UPDATED. Formato y ejemplos en Webhooks.
Errores habituales
Ver Errores > Pagos recurrentes. Resumen: 400 validacion o accion no permitida en el estado actual, 403 key/webcode/entorno, 404 no existe para tu webcode y entorno, 409 Idempotency-Key reutilizada.
Modificaciones de pago
Las modificaciones permiten operar sobre pagos ya completados (tanto online como POS). Todos los endpoints de modificacion devuelven HTTP 202 Accepted porque la operacion se procesa de forma asincrona por el procesador de pagos.
Sesion vs pago: recordatorio importante
Las modificaciones no operan sobre la sesion (sessionId), sino sobre el pago (paymentReference). La sesion es el contenedor que se crea al llamar a POST /payment/session; el pago es la transaccion real que se crea cuando el cliente paga con exito. Una vez completada la sesion, esta no cambia mas: lo que importa a partir de ese momento es el pago.
Para mas detalle sobre esta distincion, ver Sesion vs pago.
Como obtener el paymentReference
Todas las modificaciones requieren un paymentReference que identifica el pago real:
Para pagos online: consulta la sesion con GET /payment/session/{sessionId}. Cuando la sesion esta completed, el campo paymentReference contiene la referencia del pago autorizado
Para pagos POS: es el paymentReference que se devuelve directamente en la respuesta de POST /pos/payment (coincide con el posPaymentId)
Ambos tipos de referencia funcionan indistintamente en todos los endpoints de modificacion.
Reembolso (refund)
Devuelve total o parcialmente el importe de un pago completado.
Live: POST https://aviratopayments.com/external/v1/payment/refund
Test: POST https://aviratopayments.com/external/v1/test/payment/refund
Parametros del body
Campo
Tipo
Requerido
Descripcion
webcode
string
Si
Identificador de tu negocio
paymentReference
string
Si
Referencia del pago a reembolsar
amount.value
integer
Si
Importe a reembolsar en centimos (ej: 5000 = 50.00 EUR)
amount.currency
string
Si
Codigo ISO 4217, 3 letras mayusculas (ej: EUR)
reason
string
Si
Motivo del reembolso. Debe ser uno de los valores exactos de la tabla
Valores permitidos para reason
Valor
Descripcion
FRAUD
Transaccion fraudulenta
CUSTOMER REQUEST
Solicitud del cliente
RETURN
Devolucion de producto/servicio
DUPLICATE
Cobro duplicado
OTHER
Otro motivo
Importante: Los valores son case-sensitive e incluyen espacio en CUSTOMER REQUEST. Enviar customer request o Customer Request producira un error 400.
El refundReference (formato {webcode}-RFX-{timestamp} en Live, {webcode}-RFXT-{timestamp} en Test) identifica esta operacion de reembolso. Usalo para seguimiento en el listado de modificaciones.
Reembolso parcial vs total
Puedes reembolsar cualquier importe menor o igual al importe original del pago. Si necesitas hacer multiples reembolsos parciales sobre el mismo pago, puedes hacerlo siempre que la suma total no supere el importe original.
Captura (capture)
Captura total o parcialmente una preautorizacion (pago creado con isPreAuth: true).
Live: POST https://aviratopayments.com/external/v1/payment/capture
Test: POST https://aviratopayments.com/external/v1/test/payment/capture
Parametros del body
Campo
Tipo
Requerido
Descripcion
webcode
string
Si
Identificador de tu negocio
paymentReference
string
Si
Referencia del pago preautorizado
amount.value
integer
Si
Importe a capturar en centimos (puede ser menor al preautorizado)
El captureReference (formato {webcode}-CTX-{timestamp} en Live, {webcode}-CTXT-{timestamp} en Test) identifica esta operacion de captura.
Captura parcial
Si preautorizaste 500 EUR pero el importe final del servicio fue 450 EUR, puedes capturar solo 45000 centimos. La diferencia se libera automaticamente.
Captura excedente
Si intentas capturar un importe superior al preautorizado, la peticion se acepta (HTTP 202) pero el procesador rechazara la operacion. Recibiras un webhook con result: "failure" indicando que el importe excede el autorizado.
Cancelacion (cancel)
Cancela una preautorizacion antes de que se capture. Libera los fondos retenidos en la tarjeta del cliente.
Live: POST https://aviratopayments.com/external/v1/payment/cancel
Test: POST https://aviratopayments.com/external/v1/test/payment/cancel
El cancelReference (formato {webcode}-CAX-{timestamp} en Live, {webcode}-CAXT-{timestamp} en Test) identifica esta operacion de cancelacion.
Extension (extend)
Extiende el plazo de una preautorizacion antes de que expire. Las preautorizaciones tienen una validez limitada (normalmente 7-28 dias segun el banco emisor). Si necesitas mas tiempo, puedes extenderla. La extension amplia el plazo 28 dias adicionales contando desde el momento en que se solicita.
Live: POST https://aviratopayments.com/external/v1/payment/extend
Test: POST https://aviratopayments.com/external/v1/test/payment/extend
Parametros del body
Campo
Tipo
Requerido
Descripcion
webcode
string
Si
Identificador de tu negocio
paymentReference
string
Si
Referencia del pago preautorizado a extender
No se necesita enviar importe ni divisa: la extension mantiene el importe original.
El updateReference (formato {webcode}-UPX-{timestamp} en Live, {webcode}-UPXT-{timestamp} en Test) identifica esta operacion de extension. El amount devuelto es el importe original del pago.
Estado de las modificaciones
Las modificaciones se procesan de forma asincrona. El estado devuelto en la respuesta inicial depende de la operacion y evoluciona conforme el procesador confirma:
Estado
Descripcion
pending
Estado inicial de refund. Operacion enviada al procesador, pendiente de confirmacion
received
Estado inicial de capture, cancel y extend. El procesador ha recibido la peticion
success
Operacion completada con exito por el procesador
failed
Operacion rechazada por el procesador
Nota sobre los estados iniciales: Las operaciones de refund devuelven pending porque el reembolso puede tardar en procesarse. Capture, cancel y extend devuelven received porque la confirmacion del procesador es mas rapida. En ambos casos, el estado final sera success o failed.
Como saber cuando se completa una modificacion:
Webhooks (recomendado): Recibiras un webhook automatico cuando el procesador confirme la operacion. Ver Webhooks para detalles del formato y ejemplos
En el entorno Test, las modificaciones se procesan de forma simulada e inmediata. No se contacta con ningun procesador real. El backend genera un webhook simulado con el resultado (success o failed) que se envia a tu URL de webhook en segundos.
Comportamiento simulado por tipo
Operacion
Comportamiento en Test
Refund
Exito inmediato. El backend verifica que el importe no exceda el saldo disponible
Capture
Exito si el importe es menor o igual al autorizado. Fallo (webhook con result: "failure") si excede
Cancel
Exito inmediato
Extend
Exito inmediato
Importante: En Test, el webhook de confirmacion se genera automaticamente en el momento de la peticion. En Live, el webhook llega cuando el procesador real confirma la operacion (segundos a minutos).
Referencia rapida de marcadores
Cada tipo de modificacion genera una referencia con un prefijo identificativo:
Operacion
Prefijo Live
Prefijo Test
Ejemplo (Live)
Reembolso
-RFX-
-RFXT-
SHOP01-RFX-17195234567890
Captura
-CTX-
-CTXT-
SHOP01-CTX-17195345678901
Cancelacion
-CAX-
-CAXT-
SHOP01-CAX-17195456789012
Extension
-UPX-
-UPXT-
SHOP01-UPX-17195567890123
Errores comunes en modificaciones
Codigo
HTTP
Causa
Accion
12001
400
Parametros invalidos (falta paymentReference, amount incorrecto, reason no valido)
Revisa los campos requeridos y sus formatos
11008
403
El pago no fue creado via la External API, o el webcode no coincide
Verifica que usas el paymentReference correcto y que pertenece a tu webcode
10404
404
Pago no encontrado con esa referencia
Verifica el paymentReference
Consultas
Obtener detalle de un pago
Obtiene la informacion completa de una sesion de pago online, incluyendo todos los intentos de pago y, si la sesion esta completada, la referencia del pago autorizado (paymentReference).
Este endpoint es la forma principal de obtener el paymentReference que necesitas para realizar modificaciones (reembolsos, capturas, etc.).
Live: GET https://aviratopayments.com/external/v1/payment/session/{sessionId}?webcode={webcode}
Test: GET https://aviratopayments.com/external/v1/test/payment/session/{sessionId}?webcode={webcode}
Parametros
Parametro
Ubicacion
Tipo
Requerido
Descripcion
sessionId
Path
string
Si
El sessionId devuelto al crear la sesion
webcode
Query
string
Si
Identificador de tu negocio
Ejemplo
bash
curl -X GET "https://aviratopayments.com/external/v1/payment/session/SHOP01-EXT-17195000001234?webcode=SHOP01" \
-H "X-API-KEY: tu_api_key_live"
Estado de la sesion: pending, completed, failed, expired, cancelled
amount
Si
Importe y divisa solicitados al crear la sesion
countryCode
Si
Pais configurado
shopperLocale
Si
Idioma configurado
deliverAt
Si
Fecha de entrega (puede ser null)
description
Si
Descripcion (puede ser null)
customReference
Si
Tu referencia interna (puede ser null)
isPreAuth
Si
Si fue creada como preautorizacion
urlOk / urlKo
Si
URLs de retorno configuradas
createdAt
Si
Fecha y hora de creacion de la sesion
paymentReference
Solo si completed
Referencia del pago autorizado. Usa esta para modificaciones
completedAt
Solo si completed
Fecha en que se autorizo el pago
paymentStatus
Solo si completed
Estado del pago en el procesador (ej: AUTHORISED). En Live este valor puede cambiar con el tiempo si el procesador notifica eventos posteriores (chargeback, fraude, reversion). Consulta los webhooks o vuelve a llamar a este endpoint si necesitas el ultimo estado.
attempts
Si
Array informativo con los intentos de pago registrados. Puede estar vacio
Errores
Codigo
HTTP
Causa
12001
400
Falta parametro webcode
10404
404
Sesion no encontrada
11008
403
La sesion no pertenece a tu webcode o entorno
Listar pagos
Lista todas las sesiones de pago online con filtros y paginacion basada en cursor.
Live: GET https://aviratopayments.com/external/v1/payment/sessions?webcode={webcode}
Test: GET https://aviratopayments.com/external/v1/test/payment/sessions?webcode={webcode}
Parametros de query
Parametro
Tipo
Requerido
Descripcion
webcode
string
Si
Identificador de tu negocio
status
string
No
Filtrar por estado: pending, completed, failed, expired, cancelled
created_at_start
string
No
Fecha de inicio (filtro)
created_at_end
string
No
Fecha de fin (filtro)
cursor
string
No
Cursor de paginacion (de la respuesta anterior)
take
integer
No
Resultados por pagina (1-100, por defecto: 20)
order
string
No
Orden de resultados: asc o desc (por defecto: asc)
Ejemplo
bash
curl -X GET "https://aviratopayments.com/external/v1/payment/sessions?webcode=SHOP01&status=completed&take=10" \
-H "X-API-KEY: tu_api_key_live"
Referencia del pago autorizado (puede ser null si no esta completada)
paymentStatus
Estado del pago: AUTHORISED, FAILED, REFUNDED, PARTIALLYREFUNDED, CANCELED, ACTIVEDEPOSIT (puede ser null). En Live el valor puede evolucionar tras webhooks posteriores (ver Webhooks).
Paginacion con cursores
La paginacion funciona con cursores opacos (no numeros de pagina):
bash
# Primera pagina
GET .../payment/sessions?webcode=SHOP01&take=20
# Siguiente pagina (usando cursor de meta.cursor)
GET .../payment/sessions?webcode=SHOP01&take=20&cursor=eyJpZCI6NDJ9
# Repetir hasta meta.hasMore == false
Los cursores son cadenas opacas. No intentes decodificarlos ni construirlos manualmente; simplemente pasa el valor de meta.cursor tal cual.
Listar modificaciones de un pago
Lista todas las operaciones de modificacion (refund, capture, cancel, extend) asociadas a una sesion de pago online.
Live: GET https://aviratopayments.com/external/v1/payment/session/{sessionId}/modifications?webcode={webcode}
Test: GET https://aviratopayments.com/external/v1/test/payment/session/{sessionId}/modifications?webcode={webcode}
Parametros
Parametro
Ubicacion
Tipo
Requerido
Descripcion
sessionId
Path
string
Si
El sessionId de la sesion de pago
webcode
Query
string
Si
Identificador de tu negocio
type
Query
string
No
Filtrar por tipo: refund, capture, cancel, extend
cursor
Query
string
No
Cursor de paginacion
take
Query
integer
No
Resultados por pagina (1-100, por defecto: 20)
order
Query
string
No
Orden: asc o desc (por defecto: asc)
Ejemplo
bash
curl -X GET "https://aviratopayments.com/external/v1/payment/session/SHOP01-EXT-17195000001234/modifications?webcode=SHOP01" \
-H "X-API-KEY: tu_api_key_live"
Referencia del pago original sobre el que se opero
sessionId
Si
Sesion de pago asociada
status
Si
Estado: pending, success, failed
requestedAt
Si
Cuando se solicito la operacion
createdAt
Si
Fecha y hora de creacion del registro
resolvedAt
Si
Cuando se completo (o fallo). null si esta pendiente
amount
Solo refund y capture
Importe de la operacion
reason
Solo refund
Motivo del reembolso
Listar modificaciones de un pago POS
Lista todas las operaciones de modificacion asociadas a un pago POS especifico.
Live: GET https://aviratopayments.com/external/v1/pos/payment/{posPaymentId}/modifications?webcode={webcode}
Test: GET https://aviratopayments.com/external/v1/test/pos/payment/{posPaymentId}/modifications?webcode={webcode}
Parametros
Parametro
Ubicacion
Tipo
Requerido
Descripcion
posPaymentId
Path
string
Si
El posPaymentId del pago POS
webcode
Query
string
Si
Identificador de tu negocio
type
Query
string
No
Filtrar por tipo: refund, capture, cancel, extend
cursor
Query
string
No
Cursor de paginacion
take
Query
integer
No
Resultados por pagina (1-100, por defecto: 20)
order
Query
string
No
Orden: asc o desc (por defecto: asc)
Ejemplo
bash
curl -X GET "https://aviratopayments.com/external/v1/pos/payment/SHOP01-POSX-17195300001234/modifications?webcode=SHOP01" \
-H "X-API-KEY: tu_api_key_live"
Lista todas las operaciones de modificacion de tu negocio, independientemente del pago al que pertenezcan. Permite filtrar por tipo, estado, fecha y texto libre.
Live: GET https://aviratopayments.com/external/v1/modifications?webcode={webcode}
Test: GET https://aviratopayments.com/external/v1/test/modifications?webcode={webcode}
Parametros de query
Parametro
Tipo
Requerido
Descripcion
webcode
string
Si
Identificador de tu negocio
type
string
No
Filtrar por tipo: refund, capture, cancel, extend
status
string
No
Filtrar por estado: pending, success, failed
dateFrom
string
No
Fecha de inicio (formato YYYY-MM-DD)
dateTo
string
No
Fecha de fin (formato YYYY-MM-DD)
search
string
No
Busqueda por texto libre (en referencias, razones, etc.)
cursor
string
No
Cursor de paginacion
take
integer
No
Resultados por pagina (1-100, por defecto: 20)
order
string
No
Orden: asc o desc (por defecto: asc)
Ejemplo
bash
curl -X GET "https://aviratopayments.com/external/v1/modifications?webcode=SHOP01&type=refund&status=success&take=10" \
-H "X-API-KEY: tu_api_key_live"
Este endpoint devuelve modificaciones de todos los pagos (online y POS). Puedes identificar el tipo de pago por la referencia: -PXT- (pago online Live), -PXTT- (pago online Test), -POSX- (POS Live), -POSXT- (POS Test).
Paginacion
Todos los endpoints de listado usan paginacion basada en cursores. Los cursores son cadenas opacas que representan la posicion actual en el conjunto de resultados.
Como funciona
Primera peticion: Llama al endpoint sin parametro cursor. Recibiras los primeros resultados y un meta.cursor
Siguiente pagina: Si meta.hasMore es true, usa el valor de meta.cursor como parametro cursor en la siguiente peticion
Fin: Cuando meta.hasMore es false, no hay mas resultados
Campos de meta
Campo
Descripcion
cursor
Cursor para obtener la siguiente pagina. null si no hay mas
hasMore
true si hay mas resultados disponibles
total
Numero total de registros que coinciden con los filtros
Importante: Los cursores son opacos. No intentes decodificarlos, modificarlos ni construirlos manualmente. Simplemente pasa el valor tal cual lo recibes.
Webhooks
Los webhooks son notificaciones HTTP POST que Avirato Payments envia automaticamente a tu sistema cuando ocurre un evento relevante: un pago se completa, un reembolso se procesa, una captura se confirma, etc.
Por que son importantes
Los webhooks son la forma mas fiable de saber que una operacion se ha completado. A diferencia del redirect (urlOk/urlKo), que depende de que el cliente vuelva a tu pagina:
Los webhooks llegan siempre, incluso si el cliente cierra el navegador
Llegan unos segundos despues de que el procesador confirme la operacion
No dependen del comportamiento del usuario
Recomendacion: Usa los webhooks como fuente principal de confirmacion de operaciones. Usa el redirect y el polling como complementos.
Como configurar tu URL de webhooks
Desde Integraciones > Configuración > URLs de webhooks puedes registrar una URL pública por entorno (Live y Test). Cada URL puede activarse y desactivarse por separado. Recomendamos:
URL HTTPS (no HTTP) con certificado válido.
Endpoint dedicado a Avirato Payments (por ejemplo https://tu-dominio.com/avirato-payments/webhooks) que sepa procesar el formato común que se describe más abajo.
Necesitas tener una API key activa para el entorno antes de configurar su URL. Si no existe, el dashboard te lo indica con un mensaje claro y un código 422.
Importante: solo se envían los webhooks generados a partir del momento en que la URL está configurada y activa. Eventos previos no se reenvían retroactivamente.
Verificación de autenticidad (firma HMAC)
Todos los webhooks live van firmados con HMAC-SHA256 usando el mismo client_secret que se te muestra al crear (o rotar) la API key del entorno. Llegan estas dos cabeceras adicionales:
En Test, si tienes API key test creada, los webhooks de prueba se firman también con su secret. Si no, se envían sin firma para que puedas explorar el formato sin obligación de crear API key test todavía.
Política de reintentos
Cómo funciona en una línea
Cada vez que Avirato Payments te envia un webhook y tu endpoint no responde con HTTP 200, lo reintenta mas tarde. La espera entre cada fallo y el siguiente reintento crece: empieza en 10 minutos y termina en 48 horas. Tras un total de 10 intentos sin éxito Avirato Payments deja de reintentarlo automáticamente.
Cronograma completo
La tabla muestra, para un webhook que falla en cada intento, el momento exacto en el que tu endpoint recibe la siguiente llamada, contado desde que se produjo el evento original (autorización, refund, etc.).
Intento
Qué es
Cuándo lo recibes (desde el evento)
1
Envío inicial
en el momento (≈ 0)
2
1.er reintento
10 min después
3
2.º reintento
30 min después
4
3.er reintento
1 h 10 min después
5
4.º reintento
2 h 40 min después
6
5.º reintento
5 h 40 min después
7
6.º reintento
11 h 40 min después
8
7.º reintento
23 h 40 min después
9
8.º reintento
1 día 23 h 40 min después
10
9.º (y último) reintento
≈ 4 días después (95 h 40 min)
—
a partir de aquí ya no se reintenta automáticamente
En total son 10 intentos (un envío inicial + 9 reintentos) repartidos en una ventana de unos 4 días. El reloj no se reinicia en cada intento: cuanto más tarde respondes correctamente, más se habrán espaciado los siguientes reintentos.
Cómo saber en qué intento vamos
En el dashboard, en Integraciones > Actividad > Webhooks enviados (entorno Live), cada fila del historial muestra:
Intentos: número de intentos consumidos hasta ahora (1 a 10).
Último intento: la fecha y hora del último envío.
HTTP: el código HTTP que devolvió tu endpoint en ese último envío.
Estado: Entregado (success), Pendiente (todavía con reintentos por delante).
Si el endpoint sigue cayendo tras los 10 intentos
Si tras los 10 intentos (≈ 4 días) tu endpoint no ha respondido correctamente ni una sola vez, Avirato Payments deja de reintentarlo automáticamente aunque más tarde repares tu sistema. En ese caso:
Reactiva tu endpoint y verifica que ya responde correctamente con webhooks normales.
Para los eventos que quedaron pendientes, abre Integraciones > Actividad > Webhooks enviados, identifica los webhooks con estado Pendiente y fuerza el reenvío manual con el botón Reenviar. Cada reenvío manual hace una llamada HTTP nueva a tu endpoint con el mismo payload.
Si desactivas o eliminas tu URL de webhooks: los eventos siguen encolándose en Avirato Payments. El cron sigue contando reintentos para cada uno, así que si reactivas la URL dentro de la ventana de ≈ 4 días los pendientes se entregarán automáticamente en el siguiente tick (siempre que aún queden intentos disponibles para ese webhook). Pasada esa ventana los eventos quedan abandonados y no se vuelven a enviar.
Comportamiento del reenvio manual
Si reenvias manualmente un webhook que estaba pendiente de reintentos y el reenvio tiene exito, los reintentos automaticos se detienen — el webhook ya se considera entregado.
Puedes reenviar un webhook que ya fue entregado correctamente. El dashboard te pedira confirmacion antes para evitar duplicados accidentales, pero el reenvio se ejecuta igualmente si lo confirmas.
Fuente de verdad del estado del pago (Live)
En el entorno Live, las notificaciones del procesador tienen la ultima palabra sobre el estado real del pago. Esto significa que un pago puede cambiar de estado despues de que tu sistema lo haya tratado como completado.
Casos tipicos en los que puede llegar un webhook posterior que revierte un exito previo:
Chargeback: el titular reclama el cargo a su banco
Fraude detectado a posteriori: el procesador identifica una transaccion fraudulenta dias despues
Reversion bancaria: el banco emisor revierte la operacion
Correccion del procesador: una notificacion previa contenia datos incompletos o incorrectos
Cuando recibimos uno de estos eventos en Live, actualizamos el estado del pago en nuestro sistema (por ejemplo, de AUTHORISED a FAILED) y te enviamos el webhook correspondiente. Tu integracion debe:
Aceptar webhooks asincronos que cambien el resultado de un pago previamente exitoso
Tratar los webhooks (no la respuesta inmediata ni el redirect) como la referencia para la conciliacion y el estado final
Volver a consultar la API (GET /payment/session/{sessionId}) cuando necesites el ultimo estado conocido
Test vs Live: en Test los webhooks los genera nuestro propio simulador y reflejan unicamente la simulacion que has lanzado. No hay chargebacks ni reverts en Test.
Formato general
Todos los webhooks llegan como POST a tu URL con este formato:
Se envia cuando un titular de tarjeta inicia un contracargo contra un pago. Los contracargos son procesados por el emisor de la tarjeta y pueden tardar dias o semanas en resolverse.
NOTIFICATION_OF_CHARGEBACK — Aviso previo de contracargo
Aviso anticipado de que un contracargo puede estar en camino. No todos los procesadores lo envian. Te permite prepararte antes de que el contracargo formal se procese.
Se envia cuando falla el primer pago (el pago recurrente queda en error) o un cobro periodico que todavia tiene reintentos (sigue active). En este segundo caso incluye retryCount, maxRetries y nextRetryAt.
El ultimo reintento tambien ha fallado. El pago recurrente pasa a paused con statusReason: payment_failed_max_retries y no se cobra mas hasta que lo reactives (con la tarjeta actual o pidiendo una nueva con update-card). En este caso no llega SUBSCRIPTION_FAILED.
En el entorno Test, los webhooks no provienen del procesador de pagos real. Son generados automaticamente por el backend de Avirato Payments inmediatamente despues de completar la operacion simulada.
Diferencias con Live
Aspecto
Live
Test
Quien envia
El procesador de pagos
El backend de Avirato Payments
Cuando llega
Segundos a minutos despues de la operacion
1-3 segundos despues de la respuesta HTTP
Formato
Identico
Identico
Campos
Identicos
Identicos
Reintentos automaticos
Si (backoff exponencial, hasta ≈ 4 dias)
No: el simulador hace un unico envio
Reenvio manual desde el dashboard
Si
Si
Criterio de exito HTTP
HTTP 200
HTTP 200
Lo que debes saber
El formato es exactamente el mismo: Puedes desarrollar tu logica de procesamiento de webhooks en Test y funcionara en Live sin cambios
Llegan para pagos exitosos Y fallidos: Tanto en Live como en Test, recibiras webhooks cuando un pago se rechaza o una operacion falla
URLs independientes por entorno: Los webhooks de Test se envian a la URL configurada para el entorno Test, y los de Live a la URL de Live. Configura ambas desde el panel de webhooks del dashboard
Las referencias usan sufijos Test: Las paymentReference y operationReference contendran los infijos de test (-PXTT-, -RFXT-, etc.)
Criterio de exito simple: Tanto en Live como en Test, basta con que tu endpoint responda HTTP 200 para que el webhook se marque como Entregado. Cualquier otro codigo de estado se considera fallo y activara los reintentos (en Live) o quedara como Fallido en el dashboard (en Test).
Reenvio manual en Test y Live: Desde el panel de webhooks puedes reenviar manualmente cualquier fila. Tanto en Test como en Live, el reenvio utiliza la URL actualmente configurada para ese entorno, no la URL que se uso en el envio original. Si reenvias un webhook que ya aparece como Entregado, el dashboard te pedira confirmacion antes para evitar duplicados accidentales.
Tu endpoint de webhook puede recibir la misma notificacion mas de una vez (por reintentos o duplicados del procesador). Asegurate de que procesar el mismo webhook dos veces no cause problemas: usa paymentReference o refundReference como clave de deduplicacion.
Respuesta rapida
Responde al webhook lo antes posible (idealmente en menos de 5 segundos). Si necesitas hacer procesamiento pesado, encola el trabajo y responde inmediatamente con HTTP 200.
No dependas de un solo canal
Usa los webhooks como canal principal, pero implementa tambien:
Verificacion post-redirect: Cuando el cliente vuelva a urlOk, consulta GET /payment/session/{id} para confirmar
Polling de seguridad: Un proceso periodico que consulte sesiones en estado pending antiguas para detectar pagos completados que no hayas procesado
Manejo de errores
Formato de error estandar
Todas las respuestas de error siguen este formato:
Nota de seguridad: Los errores internos del servidor (5xx) devuelven un mensaje generico ("An error has occurred...") para no exponer detalles de implementacion. El traceId permite al equipo de soporte investigar el error concreto.
Nota sobre entornos: Los codigos de error, formatos y mensajes son identicos en los entornos Live y Test. No hay diferencias en el manejo de errores entre entornos.
Catalogo de codigos de error
Errores de autenticacion y autorizacion (11xxx)
Codigo
HTTP
Descripcion
Accion recomendada
11001
403
API key invalida o no proporcionada
Verifica la cabecera X-API-KEY
11002
403
IP no permitida
Configura tu IP en el dashboard (Integraciones > Configuración > API keys)
11008
403
Acceso denegado al recurso
El webcode no coincide, el pago no pertenece a la External API, o error de entorno
Errores de validacion (12xxx)
Codigo
HTTP
Descripcion
Accion recomendada
12001
400
Parametro requerido faltante o formato invalido
Revisa los campos obligatorios y sus formatos
12002
400
Fecha en formato incorrecto
Usa formato ISO 8601 (ej: 2026-07-15T14:00:00Z)
12006
400
Formato de pais invalido
Usa ISO 3166-1 alpha-2 (ej: ES, FR, DE)
12009
400
Pais no soportado
Consulta con soporte la lista de paises disponibles
Errores de recurso (10xxx)
Codigo
HTTP
Descripcion
Accion recomendada
10404
404
Recurso no encontrado
Verifica que el sessionId o paymentReference sea correcto
Errores de POS (13xxx)
Codigo
HTTP
Descripcion
Accion recomendada
13001
500
Error del proveedor de pagos
Reintenta despues de unos segundos. Si persiste, contacta soporte
13004
502
Error de comunicacion con el terminal
Verifica que el terminal esta encendido y conectado
13005
409
Terminal ocupado
Espera a que termine la transaccion en curso e intenta de nuevo
Conflictos de idempotencia (409)
Estos conflictos no llevan un codigo numerico interno: el mensaje permite distinguirlos del 409 de POS ocupado (codigo 13005).
Caso
HTTP
Mensaje (literal)
Accion recomendada
Misma Idempotency-Key, body distinto
409
Idempotency key reused with a different request body.
Usa una clave nueva o reenvia el mismo body que la peticion original
Misma Idempotency-Key, otro endpoint
409
Idempotency key already used for a different endpoint.
No reutilizar la misma clave entre endpoints distintos
Errores internos (99xxx)
Codigo
HTTP
Descripcion
Accion recomendada
99001
500
Error interno del servidor
Anota el traceId y contacta soporte
Pagos recurrentes
Mensajes propios de /subscriptions (mismo formato de error). Usa el message y el HTTP para decidir; el code es el generico de validacion o de recurso.
Recurso no encontrado (404)
Mensaje
Cuando
Subscription not found
No existe, es de otro webcode o del otro entorno (Live/Test)
Subscription link not found
Igual, para links de pago recurrente
Accion no permitida en el estado actual (400)
Mensaje
Cuando
Only active subscriptions can be paused. Current status: X
pause sobre uno que no esta active
Cancelled subscriptions cannot be reactivated
reactivate o update-card sobre uno cancelado (igual que en el panel)
Cancelled subscriptions cannot be updated
PATCH sobre uno cancelado
Payment link cannot be completed. Current status: X
Cancelar o simular un link que ya no esta pending
Validacion (400)
Mensaje
Como evitarlo
intervalCount must be at least 1
Entero >= 1
billingDay is only allowed when intervalUnit is month
Errores 4xx: No reintentes (el problema esta en la peticion)
Errores 5xx: Reintenta con backoff exponencial (1s, 2s, 4s, 8s...)
409: si es 13005 (terminal ocupado), espera 5-10 segundos y reintenta. Si el mensaje empieza por Idempotency key…, no reintentes a ciegas: corrige la clave o el body de la peticion
Siempre usa Idempotency-Key para que los reintentos sean seguros
Logging
Registra el traceId de las respuestas de error para facilitar la comunicacion con soporte tecnico.
Validacion previa
Valida los datos antes de enviar la peticion para evitar errores 400:
amount.value debe ser un entero positivo (centimos)
amount.currency debe ser exactamente 3 letras mayusculas (EUR, GBP o USD)
webcode no puede estar vacio
URLs (urlOk, urlKo) deben ser URLs validas con protocolo
reason en reembolsos debe ser uno de los 5 valores exactos permitidos
Pagos recurrentes: intervalUnit en day, week, month, year; intervalCount >= 1; billingDay (1-31) solo con month; endAt futura; returnUrl http/https
Ejemplos Completos
Ejemplos de flujos de integracion end-to-end con cURL. Sustituye la API key y el webcode por los tuyos.
Redirige al cliente a la paymentUrl devuelta. El cliente vera la pagina de pago segura y completara la transaccion. Tras pagar sera redirigido a urlOk (exito) o urlKo (fallo/cancelacion).
1.3 Consultar estado del pago
Una vez el cliente ha sido redirigido de vuelta, consulta la sesion para obtener el resultado y el paymentReference:
bash
curl -X GET "https://aviratopayments.com/external/v1/payment/session/SHOP01-EXT-17195000001234?webcode=SHOP01" \
-H "X-API-KEY: tu_api_key_live"
En Test, los webhooks de modificaciones se generan y envian automaticamente tras la peticion, sin necesidad de esperar al procesador.
9. Pago recurrente completo (Test)
Alta mensual de 29,90 EUR, renovacion, cobro fallido con reintentos, pausa y cambio de tarjeta. Todo con la key Test y sin abrir ninguna pagina gracias a los simuladores.
Devuelve un paymentUrl y un nuevo linkId; el pago recurrente pasa a pendingNewCard. Envia el link a tu cliente (o usa simulate-checkout con ese linkId). Al pagar, vuelve a active y recibes SUBSCRIPTION_REACTIVATED (en Live, SUBSCRIPTION_CARD_UPDATED).
Si en lugar de cambiar la tarjeta quieres reintentar con la actual, usa POST /subscriptions/{id}/reactivate. Un pago recurrente cancelado no admite ninguna de las dos acciones.