# Tilopay Portal para Desarrolladores y Agentes AI — texto completo > Documentación técnica de Tilopay (SDK, API, webhooks, pruebas) en Markdown, sin nada normativo dentro de imágenes. Idioma: español. Índice: https://tilopay.com/llms.txt ## Artefactos legibles por máquina - [openapi.json](https://tilopay.com/developers/openapi.json): Spec OpenAPI 3.1 del API de Tilopay, fuente de verdad de endpoints, parámetros y respuestas. - [mcp.json](https://tilopay.com/developers/mcp.json): Catálogo de las herramientas del servidor MCP de Tilopay, con parámetros, salidas y nivel de acceso. - [api-bancario/openapi.json](https://tilopay.com/developers/api-bancario/openapi.json): Spec OpenAPI 3.0.3 del API Bancario (BaaS) de Tilopay, versión 1.0.0, artefacto separado del API de adquirencia. - [skills/index.md](https://tilopay.com/developers/skills/index.md) - [cierre-de-caja/SKILL.md](https://tilopay.com/developers/skills/cierre-de-caja/SKILL.md) - [cobrar-por-whatsapp/SKILL.md](https://tilopay.com/developers/skills/cobrar-por-whatsapp/SKILL.md) - [rechazos-y-recuperacion/SKILL.md](https://tilopay.com/developers/skills/rechazos-y-recuperacion/SKILL.md) - [conciliacion-mensual/SKILL.md](https://tilopay.com/developers/skills/conciliacion-mensual/SKILL.md) - [cfo-de-bolsillo/SKILL.md](https://tilopay.com/developers/skills/cfo-de-bolsillo/SKILL.md) - [catalogo-y-cobros-fijos/SKILL.md](https://tilopay.com/developers/skills/catalogo-y-cobros-fijos/SKILL.md) --- # Autenticación > Cómo obtener el token del API y el token del SDK, cuánto duran y cómo se envían en cada llamada. - kind: api-operation - status: stable - api_version: v1 - last_verified: 2026-08-28 - url: https://tilopay.com/developers/api/autenticacion Todo el API y el SDK viven en un único host: `https://app.tilopay.com`. No hay un host distinto para pruebas — ver [entornos](/developers/entornos). ## Las dos operaciones [#operaciones] | Operación | Ruta | Para qué | |---|---|---| | Token del API | `POST /api/v1/login` | Llamadas servidor a servidor al API | | Token del SDK | `POST /api/v1/loginSdk` | El token que se le pasa a `Tilopay.Init()` | `loginSdk` es el método que el artículo anterior llamaba "GetTokenSdk". Es el mismo. ## Obtener el token del API [#token-api] ```bash curl -X POST https://app.tilopay.com/api/v1/login \ -H "Content-Type: application/json" \ -d '{ "apiuser": "TU_APIUSER", "password": "TU_PASSWORD" }' ``` ### Cuerpo [#cuerpo] Usuario de API del comercio. Contraseña de API del comercio. ### Respuesta [#respuesta] El token que se envía en las llamadas siguientes. Siempre `bearer`. Vigencia del token. El tiempo exacto viene en esta respuesta: no lo asumás desde el cliente. ## Obtener el token del SDK [#token-sdk] ```bash curl -X POST https://app.tilopay.com/api/v1/loginSdk \ -H "Content-Type: application/json" \ -d '{ "apiuser": "TU_APIUSER", "password": "TU_PASSWORD" }' ``` El token resultante es el que se pasa al parámetro `token` de [`Tilopay.Init()`](/developers/sdk/reference/init). ## Vigencia [#vigencia] - **Token del API: 24 horas.** - **Token del SDK: 1 hora.** El valor exacto siempre llega en `expires_in`. Cachealo del lado servidor y renovalo cuando expire. ## Cómo se envía [#envio] ```http Authorization: bearer ``` ## Revocación y límites [#revocacion] - **Los tokens no se pueden revocar.** Si un token se filtra, no hay una operación para invalidarlo: hay que tratar la fuga como un incidente y rotar credenciales con Tilopay. - **No hay límite** de tokens simultáneos por comercio. Podés pedir uno por proceso sin invalidar los anteriores. ## Dónde se obtienen las credenciales [#credenciales] `apiuser`, `password` y `key` se obtienen en el panel del comercio, en `admin.tilopay.com/admin/checkout`. Si no tenés acceso todavía, empezá por [el registro de developer](/developers/registro). Nunca pongas `apiuser` ni `password` en el navegador. El login corre en tu servidor; al navegador solo baja el token del SDK. --- # Hosted payment page > Camino de integración en el que el cliente paga en una página alojada por Tilopay y tu servidor recibe el resultado. - kind: guide - status: stable - api_version: v1 - last_verified: 2026-08-28 - url: https://tilopay.com/developers/hosted-payment-page ## Qué es [#que-es] Tu servidor le pide una URL de pago al API, redirige al cliente a esa página de Tilopay y recibe el resultado en tu callback URL. Los datos de tarjeta se digitan en una página de Tilopay: **vos nunca ves un número de tarjeta** y tu servidor queda fuera de ese flujo, lo que reduce al mínimo tu alcance PCI. La operación de este camino está en [API · processPayment](/developers/api/hosted-payment-page/process-payment). ## Diferencia con un link de pago [#diferencia-link] - **Hosted payment page**: tu servidor pide una URL de pago por API y redirige al cliente a ella. Es ideal para flujos de checkout integrados en tu sitio o app. - **Link de pago**: es una URL reusable que creás por API o desde el panel y compartís por mensaje, correo, redes o QR. El cliente paga cuando quiera; no necesitás redirigirlo desde tu flujo. - En resumen: HPP para checkout integrado y transacciones puntuales; link de pago para cobros compartidos y sin desarrollo de front. ## Para quién es [#para-quien] Para equipos que cobran con código propio pero prefieren no construir ni mantener el formulario de tarjeta. Lo que necesitás es backend: pedir la URL y atender el callback. ## Requisitos antes de empezar [#requisitos] 1. **Credenciales propias.** No hay credenciales de sandbox compartidas: cada desarrollador obtiene las suyas en [registro de developer](/developers/registro). 2. **Autenticación del API.** Ver [autenticación](/developers/api/autenticacion). 3. **Una URL de callback tuya** que pueda recibir el resultado de la transacción. ## Cómo confirmar el estado de un cobro [#confirmacion] El resultado que llega a tu callback no es la única señal disponible, y no todas las respuestas de error viajan con un HTTP 4xx: - Leé [cómo leer una respuesta de error](/developers/api/procesos-operativos/errors) antes de decidir un éxito. - Configurá [webhooks](/developers/api/webhooks) para los eventos que te interesen. - Si una llamada falla sin respuesta clara, resolvé el estado con [reintentos seguros](/developers/reintentos-seguros). ## Entornos [#entornos] Pruebas y producción comparten el mismo host. Ver [entornos](/developers/entornos) antes de cobrar de verdad. ## Cumplimiento [#cumplimiento] Es el camino que menos expone a tu infraestructura junto con el de sin código. Confirmá con tu equipo de cumplimiento el alcance que aplica a tu comercio. ## Si preferís el formulario en tu sitio [#alternativa] Usá el [SDK JavaScript](/developers/sdk): el diseño es tuyo y los datos siguen sin pasar por tu servidor. --- # Entornos: pruebas y producción > Pruebas y producción comparten host. El modo se cambia desde la cuenta y se verifica con el campo test de Init(). - kind: concept - status: stable - api_version: v1 - last_verified: 2026-08-28 - url: https://tilopay.com/developers/entornos **No existe un host de sandbox.** Pruebas y producción usan el mismo host: `app.tilopay.com`. La URL no te dice en qué modo estás. ## Cómo se cambia de modo [#como-se-cambia] El modo se alterna **desde la cuenta en el portal de Tilopay**, no desde la integración. No hay un parámetro, un encabezado ni una URL alterna que lo cambie desde el código. ## Cómo se verifica [#como-se-verifica] `Tilopay.Init()` devuelve un campo **`test`**: | Valor | Significado | |---|---| | `0` | Producción | | `1` | Pruebas | Esa es la única señal disponible en tiempo de ejecución. Leela y mostrala en tu propio checkout mientras desarrollás. ## El riesgo real [#riesgo] Como el host es el mismo, un integrador puede creer que está probando y estar en producción, cobrando de verdad. **Verificá `test` antes de asumir el modo.** Si tu integración va a mover dinero, hacé que un `test: 0` inesperado falle ruidosamente en tus ambientes de desarrollo. ## Tarjetas de prueba [#tarjetas] En modo de pruebas se cobra con las [tarjetas de prueba](/developers/tarjetas-de-prueba): ahí está el número, la marca, el resultado esperado y si abre la pantalla de challenge 3DS. --- # Tarjetas de prueba > Las 27 tarjetas del ambiente de pruebas de Tilopay, con el resultado esperado y la fricción 3DS de cada una. - kind: guide - status: stable - api_version: v1 - last_verified: 2026-09-03 - url: https://tilopay.com/developers/tarjetas-de-prueba Estas tarjetas sólo funcionan cuando la cuenta está en **modo de pruebas**. El modo se cambia desde la cuenta y se verifica con el campo `test` que devuelve `Init()`: ver [entornos y pruebas](/developers/entornos). ## Cómo se usan [#uso] | Dato | Qué se ingresa | | --- | --- | | Fecha de vencimiento | Cualquiera en el futuro | | CVV | Cualquiera | | Código de la pantalla de challenge 3DS | `3ds2` | En la pantalla de challenge 3DS el código a ingresar es **`3ds2`**. No hay otro código ni se envía por SMS en pruebas. ## Tarjetas [#tarjetas] La marca se deriva del prefijo: `4` Visa, `51`–`55` Mastercard, `34` American Express. | Número | Marca | Resultado esperado | Fricción | | --- | --- | --- | --- | | `4111111111111111` | Visa | Aprobada | Sin fricción | | `4012000000020089` | Visa | Aprobada | Sin fricción | | `4012000000020006` | Visa | Aprobada | Sin fricción | | `4012010000020088` | Visa | Aprobada | Sin fricción | | `5100270000000072` | Mastercard | Aprobada | Sin fricción | | `5100270000000031` | Mastercard | Aprobada | Sin fricción | | `341111000000009` | American Express | Aprobada | Sin fricción | | `341111000000011` | American Express | Aprobada | Sin fricción | | `341112000000001` | American Express | Aprobada | Sin fricción | | `341111000000037` | American Express | Aprobada | Sin fricción | | `341112000008012` | American Express | Aprobada | Sin fricción | | `4012000000020071` | Visa | Aprobada | Challenge 3DS | | `4012010000020070` | Visa | Aprobada | Challenge 3DS | | `4012010000020005` | Visa | Aprobada | Challenge 3DS | | `5100270000000023` | Mastercard | Aprobada | Challenge 3DS | | `5100271000000120` | Mastercard | Aprobada | Challenge 3DS | | `4112613451591116` | Visa | Fondos insuficientes | Challenge 3DS | | `4523080346468525` | Visa | CVV incorrecto | Sin fricción | | `4549179990476733` | Visa | Tarjeta restringida | Sin fricción | | `4012000000020121` | Visa | Rechazada | Sin fricción | | `4111111111119999` | Visa | Rechazada | Sin fricción | | `4111111111110000` | Visa | Rechazada | Sin fricción | | `5100270000000056` | Mastercard | Rechazada | Sin fricción | | `5111111111113333` | Mastercard | Rechazada | Sin fricción | | `4666666666662222` | Visa | Rechazada | Sin fricción | | `5555666666662222` | Mastercard | Rechazada | Sin fricción | | `5100270000000098` | Mastercard | Rechazada | Challenge 3DS | Las tarjetas con fricción **Challenge 3DS** abren la pantalla de autenticación; las de **Sin fricción** resuelven sin pasar por ella. El resultado esperado es el mismo cada vez: la tarjeta determina la respuesta, no el monto. --- # Reintentos seguros y orderNumber > El API no es idempotente. Qué hacer exactamente cuando una llamada de pago se cae por timeout. - kind: concept - status: stable - api_version: v1 - last_verified: 2026-08-28 - url: https://tilopay.com/developers/reintentos-seguros **El API de Tilopay no es idempotente.** No existe una llave de idempotencia ni un reintento que devuelva la transacción original. Si venís de otros procesadores, este es el supuesto que tenés que desarmar antes de escribir código. ## `orderNumber` es único para siempre [#ordernumber] `orderNumber` es único por comercio **a lo largo de toda su operación**, para siempre. No se reinicia por día, por mes ni por temporada. Si se repite, **la nueva transacción se rechaza** con la respuesta **"Transacción duplicada"**. No devuelve la transacción original: devuelve un rechazo. ## El problema del timeout [#timeout] Cuando una llamada de pago se cae por red o por timeout, no sabés si la transacción se creó o no. Y ninguna de las dos salidas intuitivas sirve: | Qué harías | Qué pasa | |---|---| | Reintentar con el mismo `orderNumber` | Rechazo por duplicado, incluso si la primera sí pasó | | Reintentar con un `orderNumber` nuevo | Riesgo de doble cobro | **Ante un timeout de red no hay reintento seguro.** ## Qué hacer entonces [#que-hacer] Consultá el estado antes de decidir: 1. Llamá a `POST /api/v1/consult` con el `orderNumber` original. 2. Si la transacción existe, usá su resultado. No reintentés. 3. Si no existe, ahí sí podés reintentar — y podés reusar el mismo `orderNumber`, porque no se consumió. ```text pago → timeout │ └─→ consult(orderNumber original) ├─ existe → usar ese resultado └─ no existe → reintentar ``` ## Consecuencias de diseño [#diseno] - Generá el `orderNumber` en tu sistema **antes** de llamar al pago y persistilo. Si lo generás al vuelo, después de un timeout no tenés con qué consultar. - Nunca derives el `orderNumber` de algo que se pueda repetir (número de carrito reciclado, timestamp truncado, contador reiniciable). - Un "Transacción duplicada" no significa que el cobro falló: significa que ese `orderNumber` ya se usó. Consultá antes de mostrarle un error al cliente. --- # Cómo leer una respuesta de error > Un HTTP 200 no significa éxito. Dónde viene el rechazo del emisor y cómo escribir el manejo de errores. - kind: concept - status: stable - api_version: v1 - last_verified: 2026-08-28 - url: https://tilopay.com/developers/api/procesos-operativos/errors ## El rechazo del emisor [#rechazo] Cuando el emisor rechaza una transacción, la respuesta trae dos campos: El código de rechazo del emisor. El texto del rechazo. ## Un HTTP 200 no significa éxito [#estado-http] **No hay un estándar definido de cuándo el API responde HTTP 4xx y cuándo responde HTTP 200 con el error en el cuerpo.** Conviven las dos formas, y hay **cuatro envolturas distintas de error según el endpoint**. Consecuencia práctica: tu manejo de errores tiene que mirar el cuerpo siempre, no solo el código de estado, y tolerar más de una forma de cuerpo. ## Cómo escribir el manejo de errores [#como-manejar] - Tratá `code` y `description` como datos para registrar y mostrar, no como una enumeración sobre la que ramificar. - No hagas `if (status === 200) éxito`. Verificá el cuerpo. - Guardá la respuesta cruda de cada rechazo: es lo que te permite reconstruir el patrón de rechazos de tu comercio. - Para decidir el estado real de una transacción después de un fallo, usá [reintentos seguros](/developers/reintentos-seguros). --- # API · Cuatro caminos de integración > Los cuatro caminos para cobrar con Tilopay y la diferencia que decide cuál te conviene: por dónde viajan los datos de tarjeta. - kind: concept - status: stable - api_version: v1 - last_verified: 2026-10-10 - url: https://tilopay.com/developers/api/caminos-de-integracion ## Cuatro caminos [#cuatro-caminos] Hay cuatro formas de cobrar con Tilopay. Cambian en dos cosas: cuánto construís vos y dónde aparecen los campos de tarjeta. Elegí una y seguí su guía; todas empiezan con tus credenciales de sandbox, que se piden en el [registro de developer](/developers/registro). ### 1 · Sin código [#sin-codigo] Extensiones y plugins para plataformas existentes. No escribís una línea de código. [Ver camino](/developers/sin-codigo) ### 2 · Hosted payment page [#hosted-payment-page] Tu servidor pide una URL al API, redirige al cliente a esa página de Tilopay y recibe el resultado en tu callback URL. [Ver camino](/developers/hosted-payment-page) ### 3 · SDK JavaScript [#sdk-javascript] Los campos de tarjeta viven en tu página; el SDK los captura y los manda directo a Tilopay. [Ver camino](/developers/sdk) ### 4 · API servidor a servidor [#servidor-a-servidor] Acceso restringido: servicio exclusivo para comercios con certificación PCI. La URL se provisiona por comercio, no es pública. [Requisitos y solicitud](/developers/server-to-server) ## Cómo elegir [#como-elegir] Elegir mal sale caro. La diferencia que más importa es por dónde viajan los datos de tarjeta. | Camino | Quién construye el formulario | Por dónde viajan los datos de tarjeta | Qué se necesita saber | Implicación de cumplimiento | | --- | --- | --- | --- | --- | | 1 · Sin código | La plataforma | Nunca pasan por tus sistemas | Configuración en el panel de la plataforma | Consultá con tu equipo de cumplimiento | | 2 · Hosted payment page | Tilopay | Tu cliente los digita en una página segura de Tilopay; vos nunca ves un número de tarjeta | Backend: pedir la URL y recibir el callback | Consultá con tu equipo de cumplimiento | | 3 · SDK JavaScript | Tu sitio | Se digitan en tu página pero viajan del navegador directo a Tilopay; no pasan por tu servidor | Frontend con JavaScript, más backend para credenciales | Consultá con tu equipo de cumplimiento | | 4 · Servidor a servidor (acceso restringido) | Tu sitio | Los datos de tarjeta pasan por tu servidor | Requiere tu certificación PCI y URL provisionada por Tilopay | Consultá con tu equipo de cumplimiento | El camino 4 no es de autoservicio: es exclusivo para comercios con certificación PCI y la URL se provisiona individualmente. Además es el único que mete a tu servidor dentro del alcance de PCI DSS. Los caminos 2 y 3 evitan ese costo y podés empezarlos hoy. ## Después de elegir [#despues-de-elegir] Con el camino elegido, seguí con [convenciones de las respuestas](/developers/api/convenciones) para saber cómo vienen tipados los montos, y con [cómo leer una respuesta de error](/developers/api/procesos-operativos/errors) antes de poner el código en producción. --- # API · Convenciones de las respuestas > Cómo vienen tipados los montos, dónde hay JSON dentro de una cadena y por qué la misma entidad cambia de forma entre consultar uno y listar. - kind: concept - status: stable - api_version: v1 - last_verified: 2026-09-02 - url: https://tilopay.com/developers/api/convenciones Las respuestas del API de adquirencia tienen tres detalles que no se deducen leyendo cada operación por separado y que rompen integraciones tipadas. Están acá porque aplican a varias operaciones a la vez. Para el manejo de errores, ver [cómo leer una respuesta de error](/developers/api/procesos-operativos/errors). ## Los montos vienen como cadena, no como número [#montos-cadena] Los montos, descuentos e importes se serializan como cadena: `"discount": "40.00"`, `"amount": "0.00"`, `"first_amount": "0.00"`, `"amount_max_daily": "1000.00"`. Cualquier deserialización tipada que declare esos campos como número falla. Declaralos como cadena y convertilos vos, con el tipo decimal de tu lenguaje, no con punto flotante. Aparece, entre otras, en [obtener un cupón](/developers/api/recurrentes/cupones/get-coupon), [listar cupones](/developers/api/recurrentes/cupones/get-coupons), [listar planes](/developers/api/recurrentes/planes/get-plans) y [pagos de suscriptor](/developers/api/recurrentes/suscriptores/suscriptor-payments). ## Hay un JSON dentro de una cadena [#doble-encoding] En [pagos de suscriptor](/developers/api/recurrentes/suscriptores/suscriptor-payments), el campo `data` de cada pago **no es un objeto: es una cadena que contiene JSON**. ```json "data": "{\"first\":1,\"expire\":\"2024-12-28T19:05:29.572648Z\",\"amount\":0,\"activeAmount\":0,\"originalAmount\":0,\"key\":\"XXXX-XXXX-XXXX-XXXX-XXXX\"}" ``` Hay que deserializar dos veces: primero la respuesta, después el contenido de `data`. Tratá esa segunda deserialización como puede fallar cualquier entrada externa: envolvela y registrá la cadena cruda si no parsea. ## La misma entidad cambia de forma entre "obtener uno" y "listar" [#uno-vs-lista] No es un descuido de la documentación: las dos operaciones devuelven formas distintas del mismo cupón, y hay que mapearlas por separado. | | [`getCoupon`](/developers/api/recurrentes/cupones/get-coupon) (uno) | [`getRepeatCoupons`](/developers/api/recurrentes/cupones/get-coupons) (lista) | | --- | --- | --- | | Fecha de creación | `created_at`, formato ISO | `create`, formato `Y-m-d H:i:s` | | Otros campos | incluye `recurrent_id`, `updated_at` y `deleted_at` | no los incluye | Lo mismo pasa en [pagos de suscriptor](/developers/api/recurrentes/suscriptores/suscriptor-payments), que también usa `create` con formato `Y-m-d H:i:s`. ## Dos formas de decir "no configurado" [#no-configurado] En [listar planes](/developers/api/recurrentes/planes/get-plans), los campos de webhook de un plan vienen como cadena vacía cuando no están configurados, mientras que `return_url` viene como `null`. Son dos representaciones del mismo estado en el mismo objeto: al verificar si un webhook está configurado, tratá la cadena vacía y `null` como el mismo caso. --- # Obtener token del API > Operación de login del API: devuelve el token bearer que firma el resto de las llamadas. - kind: api-operation - status: stable - api_version: v1 - last_verified: 2026-08-29 - url: https://tilopay.com/developers/api/autenticacion/token-api ```http POST /api/v1/login ``` ## Qué hace [#que-hace] Devuelve el token de seguridad necesario para consumir los servicios del API. El usuario y la contraseña de API se obtienen en [Admin · Tilopay Checkout](https://admin.tilopay.com/admin/checkout). ## Autenticación [#autenticacion] No requiere token: es la operación que lo emite. Ver [autenticación](/developers/api/autenticacion). ## Parámetros [#parametros] Usuario de API del comercio, obtenido en Admin · Tilopay Checkout. Contraseña de API del comercio, obtenida en Admin · Tilopay Checkout. ## Ejemplo de request [#request] Los valores `<...>` son marcadores: reemplazalos por tus credenciales y datos. ```json { "apiuser": "", "password": "" } ``` ## Respuesta [#respuesta] ```json { "access_token": "", "token_type": "bearer", "expires_in": 86400 } ``` Para interpretar una respuesta que no es de éxito, ver [cómo leer una respuesta de error](/developers/api/procesos-operativos/errors). --- # Hosted payment page > Parámetros, ejemplo de request y respuesta de processPayment, la operación que abre el formulario de pago. - kind: api-operation - status: stable - api_version: v1 - last_verified: 2026-08-29 - url: https://tilopay.com/developers/api/hosted-payment-page/process-payment ```http POST /api/v1/processPayment ``` ## Qué hace [#que-hace] Devuelve la URL del formulario de pago para una compra. ## Autenticación [#autenticacion] Requiere el token bearer del API en el header `Authorization` — ver [autenticación](/developers/api/autenticacion). ## Parámetros [#parametros] Sitio donde esperás la respuesta de la transacción, por ejemplo `mywebsite.com`. Debe soportar el método **GET**. Ejemplo de respuesta al redirect: `mywebsite.com?code=1&description=Transaction%20is%20approved.&auth=123456&order=TPYS-881WROIBQA1405468&tpt=4300&crd=&tilopay-transaction=4300&OrderHash=b02927cb...&returnData=Tilopay-dataReturn123456789&form_update=ok`. Si `code = 1` la transacción está aprobada; en cualquier otro caso, rechazada. `OrderHash` es un string único por transacción: para usarlo del lado del comercio hay que escribir a `soporte@tilopay.com` y pedir las instrucciones. Llave relacionada con el cliente. Se obtiene en Admin · Tilopay Checkout. Monto de la compra. Moneda de la compra en formato ISO, por ejemplo USD, CRC, GTQ. Número de orden, puede ser alfanumérico. Captura y autoriza: 1 sí, 0 no. Nombre. Apellidos. Dirección. Dirección 2. Ciudad. Estado en formato ISO, por ejemplo CR-SJ (San José, Costa Rica) o US-CA (California, EE. UU.). Código postal. País en código ISO Alpha-2, por ejemplo CR (Costa Rica), US (EE. UU.) o GT (Guatemala). Teléfono. Correo del comprador. Nombre. Apellidos. Dirección. Dirección 2. Ciudad. Estado en formato ISO, por ejemplo CR-SJ (San José, Costa Rica) o US-CA (California, EE. UU.). Código postal. País en código ISO Alpha-2, por ejemplo CR (Costa Rica), US (EE. UU.) o GT (Guatemala). Teléfono. 1 para forzar que el cliente guarde la tarjeta en Tilopay, 0 para no. Nombre de la plataforma donde se genera la transacción. Valor que Tilopay devuelve en la respuesta final. Se recomienda enviar un string en base 64. Solo se usa al implementar la verificación de hash. Valores posibles [V1, V2]; por defecto V1. Enviar como valor "v2". ## Ejemplo de request [#request] Los valores `<...>` son marcadores: reemplazalos por tus credenciales y datos. ```json { "redirect": "https://www.urlToRedirect.com", "key": "", "amount": "1.00", "currency": "USD", "orderNumber": "1212122", "capture": "1", "billToFirstName": "DEMO", "billToLastName": "DEMO", "billToAddress": "San Jose", "billToAddress2": "Catedral", "billToCity": "JS", "billToState": "SJ", "billToZipPostCode": "10061", "billToCountry": "CR", "billToTelephone": "88888888", "billToEmail": "cliente@ejemplo.com", "shipToFirstName": "DEMO", "shipToLastName": "DEMO", "shipToAddress": "San Jose", "shipToAddress2": "Catedral", "shipToCity": "JS", "shipToState": "SJ", "shipToZipPostCode": "10061", "shipToCountry": "CR", "shipToTelephone": "88888888", "subscription": "0", "platform": "api", "returnData": "dXNlcl9pZD0xMg==", "hashVersion": "V2", "token_version": "v2" } ``` ## Respuesta [#respuesta] ```json { "type": "100", "html": "Use url redirect", "url": "https://secure.tilopay.com/htmls/1212122_574572148file.html" } ``` Para interpretar una respuesta que no es de éxito, ver [cómo leer una respuesta de error](/developers/api/procesos-operativos/errors). --- # Servidor a servidor > Servicio exclusivo para comercios con certificación PCI. La URL se provisiona por comercio: no es autoservicio. - kind: guide - status: stable - api_version: v1 - last_verified: 2026-08-28 - url: https://tilopay.com/developers/server-to-server **Acceso restringido. No es un camino de autoservicio.** No podés empezar esta integración hoy por tu cuenta: requiere que tu empresa tenga certificación PCI y una URL provisionada individualmente por Tilopay. ## Qué es [#que-es] El camino en el que los datos de tarjeta pasan por tu servidor y este los envía al API de Tilopay. ## Para quién es [#para-quien] - Es un **servicio exclusivo para comercios que cuentan con certificación PCI**. - La **URL es personalizada por comercio**, con una llave propia. **No es una URL pública.** Por eso los ejemplos de esta página no traen una URL real: el `Host` y la llave del proxy se entregan a cada comercio aprobado. ## Requisitos [#requisitos] 1. Certificación PCI vigente de tu empresa. 2. Cuenta Tilopay activa. 3. Solicitud aprobada, con la URL y la llave provisionadas por Tilopay para tu comercio. ## Cómo se solicita [#solicitud] Escribí a `soporte@tilopay.com` con el nombre de tu comercio y el estado de tu certificación PCI. La URL y la llave se entregan directamente al comercio aprobado. ## Referencia de la petición [#referencia] El `Host` y el header `tx-proxy-key` los entrega Tilopay a cada comercio aprobado. No hay una URL pública: los ejemplos usan marcadores. ```http POST / HTTP/1.1 Host: url provided by tilopay ``` ### Encabezados [#encabezados] `bearer {token del API}` — ver [autenticación](/developers/api/autenticacion). Llave del proxy de transacciones, provista por Tilopay. ### Parámetros [#parametros] Llave relacionada con el comercio (obligatorio). Número de tarjeta (obligatorio). Código de seguridad (obligatorio). Fecha de expiración en formato mesAño, por ejemplo `1023` (obligatorio). Nombre del tarjetahabiente (requerido). Apellidos del tarjetahabiente (requerido). Teléfono del cliente (requerido). Correo del cliente (obligatorio). Dirección del cliente (requerido). Ciudad del cliente (requerido). Estado en formato ISO, por ejemplo `CR-SJ` (San José, Costa Rica) o `US-CA` (California, EEUU) (requerido). Código postal (requerido). País en código ISO Alpha-2, por ejemplo `CR`, `US`, `GT` (requerido). Monto de la compra (obligatorio). Moneda en formato ISO, por ejemplo `USD`, `CRC`, `GTQ` (obligatorio). Número de orden (obligatorio). `1` captura y autoriza, `0` solo autoriza (obligatorio). URL de respuesta (obligatorio). Los campos `shipTo*` (`shipToFirstName`, `shipToLastName`, `shipToAddress`, `shipToAddress2`, `shipToCity`, `shipToState`, `shipToZipPostCode`, `shipToCountry`, `shipToTelephone`) aparecen en los ejemplos de la colección como datos de envío. ### Petición [#peticion] ```json { "key": "key", "card": "card PAN", "cvv": "CVV Number", "expire": "1023", "name": "firstname", "lastname": "lastname", "phone": "88888888", "email": "email@user.com", "address": "user address", "city": "city", "state": "state", "zipcode": "zipcode", "country": "country", "shipToFirstName": "Nombre", "shipToLastName": "Apellido", "shipToAddress": "San Jose", "shipToAddress2": "Escazu", "shipToCity": "San Jose", "shipToState": "SJ", "shipToZipPostCode": "10101", "shipToCountry": "CR", "shipToTelephone": "88778877", "amount": "amount", "currency": "currency code", "orderNumber": "Order Number", "capture": 1, "redirect": "url to redirect" } ``` La colección incluye dos ejemplos, **con 3DS** y **sin 3DS**, con el mismo cuerpo de petición. ### Respuesta [#respuesta] ```json { "code": "1", "description": "Transaccion aprobada", "auth": "123456", "orderNumber": "12345", "urlRedirect": "", "error": "" } ``` Cuando la transacción requiere autenticación 3DS, la respuesta trae la URL en `urlRedirect`; ahí es donde se envía al tarjetahabiente. Para interpretar `code`, `description` y `error`, ver [convenciones de las respuestas](/developers/api/convenciones) y [cómo leer una respuesta de error](/developers/api/procesos-operativos/errors). ## Alternativas sin certificación PCI [#alternativas] Si no tenés certificación PCI, estos caminos evitan por completo ese alcance: - [Hosted payment page](/developers/hosted-payment-page) — Tilopay hospeda el formulario. - [SDK JavaScript](/developers/sdk) — el formulario vive en tu página, pero los datos viajan del navegador directo a Tilopay. - [Sin código](/developers/sin-codigo) — plugin o plataforma ya integrada. --- # Links de pago > Operaciones de links de pago del API de Tilopay, con parámetros y ejemplos. - kind: api-index - status: stable - api_version: v1 - last_verified: 2026-08-29 - url: https://tilopay.com/developers/api/links-de-pago ## Operaciones [#operaciones] - [Crear link de pago](/developers/api/links-de-pago/create-link-payment) - [Detalle de un link de pago](/developers/api/links-de-pago/detail-link-payment) - [Eliminar un link de pago](/developers/api/links-de-pago/delete-link-payment) - [Listar links de pago](/developers/api/links-de-pago/payment-item-list) - [Obtener un link de pago por id](/developers/api/links-de-pago/payment-by-id) Todas las operaciones viven en `https://app.tilopay.com` y, salvo las de login, requieren el token del API — ver [autenticación](/developers/api/autenticacion). --- # API · Crear link de pago > Creación de links de pago por API, con callback y webhook de respuesta. - kind: api-operation - status: stable - api_version: v1 - last_verified: 2026-08-29 - url: https://tilopay.com/developers/api/links-de-pago/create-link-payment ```http POST /api/v1/createLinkPayment ``` ## Qué hace [#que-hace] Crea un link de pago con monto, moneda y comportamiento de uso. ## Autenticación [#autenticacion] Requiere el token bearer del API en el header `Authorization` — ver [autenticación](/developers/api/autenticacion). ## Parámetros [#parametros] Key de la integración Tilopay. Monto para el link de pago. Código de moneda en formato ISO 4217. Referencia del link de pago. Tipo de link: 0 ilimitado, 1 de un solo uso. Descripción del pago. Nombre del cliente, aplica solo cuando type es 1. Campo opcional. URL, por método **GET**, a la que se redirige con la respuesta al completar el pago. Ejemplo de los datos enviados: `code=Val&description=Val&auth=Val&tilopayLinkId=Val&orderNumber=Val&tilopayOrderId=Val&creditCardToken=Val&creditCardBrand=Val&last4CreditCardNumber=Val&orderHash=Val` Campo opcional. URL para enviar el webhook de respuesta al completar el pago. Debe ser de método **POST** para que reciba los datos. Ejemplo de los datos enviados: ```json { "code": "1", "codeDescription": "Aprobada", "auth": "123456", "tilopayLinkId": 54421, "orderNumber": "TPT123", "tilopayOrderId": 12233, "creditCardToken": "41111******11111", "creditCardBrand": "Visa", "last4CreditCardNumber": "1111", "linkDescription": "Descripcion del link de pago", "orderHash": "" } ``` ## Ejemplo de request [#request] Los valores `<...>` son marcadores: reemplazalos por tus credenciales y datos. ```json { "key": "", "amount": "10", "currency": "USD", "reference": "123456", "type": 0, "description": "Description", "client": "Client name", "callback_url": "", "webhook_url": "" } ``` ## Respuesta [#respuesta] ```json { "type": "200", "message": "Success", "url": "https://app.tilopay.com/link/MjMwMjQ=", "id": 1 } ``` Para interpretar una respuesta que no es de éxito, ver [cómo leer una respuesta de error](/developers/api/procesos-operativos/errors). --- # API · Detalle de un link de pago > Detalle de un link de pago y sus pagos, consultado por id. - kind: api-operation - status: stable - api_version: v1 - last_verified: 2026-08-29 - url: https://tilopay.com/developers/api/links-de-pago/detail-link-payment ```http GET /api/v1/getDetailLinkPayment/{link_payment_id}/{api_key} ``` ## Qué hace [#que-hace] Devuelve el detalle de un link de pago y sus pagos asociados. No lleva cuerpo: los datos van en la ruta. ## Autenticación [#autenticacion] Requiere el token bearer del API en el header `Authorization` — ver [autenticación](/developers/api/autenticacion). ## Parámetros [#parametros] Parámetros de ruta, en el orden en que aparecen en la URL: Id del link de pago a consultar. Api Key del comercio. ## Respuesta [#respuesta] ```json { "type": "200", "message": "Success", "detail": { "id": 6201, "amount": "45.00", "currency": "USD", "reference": "Producto de prueba 1 TP-Shop", "client": "NA", "type": "Unlimited", "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", "callback_url": null, "create": "2022-10-24 08:45:14" }, "payments": [] } ``` Para interpretar una respuesta que no es de éxito, ver [cómo leer una respuesta de error](/developers/api/procesos-operativos/errors). --- # API · Eliminar un link de pago > Eliminación de un link de pago por id. - kind: api-operation - status: stable - api_version: v1 - last_verified: 2026-08-29 - url: https://tilopay.com/developers/api/links-de-pago/delete-link-payment ```http POST /api/v1/deleteLinkPayment ``` ## Qué hace [#que-hace] Elimina un link de pago existente. ## Autenticación [#autenticacion] Requiere el token bearer del API en el header `Authorization` — ver [autenticación](/developers/api/autenticacion). ## Parámetros [#parametros] Key de la integración Tilopay. Id del link de pago. ## Ejemplo de request [#request] Los valores `<...>` son marcadores: reemplazalos por tus credenciales y datos. ```json { "key": "", "id": "35" } ``` ## Respuesta [#respuesta] ```json { "type": "200", "status": 1, "message": "Success" } ``` Para interpretar una respuesta que no es de éxito, ver [cómo leer una respuesta de error](/developers/api/procesos-operativos/errors). --- # API · Listar links de pago > Listado paginado de los links de pago del comercio. - kind: api-operation - status: stable - api_version: v1 - last_verified: 2026-08-29 - url: https://tilopay.com/developers/api/links-de-pago/payment-item-list ```http GET /api/v1/getLinkPaymentList/{api_key}/{limit} ``` ## Qué hace [#que-hace] Devuelve la lista paginada de links de pago del comercio. No lleva cuerpo: los datos van en la ruta. ## Autenticación [#autenticacion] Requiere el token bearer del API en el header `Authorization` — ver [autenticación](/developers/api/autenticacion). ## Parámetros [#parametros] Parámetros de ruta, en el orden en que aparecen en la URL: Api Key del comercio. Cantidad de registros por página. ## Respuesta [#respuesta] ```json { "type": "200", "message": "Success", "data": { "current_page": 1, "first_page_url": "http://app.tilopay.com/api/v1/getLinkPaymentList//10?page=1", "from": 1, "last_page": 2, "last_page_url": "http://app.tilopay.com/api/v1/getLinkPaymentList//10?page=2", "next_page_url": "http://app.tilopay.com/api/v1/getLinkPaymentList//10?page=2", "path": "http://app.tilopay.com/api/v1/getLinkPaymentList//10", "per_page": 10, "prev_page_url": null, "to": 10, "total": 16, "payment_link": [ { "id": 1, "amount": "45.00", "currency": "USD", "reference": "Producto de prueba 1 TP-Shop", "url": "https://admin.tilopay.com/link/3dNjE2MA3sdd==", "callback_url": null, "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", "times_used": null, "picture": "https://storage.googleapis.com/tilo-uploads/items/51087219_.png", "create": "2022-10-24 08:45:14" }, { "id": 2, "amount": "35.00", "currency": "USD", "reference": "Producto de prueba 2", "url": "https://admin.tilopay.com/link/dwNjE2see3MA==", "callback_url": null, "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", "times_used": null, "picture": "https://storage.googleapis.com/tilo-uploads/items/64156766_.png", "create": "2022-10-24 08:45:14" }, { "id": 3, "amount": "45.00", "currency": "USD", "reference": "Producto de prueba 3", "url": "https://admin.tilopay.com/link/f4NjE2MwsdA==", "callback_url": null, "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", "times_used": null, "picture": "https://storage.googleapis.com/tilo-uploads/items/88435879_.png", "create": "2022-10-24 08:45:14" }, { "id": 4, "amount": "45.00", "currency": "USD", "reference": "test", "url": "https://admin.tilopay.com/link/ceNjE2sxw2MA==", "callback_url": null, "description": "ddd", "times_used": null, "picture": "https://storage.googleapis.com/tilo-uploads/items/37716065_.png", "create": "2022-10-24 08:45:14" }, { "id": 5, "amount": "45.00", "currency": "USD", "reference": "test", "url": "https://admin.tilopay.com/link/cweNjE2Mfd5A==", "callback_url": null, "description": "ddd", "times_used": null, "picture": "https://storage.googleapis.com/tilo-uploads/items/37716065_.png", "create": "2022-10-24 08:45:14" }, { "id": 6, "amount": "45.00", "currency": "USD", "reference": "test", "url": "https://admin.tilopay.com/link/ce3NjE2fg5eMA==", "callback_url": null, "description": "ddd", "times_used": null, "picture": "https://storage.googleapis.com/tilo-uploads/items/37716065_.png", "create": "2022-10-24 08:45:14" }, { "id": 7, "amount": "45.00", "currency": "USD", "reference": "test", "url": "https://admin.tilopay.com/link/dsNjE2MAd32==", "callback_url": null, "description": "ddd", "times_used": null, "picture": "https://storage.googleapis.com/tilo-uploads/items/37716065_.png", "create": "2022-10-24 08:45:14" }, { "id": 8, "amount": "45.00", "currency": "USD", "reference": "test", "url": "https://admin.tilopay.com/link/NjE2sd32MA==", "callback_url": null, "description": "ddd", "times_used": null, "picture": "https://storage.googleapis.com/tilo-uploads/items/37716065_.png", "create": "2022-10-24 08:45:14" }, { "id": 9, "amount": "45.00", "currency": "USD", "reference": "test", "url": "https://admin.tilopay.com/link/sd3NjE2MA==", "callback_url": null, "description": "ddd", "times_used": null, "picture": "https://storage.googleapis.com/tilo-uploads/items/37716065_.png", "create": "2022-10-24 08:45:14" }, { "id": 10, "amount": "45.00", "currency": "USD", "reference": "test", "url": "https://admin.tilopay.com/link/d3dNjE2MA==", "callback_url": null, "description": "ddd", "times_used": null, "picture": "https://storage.googleapis.com/tilo-uploads/items/37716065_.png", "create": "2022-10-24 08:45:14" } ] } } ``` Para interpretar una respuesta que no es de éxito, ver [cómo leer una respuesta de error](/developers/api/procesos-operativos/errors). --- # API · Obtener un link de pago por id > Consulta de un link de pago puntual por su id. - kind: api-operation - status: stable - api_version: v1 - last_verified: 2026-08-29 - url: https://tilopay.com/developers/api/links-de-pago/payment-by-id ```http GET /api/v1/getLinkPaymentById/{link_payment_id}/{api_key} ``` ## Qué hace [#que-hace] Devuelve un link de pago puntual. No lleva cuerpo: los datos van en la ruta. ## Autenticación [#autenticacion] Requiere el token bearer del API en el header `Authorization` — ver [autenticación](/developers/api/autenticacion). ## Parámetros [#parametros] Parámetros de ruta, en el orden en que aparecen en la URL: Id del link de pago a consultar. Api Key del comercio. ## Respuesta [#respuesta] ```json { "type": "200", "message": "Success", "data": { "id": 1, "amount": "45.00", "currency": "USD", "reference": "Producto de prueba 1 TP-Shop", "url": "https://admin.tilopay.com/link/loNj8E2MA==", "callback_url": null, "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", "times_used": null, "picture": "https://storage.googleapis.com/tilo-uploads/items/51087219_.png", "create": "2022-10-24 08:45:14", "payments": [] } } ``` Para interpretar una respuesta que no es de éxito, ver [cómo leer una respuesta de error](/developers/api/procesos-operativos/errors). --- # Cobros Recurrentes > Operaciones de cobros recurrentes del API de Tilopay, con parámetros y ejemplos. - kind: api-index - status: stable - api_version: v1 - last_verified: 2026-08-29 - url: https://tilopay.com/developers/api/recurrentes ## Operaciones [#operaciones] 16 operaciones en tres subgrupos: - [Planes](/developers/api/recurrentes/planes) — 5 - [Suscriptores](/developers/api/recurrentes/suscriptores) — 7 - [Cupones](/developers/api/recurrentes/cupones) — 4 Todas las operaciones viven en `https://app.tilopay.com` y, salvo las de login, requieren el token del API — ver [autenticación](/developers/api/autenticacion). --- # API · Recurrentes · Planes > Operaciones de recurrentes · planes del API de Tilopay, con parámetros y ejemplos. - kind: api-index - status: stable - api_version: v1 - last_verified: 2026-08-29 - url: https://tilopay.com/developers/api/recurrentes/planes ## Operaciones [#operaciones] - [Crear plan recurrente](/developers/api/recurrentes/planes/create-plan) - [Editar plan recurrente](/developers/api/recurrentes/planes/edit-plan) - [Obtener un plan recurrente](/developers/api/recurrentes/planes/get-plan) - [Listar planes recurrentes](/developers/api/recurrentes/planes/get-plans) - [Eliminar plan recurrente](/developers/api/recurrentes/planes/delete-plan) Todas las operaciones viven en `https://app.tilopay.com` y, salvo las de login, requieren el token del API — ver [autenticación](/developers/api/autenticacion). --- # API · Crear plan recurrente > Creación de planes recurrentes: frecuencias, prueba gratis, modalidades y webhooks. - kind: api-operation - status: stable - api_version: v1 - last_verified: 2026-08-29 - url: https://tilopay.com/developers/api/recurrentes/planes/create-plan ```http POST /api/v1/createPlanRepeat ``` ## Qué hace [#que-hace] Crea un plan de suscripción: frecuencia de cobro, moneda, periodo de prueba, modalidades y webhooks. ## Autenticación [#autenticacion] Requiere el token bearer del API en el header `Authorization` — ver [autenticación](/developers/api/autenticacion). ## Parámetros [#parametros] Key de la integración Tilopay. Título del plan recurrente. Descripción del plan. Frecuencia de cobro. | Código | Valor | | --- | --- | | 1 | Diario | | 2 | Semanal | | 3 | Mensual | | 4 | Anual | | 5 | Quincenal | | 6 | Bimestral | | 7 | Trimestral | | 8 | Cuatrimestral | | 9 | Semestral | Código de moneda en formato ISO 4217. Monto por pago inicial. Activa el periodo de prueba gratis: 0 no, 1 sí. Días del periodo de prueba gratis. Cantidad de reintentos para cobros fallidos. Array de modalidades del plan. Campo opcional. URL de agradecimiento propia del comercio; debe soportar el método **GET**. Campo opcional. URL del webhook, por método **POST**, que recibe el callback en el cuerpo de la solicitud cuando un cliente adquiere una suscripción de forma exitosa. Ejemplo de los datos enviados: `{'id_plan' : 1, 'email' : 'email@email.com', 'modality' : 'ModalityName', 'amount' : 25, 'frequency' : '', 'coupon' : '5HT5W8YT', 'free_trial' : 1, 'next_payment_date' : '2023-02-25'}` Campo opcional. URL del webhook, por método **POST**, que recibe el callback en el cuerpo de la solicitud cuando el cargo al cliente se realiza con éxito. Ejemplo de los datos enviados: `{'id_plan' : 1, 'email' : 'email@email.com', 'amount' : 25, 'auth' : '123456', 'orderNumber' : 'PRE123456'}` Campo opcional. URL del webhook, por método **POST**, que recibe el callback en el cuerpo de la solicitud cuando un pago falla. Ejemplo de los datos enviados: `{'id_plan' : 1, 'email' : 'email@email.com', 'amount' : 25}` Campo opcional. URL del webhook, por método **POST**, que recibe el callback en el cuerpo de la solicitud cuando un cliente cancela la suscripción a uno de sus planes. Ejemplo de los datos enviados: `{'id_plan' : 1, 'email' : 'email@email.com', 'expire' : '2023-02-25'}` Campo opcional. URL del webhook, por método **POST**, que recibe el callback en el cuerpo de la solicitud cuando un cliente reactiva la suscripción a uno de sus planes. Ejemplo de los datos enviados: `{'id_plan' : 1, 'email' : 'email@email.com', 'next_payment_date' : '2023-02-25'}` Fecha de finalización del plan recurrente, formato `d-m-Y` (por ejemplo 25-09-2022). Si el plan no tiene fecha de fin, se envía vacío. En 1 agrega al correo de notificación el texto de `notify_detail` y `notify_note`. En 0 no agrega ninguno de los dos. Texto del detalle en español. Opcional si `notify` es 0. Texto del detalle en inglés. Opcional si `notify` es 0. Texto de las notas en español. Opcional si `notify` es 0. Texto de las notas en inglés. Opcional si `notify` es 0. ## Ejemplo de request [#request] Los valores `<...>` son marcadores: reemplazalos por tus credenciales y datos. ```json { "key": "", "title": "Plan title", "description": "Plan description", "frecuency": 1, "currency": "USD", "first_amount": 0, "trial": 0, "trial_days": 0, "attempts": 1, "modality": [ { "title": "Basic", "amount": 10 }, { "title": "Premium", "amount": 30 } ], "thanks_url": "", "webhook_subscribe": "", "webhook_payment": "", "webhook_rejected": "", "webhook_unsubscribe": "", "webhook_reactive": "", "end_at": "25-10-2023", "notify": 0, "notify_detail_es": "", "notify_detail_en": "", "notify_note_es": "", "notify_note_en": "" } ``` ## Respuesta [#respuesta] ```json { "type": "200", "status": 1, "message": "Success", "id": 624, "url": "https://app.tilopay.com/link/TmpJMHwx" } ``` Para interpretar una respuesta que no es de éxito, ver [cómo leer una respuesta de error](/developers/api/procesos-operativos/errors). --- # API · Editar plan recurrente > Edición de un plan recurrente y de su estado. - kind: api-operation - status: stable - api_version: v1 - last_verified: 2026-08-29 - url: https://tilopay.com/developers/api/recurrentes/planes/edit-plan ```http POST /api/v1/editPlanRepeat ``` ## Qué hace [#que-hace] Edita un plan existente, incluido su estado. ## Autenticación [#autenticacion] Requiere el token bearer del API en el header `Authorization` — ver [autenticación](/developers/api/autenticacion). ## Parámetros [#parametros] Key de la integración Tilopay. Id del plan recurrente. Título del plan recurrente. Descripción del plan. Frecuencia de cobro. | Código | Valor | | --- | --- | | 1 | Diario | | 2 | Semanal | | 3 | Mensual | | 4 | Anual | | 5 | Quincenal | | 6 | Bimestral | | 7 | Trimestral | | 8 | Cuatrimestral | | 9 | Semestral | Código de moneda en formato ISO 4217. Monto por pago inicial. Activa el periodo de prueba gratis: 0 no, 1 sí. Días del periodo de prueba gratis. Cantidad de reintentos para cobros fallidos. Estado del plan recurrente. | Código | Valor | | --- | --- | | 0 | Inactivo | | 1 | Activo | | 2 | Activo pero sin registros nuevos | Campo opcional. URL de agradecimiento propia del comercio; debe soportar el método **GET**. Campo opcional. URL del webhook, por método **POST**, que recibe el callback en el cuerpo de la solicitud cuando un cliente adquiere una suscripción de forma exitosa. Ejemplo de los datos enviados: `{'id_plan' : 1, 'email' : 'email@email.com', 'modality' : 'ModalityName', 'amount' : 25, 'frequency' : '', 'coupon' : '5HT5W8YT', 'free_trial' : 1, 'next_payment_date' : '2023-02-25'}` Campo opcional. URL del webhook, por método **POST**, que recibe el callback en el cuerpo de la solicitud cuando el cargo al cliente se realiza con éxito. Ejemplo de los datos enviados: `{'id_plan' : 1, 'email' : 'email@email.com', 'amount' : 25, 'auth' : '123456', 'orderNumber' : 'PRE123456'}` Campo opcional. URL del webhook, por método **POST**, que recibe el callback en el cuerpo de la solicitud cuando un pago falla. Ejemplo de los datos enviados: `{'id_plan' : 1, 'email' : 'email@email.com', 'amount' : 25}` Campo opcional. URL del webhook, por método **POST**, que recibe el callback en el cuerpo de la solicitud cuando un cliente cancela la suscripción a uno de sus planes. Ejemplo de los datos enviados: `{'id_plan' : 1, 'email' : 'email@email.com', 'expire' : '2023-02-25'}` Campo opcional. URL del webhook, por método **POST**, que recibe el callback en el cuerpo de la solicitud cuando un cliente reactiva la suscripción a uno de sus planes. Ejemplo de los datos enviados: `{'id_plan' : 1, 'email' : 'email@email.com', 'next_payment_date' : '2023-02-25'}` Fecha de finalización del plan recurrente, formato `d-m-Y` (por ejemplo 25-09-2022). Si el plan no tiene fecha de fin, se envía vacío. ## Ejemplo de request [#request] Los valores `<...>` son marcadores: reemplazalos por tus credenciales y datos. ```json { "key": "", "id": 3, "title": "Plan title", "description": "Plan description", "frecuency": 2, "currency": "USD", "first_amount": 0, "trial": 0, "trial_days": 0, "attempts": 5, "status": 1, "thanks_url": "", "webhook_subscribe": "", "webhook_payment": "", "webhook_rejected": "", "webhook_unsubscribe": "", "webhook_reactive": "", "end_at": "25-10-2023" } ``` Para interpretar una respuesta que no es de éxito, ver [cómo leer una respuesta de error](/developers/api/procesos-operativos/errors). --- # API · Obtener un plan recurrente > Consulta de un plan recurrente por id. - kind: api-operation - status: stable - api_version: v1 - last_verified: 2026-08-29 - url: https://tilopay.com/developers/api/recurrentes/planes/get-plan ```http POST /api/v1/getPlanRepeat ``` ## Qué hace [#que-hace] Devuelve un plan recurrente puntual. ## Autenticación [#autenticacion] Requiere el token bearer del API en el header `Authorization` — ver [autenticación](/developers/api/autenticacion). ## Parámetros [#parametros] Key de la integración Tilopay. Id del plan recurrente. ## Ejemplo de request [#request] Los valores `<...>` son marcadores: reemplazalos por tus credenciales y datos. ```json { "key": "", "id": "3" } ``` ## Respuesta [#respuesta] ```json { "type": "200", "message": "Success", "plan": { "id": 232, "title": "Prueba repeat", "description": "Plan repeat de prueba mensual", "frequency": 3, "currency": "USD", "first_amount": "5.00", "trial": 0, "trial_days": 0, "attempts": 5, "thanks_url": null, "webhook_subscribe": null, "webhook_payment": null, "webhook_rejected": null, "webhook_unsubscribe": null, "webhook_reactive": null, "modality": [ { "id": 292, "title": "Pago mensual prueba repeat modalidad", "amount": "10.00" } ], "end_at": null } } ``` Para interpretar una respuesta que no es de éxito, ver [cómo leer una respuesta de error](/developers/api/procesos-operativos/errors). --- # API · Listar planes recurrentes > Listado de los planes recurrentes de la integración. - kind: api-operation - status: stable - api_version: v1 - last_verified: 2026-08-29 - url: https://tilopay.com/developers/api/recurrentes/planes/get-plans ```http POST /api/v1/getPlansRepeat ``` ## Qué hace [#que-hace] Devuelve los planes recurrentes del comercio. ## Autenticación [#autenticacion] Requiere el token bearer del API en el header `Authorization` — ver [autenticación](/developers/api/autenticacion). ## Parámetros [#parametros] Key de la integración Tilopay. ## Ejemplo de request [#request] Los valores `<...>` son marcadores: reemplazalos por tus credenciales y datos. ```json { "key": "" } ``` Para interpretar una respuesta que no es de éxito, ver [cómo leer una respuesta de error](/developers/api/procesos-operativos/errors). --- # API · Eliminar plan recurrente > Eliminación de un plan recurrente por id. - kind: api-operation - status: stable - api_version: v1 - last_verified: 2026-08-29 - url: https://tilopay.com/developers/api/recurrentes/planes/delete-plan ```http POST /api/v1/deletePlanRepeat ``` ## Qué hace [#que-hace] Elimina un plan recurrente. ## Autenticación [#autenticacion] Requiere el token bearer del API en el header `Authorization` — ver [autenticación](/developers/api/autenticacion). ## Parámetros [#parametros] Key de la integración Tilopay. Id del plan recurrente. ## Ejemplo de request [#request] Los valores `<...>` son marcadores: reemplazalos por tus credenciales y datos. ```json { "key": "", "id": "625" } ``` ## Respuesta [#respuesta] ```json { "type": "200", "status": 1, "message": "Success" } ``` Para interpretar una respuesta que no es de éxito, ver [cómo leer una respuesta de error](/developers/api/procesos-operativos/errors). --- # API · Recurrentes · Suscriptores > Operaciones de recurrentes · suscriptores del API de Tilopay, con parámetros y ejemplos. - kind: api-index - status: stable - api_version: v1 - last_verified: 2026-08-29 - url: https://tilopay.com/developers/api/recurrentes/suscriptores ## Operaciones [#operaciones] - [Suscriptores de un plan](/developers/api/recurrentes/suscriptores/get-suscriptor-plan) - [Editar suscriptor](/developers/api/recurrentes/suscriptores/edit-suscriptor-plan) - [Pausar suscriptor](/developers/api/recurrentes/suscriptores/pause-suscriptor-plan) - [Reactivar suscriptor](/developers/api/recurrentes/suscriptores/reactive-suscriptor-plan) - [Eliminar suscriptor](/developers/api/recurrentes/suscriptores/delete-suscriptor-plan) - [URL de registro y renovación](/developers/api/recurrentes/suscriptores/consult-url) - [Pagos de suscriptor](/developers/api/recurrentes/suscriptores/suscriptor-payments) Todas las operaciones viven en `https://app.tilopay.com` y, salvo las de login, requieren el token del API — ver [autenticación](/developers/api/autenticacion). --- # API · Suscriptores de un plan > Consulta de los suscriptores de un plan recurrente. - kind: api-operation - status: stable - api_version: v1 - last_verified: 2026-08-29 - url: https://tilopay.com/developers/api/recurrentes/suscriptores/get-suscriptor-plan ```http POST /api/v1/getSuscriptorRepeat ``` ## Qué hace [#que-hace] Devuelve los suscriptores asociados a un plan recurrente. ## Autenticación [#autenticacion] Requiere el token bearer del API en el header `Authorization` — ver [autenticación](/developers/api/autenticacion). ## Parámetros [#parametros] Key de la integración Tilopay. Id del plan recurrente. ## Ejemplo de request [#request] Los valores `<...>` son marcadores: reemplazalos por tus credenciales y datos. ```json { "key": "", "id": "2" } ``` ## Respuesta [#respuesta] ```json { "type": "200", "message": "Success", "suscriptor": [ { "id": 360, "name": "Jhon 1", "lastname": "D", "email": "customer1@example.com", "modality": "Pago mensual prueba repeat modalidad", "amount": "10.00", "expire": "2023-03-26", "coupon": "", "status": "Delete", "create": "2022-10-19 12:48:59" }, { "id": 33364, "name": "Jhon 2", "lastname": "D", "email": "customer2@example.com", "modality": "Pago mensual prueba repeat modalidad", "amount": "10.00", "expire": "2023-08-05", "coupon": "", "status": "Active", "create": "2023-06-05 14:24:18" } ] } ``` Para interpretar una respuesta que no es de éxito, ver [cómo leer una respuesta de error](/developers/api/procesos-operativos/errors). --- # API · Editar suscriptor > Edición del estado y la expiración de un suscriptor. - kind: api-operation - status: stable - api_version: v1 - last_verified: 2026-08-29 - url: https://tilopay.com/developers/api/recurrentes/suscriptores/edit-suscriptor-plan ```http POST /api/v1/editSuscriptorRepeat ``` ## Qué hace [#que-hace] Cambia el estado o la fecha de expiración de un suscriptor. ## Autenticación [#autenticacion] Requiere el token bearer del API en el header `Authorization` — ver [autenticación](/developers/api/autenticacion). ## Parámetros [#parametros] Key de la integración Tilopay. Id del suscriptor. Estado del suscriptor. | Código | Valor | | --- | --- | | 1 | Activo | | 3 | Pausado | | 4 | Eliminado | Fecha de expiración del plan, formato `yy-m-d`. ## Ejemplo de request [#request] Los valores `<...>` son marcadores: reemplazalos por tus credenciales y datos. ```json { "key": "", "id": "2", "status": "2", "expire": "2023-10-25" } ``` ## Respuesta [#respuesta] ```json { "type": "200", "status": 1, "message": "Success" } ``` Para interpretar una respuesta que no es de éxito, ver [cómo leer una respuesta de error](/developers/api/procesos-operativos/errors). --- # API · Pausar suscriptor > Pausa de la suscripción de un suscriptor. - kind: api-operation - status: stable - api_version: v1 - last_verified: 2026-08-29 - url: https://tilopay.com/developers/api/recurrentes/suscriptores/pause-suscriptor-plan ```http POST /api/v1/pauseSuscriptorRepeat ``` ## Qué hace [#que-hace] Pausa la suscripción de un suscriptor. ## Autenticación [#autenticacion] Requiere el token bearer del API en el header `Authorization` — ver [autenticación](/developers/api/autenticacion). ## Parámetros [#parametros] Key de la integración Tilopay. Id del suscriptor. ## Ejemplo de request [#request] Los valores `<...>` son marcadores: reemplazalos por tus credenciales y datos. ```json { "key": "", "id_suscriptor": "1" } ``` ## Respuesta [#respuesta] ```json { "type": "200", "status": 1, "message": "Success" } ``` Para interpretar una respuesta que no es de éxito, ver [cómo leer una respuesta de error](/developers/api/procesos-operativos/errors). --- # API · Reactivar suscriptor > Reactivación de la suscripción de un suscriptor. - kind: api-operation - status: stable - api_version: v1 - last_verified: 2026-08-29 - url: https://tilopay.com/developers/api/recurrentes/suscriptores/reactive-suscriptor-plan ```http POST /api/v1/reactiveSuscriptorRepeat ``` ## Qué hace [#que-hace] Reactiva la suscripción de un suscriptor pausado. ## Autenticación [#autenticacion] Requiere el token bearer del API en el header `Authorization` — ver [autenticación](/developers/api/autenticacion). ## Parámetros [#parametros] Key de la integración Tilopay. Id del suscriptor. ## Ejemplo de request [#request] Los valores `<...>` son marcadores: reemplazalos por tus credenciales y datos. ```json { "key": "", "id_suscriptor": "1" } ``` ## Respuesta [#respuesta] ```json { "type": "200", "status": 1, "message": "Success" } ``` Para interpretar una respuesta que no es de éxito, ver [cómo leer una respuesta de error](/developers/api/procesos-operativos/errors). --- # API · Eliminar suscriptor > Eliminación de un suscriptor de un plan recurrente. - kind: api-operation - status: stable - api_version: v1 - last_verified: 2026-08-29 - url: https://tilopay.com/developers/api/recurrentes/suscriptores/delete-suscriptor-plan ```http POST /api/v1/deleteSuscriptorRepeat ``` ## Qué hace [#que-hace] Elimina un suscriptor de un plan recurrente. ## Autenticación [#autenticacion] Requiere el token bearer del API en el header `Authorization` — ver [autenticación](/developers/api/autenticacion). ## Parámetros [#parametros] Key de la integración Tilopay. Id del suscriptor. ## Ejemplo de request [#request] Los valores `<...>` son marcadores: reemplazalos por tus credenciales y datos. ```json { "key": "", "id_suscriptor": "1" } ``` ## Respuesta [#respuesta] ```json { "type": "200", "status": 1, "message": "Success" } ``` Para interpretar una respuesta que no es de éxito, ver [cómo leer una respuesta de error](/developers/api/procesos-operativos/errors). --- # API · URL de registro y renovación > URL de registro o renovación de un plan recurrente para un correo dado. - kind: api-operation - status: stable - api_version: v1 - last_verified: 2026-08-29 - url: https://tilopay.com/developers/api/recurrentes/suscriptores/consult-url ```http POST /api/v1/recurrentUrl ``` ## Qué hace [#que-hace] Devuelve la URL de registro de un plan recurrente para un usuario nuevo, o la URL de renovación si el correo ya está registrado. ## Autenticación [#autenticacion] Requiere el token bearer del API en el header `Authorization` — ver [autenticación](/developers/api/autenticacion). ## Parámetros [#parametros] Key de la integración Tilopay. Id del plan recurrente. Correo del usuario para el que se quiere crear el link de registro. ## Ejemplo de request [#request] Los valores `<...>` son marcadores: reemplazalos por tus credenciales y datos. ```json { "key": "", "id": "1", "email": "email@user.com" } ``` ## Respuesta [#respuesta] ```json { "type": "200", "message": "", "url_register": "https://app.tilopay.com/admin/recurrent/register/MjMy?email=email@user.com", "url_renew": "" } ``` Para interpretar una respuesta que no es de éxito, ver [cómo leer una respuesta de error](/developers/api/procesos-operativos/errors). --- # API · Pagos de suscriptor > Historial de pagos de los suscriptores de un plan recurrente. - kind: api-operation - status: stable - api_version: v1 - last_verified: 2026-08-29 - url: https://tilopay.com/developers/api/recurrentes/suscriptores/suscriptor-payments ```http POST /api/v1/getSuscriptorPayments ``` ## Qué hace [#que-hace] Devuelve los pagos de los suscriptores de un plan recurrente. ## Autenticación [#autenticacion] Requiere el token bearer del API en el header `Authorization` — ver [autenticación](/developers/api/autenticacion). ## Parámetros [#parametros] Key de la integración Tilopay. Id del plan recurrente. ## Ejemplo de request [#request] Los valores `<...>` son marcadores: reemplazalos por tus credenciales y datos. ```json { "key": "", "id": "1" } ``` Para interpretar una respuesta que no es de éxito, ver [cómo leer una respuesta de error](/developers/api/procesos-operativos/errors). --- # API · Recurrentes · Cupones > Operaciones de recurrentes · cupones del API de Tilopay, con parámetros y ejemplos. - kind: api-index - status: stable - api_version: v1 - last_verified: 2026-08-29 - url: https://tilopay.com/developers/api/recurrentes/cupones ## Operaciones [#operaciones] - [Crear cupón](/developers/api/recurrentes/cupones/create-coupon) - [Listar cupones de un plan](/developers/api/recurrentes/cupones/get-coupons) - [Obtener un cupón](/developers/api/recurrentes/cupones/get-coupon) - [Eliminar cupón](/developers/api/recurrentes/cupones/delete-coupon) Todas las operaciones viven en `https://app.tilopay.com` y, salvo las de login, requieren el token del API — ver [autenticación](/developers/api/autenticacion). --- # API · Crear cupón > Creación de cupones de descuento para planes recurrentes. - kind: api-operation - status: stable - api_version: v1 - last_verified: 2026-08-29 - url: https://tilopay.com/developers/api/recurrentes/cupones/create-coupon ```http POST /api/v1/createCoupon ``` ## Qué hace [#que-hace] Crea un cupón de descuento para un plan recurrente: tipo de descuento, expiración, permisos de usuario y de correo, y límites de uso. ## Autenticación [#autenticacion] Requiere el token bearer del API en el header `Authorization` — ver [autenticación](/developers/api/autenticacion). ## Parámetros [#parametros] Key de la integración Tilopay. Id del plan recurrente. Permiso de usuarios. | Código | Valor | | --- | --- | | 0 | Permitir solo usuarios nuevos | | 1 | Permitir usuarios ya registrados | Tipo de descuento. | Código | Valor | | --- | --- | | 1 | Porcentaje | | 2 | Monto fijo | Valor numérico del descuento. Fecha de expiración del cupón, formato `Y-m-d` (por ejemplo 2025-10-20). Permiso de correos. | Código | Valor | | --- | --- | | 1 | Correos específicos | | 2 | Cualquier correo | Lista de correos separados por coma. Requerido si `email_group` se envía en 1. Cantidad total de usos. Cantidad total de renovaciones válidas. Total de usos por un mismo usuario. ## Ejemplo de request [#request] Los valores `<...>` son marcadores: reemplazalos por tus credenciales y datos. ```json { "key": "", "planId": 10, "active_users": 1, "type_discount": 1, "discount": 40, "expire": "2025-10-20", "email_group": 1, "email": "cliente@ejemplo.com, cliente@ejemplo.com", "usage": 1, "renews": 2, "renews_by_user": 2 } ``` Para interpretar una respuesta que no es de éxito, ver [cómo leer una respuesta de error](/developers/api/procesos-operativos/errors). --- # API · Listar cupones de un plan > Listado de los cupones de un plan recurrente. - kind: api-operation - status: stable - api_version: v1 - last_verified: 2026-08-29 - url: https://tilopay.com/developers/api/recurrentes/cupones/get-coupons ```http POST /api/v1/getRepeatCoupons ``` ## Qué hace [#que-hace] Devuelve los cupones asociados a un plan recurrente. ## Autenticación [#autenticacion] Requiere el token bearer del API en el header `Authorization` — ver [autenticación](/developers/api/autenticacion). ## Parámetros [#parametros] Key de la integración Tilopay. Id del plan recurrente. ## Ejemplo de request [#request] Los valores `<...>` son marcadores: reemplazalos por tus credenciales y datos. ```json { "key": "", "id": "1" } ``` Para interpretar una respuesta que no es de éxito, ver [cómo leer una respuesta de error](/developers/api/procesos-operativos/errors). --- # API · Obtener un cupón > Consulta de un cupón recurrente por id. - kind: api-operation - status: stable - api_version: v1 - last_verified: 2026-08-29 - url: https://tilopay.com/developers/api/recurrentes/cupones/get-coupon ```http POST /api/v1/getCoupon ``` ## Qué hace [#que-hace] Devuelve un cupón puntual. ## Autenticación [#autenticacion] Requiere el token bearer del API en el header `Authorization` — ver [autenticación](/developers/api/autenticacion). ## Parámetros [#parametros] Key de la integración Tilopay. Id del cupón. ## Ejemplo de request [#request] Los valores `<...>` son marcadores: reemplazalos por tus credenciales y datos. ```json { "key": "", "id": "1" } ``` Para interpretar una respuesta que no es de éxito, ver [cómo leer una respuesta de error](/developers/api/procesos-operativos/errors). --- # API · Eliminar cupón > Eliminación de un cupón recurrente por id. - kind: api-operation - status: stable - api_version: v1 - last_verified: 2026-08-29 - url: https://tilopay.com/developers/api/recurrentes/cupones/delete-coupon ```http POST /api/v1/deleteCoupon ``` ## Qué hace [#que-hace] Elimina un cupón. ## Autenticación [#autenticacion] Requiere el token bearer del API en el header `Authorization` — ver [autenticación](/developers/api/autenticacion). ## Parámetros [#parametros] Key de la integración Tilopay. Id del cupón. ## Ejemplo de request [#request] Los valores `<...>` son marcadores: reemplazalos por tus credenciales y datos. ```json { "key": "", "id": "1" } ``` Para interpretar una respuesta que no es de éxito, ver [cómo leer una respuesta de error](/developers/api/procesos-operativos/errors). --- # Credential on File (CoF) > Operaciones de credential on file (cof) del API de Tilopay, con parámetros y ejemplos. - kind: api-index - status: stable - api_version: v1 - last_verified: 2026-08-29 - url: https://tilopay.com/developers/api/cof ## Operaciones [#operaciones] 3 operaciones: - [Tokenizar tarjeta](/developers/api/cof/process-tokenize) — 1 - [Eliminar tarjeta](/developers/api/cof/remove-card) — 1 - [Realizar cobro](/developers/api/cof/realizar-cobro) — 1 Todas las operaciones viven en `https://app.tilopay.com` y, salvo las de login, requieren el token del API — ver [autenticación](/developers/api/autenticacion). --- # API · Crear CoF (Tokenizar) > Tokenización de tarjeta con processTokenize: parámetros, request y respuesta. - kind: api-operation - status: stable - api_version: v1 - last_verified: 2026-08-29 - url: https://tilopay.com/developers/api/cof/process-tokenize ```http POST /api/v1/processTokenize ``` ## Qué hace [#que-hace] Tokeniza una tarjeta: devuelve la URL del formulario de tokenización. ## Autenticación [#autenticacion] Requiere el token bearer del API en el header `Authorization` — ver [autenticación](/developers/api/autenticacion). ## Parámetros [#parametros] Sitio donde espera la respuesta de la transacción. Key asociado al comercio. Correo electrónico del tarjetahabiente. Idioma [es, en]. Nombre del tarjetahabiente. Apellido del tarjetahabiente. Enviar como valor "v2". ## Ejemplo de request [#request] Los valores `<...>` son marcadores: reemplazalos por tus credenciales y datos. ```json { "redirect": "https://urlToRedirect.com", "key": "", "email": "email@user.com", "language": "es", "firstName": "name", "lastName": "lastname", "token_version": "v2" } ``` ## Respuesta [#respuesta] ```json { "type": "100", "url": "https://secure.tilopay.com/htmls/TOK-5063-740506121440_1648145457file.html" } ``` Para interpretar una respuesta que no es de éxito, ver [cómo leer una respuesta de error](/developers/api/procesos-operativos/errors). --- # API · Eliminar CoF > Eliminación de un token de tarjeta guardado en la bóveda privada del comercio. - kind: api-operation - status: stable - api_version: v1 - last_verified: 2026-08-29 - url: https://tilopay.com/developers/api/cof/remove-card ```http POST /api/v1/user/card-remove ``` ## Qué hace [#que-hace] Elimina un token de tarjeta guardado. **Requisito:** el comercio debe contar con una bóveda de tokens privada. ## Autenticación [#autenticacion] Requiere el token bearer del API en el header `Authorization` — ver [autenticación](/developers/api/autenticacion). ## Parámetros [#parametros] Llave relacionada con el comercio. Correo del cliente asociado al token. Token a eliminar. ## Ejemplo de request [#request] Los valores `<...>` son marcadores: reemplazalos por tus credenciales y datos. ```json { "key": "1234-1234-1234-1234-1234", "email": "email@card.com", "token": "411111.......1111" } ``` Para interpretar una respuesta que no es de éxito, ver [cómo leer una respuesta de error](/developers/api/procesos-operativos/errors). --- # API · Realizar cobro CoF > Cobro servidor a servidor con token de tarjeta v2 mediante Credential on File. - kind: api-operation - status: stable - api_version: v1 - last_verified: 2026-08-29 - url: https://tilopay.com/developers/api/cof/realizar-cobro ```http POST /api/v1/processRecurrentPayment ``` ## Qué hace [#que-hace] Procesa un cobro con una tarjeta ya tokenizada, sin formulario. ## Autenticación [#autenticacion] Requiere el token bearer del API en el header `Authorization` — ver [autenticación](/developers/api/autenticacion). ## Parámetros [#parametros] Llave relacionada con el cliente. Se obtiene en Admin · Tilopay Checkout. Monto de la compra. Moneda de la compra en formato ISO, por ejemplo USD, CRC, GTQ. Número de orden, puede ser alfanumérico. Captura y autoriza: 1 sí, 0 no. Correo del tarjetahabiente. Token de tarjeta, debe ser el token v2 - **hashVersion**: Utilizar solo en caso de implementar la verificación de hash, posibles valores [V1, V2], pod defecto se usa V1. ## Ejemplo de request [#request] Los valores `<...>` son marcadores: reemplazalos por tus credenciales y datos. ```json { "key": "", "amount": "10.00", "currency": "USD", "orderNumber": "1213", "capture": "1", "email": "myemail@exapmle.com", "card": "511111_00GOB1111" } ``` ## Respuesta [#respuesta] ```json { "type": "200", "response": "1", "description": "Transacción aprobada", "auth": "123456", "tpt": 734329, "order_id": "12135", "tilopayTransaction": 734329, "orderHash": "f3ad85046d249bc7a781eed5285a5ded92045a2e11108063504deec72ec9b338" } ``` Para interpretar una respuesta que no es de éxito, ver [cómo leer una respuesta de error](/developers/api/procesos-operativos/errors). --- # Procesos operativos > Operaciones de procesos operativos del API de Tilopay, con parámetros y ejemplos. - kind: api-index - status: stable - api_version: v1 - last_verified: 2026-08-29 - url: https://tilopay.com/developers/api/procesos-operativos ## Operaciones [#operaciones] - [processModification](/developers/api/procesos-operativos/process-modification) - [consult](/developers/api/procesos-operativos/consult) - [consultTransactions](/developers/api/procesos-operativos/consult-transactions) - [Dividir liquidación (split)](/developers/api/procesos-operativos/split) Estas operaciones son transversales: sirven para cualquiera de los cuatro [caminos de integración](/developers), sin importar cómo se originó el cobro. Para interpretar una respuesta que no es de éxito, ver [cómo leer una respuesta de error](/developers/api/procesos-operativos/errors). Todas las operaciones viven en `https://app.tilopay.com` y, salvo las de login, requieren el token del API — ver [autenticación](/developers/api/autenticacion). --- # API · processModification > Captura, reembolso y reverso de una transacción con processModification. - kind: api-operation - status: stable - api_version: v1 - last_verified: 2026-08-29 - url: https://tilopay.com/developers/api/procesos-operativos/process-modification ```http POST /api/v1/processModification ``` ## Qué hace [#que-hace] Permite modificar una transacción ya procesada: captura, reembolso o reverso. ## Autenticación [#autenticacion] Requiere el token bearer del API en el header `Authorization` — ver [autenticación](/developers/api/autenticacion). ## Parámetros [#parametros] Ejemplo: `1214352` Ejemplo: `2` Ejemplo: `1.00` Llave relacionada con el cliente. Se obtiene en Admin · Tilopay Checkout. ## Ejemplo de request [#request] Los valores `<...>` son marcadores: reemplazalos por tus credenciales y datos. ```json { "orderNumber": "1214352", "type": "2", "amount": "1.00", "key": "" } ``` ## Respuesta [#respuesta-modificacion] Tipo de modificación aplicada. Identificador de la transacción. Código de resultado de la modificación. Texto del resultado. Hash de la orden. Ver la nota sobre `orderHash` en [webhooks](/developers/api/webhooks#verificacion). Para interpretar una respuesta que no es de éxito, ver [cómo leer una respuesta de error](/developers/api/procesos-operativos/errors). --- # API · consult > Consulta del estado y el monto procesado de una transacción puntual. - kind: api-operation - status: stable - api_version: v1 - last_verified: 2026-08-29 - url: https://tilopay.com/developers/api/procesos-operativos/consult ```http POST /api/v1/consult ``` ## Qué hace [#que-hace] Consulta una transacción específica: devuelve el monto procesado y el estado de la transacción. ## Autenticación [#autenticacion] Requiere el token bearer del API en el header `Authorization` — ver [autenticación](/developers/api/autenticacion). ## Parámetros [#parametros] Key de la integración Tilopay. Número de orden consultado. Id de comercio. ## Ejemplo de request [#request] Los valores `<...>` son marcadores: reemplazalos por tus credenciales y datos. ```json { "key": "", "orderNumber": "1212122", "merchantId": "" } ``` ## Respuesta [#respuesta] ```json { "type": "200", "message": "", "response": [ { "id_tilopay": 734312, "orderNumber": "1212122", "amount": "5.00", "currency": "USD", "merchantId": "88803956", "code": "1", "response": "Transacción aprobada", "auth": "123456", "commission": 0.18, "iva_commission": 0.02, "retention_iva": 0.27, "retention_rent": 0.09, "cost": 0.35, "cost_iva": 0.05, "net_to_liquidate": "4.04", "capture": "Capture", "card": "4021", "last": "5221", "environment": "Test", "type": "Payment", "date": "2024-07-31 16:59:20" } ] } ``` Para interpretar una respuesta que no es de éxito, ver [cómo leer una respuesta de error](/developers/api/procesos-operativos/errors). --- # API · consultTransactions > Consulta masiva de transacciones por rango de fechas, moneda, orden o correo. - kind: api-operation - status: stable - api_version: v1 - last_verified: 2026-08-29 - url: https://tilopay.com/developers/api/procesos-operativos/consult-transactions ```http POST /api/v1/consultTransactions ``` ## Qué hace [#que-hace] Consulta transacciones por rango de fechas, con filtros opcionales. ## Autenticación [#autenticacion] Requiere el token bearer del API en el header `Authorization` — ver [autenticación](/developers/api/autenticacion). ## Parámetros [#parametros] Key de la integración Tilopay. Fecha de inicio, formato `Y-m-d H:i:s` — por ejemplo "2022-01-15 00:00:00". Fecha de fin, formato `Y-m-d H:i:s` — por ejemplo "2022-08-01 23:59:59". Indica si se obtienen solo transacciones aprobadas. | Código | Valor | | --- | --- | | 0 | Cualquiera | | 1 | Solo aprobadas | Ambiente de las transacciones a obtener. | Código | Valor | | --- | --- | | 0 | Producción | | 1 | Pruebas | Array de monedas que se desean obtener, por ejemplo ["USD", "CRC"]. Id de comercio. Número de orden. Correo del cliente. Número de autorización. ## Ejemplo de request [#request] Los valores `<...>` son marcadores: reemplazalos por tus credenciales y datos. ```json { "key": "", "startDate": "2023-06-01 00:00:00", "endDate": "2023-06-30 23:59:59", "onlyAproved": 1, "environment": 1, "currency": [ "USD", "CRC" ], "merchantId": "", "orderNumber": "12135", "email": "customer@example.com", "auth": "123456" } ``` ## Respuesta [#respuesta] ```json { "type": "200", "message": "", "response": [ { "id": 734329, "orderNumber": "12135", "amount": "5.00", "taxes": "0.00", "discount": "0.00", "discount_name": "", "currency": "USD", "merchantId": "", "code": "1", "response": "Transacción aprobada", "auth": "123456", "card": "4021", "last": "5221", "email": "customer@example.com", "commission": 0.18, "iva_commission": 0.02, "retention_iva": 0.27, "retention_rent": 0.09, "cost": 0.35, "cost_iva": 0.05, "net_to_liquidate": 4.04, "capture": "Capture", "type": "Payment", "environment": "Production", "date": "2024-07-31 16:59:20" }, { "id": 734330, "orderNumber": "12136", "amount": "5.00", "taxes": "0.00", "discount": "0.00", "discount_name": "", "currency": "USD", "merchantId": "", "code": "1", "response": "Transacción aprobada", "auth": "123456", "card": "4021", "last": "5221", "email": "customer@example.com", "commission": 0.18, "iva_commission": 0.02, "retention_iva": 0.27, "retention_rent": 0.09, "cost": 0.35, "cost_iva": 0.05, "net_to_liquidate": 4.04, "capture": "Capture", "type": "Payment", "environment": "Production", "date": "2024-07-31 17:25:35" } ] } ``` Para interpretar una respuesta que no es de éxito, ver [cómo leer una respuesta de error](/developers/api/procesos-operativos/errors). --- # API · Dividir liquidación (split) > División de la liquidación de una orden entre varios comercios facilitados. - kind: api-operation - status: stable - api_version: v1 - last_verified: 2026-08-29 - url: https://tilopay.com/developers/api/procesos-operativos/split ```http POST /api/v1/orders/liquidation/split ``` ## Qué hace [#que-hace] Divide la liquidación de una orden entre varios comercios. Solo aplica a comercios que usan Tilopay como facilitador de pago, y las órdenes resultantes se identifican con el prefijo `SL|`. Reglas: - Los comercios deben estar aprobados y ser del mismo país. - Si la partición es menor al monto total de la orden, el restante se le asigna al comercio que realizó la transacción original. - Solo aplica sobre órdenes aprobadas completamente. ## Autenticación [#autenticacion] Requiere el token bearer del API en el header `Authorization` — ver [autenticación](/developers/api/autenticacion). ## Parámetros [#parametros] Id de la orden aprobada en Tilopay. Array asociativo con las llaves `email` y `amount` de cada comercio con el que se divide la liquidación. Incluir al comercio propietario es opcional: si no se especifica su monto, se le asigna el excedente de la partición, y si se incluye y hay excedente, se le suma. Idioma de la solicitud. ## Ejemplo de request [#request] Los valores `<...>` son marcadores: reemplazalos por tus credenciales y datos. ```json { "order_id": "1", "commerces": [ { "email": "commerce-1@example.com", "amount": "7.5" }, { "email": "commerce-2@example.com", "amount": "5.5" } ], "lang": "en" } ``` ## Respuesta [#respuesta] ```json { "type": "200", "message": "Great", "description": "Order splitted successfully", "response": { "total_order_splitted": 3, "order_id": 1, "order_number": "PFC000069-TYP785237_313", "order_key": "", "order_currency": "USD", "order_amount": "33.00", "splitted_orders": [ { "id": 1, "amount": 20, "commerce_name": "Commerce owner name", "commerce_email": "owner@example.com" }, { "id": 2, "amount": 7.5, "commerce_name": "Commerce name", "commerce_email": "commerce-1@example.com" }, { "id": 3, "amount": 5.5, "commerce_name": "Commerce name", "commerce_email": "commerce-2@example.com" } ] } } ``` Para interpretar una respuesta que no es de éxito, ver [cómo leer una respuesta de error](/developers/api/procesos-operativos/errors). --- # Webhooks > Qué eventos existen, cuántos reintentos hay, en qué formato llegan y cómo confirmar el estado de un cobro. - kind: concept - status: stable - api_version: v1 - last_verified: 2026-08-28 - url: https://tilopay.com/developers/api/webhooks ## Recurrencia [#recurrencia] Son 6 campos que se configuran al **crear o editar un plan**. Todos opcionales. | Campo | Qué es | |---|---| | `webhook_subscribe` | Webhook de suscripción | | `webhook_payment` | Webhook de cobro | | `webhook_rejected` | Webhook de cobro rechazado | | `webhook_unsubscribe` | Webhook de baja | | `webhook_reactive` | Webhook de reactivación | | `thanks_url` | **No es un webhook:** es un callback GET | ## Links de pago [#links-de-pago] Se configura `webhook_url` al crear el link. ## Reintentos [#reintentos] | Origen | Intentos | Cuándo reintenta | |---|---|---| | Recurrencia | 5 | Cuando tu respuesta es 400, 404, 502, 504 o 403 | | Compras | 1 | — | Se da por entregado con un **HTTP 200**. Respondé 200 en cuanto recibás el evento y procesalo aparte: cualquier otra cosa cuenta como fallo, y en compras no hay segundo intento. ## Formato [#formato] JSON. ## El token de tarjeta [#token] | Origen | Token | |---|---| | Recurrencia | **No se envía** | | Compras | Se envía y **es utilizable** | ## Verificación de origen [#verificacion] La única verificación de origen disponible es el `orderHash`, y **su algoritmo no es público**: se entrega al comercio que lo solicita escribiendo a `soporte@tilopay.com`. Mientras no tengás el algoritmo, no tomés decisiones de negocio irreversibles solo con el contenido del webhook: confirmá el estado contra el API antes de despachar o liberar un servicio. ## Webhook del flujo principal [#processpayment] `processPayment` también tiene webhook. Su especificación técnica (los campos que envía) **te la entregamos cuando la solicitás**, para que tu equipo lo implemente: escribí a `soporte@tilopay.com` para recibirlo. --- # SDK JavaScript > Camino de integración en el que el formulario de tarjeta vive en tu página y el SDK manda los datos directo a Tilopay. - kind: guide - status: stable - sdk_version: v2 - last_verified: 2026-08-28 - url: https://tilopay.com/developers/sdk ## Qué es [#que-es] Los campos de tarjeta viven en tu página. El SDK V2 toma control de esos inputs y manda los datos **del navegador directo a Tilopay**: no pasan por tu servidor. ## Para quién es [#para-quien] Para equipos que quieren controlar el diseño del checkout sin que los datos de tarjeta toquen su backend. Necesitás frontend con JavaScript y un backend mínimo para obtener el token del SDK. ## Cómo se arma, en orden [#orden] 1. **Credenciales.** No hay credenciales de sandbox compartidas: obtené las tuyas en [registro de developer](/developers/registro). 2. **Token del SDK.** Tu backend lo pide con `POST /api/v1/loginSdk`. Ver [autenticación](/developers/api/autenticacion). 3. **Cargá el script.** Ver [instalación](/developers/sdk/instalacion). 4. **Poné los inputs con los ids del contrato** y el contenedor `responseTilopay`. Ver [campos del formulario](/developers/sdk/campos-del-formulario). 5. **Iniciá la compra** con [`Tilopay.Init()`](/developers/sdk/reference/init) y mostrale al cliente los métodos de pago que devuelve. 6. **Cerrá la compra** con [`Tilopay.startPayment()`](/developers/sdk/reference/startpayment). El SDK maneja 3DS y renderiza el resultado en tu URL de `redirect`. ## Antes de asumir que estás en pruebas [#entornos] Pruebas y producción comparten host: el modo se verifica con el campo `test` de `Init()`. Ver [entornos](/developers/entornos). ## Cumplimiento [#cumplimiento] Los datos de tarjeta no pasan por tu servidor, pero tu página los captura: consultá con tu equipo de cumplimiento el alcance que te corresponde. --- # Obtener token del SDK > Login del SDK: devuelve el token que usa Tilopay.Init() en el navegador. - kind: api-operation - status: stable - api_version: v1 - last_verified: 2026-08-29 - url: https://tilopay.com/developers/api/autenticacion/token-sdk ```http POST /api/v1/loginSdk ``` ## Qué hace [#que-hace] Devuelve el token de seguridad necesario para consumir el SDK. Las tres credenciales se obtienen en [Admin · Tilopay Checkout](https://admin.tilopay.com/admin/checkout). ## Autenticación [#autenticacion] No requiere token: es la operación que lo emite. Ver [autenticación](/developers/api/autenticacion). ## Parámetros [#parametros] Usuario de API del comercio. Contraseña de API del comercio. Api key del comercio. ## Ejemplo de request [#request] Los valores `<...>` son marcadores: reemplazalos por tus credenciales y datos. ```json { "apiuser": "", "password": "", "key": "" } ``` ## Respuesta [#respuesta] ```json { "access_token": "351d477adaaa51cdbb33ae4b4b8c843aa759f131c1c38415180b5035543d59d2f23f4e049706f5fa71c5f0d9ff763960a3cd035b4c1cefa428c90bedb672f780", "token_type": "bearer", "expires_in": "2023-06-05 13:32:06" } ``` Para interpretar una respuesta que no es de éxito, ver [cómo leer una respuesta de error](/developers/api/procesos-operativos/errors). --- # Instalación del SDK > La etiqueta script del SDK V2, qué versiones existen y qué garantías de versionado no hay. - kind: guide - status: stable - sdk_version: v2 - last_verified: 2026-08-28 - url: https://tilopay.com/developers/sdk/instalacion ## El script [#script] ```html ``` Cargalo antes de tu propio código de checkout. El SDK expone el objeto global `Tilopay`. ## jQuery no es requerido [#jquery] **jQuery NO es requerido.** Era un residuo del SDK V1. El artículo publicado hasta ahora decía lo contrario y está mal: podés instalar el SDK V2 sin jQuery en la página. ## Versiones [#versiones] Existen solo dos versiones: | Versión | Estado | |---|---| | `v1` | Sin soporte | | `v2` | Actual | ## Lo que no hay [#garantias] **No hay versionado inmutable, no hay hash SRI y no hay changelog.** La URL `/sdk/v2/sdk_tpay.min.js` no está anclada a una versión concreta: su contenido puede cambiar sin aviso previo y sin una nota de cambios pública. Consecuencias prácticas: - No podés fijar `integrity="sha384-..."` en la etiqueta `script`, porque el archivo cambia. - No podés depender de un número de build para reproducir un bug. - Conviene tener pruebas de humo de tu checkout que corran periódicamente, no solo al desplegar. ## Qué sigue [#que-sigue] - [Campos del formulario](/developers/sdk/campos-del-formulario) — los ids que el SDK busca. - [`Tilopay.Init()`](/developers/sdk/reference/init) — iniciar la compra. --- # Campos del formulario > Los ids tlpy_* que el SDK V2 busca en tu formulario y el contenedor responseTilopay que necesita para 3DS. - kind: concept - status: stable - sdk_version: v2 - last_verified: 2026-08-28 - url: https://tilopay.com/developers/sdk/campos-del-formulario El SDK V2 no renderiza el formulario: toma control de los inputs que ya existen en tu página, buscándolos por `id`. Esos ids son un contrato — si cambiás uno, el SDK deja de encontrar el campo. **El contrato son los inputs, no los contenedores.** Los `div` que envuelven a los campos podés nombrarlos como quieras: el SDK no los busca. La única excepción es `responseTilopay`, que sí es requerido. ## Campos [#campos] Contiene el id del método de pago obtenido de Tilopay. Puede estar visible u oculto, a tu discreción. Contiene el id de la tarjeta guardada obtenida de Tilopay. Si el cliente no tiene tarjetas guardadas, ocultalo. Número de tarjeta. Fecha de expiración en formato mes/año, por ejemplo `01/25`. Código de seguridad. Cuando el cliente usa una tarjeta guardada, hay que habilitar este campo para que digite el CVV. Contenedor requerido, **fuera del formulario**. Es donde el SDK monta el flujo 3DS. ## El teléfono de Yappy no viaja por el DOM [#yappy] El teléfono de Yappy **no** se toma de un campo del formulario: se envía en el parámetro `phoneYappy` de [`Init()`](/developers/sdk/reference/init) o de [`updateOptions()`](/developers/sdk/reference/update-options). ## Estructura de ejemplo [#estructura] Los `div` de este ejemplo son libres; los `id` de los inputs y `responseTilopay` no. ```html
``` --- # Tilopay.Init() > Inicia una compra: autentica el checkout y devuelve los métodos de pago disponibles y las tarjetas guardadas del cliente. - kind: sdk-method - status: stable - sdk_version: v2 - last_verified: 2026-08-28 - url: https://tilopay.com/developers/sdk/reference/init Inicia una compra. Autentica el checkout con el token del SDK y devuelve los métodos de pago disponibles para vos. Para guardar una tarjeta sin cobrarla, el SDK tiene un segundo flujo de inicio: **`Tilopay.InitTokenize()`**, con los mismos parámetros de `Init()` excepto `amount`, `orderNumber`, `capture` y `subscription`, que no aplican porque no se está cobrando nada. ## Firma [#firma] ```js await Tilopay.Init({ /* parámetros */ }) ``` ## Parámetros [#parametros] Token del SDK, obtenido con `POST /api/v1/loginSdk`. Ver [autenticación](/developers/api/autenticacion). Moneda de la compra, ISO 4217. **Idioma** del checkout, ISO 639-1. Solo se soportan `es` y `en`; por defecto carga `es`. Monto de la compra. Correo del cliente. Es obligatorio para que la respuesta traiga las tarjetas guardadas. Número de orden, único por comercio. Ver [reintentos seguros](/developers/reintentos-seguros). Tipo de identificación del cliente. Condicionado. Ver la [tabla de tipos](/developers/sdk/reference/update-options#tipos-de-identificacion). Número de identificación del cliente. Condicionado. Nombre del cliente. Apellidos del cliente. Dirección 1 del cliente. Dirección 2 del cliente. Opcional. Ciudad. Recomendado. Provincia o estado. Recomendado. Código postal. Recomendado. País, ISO 3166-1 alpha-2. Recomendado. Teléfono del cliente. Recomendado. `0` autoriza; `1` autoriza y captura. URL donde el SDK renderiza la respuesta final de la compra. `1` guarda la tarjeta del cliente en Tilopay; `0` no la guarda. Teléfono Yappy. Obligatorio cuando se paga con Yappy. No se toma del DOM. Opcional. Valores `"V1"` o `"V2"`. Si no se envía, el hash de la respuesta final se fabrica con V1. Opcional. Se devuelve tal cual en la respuesta final del pago y se recupera en la URL de respuesta de la transacción. Soporta hasta **65.535 caracteres**, aunque un valor muy extenso puede afectar la URL de respuesta. Podés enviar un array serializado en base64 para que cumpla el formato de string. ## Llamada [#llamada] ```js const init = await Tilopay.Init({ token: sdkToken, currency: "CRC", language: "es", amount: 100.0, billToEmail: "cliente@ejemplo.com", orderNumber: "ORD-2026-000123", billToFirstName: "Ana", billToLastName: "Rojas", billToAddress: "Avenida 1, Local 2", billToCountry: "CR", capture: 1, redirect: "https://ejemplo.com/checkout/respuesta", subscription: 0, }); ``` ## Respuesta [#respuesta] `Success`, o la descripción del error. `0` producción, `1` pruebas. Ver [entornos](/developers/entornos). Objeto con `code` y `amount`, presente cuando tenés SINPE Móvil. Los datos completos, incluido el teléfono destino, se obtienen con [`getSinpeMovil()`](/developers/sdk/reference/get-sinpe-movil). Arreglo de `{id, name, type}` con los métodos de pago disponibles. Arreglo de `{id, name, brand}` con las tarjetas guardadas del cliente. ## Formato del id de método de pago [#formato-id-metodo] El `id` de cada método tiene la forma `A:B:C`. **El segundo segmento define el método de pago, y `18` corresponde a Yappy.** ## Tarjetas guardadas [#tarjetas-guardadas] - Para que la respuesta traiga `cards` es **obligatorio enviar `billToEmail`**. - Una vez obtenidas las tarjetas, **el correo ya no se puede cambiar** con [`updateOptions()`](/developers/sdk/reference/update-options). --- # Tilopay.startPayment() > Cierra la compra. El SDK maneja el flujo 3DS completo y renderiza la respuesta en la URL de redirect. - kind: sdk-method - status: stable - sdk_version: v2 - last_verified: 2026-08-28 - url: https://tilopay.com/developers/sdk/reference/startpayment Cierra la compra iniciada con [`Tilopay.Init()`](/developers/sdk/reference/init). ## Firma [#firma] ```js await Tilopay.startPayment() ``` No recibe parámetros. ## 3DS: lo maneja el SDK [#tres-ds] **El SDK maneja todo el flujo de 3D Secure.** Lo único que tenés que hacer es asegurarte de tener el contenedor `responseTilopay` en la página: ahí el SDK inserta lo necesario para 3DS y conduce el proceso. ```html
``` Ver [campos del formulario](/developers/sdk/campos-del-formulario#campos). ## Dónde llega el resultado [#resultado] Al finalizar, el SDK renderiza la respuesta en la URL indicada en el parámetro `redirect` de `Init()`. **Esa es la respuesta final de la compra**: tratá la URL de `redirect` como el punto donde tu aplicación decide el resultado. En caso de error, el método devuelve la descripción: ```json { "message": "descripción del error" } ``` --- # Tilopay.getCardType() > Devuelve la marca de la tarjeta que el cliente está digitando, para mostrarle un ícono mientras escribe. - kind: sdk-method - status: stable - sdk_version: v2 - last_verified: 2026-08-28 - url: https://tilopay.com/developers/sdk/reference/get-card-type Devuelve la marca de la tarjeta a partir del número que el cliente ya digitó en `tlpy_cc_number`. El uso típico es mostrar el ícono de la marca mientras el cliente escribe. ## Firma [#firma] ```js await Tilopay.getCardType() ``` No recibe parámetros. **Precondición:** el cliente ya tiene que haber digitado el número de tarjeta. ## Llamada [#llamada] ```js const type = await Tilopay.getCardType(); ``` ## Respuesta [#respuesta] ```json { "message": "visa" } ``` La marca de la tarjeta. ## Marcas soportadas [#marcas-soportadas] VISA · MASTERCARD · AMEX Usá el resultado solo para presentación: la validación de la marca la hace Tilopay al procesar el cobro, no este método. --- # Tilopay.getSinpeMovil() > Devuelve los datos que hay que mostrarle al cliente para pagar por SINPE Móvil y activa el listener del cobro. - kind: sdk-method - status: stable - sdk_version: v2 - last_verified: 2026-08-28 - url: https://tilopay.com/developers/sdk/reference/get-sinpe-movil SINPE Móvil no se cobra desde el formulario: el cliente hace la transferencia desde su propio banco. Este método devuelve los datos que hay que mostrarle — teléfono destino, monto exacto y código de descripción. ## Cuándo se usa [#cuando] Cuando tenés un método SINPE Móvil disponible y el cliente lo selecciona de la lista que devolvió [`Init()`](/developers/sdk/reference/init). **No es solo un getter.** Además de devolver los datos, este método **dispara el listener de SINPE con el backend de Tilopay**. Llamarlo es parte del flujo de cobro, no un detalle de presentación. ## Firma [#firma] ```js await Tilopay.getSinpeMovil() ``` No recibe parámetros. **Precondiciones:** - El cliente tiene que haber seleccionado SINPE Móvil como método de pago. - `typeDni` y `dni` tienen que haberse enviado antes, por `Init()` o por [`updateOptions()`](/developers/sdk/reference/update-options). ## Llamada [#llamada] ```js const params = await Tilopay.getSinpeMovil(); ``` ## Respuesta [#respuesta] ```json { "message": "Success", "code": "863", "amount": 10, "number": "70599200" } ``` `Success` cuando la operación salió bien. El código que el cliente debe escribir en la descripción de la transferencia. Es lo que permite identificar el pago. El monto exacto que debe transferir. El número de teléfono destino de la transferencia. ### En caso de error [#respuesta-de-error] **En caso de error no devuelve nada.** No esperés un objeto con campos vacíos: tratá la ausencia de respuesta como el caso de error. ## Qué hacer con estos datos [#que-hacer] Al seleccionar SINPE Móvil hay que ocultar los campos de tarjeta y mostrarle al cliente estos datos: teléfono destino, monto exacto y código para la descripción. **No se necesita botón de pagar:** el cobro se procesa cuando llega la transferencia. --- # Tilopay.updateOptions() > Actualiza parcialmente los parámetros enviados a Init() cuando cambian antes de cerrar el pago. - kind: sdk-method - status: stable - sdk_version: v2 - last_verified: 2026-08-28 - url: https://tilopay.com/developers/sdk/reference/update-options Actualiza valores que ya se habían enviado en [`Tilopay.Init()`](/developers/sdk/reference/init) y que cambiaron durante el checkout — típicamente cuando el cliente edita sus datos, o cuando selecciona SINPE Móvil o Yappy y hay que agregar información que antes no aplicaba. **Es un patch.** Se envían solo los campos que se quieren actualizar; no hay que reenviar todo. ## Qué significa "obligatorio" acá [#obligatorio] En la lista de abajo, "obligatorio" significa que el campo **debe haberse enviado en `Init()` o en `updateOptions()`**. Si no se envió en ninguno de los dos, el pago no puede avanzar. No significa que haya que reenviarlo en cada llamada. ## Firma [#firma] ```js await Tilopay.updateOptions({ /* solo los campos que cambian */ }) ``` ## Llamada [#llamada] ```js const update = await Tilopay.updateOptions({ typeDni: 1, dni: "0707770777", billToFirstName: "Ana", billToLastName: "Rojas", }); ``` ## Parámetros [#parametros] Tipo de identificación del cliente. Obligatorio para SINPE Móvil. Ver [tipos de identificación](#tipos-de-identificacion). Número de identificación del cliente. Obligatorio para SINPE Móvil. **Acepta con guiones y sin guiones.** Nombre del cliente. Apellidos del cliente. Dirección 1 del cliente. Dirección 2 del cliente. Opcional. Ciudad del cliente. Recomendado. Provincia o estado. Recomendado. Código postal. Recomendado. País, ISO 3166-1 alpha-2. Recomendado. Teléfono del cliente. Recomendado. `0` autoriza; `1` autoriza y captura. URL donde se espera la respuesta final de la compra. `1` si el cliente quiere guardar su tarjeta en Tilopay; `0` si no. Teléfono Yappy. Obligatorio cuando el cliente paga con Yappy. **`billToEmail` no se puede actualizar después de obtener las tarjetas guardadas.** Una vez que `Init()` devolvió las tarjetas del cliente, el correo no se puede cambiar por este método. ## Tipos de identificación [#tipos-de-identificacion] Aplica al parámetro `typeDni`, tanto acá como en `Tilopay.Init()`. En las máscaras, `#` es un carácter **numérico** y `&` es **alfanumérico**. Las longitudes no cuentan los guiones. | Código | Tipo | Formato | Longitud | |---|---|---|---| | 1 | Cédula de identidad | `0#-####-####` | 10 | | 2 | Cédula jurídica | `3-###-######` | 10 | | 3 | Gobierno central | `2-###-######` | 10 | | 4 | Institución autónoma | `4-###-######` | 10 | | 5 | Extranjero no residente | `9&&&&&&&&&&&&&&&&&&&` | 20 | | 6 | DIMEX | `1###########` | 12 | | 7 | DIDI | `5###########` | 12 | ## Respuesta [#respuesta] ```json { "message": "Success" } ``` `Success` cuando la actualización salió bien; la descripción del error en caso contrario. --- # API Bancario de Tilopay > Referencia del API Bancario (BaaS) de Tilopay generada desde su spec OpenAPI 3.0.3, versión 1.0.0. - kind: api-index - status: stable - api_version: 1.0.0 - last_verified: 2026-10-09 - url: https://tilopay.com/developers/api-bancario Con nuestro API Bancario podés iniciar pagos (PIN y SINPE Móvil), consultar su estado, administrar tus cuentas y recibir webhooks de eventos de pago desde tus propios sistemas, siempre limitado a las cuentas que autoriza tu token de acceso. **Es un producto separado de la pasarela de pagos.** Corre en su propia infraestructura, con host, credenciales y autenticación propias. Si ya integrás nuestro API de adquirencia, el acceso a este se habilita por separado. En esta documentación encontrás los endpoints, modelos y flujos oficiales de la versión **1.0.0** del API Bancario. ## Qué permite hacer [#que-permite] **Pagos.** Creá un pago, consultalo por identificador, listalo por cuenta y buscalo por `payment_id`, `public_id` o `client_reference`; los métodos disponibles son `PIN` y `SINPE_MOVIL`, en dirección `OUT` o `IN`. [Ver operaciones de pagos](/developers/api-bancario/pagos). **Cuentas.** Validá una cuenta destino antes de transferir, listá tus cuentas con o sin saldos, consultá el saldo de una cuenta y solicitá estados de cuenta de forma asincrónica. [Ver operaciones de cuentas](/developers/api-bancario/cuentas). **Webhooks.** Registrá tu destino HTTPS cifrado, consultá los eventos a los que podés suscribirte por método de pago y la estructura de datos que te enviamos en cada uno. [Ver operaciones de webhooks](/developers/api-bancario/webhooks). **Catálogos.** Tipos de persona de identificación de cliente por país. [Ver catálogos](/developers/api-bancario/catalogos). Además, ponemos a tu disposición `GET /api/public/v1/healthz` para chequeo de salud, y `GET /openapi.yaml` y `GET /docs` con la definición OpenAPI y la documentación interactiva directamente en el host del API. ## Entornos [#entornos] Hay dos entornos, con las mismas rutas y contratos. El de pruebas: ```text https://api-baas-sandbox.tilopay.com ``` El de producción es el mismo host sin el sufijo `-sandbox`: ```text https://api-baas.tilopay.com ``` Podés empezar en el entorno de pruebas y, cuando estés listo, te entregamos las credenciales de producción al habilitar tu acceso. ## Artefactos legibles por máquina [#artefactos] Publicamos la definición OpenAPI completa del API Bancario, con CORS abierto, en dos formatos: - [openapi.json](/developers/api-bancario/openapi.json) - [openapi.yaml](/developers/api-bancario/openapi.yaml) Es independiente de la definición de nuestro API de adquirencia ([/developers/openapi.json](/developers/openapi.json)): son dos productos separados. ## Cómo obtener acceso [#acceso] El acceso es restringido y se otorga por solicitud, para operaciones en Costa Rica. Para conocer el producto y solicitarlo, visitá [baas.tilopay.com](https://baas.tilopay.com), indicando volumen mensual estimado, caso de uso y sistemas a integrar. ## Por dónde seguir [#siguiente] 1. [Autenticación](/developers/api-bancario/autenticacion) — login, intercambio de token y Bearer. 2. [Convenciones](/developers/api-bancario/convenciones) — envelope, correlación, reintentos seguros, paginación y fechas. 3. [Códigos de respuesta](/developers/api-bancario/errores) — catálogo completo de `response_code`. --- # Autenticación del API Bancario > Login, intercambio de token y uso del Bearer JWT en el API Bancario de Tilopay. - kind: concept - status: stable - api_version: 1.0.0 - last_verified: 2026-09-02 - url: https://tilopay.com/developers/api-bancario/autenticacion El API Bancario usa un flujo de dos pasos: primero autenticás al cliente con correo y contraseña, después intercambiás el token resultante por un access token JWT que firma todas las demás llamadas. Los tres endpoints del grupo `Auth` son los únicos que **no** llevan `Authorization`. Todo el resto del API exige `Authorization: Bearer `. ## Paso 1 — Login [#login] ```http POST /api/public/v1/auth/login ``` Cuerpo requerido: `email` (formato email) y `password`. ```json { "email": "operaciones@comercio.com", "password": "••••••••" } ``` La respuesta `200` devuelve en `data`: | Campo | Tipo | Descripción | |---|---|---| | `gidp_id_token` | string | Token de identidad para el paso 2. | | `assignments` | array | Contextos disponibles del cliente. | Cada elemento de `assignments` trae `assignment_id`, `owner_type`, `owner_id`, `tenant_id`, `tenant_code`, `country_code`, `role`, `roles` y `status`. Elegí el `assignment_id` del contexto con el que vas a operar. ## Paso 2 — Intercambio de token [#exchange] ```http POST /api/public/v1/auth/token/exchange ``` Cuerpo requerido: `gidp_id_token` (el del paso 1) y `assignment_id` (el contexto elegido). ```json { "gidp_id_token": "eyJhbGciOi...", "assignment_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6" } ``` La respuesta `200` devuelve en `data`: | Campo | Tipo | Descripción | |---|---|---| | `token` | string | Access token JWT. | | `expires_in` | integer | Vigencia del token en segundos. | | `claims` | object | Contexto resuelto del token. | `claims` incluye `sub`, `subject_kind`, `user_type`, `tenant_id`, `owner_type`, `owner_id`, `roles`, `scopes`, `country_code`, `locale`, `channel`, `idp`, `idp_sub` e `idempotency_key`. ## Paso 3 — Usar el Bearer [#bearer] El esquema de seguridad declarado es `BearerAuth`: HTTP bearer con formato JWT. ```http Authorization: Bearer ``` El contexto viaja **dentro** del token: no se envían `tenant_id`, `owner_id` ni `owner_type` como parámetros en las operaciones de negocio. El token acota por sí solo a qué cuentas y pagos podés acceder. Cuando el token está ausente, vencido o es inválido, la respuesta es `401` con `response_code: UNAUTHORIZED`. Si el token es válido pero el contexto no autoriza el recurso, es `403` con `FORBIDDEN`. Repetí el paso 2 para renovar el access token antes de que se cumpla `expires_in`. ## Contraseñas [#password] ```http POST /api/public/v1/auth/request-set-password ``` Inicia el proceso de establecer o restablecer la contraseña del correo indicado. No requiere autenticación previa y responde siempre igual, exista o no la cuenta, para no revelar si un correo está registrado. ```json { "email": "operaciones@comercio.com" } ``` --- # Convenciones del API Bancario > Envelope de respuesta, correlación, reintentos seguros, paginación y formato de fechas del API Bancario. - kind: concept - status: stable - api_version: 1.0.0 - last_verified: 2026-09-02 - url: https://tilopay.com/developers/api-bancario/convenciones Todas las operaciones del API Bancario comparten el mismo formato de respuesta, las mismas reglas de paginación y el mismo formato de fechas. Acá te explicamos esas reglas comunes. ## Envelope de respuesta [#envelope] Cada respuesta, exitosa o no, viaja en el mismo sobre: ```json { "success": true, "http_status_code": 200, "response_code": "OK", "message": "The request was processed successfully.", "correlation_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "data": {} } ``` | Campo | Tipo | Descripción | |---|---|---| | `success` | boolean | `true` en las respuestas exitosas; `false` en las de error. | | `http_status_code` | integer | Repite el status HTTP en el cuerpo. | | `response_code` | string | Código del [catálogo de `response_code`](/developers/api-bancario/errores). | | `message` | string | Mensaje legible de la respuesta. | | `correlation_id` | string | Identificador de la llamada. | | `data` | object | Carga útil de la operación. | En las respuestas de error el sobre trae además `errors`, un objeto de detalle que puede incluir campos arbitrarios como `code`, `message` o `detail`. Ramificá tu lógica por `response_code`, no por el texto de `message`. ## Correlación [#correlacion] Enviá `X-Correlation-Id` en el request para propagar tu propio identificador; el valor vuelve como `correlation_id` en el sobre. Guardalo en tus logs: es el dato con el que soporte rastrea una llamada puntual. ## Reintentos seguros [#reintentos] Dos operaciones aceptan la cabecera `Idempotency-Key`: ```http POST /api/public/v1/transactions/payments POST /api/public/v1/accounts/statements ``` Reenviar la misma llave con el mismo cuerpo devuelve el resultado original en vez de crear un segundo registro, así un timeout de red se puede reintentar sin duplicar. Si reusás una llave con un cuerpo distinto, la respuesta es `409` con `response_code: IDEMPOTENCY_CONFLICT`. Generá una llave por intención de negocio (por ejemplo un UUID por orden), no una por reintento. El resto de las operaciones son consultas y se pueden repetir sin efectos adicionales. ## Paginación [#paginacion] El API usa dos esquemas según el recurso. **Cursor, en el listado de pagos.** `GET /api/public/v1/transactions/payments` acepta `limit` (por defecto 20, máximo 100) y `cursor`. La respuesta trae `pagination.next_cursor`: pasalo como `cursor` en el siguiente request. Cuando viene vacío u omitido, no hay más páginas. **Offset, en cuentas.** `GET /api/public/v1/accounts` y `GET /api/public/v1/accounts/balances` aceptan `limit` (1 a 100) y `offset` (desde 0), y devuelven `pagination` con `limit`, `offset` y `total`. ## Fechas y montos [#formatos] Los parámetros y campos de fecha usan RFC 3339, por ejemplo `2026-09-02T15:04:05Z`. Los filtros `date_from` y `date_to` del listado de pagos siguen ese mismo formato. ## Salud y documentación del host [#host] El propio host expone tres rutas de servicio: ```http GET /api/public/v1/healthz GET /openapi.yaml GET /docs ``` `healthz` sirve para chequeo de disponibilidad, `openapi.yaml` devuelve la definición OpenAPI y `/docs` la documentación interactiva. En este portal también la publicamos en [openapi.json](/developers/api-bancario/openapi.json) y [openapi.yaml](/developers/api-bancario/openapi.yaml). --- # Pagos del API Bancario > Operaciones de pagos del API Bancario: crear, consultar, listar y buscar pagos PIN y SINPE Móvil. - kind: api-operation - status: stable - api_version: 1.0.0 - last_verified: 2026-09-02 - url: https://tilopay.com/developers/api-bancario/pagos El grupo `Payments` cubre el ciclo completo de un pago: crearlo, consultarlo por identificador, listarlo con filtros y buscarlo por cualquiera de sus referencias. ```http POST /api/public/v1/transactions/payments GET /api/public/v1/transactions/payments GET /api/public/v1/transactions/payments/{payment_id} POST /api/public/v1/transactions/payments/search ``` ## Reglas del recurso [#reglas] **Métodos.** `payment_method_code` admite `PIN` y `SINPE_MOVIL`. **Dirección.** `direction` admite `OUT` (salida) e `IN` (entrada). **Cuenta destino.** se identifica por `IBAN` o por `PHONE`, según el método. **Referencia propia.** `client_reference` es tu identificador del pago y es único por tenant: dos pagos del mismo cliente no pueden compartirlo. Sirve para buscar el pago sin guardar el `payment_id`. **Reintentos seguros.** La creación acepta `Idempotency-Key`; reenviar la misma llave con el mismo cuerpo devuelve el pago original en vez de crear otro. Ver [reintentos seguros](/developers/api-bancario/convenciones#reintentos). ## Estados [#estados] Un pago recorre cinco estados: `pending`, `processing`, `confirmed`, `posted` y `failed`. La reversión **no es un estado**: un pago revertido sigue en `posted` y se reconoce por `result: reversed` y `has_reversal: true`, además del evento [`payment.reversed`](/developers/api-bancario/webhooks). Consultá siempre esos dos campos antes de dar un pago por definitivo. ## Operaciones [#operaciones] ### List customer payments [#get-transactions-payments] ```http GET /api/public/v1/transactions/payments ``` Host: `https://api-baas-sandbox.tilopay.com` — requiere `Authorization: Bearer `. Simple REST list of payments for an owned account (IBAN). Filters are query parameters. Ownership (`tenant_id`, `owner_type`, `owner_id`) is derived from the access token; clients must not send ownership filters. **Account identification (required):** `type` + `value` (identifier scheme + value, e.g. `IBAN` + IBAN string). This is not the internal account classification. Pagination is cursor-based (`limit`, `cursor`). Default limit is 20 (max 100). `status` in the response and as a filter uses the public lowercase catalog (`pending`, `processing`, `confirmed`, `posted`, `failed`). Same values as webhooks. REST also returns `status_detail` (uppercase operational name). Each item includes a consolidated `result` (`succeeded`, `failed`, `reversed`, `pending`) for reconciliation when a webhook was missed. `status` is only the processing/lifecycle catalog and does not change to `failed` when a posted payment is later reversed — use `result=reversed` and `has_reversal=true` (webhook `payment.reversed`). `error` is `null` when there is no failure information; it is an object only when `domain` / `platform` is present (`result` is `failed` or `reversed`), same shape as webhook `payment.failed` `payment.error`. `source` / `destination` use `null` for unknown `account`, `name`, and `identification`; account values are IBAN or PHONE only (never ledger UUIDs). For PIN payments created after public identification persistence, `identification.number` is the partner-submitted public number (no SINPE hyphens); older payments may still show the hyphenated SINPE form. See `docs/PAYMENT-IDENTIFICATION.md`. **Parámetros** | Parámetro | En | Tipo | Obligatorio | Descripción | |---|---|---|---|---| | `X-Correlation-Id` | header | string | — | Optional client-supplied correlation id for end-to-end tracing. Echoed back as `correlation_id` in the response envelope. If omitted, the API generates one and still returns it. | | `type` | query | string | sí | Account **identifier scheme** (e.g. `IBAN`). This is **not** the internal account classification (e.g. operational). Values: IBAN | | `value` | query | string | sí | Account identifier value (IBAN). Spaces are ignored. | | `status` | query | string | — | Optional payment status filter. Public catalog is lowercase: `pending`, `processing`, `confirmed`, `posted`, `failed`. Uppercase aliases of the same values are accepted. Legacy values such as `INITIATED` map to `pending`. Values: pending, processing, confirmed, posted, failed | | `date_from` | query | string (date-time) | — | Inclusive lower bound for `created_at`. RFC 3339 (UTC `Z` or offset; optional fractional seconds). | | `date_to` | query | string (date-time) | — | Inclusive upper bound for `created_at`. RFC 3339 (UTC `Z` or offset; optional fractional seconds). | | `client_reference` | query | string | — | Filter by partner client reference (exact match against the value sent at payment creation). | | `currency` | query | string | — | Filter by payment currency (ISO 4217, e.g. CRC). | | `payment_method_code` | query | string | — | Filter by public payment method code. Values: PIN, SINPE_MOVIL | | `direction` | query | string | — | Filter by payment direction. Accepts public values `OUT`/`IN` or `PAYOUT`/`PAYIN` (internally normalized to `payout`/`payin`). Values: OUT, IN, PAYOUT, PAYIN | | `limit` | query | integer | — | Page size (default 20, max 100). | | `cursor` | query | string | — | Opaque cursor from a previous response `pagination.next_cursor`. | **200** — The request was processed successfully. `response_code`: `OK` Campos de `data`: | Campo | Tipo | Obligatorio | Descripción | |---|---|---|---| | `items` | array | sí | — | | `items[].amount` | object | sí | — | | `items[].amount.amount` | string | sí | — | | `items[].amount.currency` | string | sí | — | | `items[].client_reference` | string | sí | — | | `items[].created_at` | string | sí | — | | `items[].destination` | object | sí | — | | `items[].destination.account` | object | sí | — | | `items[].destination.identification` | object | sí | — | | `items[].destination.name` | string | sí | — | | `items[].error` | object | sí | — | | `items[].error.domain` | string | sí | — | | `items[].error.platform` | object | sí | — | | `items[].external_reference` | string | sí | — | | `items[].has_reversal` | boolean | sí | — | | `items[].payment_id` | string | sí | — | | `items[].payment_method_code` | string | sí | — | | `items[].provider` | object | sí | — | | `items[].provider.correlation_id` | string | sí | — | | `items[].provider.occurred_at` | string | sí | — | | `items[].provider.provider_status_code` | string | sí | — | | `items[].provider.provider_status_desc` | string | sí | — | | `items[].provider.provider_status_semantic` | string | sí | — | | `items[].public_id` | string | sí | — | | `items[].result` | string | sí | — | | `items[].reversed_at` | string | sí | — | | `items[].schema_version` | string | sí | — | | `items[].source` | object | sí | — | | `items[].source.account` | object | sí | — | | `items[].source.identification` | object | sí | — | | `items[].source.name` | string | sí | — | | `items[].status` | string | sí | — | | `items[].status_detail` | string | — | — | | `items[].succeeded_at` | string | sí | — | | `items[].type` | string | sí | — | | `items[].updated_at` | string | sí | — | | `pagination` | object | — | — | | `pagination.limit` | integer | sí | — | | `pagination.next_cursor` | string | — | — | | `schema_version` | string | sí | — | **Respuestas de error** | HTTP | response_code | Descripción | |---|---|---| | 400 | `INVALID_REQUEST` | Invalid request. Check the required fields and try again. | | 401 | `UNAUTHORIZED` | Unauthorized. Verify your session or credentials. | | 403 | `FORBIDDEN`, `ACCOUNT_ACCESS_DENIED` | You do not have permission to perform this action. | | 429 | `TOO_MANY_REQUESTS` | Too many requests. Please retry after a short delay. | | 500 | `INTERNAL_ERROR` | An unexpected error occurred. Please try again later. | | 502 | `PROVIDER_ERROR` | Unable to complete the request with the payment provider. Please try again later. | | 503 | `SERVICE_UNAVAILABLE` | A required service is temporarily unavailable. Please try again later. | ### Create payment [#post-transactions-payments] ```http POST /api/public/v1/transactions/payments ``` Host: `https://api-baas-sandbox.tilopay.com` — requiere `Authorization: Bearer `. Creates a payment using an authorized internal source account. Processing may be asynchronous; HTTP 201 does not imply the payment is finalized. `source.identification.number` and `destination.identification.number` are stored in public form (the submitted digits, without SINPE hyphens) and returned on later payment reads. The GX/SINPE hyphenated form is used only internally and is not the public contract. Idempotency-Key is optional; if omitted, each request is treated as a new attempt. A repeated `client_reference` returns 409 PAYMENT_DUPLICATE when an in-flight or completed payment already uses it; a prior `failed` (or rejected/cancelled/expired) payment does not block a retry with the same `client_reference`. If Idempotency-Key is provided, the same key with the same payload replays the prior response; a different payload with the same key returns 409 IDEMPOTENCY_CONFLICT. **Parámetros** | Parámetro | En | Tipo | Obligatorio | Descripción | |---|---|---|---|---| | `X-Correlation-Id` | header | string | — | Optional client-supplied correlation id for end-to-end tracing. Echoed back as `correlation_id` in the response envelope. If omitted, the API generates one and still returns it. | | `Idempotency-Key` | header | string | — | Optional opaque client key for safe retries. When omitted, each call is a new attempt (duplicates are detected by client_reference on in-flight or completed payments). Reusing a key with a different body returns 409. | **Cuerpo del request** | Campo | Tipo | Obligatorio | Descripción | |---|---|---|---| | `payment_method_code` | string | sí | Public payment method catalog (`PIN`, `SINPE_MOVIL`). Values: PIN, SINPE_MOVIL | | `direction` | string | sí | Operation direction (OUT = payout from internal source) Values: OUT, IN | | `country_code` | string | — | Operational country when multi-country applies | | `amount` | object | sí | — | | `amount.amount` | string | — | — | | `amount.currency` | string | — | — | | `source` | object | sí | — | | `source.account` | object | sí | — | | `source.account.type` | string | sí | Account **identifier scheme**. Only `IBAN` is supported here. This is not the internal account classification (e.g. operational). Values: IBAN | | `source.account.value` | string | sí | IBAN (spaces allowed; normalized server-side) | | `source.name` | string | sí | Account holder name | | `source.identification` | object | sí | Counterparty identification for payment create. `type` uses platform identification-catalog keys (e.g. `cedula`, `juridica`, `dimex`). Same vocabulary as `holder.id_type` from `POST /accounts/validate`. `number` is the public identification (digits, no SINPE hyphens). The platform may reformat it internally for GX/SINPE; that internal form is not echoed on public payment reads for payments created after public identification persistence. For SINPE_MOVIL, account validate may return `unknown` because the wallet operation does not expose identification type; do not assume a confirmed type. | | `source.identification.type` | string | — | Identification catalog key (lowercase), e.g. `cedula`, `juridica`. May be copied from `holder.id_type` after account validate. For SINPE_MOVIL that value may be `unknown` (expected limitation, not an error). | | `source.identification.number` | string | — | Public identification number as submitted by the partner. Digits only; do not send SINPE hyphenation (e.g. `01-1234-3005`) or treat this field as the internal GX/SINPE display form. Supported types include `cedula`, `juridica`, `dimex`, `gobierno`, `institucion_autonoma`, `didi`, and `pasaporte`. | | `destination` | object | sí | — | | `destination.account` | object | sí | — | | `destination.account.type` | string | sí | Counterparty account **identifier scheme** (`IBAN` for PIN, `PHONE` for SINPE_MOVIL). Not the internal account classification. Values: IBAN, PHONE | | `destination.account.value` | string | sí | — | | `destination.name` | string | sí | Counterparty name | | `destination.identification` | object | sí | Counterparty identification for payment create. `type` uses platform identification-catalog keys (e.g. `cedula`, `juridica`, `dimex`). Same vocabulary as `holder.id_type` from `POST /accounts/validate`. `number` is the public identification (digits, no SINPE hyphens). The platform may reformat it internally for GX/SINPE; that internal form is not echoed on public payment reads for payments created after public identification persistence. For SINPE_MOVIL, account validate may return `unknown` because the wallet operation does not expose identification type; do not assume a confirmed type. | | `destination.identification.type` | string | — | Identification catalog key (lowercase), e.g. `cedula`, `juridica`. May be copied from `holder.id_type` after account validate. For SINPE_MOVIL that value may be `unknown` (expected limitation, not an error). | | `destination.identification.number` | string | — | Public identification number as submitted by the partner. Digits only; do not send SINPE hyphenation (e.g. `01-1234-3005`) or treat this field as the internal GX/SINPE display form. Supported types include `cedula`, `juridica`, `dimex`, `gobierno`, `institucion_autonoma`, `didi`, and `pasaporte`. | | `detail_reference` | string | sí | Operational / transactional description stored on the payment | | `client_reference` | string | — | Partner functional reference. Unique per tenant among in-flight and completed payments; a failed attempt can be retried with the same value. | | `channel_reference` | string | — | — | | `originator` | object | — | Optional Ultimate Debtor / Travel Rule originator information. Informational only in this release; no validation is applied. Stored under payment metadata when provided. | | `originator.company` | object | — | — | | `originator.company.legal_name` | string | — | — | | `originator.company.id_type` | string | — | — | | `originator.company.id_number` | string | — | — | | `originator.customer` | object | — | — | | `originator.customer.name` | string | — | — | | `originator.customer.id_type` | string | — | — | | `originator.customer.id_number` | string | — | — | **201** — The resource was created successfully. `response_code`: `CREATED` Campos de `data`: | Campo | Tipo | Obligatorio | Descripción | |---|---|---|---| | `created_at` | string | sí | — | | `payment_id` | string | sí | — | | `payment_method_code` | string | sí | — | | `public_id` | string | sí | — | | `status` | string | sí | — | | `status_detail` | string | sí | — | **Respuestas de error** | HTTP | response_code | Descripción | |---|---|---| | 400 | `PAYMENT_INVALID_PAYLOAD`, `INVALID_PAYMENT_METHOD`, `INVALID_ACCOUNT_TYPE`, `ACCOUNT_INVALID`, `ACCOUNT_HOLDER_MISMATCH` | Invalid payment request payload. | | 401 | `UNAUTHORIZED` | Unauthorized. Verify your session or credentials. | | 403 | `FORBIDDEN`, `ACCOUNT_ACCESS_DENIED` | You do not have permission to perform this action. | | 404 | `ACCOUNT_NOT_FOUND` | Account not found. | | 409 | `IDEMPOTENCY_CONFLICT`, `PAYMENT_DUPLICATE`, `CONFLICT` | Idempotency conflict: the same Idempotency-Key was reused with a different request body, or a previous request is still in progress. | | 422 | `INSUFFICIENT_FUNDS`, `LIMIT_EXCEEDED`, `UNPROCESSABLE_ENTITY` | Insufficient funds to complete the payment. | | 429 | `TOO_MANY_REQUESTS` | Too many requests. Please retry after a short delay. | | 500 | `INTERNAL_ERROR` | An unexpected error occurred. Please try again later. | | 502 | `PROVIDER_ERROR` | Unable to complete the request with the payment provider. Please try again later. | | 503 | `SERVICE_UNAVAILABLE` | A required service is temporarily unavailable. Please try again later. | ### Search payment by identifier [#post-transactions-payments-search] ```http POST /api/public/v1/transactions/payments/search ``` Host: `https://api-baas-sandbox.tilopay.com` — requiere `Authorization: Bearer `. Looks up a single payment within the supplied customer account by exactly one of: - `payment_id` (internal UUID) - `public_id` (numeric public identifier) - `client_reference` (partner reference sent at creation) Sending more than one identifier returns `400`. Response shape matches get-by-id (`schema_version`, payment-level `external_reference`, shared `provider` object, `provider.provider_status_*`, webhook-aligned `error`). Same public contract as `GET /transactions/payments`, including public `identification.number` for PIN payments created after public identification persistence. If several payments share a `client_reference` (failed attempt plus retry), the in-flight or completed payment is returned when one exists. **Parámetros** | Parámetro | En | Tipo | Obligatorio | Descripción | |---|---|---|---|---| | `X-Correlation-Id` | header | string | — | Optional client-supplied correlation id for end-to-end tracing. Echoed back as `correlation_id` in the response envelope. If omitted, the API generates one and still returns it. | **Cuerpo del request** | Campo | Tipo | Obligatorio | Descripción | |---|---|---|---| | `account` | object | sí | — | | `account.type` | string | sí | Account **identifier scheme** (e.g. `IBAN`, `PHONE`). Not the internal account classification (e.g. operational). Values: IBAN, PHONE | | `account.value` | string | sí | — | | `account.currency` | string | — | Optional account currency in response payloads. | | `payment_id` | string (uuid) | — | Internal payment UUID. | | `public_id` | string | — | Numeric public payment identifier. | | `client_reference` | string | — | Partner reference sent at payment creation. | **Ejemplo de request** — byPaymentId ```json { "account": { "type": "IBAN", "value": "CR08036900101010933608" }, "payment_id": "11111111-1111-1111-1111-111111111111" } ``` **Ejemplo de request** — byPublicId ```json { "account": { "type": "IBAN", "value": "CR08036900101010933608" }, "public_id": "134729" } ``` **Ejemplo de request** — byClientReference ```json { "account": { "type": "IBAN", "value": "CR08036900101010933608" }, "client_reference": "INV-01082" } ``` **200** — The request was processed successfully. `response_code`: `OK` Campos de `data`: | Campo | Tipo | Obligatorio | Descripción | |---|---|---|---| | `amount` | object | sí | — | | `amount.amount` | string | sí | — | | `amount.currency` | string | sí | — | | `client_reference` | string | sí | — | | `created_at` | string | sí | — | | `destination` | object | sí | — | | `destination.account` | object | sí | — | | `destination.account.currency` | string | — | — | | `destination.account.type` | string | sí | — | | `destination.account.value` | string | sí | — | | `destination.identification` | object | sí | — | | `destination.identification.number` | string | sí | — | | `destination.identification.type` | string | sí | — | | `destination.name` | string | sí | — | | `error` | object | sí | — | | `error.domain` | string | sí | — | | `error.platform` | object | sí | — | | `error.platform.code` | string | sí | — | | `error.platform.message` | string | sí | — | | `external_reference` | string | sí | — | | `has_reversal` | boolean | sí | — | | `payment_id` | string | sí | — | | `payment_method_code` | string | sí | — | | `provider` | object | sí | — | | `provider.correlation_id` | string | sí | — | | `provider.occurred_at` | string | sí | — | | `provider.provider_status_code` | string | sí | — | | `provider.provider_status_desc` | string | sí | — | | `provider.provider_status_semantic` | string | sí | — | | `public_id` | string | sí | — | | `result` | string | sí | — | | `reversed_at` | string | sí | — | | `schema_version` | string | sí | — | | `source` | object | sí | — | | `source.account` | object | sí | — | | `source.account.currency` | string | — | — | | `source.account.type` | string | sí | — | | `source.account.value` | string | sí | — | | `source.identification` | object | sí | — | | `source.identification.number` | string | sí | — | | `source.identification.type` | string | sí | — | | `source.name` | string | sí | — | | `status` | string | sí | — | | `status_detail` | string | — | — | | `succeeded_at` | string | sí | — | | `type` | string | sí | — | | `updated_at` | string | sí | — | **Respuestas de error** | HTTP | response_code | Descripción | |---|---|---| | 400 | `INVALID_REQUEST` | Invalid request. Check the required fields and try again. | | 401 | `UNAUTHORIZED` | Unauthorized. Verify your session or credentials. | | 403 | `FORBIDDEN`, `ACCOUNT_ACCESS_DENIED` | You do not have permission to perform this action. | | 404 | `PAYMENT_NOT_FOUND` | Payment not found. | | 429 | `TOO_MANY_REQUESTS` | Too many requests. Please retry after a short delay. | | 500 | `INTERNAL_ERROR` | An unexpected error occurred. Please try again later. | | 502 | `PROVIDER_ERROR` | Unable to complete the request with the payment provider. Please try again later. | | 503 | `SERVICE_UNAVAILABLE` | A required service is temporarily unavailable. Please try again later. | ### Get payment by id [#get-transactions-payments-payment-id] ```http GET /api/public/v1/transactions/payments/{payment_id} ``` Host: `https://api-baas-sandbox.tilopay.com` — requiere `Authorization: Bearer `. Returns a single payment using the same public contract as the list endpoint, including consolidated `result`, `succeeded_at`, `has_reversal`, and `error`. `error` is `null` when there is no failure information; it is an object only when `domain` / `platform` is present (`result` is `failed` or `reversed`), same shape as webhook `payment.failed` `payment.error`. `source` / `destination` use `null` for unknown nested fields and never expose ledger UUIDs. `identification.number` on PIN payments created after public identification persistence is the partner-submitted public number (digits, no SINPE hyphens). Older payments may still return the hyphenated SINPE form from processing metadata. Use this as a webhook backup. Looks up a payment by either identifier: - `payment_id` (internal UUID) - `public_id` (numeric public identifier) For `client_reference`, use `POST /api/public/v1/transactions/payments/search`. **Parámetros** | Parámetro | En | Tipo | Obligatorio | Descripción | |---|---|---|---|---| | `X-Correlation-Id` | header | string | — | Optional client-supplied correlation id for end-to-end tracing. Echoed back as `correlation_id` in the response envelope. If omitted, the API generates one and still returns it. | | `payment_id` | path | string | sí | Internal payment UUID or numeric public_id. | **200** — The request was processed successfully. `response_code`: `OK` Campos de `data`: | Campo | Tipo | Obligatorio | Descripción | |---|---|---|---| | `amount` | object | sí | — | | `amount.amount` | string | sí | — | | `amount.currency` | string | sí | — | | `client_reference` | string | sí | — | | `created_at` | string | sí | — | | `destination` | object | sí | — | | `destination.account` | object | sí | — | | `destination.account.currency` | string | — | — | | `destination.account.type` | string | sí | — | | `destination.account.value` | string | sí | — | | `destination.identification` | object | sí | — | | `destination.identification.number` | string | sí | — | | `destination.identification.type` | string | sí | — | | `destination.name` | string | sí | — | | `error` | object | sí | — | | `error.domain` | string | sí | — | | `error.platform` | object | sí | — | | `error.platform.code` | string | sí | — | | `error.platform.message` | string | sí | — | | `external_reference` | string | sí | — | | `has_reversal` | boolean | sí | — | | `payment_id` | string | sí | — | | `payment_method_code` | string | sí | — | | `provider` | object | sí | — | | `provider.correlation_id` | string | sí | — | | `provider.occurred_at` | string | sí | — | | `provider.provider_status_code` | string | sí | — | | `provider.provider_status_desc` | string | sí | — | | `provider.provider_status_semantic` | string | sí | — | | `public_id` | string | sí | — | | `result` | string | sí | — | | `reversed_at` | string | sí | — | | `schema_version` | string | sí | — | | `source` | object | sí | — | | `source.account` | object | sí | — | | `source.account.currency` | string | — | — | | `source.account.type` | string | sí | — | | `source.account.value` | string | sí | — | | `source.identification` | object | sí | — | | `source.identification.number` | string | sí | — | | `source.identification.type` | string | sí | — | | `source.name` | string | sí | — | | `status` | string | sí | — | | `status_detail` | string | — | — | | `succeeded_at` | string | sí | — | | `type` | string | sí | — | | `updated_at` | string | sí | — | **Respuestas de error** | HTTP | response_code | Descripción | |---|---|---| | 400 | `INVALID_REQUEST` | Invalid request. Check the required fields and try again. | | 401 | `UNAUTHORIZED` | Unauthorized. Verify your session or credentials. | | 403 | `FORBIDDEN`, `ACCOUNT_ACCESS_DENIED` | You do not have permission to perform this action. | | 404 | `PAYMENT_NOT_FOUND` | Payment not found. | | 429 | `TOO_MANY_REQUESTS` | Too many requests. Please retry after a short delay. | | 500 | `INTERNAL_ERROR` | An unexpected error occurred. Please try again later. | | 502 | `PROVIDER_ERROR` | Unable to complete the request with the payment provider. Please try again later. | | 503 | `SERVICE_UNAVAILABLE` | A required service is temporarily unavailable. Please try again later. | ### Validate external account for a payment method [#post-accounts-validate] ```http POST /api/public/v1/accounts/validate ``` Host: `https://api-baas-sandbox.tilopay.com` — requiere `Authorization: Bearer `. Validates a counterparty account (IBAN or phone) via the SINPE provider for the given payment method. Does not validate internal ledger accounts. When valid, `data.holder.id_type` uses the same identification catalog keys as `identification.type` in `POST /payments` (e.g. `cedula`, `juridica`, `dimex`). ## SINPE_MOVIL field availability (expected, stable) For `payment_method_code = SINPE_MOVIL`, the backing wallet operation (`ObtenerInfoMonedero`) does not return identification type or institution name. A successful validation **may** therefore return: - `data.holder.id_type` = `unknown` - `data.financial_institution.entity_name` = `""` (empty string) This is **expected, stable behavior**, not a mapping bug or a transient provider error. PIN (`ObtenerInformacionCuentaSinpe`) does populate both fields. Integrators must not report these values as defects, and must not assume that `holder.id_type` or `financial_institution.entity_name` are always populated when `is_valid` is true. ## SINPE rejection codes (`data.rejection`) When `is_valid` is `false`, `data.rejection` explains why (see the `rejected` example on the `200` response below). `rejection.code` is one of a fixed set of normalized semantics (see the `WebhookRejection.code` schema enum). **Most rows in the table below do NOT get a distinct `code`** — only a subset of `reason_code` values has a dedicated semantic; every other `reason_code`, even one listed below with a specific `message`, returns `code = SINPE_REJECTED` (e.g. `reason_code = 21` "fondos insuficientes" still returns `SINPE_REJECTED`). This same object and catalog is also used by the `payment.failed` webhook's `rejection` field. A `reason_code` not listed here at all still produces a response — `message` falls back to a generic text and `code` falls back to `SINPE_REJECTED`. **Cuenta / perfil / límites** | Code | Message | |---|---| | 21 | Cuenta Cliente con fondos insuficientes | | 22 | Cuenta Cliente no admite créditos | | 23 | Cuenta Cliente cerrada | | 24 | Cuenta Cliente inactiva | | 25 | Cuenta Cliente no admite débitos | | 26 | Cuenta Cliente no es de fondos | | 27 | Moneda de la Cuenta Cliente no corresponde | | 28 | Cuenta cliente no existe | | 29 | Cuenta Cliente no registrada en el SINPE | | 30 | Cuenta Cliente no habilitada para el servicio | | 31 | Cuenta Cliente bloqueada | | 32 | Id cliente destino no coincide con registrado en la entidad | | 33 | Nombre del cliente destino no coincide con el registrado en la entidad | | 34 | Cuenta Cliente en proceso de cierre | | 35 | Cuenta Cliente embargada | | 36 | Cuenta Cliente con retención judicial | | 37 | Cuenta de expediente simplificado no permite el monto indicado | | 38 | Límite transaccional de la Cuenta Cliente excedido | | 39 | Cuenta Cliente incorrecta | | 40 | IBAN de la cuenta destino inválido | | 41 | IBAN de la cuenta origen inválido | | 42 | Tipo de cuenta no permite la transacción | | 43 | Cuenta Cliente no pertenece a la entidad indicada | | 44 | Producto de la cuenta no admite el servicio | | 45 | Cuenta Cliente en estado de cancelación | | 46 | Cuenta Cliente restringida por política de la entidad | | 47 | Cuenta Cliente no permite pagos inmediatos | | 48 | Cuenta Cliente no permite SINPE Móvil | | 49 | Titular de la cuenta destino fallecido | | 50 | Cuenta Cliente consolidada o migrada | | 51 | Identificación del cliente origen no coincide | | 52 | Identificación del cliente destino inválida | | 53 | Cliente destino no autorizado para recibir el pago | | 54 | Cliente origen no autorizado para enviar el pago | | 55 | Perfil del cliente origen no permite la transacción | | 56 | Monto inferior al mínimo permitido | | 57 | Monto superior al máximo permitido | | 58 | Cantidad de transacciones diarias excedida | | 59 | Cantidad de transacciones mensuales excedida | | 60 | Límite acumulado diario excedido | | 61 | Límite acumulado mensual excedido | | 62 | Comisión no pudo ser aplicada | | 63 | Tipo de cambio no disponible | | 64 | Transacción rechazada por control de lavado de dinero | | 65 | Transacción rechazada por listas de control | | 66 | Transacción en revisión de cumplimiento | | 67 | Documento de respaldo requerido no presente | | 68 | Firma o autenticación inválida | | 69 | Token o segundo factor inválido | | 70 | Sesión de usuario expirada | | 71 | Usuario no autorizado para el canal | | 72 | Dispositivo no registrado | | 73 | Geolocalización no permitida | | 74 | Operación no soportada en la moneda indicada | | 75 | Operación no soportada para el tipo de cliente | | 76 | Problemas de comunicación | | 77 | Tiempo de espera agotado en la entidad origen | | 78 | Tiempo de espera agotado en el SINPE | | 79 | Error interno de la entidad origen | | 80 | Error interno de la entidad destino | | 81 | Entidad origen no disponible | | 82 | Entidad destino no encontrada | | 83 | Problemas en la respuesta del destino | | 84 | Respuesta de la entidad origen incorrecta | | 85 | Mensaje con formato electrónico inválido | | 86 | Versión del estándar electrónico no soportada | | 87 | Campo obligatorio no informado | | 88 | Campo con valor fuera de catálogo | | 89 | Checksum o integridad del mensaje inválida | | 90 | Referencia SINPE duplicada | | 91 | Moneda no corresponde | | 92 | Transacción no autorizada por entidad destino | | 93 | Transacción no autorizada por cliente destino | | 94 | Transacción no autorizada por entidad origen | | 95 | Transacción no autorizada por cliente origen | | 96 | Reverso no permitido para el estado de la transacción | | 97 | Reverso ya aplicado | | 98 | Confirmación no permitida para el estado de la transacción | | 99 | Liquidación no permitida para el estado de la transacción | | 100 | Entidad Destino no disponible para procesar en tiempo real | | 101 | Entidad origen no disponible para procesar en tiempo real | | 102 | Servicio PIN no habilitado para la entidad destino | | 103 | Servicio PIN no habilitado para la entidad origen | | 104 | Código de entidad destino inválido | | 105 | Código de entidad origen inválido | | 106 | Código de país de la entidad destino inválido | | 107 | Código de país de la entidad origen inválido | | 108 | Número de referencia interna inválido | | 109 | Número de referencia SINPE inválido | | 110 | Transacción no se encuentra en un estado que permita la consulta | **Compensación con entidad destino** | Code | Message | |---|---| | 201 | Tiempo respuesta excedido por la entidad destino | | 202 | Respuesta de la entidad destino incorrecta según el estándar electrónico | | 203 | Se recibió una excepción de la entidad destino | | 204 | Error de comunicación con la entidad destino | | 205 | Falló procesamiento en el SINPE | | 206 | Transacción no autorizada por cliente destino | | 207 | Perfil transaccional del cliente destino no permite recibir el pago | | 208 | Falló la acreditación en la cuenta destino | | 209 | Falló el débito en la cuenta origen | | 210 | Conciliación de la transacción no fue posible | **Identificación** | Code | Message | |---|---| | 801 | Identificación inválida | | 802 | Identificación del cliente origen no encontrada | | 803 | Identificación del cliente destino no encontrada | | 804 | Identificación no vigente | | 805 | Identificación vencida | | 806 | Identificación no corresponde al tipo indicado | | 807 | Tipo de identificación inválido | | 808 | País de la identificación no soportado | | 809 | Identificación de menor de edad no permitida | | 810 | Identificación de persona jurídica no permitida para el servicio | **Validación de formato / Core Bancario** | Code | Message | |---|---| | 1001 | Cuenta cliente activa | | 1002 | El Id de cliente destino no cumple con el formato esperado por el SINPE | | 1003 | El Id de cliente origen no fue informado | | 1004 | El Id de cliente origen no cumple con el formato esperado por el SINPE | | 1005 | Monto con formato inválido | | 1006 | Moneda con formato inválido | | 1007 | Problemas de comunicación con el Core Bancario | | 1008 | Core Bancario no disponible | | 1009 | El valor para el campo no puede ser nulo o infringir su longitud mínima o máxima | | 1010 | El valor para el campo no corresponde al tipo de dato esperado | | 1011 | El valor para el campo no corresponde al catálogo permitido | | 1012 | Fecha con formato inválido | | 1013 | Hora con formato inválido | | 1014 | Número de referencia con formato inválido | | 1015 | IBAN con formato inválido | **Canal / tipo de identificación** | Code | Message | |---|---| | 1040 | Canal no informado | | 1041 | Canal inválido | | 1042 | Canal no corresponde | | 1043 | Canal no habilitado para la entidad | | 1044 | Canal no habilitado para el servicio | | 1045 | El formato de la identificación es inválido | | 1046 | Tipo de identificación no informado | | 1080 | Tipo de identificación no corresponde al cliente origen | | 1081 | Tipo de identificación no corresponde al cliente destino | | 1082 | Tipo de identificación no vigente | | 1083 | Tipo de identificación no soportado por el servicio | | 1084 | Tipo de identificación inválido | | 1085 | Tipo de identificación no soportado por la entidad | **SINPE Móvil (monedero)** | Code | Message | |---|---| | 15300 | El número de teléfono origen indicado es inválido | | 15301 | El número de teléfono origen no tiene activo el Servicio Monedero | | 15302 | El número de teléfono destino indicado es inválido | | 15303 | El número de teléfono destino no está registrado en el padrón móvil del BCCR | | 15304 | No es posible inactivar el monedero indicado pues no existe | | 15305 | El número de teléfono indicado ya se encuentra activo como monedero en el padrón local | ⚠️ This catalog is under review — some entries (notably `208` and `209`) are known to be pending verification against the official SINPE source and may be corrected in a future revision without notice. **Parámetros** | Parámetro | En | Tipo | Obligatorio | Descripción | |---|---|---|---|---| | `X-Correlation-Id` | header | string | — | Optional client-supplied correlation id for end-to-end tracing. Echoed back as `correlation_id` in the response envelope. If omitted, the API generates one and still returns it. | **Cuerpo del request** | Campo | Tipo | Obligatorio | Descripción | |---|---|---|---| | `payment_method_code` | string | sí | Payment method used to route validation (PIN for external IBAN, SINPE_MOVIL for phone wallet). Values: PIN, SINPE_MOVIL | | `account` | object | sí | — | | `account.type` | string | sí | Values: IBAN, PHONE | | `account.value` | string | sí | — | **Ejemplo de request** — pin ```json { "payment_method_code": "PIN", "account": { "type": "IBAN", "value": "CR16010400000000000031" } } ``` **Ejemplo de request** — sinpe_movil ```json { "payment_method_code": "SINPE_MOVIL", "account": { "type": "PHONE", "value": "88887777" } } ``` **200** — The request was processed successfully. `response_code`: `OK` Campos de `data`: | Campo | Tipo | Obligatorio | Descripción | |---|---|---|---| | `account` | object | sí | — | | `account.currency` | string | sí | — | | `account.product_name` | string | sí | — | | `account.type` | string | sí | — | | `account.value` | string | sí | — | | `financial_institution` | object | sí | — | | `financial_institution.country_code` | string | sí | — | | `financial_institution.entity_code` | string | sí | — | | `financial_institution.entity_name` | string | sí | — | | `holder` | object | sí | — | | `holder.id_number` | string | sí | — | | `holder.id_type` | string | sí | — | | `holder.name` | string | sí | — | | `is_valid` | boolean | sí | — | | `provider` | object | sí | — | | `provider.correlation_id` | string | — | — | | `provider.occurred_at` | string | — | — | | `provider.operation` | string | sí | — | | `rejection` | object | sí | — | | `rejection.code` | string | sí | — | | `rejection.message` | string | sí | — | | `rejection.reason_code` | string | sí | — | **Respuestas de error** | HTTP | response_code | Descripción | |---|---|---| | 400 | `INVALID_REQUEST`, `INVALID_ACCOUNT_TYPE`, `INVALID_ACCOUNT_FORMAT`, `INVALID_PAYMENT_METHOD` | Invalid request. Check the required fields and try again. | | 401 | `UNAUTHORIZED` | Unauthorized. Verify your session or credentials. | | 403 | `FORBIDDEN`, `ACCOUNT_ACCESS_DENIED` | You do not have permission to perform this action. | | 422 | `UNPROCESSABLE_ENTITY` | The request is well-formed but cannot be processed due to business rules. | | 429 | `TOO_MANY_REQUESTS` | Too many requests. Please retry after a short delay. | | 500 | `INTERNAL_ERROR` | An unexpected error occurred. Please try again later. | | 502 | `PROVIDER_ERROR` | Unable to complete the request with the payment provider. Please try again later. | --- # Cuentas del API Bancario > Operaciones de cuentas del API Bancario: validación, listado, saldos y estados de cuenta. - kind: api-operation - status: stable - api_version: 1.0.0 - last_verified: 2026-09-02 - url: https://tilopay.com/developers/api-bancario/cuentas El grupo `Accounts` cubre la cuenta como recurso: validar una cuenta destino antes de transferir, listar las cuentas accesibles, consultar saldos y pedir estados de cuenta. ```http POST /api/public/v1/accounts/validate GET /api/public/v1/accounts GET /api/public/v1/accounts/balances GET /api/public/v1/accounts/balance POST /api/public/v1/accounts/statements GET /api/public/v1/accounts/statements/{request_id} ``` ## Reglas del recurso [#reglas] **Alcance.** El listado devuelve sólo las cuentas que autoriza el token; no se envía `tenant_id` ni `owner_id` como parámetro. **Validación previa.** Validá la cuenta destino antes de crear un pago: la operación confirma que la cuenta existe y es apta, y devuelve los datos del titular que el servicio expone. **Estados de cuenta asincrónicos.** La generación se solicita con un `POST` que acepta `Idempotency-Key` y devuelve un `request_id`; después consultás ese `request_id` hasta que el resultado esté disponible. Ver [reintentos seguros](/developers/api-bancario/convenciones#reintentos). **Paginación.** `GET /api/public/v1/accounts` y `GET /api/public/v1/accounts/balances` usan `limit` y `offset`, y devuelven `pagination` con `limit`, `offset` y `total`. ## Operaciones [#operaciones] ### List balances for accessible accounts [#get-accounts-balances] ```http GET /api/public/v1/accounts/balances ``` Host: `https://api-baas-sandbox.tilopay.com` — requiere `Authorization: Bearer `. Returns paginated account balances (`account`, `amounts`, `as_of`). This endpoint checks the current balance in real time and may respond more slowly than `GET /accounts`. For account attributes without amounts, use `GET /accounts`. Optional filters use the public account identification standard: `type` + `value` (identifier scheme + value). `type` is not the internal account classification. **Parámetros** | Parámetro | En | Tipo | Obligatorio | Descripción | |---|---|---|---|---| | `X-Correlation-Id` | header | string | — | Optional client-supplied correlation id for end-to-end tracing. Echoed back as `correlation_id` in the response envelope. If omitted, the API generates one and still returns it. | | `limit` | query | integer | — | — | | `offset` | query | integer | — | — | | `type` | query | string | — | Optional filter by account **identifier scheme** (e.g. `IBAN`). Not the internal account classification. | | `value` | query | string | — | Optional filter by account identifier value (partial match supported for list endpoints). | **200** — The request was processed successfully. `response_code`: `OK` Campos de `data`: | Campo | Tipo | Obligatorio | Descripción | |---|---|---|---| | `items` | array | sí | — | | `items[].account` | object | sí | — | | `items[].account.currency` | string | — | — | | `items[].account.type` | string | sí | — | | `items[].account.value` | string | sí | — | | `items[].amounts` | object | sí | — | | `items[].amounts.available` | string | sí | — | | `items[].amounts.inbound_in_transit` | string | sí | — | | `items[].amounts.outbound_in_transit` | string | sí | — | | `items[].amounts.posted` | string | sí | — | | `items[].as_of` | string | sí | — | | `pagination` | object | sí | — | | `pagination.limit` | integer | sí | — | | `pagination.offset` | integer | sí | — | | `pagination.total` | integer | sí | — | **Respuestas de error** | HTTP | response_code | Descripción | |---|---|---| | 400 | `INVALID_REQUEST` | Invalid request. Check the required fields and try again. | | 401 | `UNAUTHORIZED` | Unauthorized. Verify your session or credentials. | | 403 | `FORBIDDEN`, `ACCOUNT_ACCESS_DENIED` | You do not have permission to perform this action. | | 404 | `NOT_FOUND` | The requested resource was not found. | | 429 | `TOO_MANY_REQUESTS` | Too many requests. Please retry after a short delay. | | 500 | `INTERNAL_ERROR` | An unexpected error occurred. Please try again later. | | 502 | — | Dependency error | | 503 | `SERVICE_UNAVAILABLE` | A required service is temporarily unavailable. Please try again later. | ### List accessible accounts without balances [#get-accounts] ```http GET /api/public/v1/accounts ``` Host: `https://api-baas-sandbox.tilopay.com` — requiere `Authorization: Bearer `. Returns paginated accessible accounts without querying current balances. Each item is account attributes only (`account.type`, `account.value`, `account.currency`). `amounts` and `as_of` are not included; use `GET /accounts/balances` or `POST /accounts/balance`. Optional filters use the public account identification standard: `type` + `value` (identifier scheme + value). `type` is not the internal account classification. **Parámetros** | Parámetro | En | Tipo | Obligatorio | Descripción | |---|---|---|---|---| | `X-Correlation-Id` | header | string | — | Optional client-supplied correlation id for end-to-end tracing. Echoed back as `correlation_id` in the response envelope. If omitted, the API generates one and still returns it. | | `limit` | query | integer | — | — | | `offset` | query | integer | — | — | | `type` | query | string | — | Optional filter by account **identifier scheme** (e.g. `IBAN`). Not the internal account classification. | | `value` | query | string | — | Optional filter by account identifier value (partial match supported for list endpoints). | **200** — The request was processed successfully. `response_code`: `OK` Campos de `data`: | Campo | Tipo | Obligatorio | Descripción | |---|---|---|---| | `items` | array | sí | — | | `items[].account` | object | sí | — | | `items[].account.currency` | string | — | — | | `items[].account.type` | string | sí | — | | `items[].account.value` | string | sí | — | | `pagination` | object | sí | — | | `pagination.limit` | integer | sí | — | | `pagination.offset` | integer | sí | — | | `pagination.total` | integer | sí | — | **Respuestas de error** | HTTP | response_code | Descripción | |---|---|---| | 400 | `INVALID_REQUEST` | Invalid request. Check the required fields and try again. | | 401 | `UNAUTHORIZED` | Unauthorized. Verify your session or credentials. | | 403 | `FORBIDDEN` | You do not have permission to perform this action. | | 404 | `NOT_FOUND` | The requested resource was not found. | | 429 | `TOO_MANY_REQUESTS` | Too many requests. Please retry after a short delay. | | 500 | `INTERNAL_ERROR` | An unexpected error occurred. Please try again later. | | 502 | — | Dependency error | | 503 | `SERVICE_UNAVAILABLE` | A required service is temporarily unavailable. Please try again later. | ### Get account balance [#post-accounts-balance] ```http POST /api/public/v1/accounts/balance ``` Host: `https://api-baas-sandbox.tilopay.com` — requiere `Authorization: Bearer `. Returns a single account snapshot with `amounts` and `as_of`. For account attributes without balances, use `GET /accounts`. **Parámetros** | Parámetro | En | Tipo | Obligatorio | Descripción | |---|---|---|---|---| | `X-Correlation-Id` | header | string | — | Optional client-supplied correlation id for end-to-end tracing. Echoed back as `correlation_id` in the response envelope. If omitted, the API generates one and still returns it. | **Cuerpo del request** | Campo | Tipo | Obligatorio | Descripción | |---|---|---|---| | `account` | object | sí | — | | `account.type` | string | sí | Account **identifier scheme**. Only `IBAN` is supported here. This is not the internal account classification (e.g. operational). Values: IBAN | | `account.value` | string | sí | IBAN (spaces allowed; normalized server-side) | **200** — The request was processed successfully. `response_code`: `OK` Campos de `data`: | Campo | Tipo | Obligatorio | Descripción | |---|---|---|---| | `account` | object | sí | — | | `account.currency` | string | — | — | | `account.type` | string | sí | — | | `account.value` | string | sí | — | | `amounts` | object | sí | — | | `amounts.available` | string | sí | — | | `amounts.inbound_in_transit` | string | sí | — | | `amounts.outbound_in_transit` | string | sí | — | | `amounts.posted` | string | sí | — | | `as_of` | string | sí | — | **Respuestas de error** | HTTP | response_code | Descripción | |---|---|---| | 400 | `INVALID_REQUEST` | Invalid request. Check the required fields and try again. | | 401 | `UNAUTHORIZED` | Unauthorized. Verify your session or credentials. | | 403 | `FORBIDDEN`, `ACCOUNT_ACCESS_DENIED` | You do not have permission to perform this action. | | 404 | `ACCOUNT_NOT_FOUND` | Account not found. | | 422 | `ACCOUNT_NOT_CONFIGURED`, `UNPROCESSABLE_ENTITY` | This account is not mapped in the system. Please contact support to configure it correctly. | | 429 | `TOO_MANY_REQUESTS` | Too many requests. Please retry after a short delay. | | 500 | `INTERNAL_ERROR` | An unexpected error occurred. Please try again later. | | 502 | `PROVIDER_ERROR` | Unable to complete the request with the payment provider. Please try again later. | | 503 | `SERVICE_UNAVAILABLE` | A required service is temporarily unavailable. Please try again later. | ### Request account statement generation [#post-accounts-statements] ```http POST /api/public/v1/accounts/statements ``` Host: `https://api-baas-sandbox.tilopay.com` — requiere `Authorization: Bearer `. Creates an asynchronous account statement request for a date range (max 60 days). Identify the account with `account.type` + `account.value` (identifier scheme + value, e.g. IBAN). This follows the public account identification standard. `account.type` is not the internal account classification. Returns `{request_id, status: PENDING}` immediately. Poll `GET /accounts/statements/{request_id}` for status; when `DONE`, the response includes a signed `download_url`. **Parámetros** | Parámetro | En | Tipo | Obligatorio | Descripción | |---|---|---|---|---| | `X-Correlation-Id` | header | string | — | Optional client-supplied correlation id for end-to-end tracing. Echoed back as `correlation_id` in the response envelope. If omitted, the API generates one and still returns it. | | `Idempotency-Key` | header | string | — | — | **Cuerpo del request** | Campo | Tipo | Obligatorio | Descripción | |---|---|---|---| | `account` | object | sí | — | | `account.type` | string | sí | Account **identifier scheme**. Only `IBAN` is supported here. This is not the internal account classification (e.g. operational). Values: IBAN | | `account.value` | string | sí | IBAN (spaces allowed; normalized server-side) | | `date_from` | string (date-time) | sí | RFC 3339 timestamp accepted on requests. UTC `Z` or a numeric offset is allowed. Optional fractional seconds are accepted and truncated to seconds. | | `date_to` | string | sí | RFC 3339 (max 60 days after date_from) | | `notify_email` | boolean | — | — | **200** — The request was processed successfully. `response_code`: `OK` Campos de `data`: | Campo | Tipo | Obligatorio | Descripción | |---|---|---|---| | `request_id` | string | sí | — | | `status` | string | sí | — | **202** — Statement request accepted. Campos de `data`: | Campo | Tipo | Obligatorio | Descripción | |---|---|---|---| | `request_id` | string (uuid) | sí | — | | `status` | string | sí | Values: PENDING, PROCESSING, DONE, ERROR | **Respuestas de error** | HTTP | response_code | Descripción | |---|---|---| | 400 | `INVALID_REQUEST` | Invalid request. Check the required fields and try again. | | 401 | `UNAUTHORIZED` | Unauthorized. Verify your session or credentials. | | 403 | `FORBIDDEN`, `ACCOUNT_ACCESS_DENIED` | You do not have permission to perform this action. | | 404 | `NOT_FOUND` | The requested resource was not found. | | 409 | `IDEMPOTENCY_CONFLICT` | Idempotency conflict: the same Idempotency-Key was reused with a different request body, or a previous request is still in progress. | | 429 | `TOO_MANY_REQUESTS` | Too many requests. Please retry after a short delay. | | 500 | `INTERNAL_ERROR` | An unexpected error occurred. Please try again later. | | 502 | — | Dependency error | | 503 | `SERVICE_UNAVAILABLE` | A required service is temporarily unavailable. Please try again later. | ### Get account statement request status [#get-accounts-statements-request-id] ```http GET /api/public/v1/accounts/statements/{request_id} ``` Host: `https://api-baas-sandbox.tilopay.com` — requiere `Authorization: Bearer `. Returns request status. When `DONE`, includes a GCS signed `download_url` (48h from generation) and `expires_at`. When `ERROR`, includes a generic `message` without internal details. Unknown or unauthorized `request_id` returns 404. **Parámetros** | Parámetro | En | Tipo | Obligatorio | Descripción | |---|---|---|---|---| | `X-Correlation-Id` | header | string | — | Optional client-supplied correlation id for end-to-end tracing. Echoed back as `correlation_id` in the response envelope. If omitted, the API generates one and still returns it. | | `request_id` | path | string (uuid) | sí | — | **200** — The request was processed successfully. `response_code`: `OK` Campos de `data`: | Campo | Tipo | Obligatorio | Descripción | |---|---|---|---| | `download_url` | string | — | — | | `expires_at` | string | — | — | | `message` | string | — | — | | `request_id` | string | sí | — | | `status` | string | sí | — | **Respuestas de error** | HTTP | response_code | Descripción | |---|---|---| | 401 | `UNAUTHORIZED` | Unauthorized. Verify your session or credentials. | | 403 | `FORBIDDEN` | You do not have permission to perform this action. | | 404 | `NOT_FOUND` | The requested resource was not found. | | 429 | `TOO_MANY_REQUESTS` | Too many requests. Please retry after a short delay. | | 500 | `INTERNAL_ERROR` | An unexpected error occurred. Please try again later. | | 503 | `SERVICE_UNAVAILABLE` | A required service is temporarily unavailable. Please try again later. | --- # Webhooks del API Bancario > Registro de destino, features suscribibles y contratos de payload de los webhooks del API Bancario. - kind: api-operation - status: stable - api_version: 1.0.0 - last_verified: 2026-09-02 - url: https://tilopay.com/developers/api-bancario/webhooks El grupo `Webhooks` permite registrar el destino HTTPS donde recibís los eventos, ver qué features podés suscribir por método de pago y consultar el contrato de payload de cada evento antes de escribir el receptor. ```http POST /api/public/v1/webhook/destination GET /api/public/v1/webhook/features GET /api/public/v1/webhook/event-contracts/{event_type} ``` ## Eventos [#eventos] Nuestro API te notifica cuatro tipos de evento: | Evento | Cuándo llega | |---|---| | `payin.posted` | Se acreditó un movimiento de entrada. | | `payment.succeeded` | El pago terminó de forma exitosa. | | `payment.failed` | El pago terminó con falla. | | `payment.reversed` | El pago fue revertido. | Un pago revertido conserva el estado `posted` y se distingue por `result: reversed` y `has_reversal: true`; ver [estados del pago](/developers/api-bancario/pagos#estados). ## Buenas prácticas del receptor [#receptor] Respondé `2xx` en cuanto recibís el evento y procesá aparte: un receptor lento provoca reenvíos. Tratá los eventos como potencialmente repetidos y deduplicá por el identificador del pago. Y no confíes el estado final sólo al webhook: confirmalo con [la consulta del pago](/developers/api-bancario/pagos#operaciones). ## Operaciones [#operaciones] ### Create webhook destination [#post-webhook-destination] ```http POST /api/public/v1/webhook/destination ``` Host: `https://api-baas-sandbox.tilopay.com` — requiere `Authorization: Bearer `. Valid fields depend on `destination_kind` and `scope_kind`. Send only the fields that apply to your combination; other scope fields must be omitted (not null placeholders). **Event payloads** Inspect outbound contracts with `GET /api/public/v1/webhook/event-contracts/{event_type}` (`payin.posted`, `payment.succeeded`, `payment.failed`, `payment.reversed`). **destination_kind** - `EXTERNAL_WEBHOOK` (only kind available on the public API): requires `webhook_url` (must start with `https://`) and `secret_ref`. Optional delivery tuning (`timeout_ms`, `max_attempts`). Payloads are always encrypted with `AES_GCM` using `secret_ref`; the HTTP body is `{"data":""}`. - `INTERNAL` is reserved for platform administration and cannot be created through this endpoint. **scope_kind** - `TENANT`: omit `scope_account_id`, `scope_owner_type`, and `scope_owner_id`. - `ACCOUNT`: require `scope_account_id`; omit owner fields. - `OWNER`: require `scope_owner_type` and `scope_owner_id`; omit `scope_account_id`. `scope_owner_type` is one of `tenant`, `partner`, `user`, `platform`, `customer` (lowercase in payload). ## Webhook encryption (EXTERNAL_WEBHOOK) Deliveries always send `Content-Type: application/json` and `Accept: application/json`. The HTTP body is always `{"data": ""}`. The base64-decoded bytes are: ``` nonce (12 bytes, random) || AES-256-GCM ciphertext || 16-byte auth tag ``` ``` key = SHA256(secret_ref) # 32 bytes → AES-256 wire = base64_decode(data) nonce, sealed = wire[:12], wire[12:] # sealed = ciphertext || tag plaintext = AES-GCM-Open(key, nonce, sealed, additional_data = none) ``` No additional authenticated data (AAD) is used. `plaintext` is the same JSON envelope documented per event type in `GET /webhook/event-contracts/{event_type}` — decrypt first, then apply that contract. Authenticity is provided by the GCM auth tag (decryption fails if the body was tampered with). Deduplicate retries using `event.event_id` in the payload envelope — delivery retries can redeliver the same event with the same `event_id`. **Parámetros** | Parámetro | En | Tipo | Obligatorio | Descripción | |---|---|---|---|---| | `X-Correlation-Id` | header | string | — | Optional client-supplied correlation id for end-to-end tracing. Echoed back as `correlation_id` in the response envelope. If omitted, the API generates one and still returns it. | **Cuerpo del request** | Campo | Tipo | Obligatorio | Descripción | |---|---|---|---| | `feature_id` | string (uuid) | sí | Feature to subscribe (from `GET /api/public/v1/webhook/features`). Must exist or create fails. | | `is_enabled` | boolean | — | Defaults to true if omitted. | | `destination_kind` | string | sí | Public API accepts only `EXTERNAL_WEBHOOK` (HTTPS callback with shared secret). `INTERNAL` destinations are managed administratively. Values: EXTERNAL_WEBHOOK | | `destination_ref` | string | — | Not used on the public API. Reserved for internal destinations. | | `webhook_url` | string (uri) | — | Required (must use `https://`). | | `secret_ref` | string | — | Required shared secret used to decrypt AES_GCM payloads (`key = SHA256(secret_ref)`). See "Webhook encryption" in this operation's description. | | `signature_algo` | string | — | Fixed to `AES_GCM` for `EXTERNAL_WEBHOOK`. Omitted on create; stored as `AES_GCM`. `HMAC_SHA256` is no longer supported. Values: AES_GCM | | `replay_window_sec` | integer | — | Reserved for legacy destinations. Not used for `EXTERNAL_WEBHOOK` AES_GCM deliveries. | | `timeout_ms` | integer | — | HTTP timeout for delivery attempts (`EXTERNAL_WEBHOOK`). | | `max_attempts` | integer | — | Max delivery attempts (`EXTERNAL_WEBHOOK`). | | `backoff_policy` | object | — | Optional free-form JSON retry/backoff override, stored as-is and not currently validated or documented by the platform. Omit to use the platform's default backoff policy. | | `scope_kind` | string | sí | - `TENANT`: no scope id fields. - `ACCOUNT`: set `scope_account_id` only. - `OWNER`: set `scope_owner_type` and `scope_owner_id` only. Values: TENANT, ACCOUNT, OWNER | | `scope_account_id` | string (uuid) | — | Required when `scope_kind` is `ACCOUNT`. Must be omitted for `TENANT` and `OWNER`. | | `scope_owner_type` | string | — | Required when `scope_kind` is `OWNER`. Allowed values (lowercase) `tenant`, `partner`, `user`, `platform`, `customer`. Omit for `TENANT` and `ACCOUNT`. | | `scope_owner_id` | string (uuid) | — | Required when `scope_kind` is `OWNER`. Omit for `TENANT` and `ACCOUNT`. | **Ejemplo de request** — external_webhook_tenant ```json { "feature_id": "11111111-1111-1111-1111-111111111111", "destination_kind": "EXTERNAL_WEBHOOK", "scope_kind": "TENANT" } ``` **201** — The resource was created successfully. `response_code`: `CREATED` Campos de `data`: | Campo | Tipo | Obligatorio | Descripción | |---|---|---|---| | `created_at` | string | — | — | | `destination_kind` | string | sí | — | | `destination_ref` | string | — | — | | `feature_id` | string | sí | — | | `id` | string | sí | — | | `is_enabled` | boolean | sí | — | | `max_attempts` | integer | — | — | | `replay_window_sec` | integer | sí | — | | `scope_account_id` | string | — | — | | `scope_kind` | string | sí | — | | `scope_owner_id` | string | — | — | | `scope_owner_type` | string | — | — | | `secret_ref` | string | — | — | | `signature_algo` | string | sí | — | | `timeout_ms` | integer | — | — | | `updated_at` | string | — | — | | `webhook_url` | string | — | — | **Respuestas de error** | HTTP | response_code | Descripción | |---|---|---| | 400 | `INVALID_REQUEST` | Invalid request. Check the required fields and try again. | | 401 | `UNAUTHORIZED` | Unauthorized. Verify your session or credentials. | | 403 | `FORBIDDEN` | You do not have permission to perform this action. | | 429 | `TOO_MANY_REQUESTS` | Too many requests. Please retry after a short delay. | | 500 | `INTERNAL_ERROR` | An unexpected error occurred. Please try again later. | | 503 | `SERVICE_UNAVAILABLE` | A required service is temporarily unavailable. Please try again later. | ### List webhook features by payment method [#get-webhook-features] ```http GET /api/public/v1/webhook/features ``` Host: `https://api-baas-sandbox.tilopay.com` — requiere `Authorization: Bearer `. Returns feature IDs and the `event_types` each feature can emit. Tenant scope is taken from the access token; clients must not send `tenant_id`. **Naming:** `event_types` use `payment.*` for resource-level outcomes (`payment.succeeded`, `payment.failed`, `payment.reversed`) and `payin.posted` for the inbound direction only (funds received). There is no `payout.posted` and no `transaction.*` events. The delivered JSON object is always `payment`. Inspect payload shapes with `GET /api/public/v1/webhook/event-contracts/{event_type}` (`payin.posted`, `payment.succeeded`, `payment.failed`, `payment.reversed`). **Parámetros** | Parámetro | En | Tipo | Obligatorio | Descripción | |---|---|---|---|---| | `X-Correlation-Id` | header | string | — | Optional client-supplied correlation id for end-to-end tracing. Echoed back as `correlation_id` in the response envelope. If omitted, the API generates one and still returns it. | | `country_code` | query | string | — | — | | `payment_method_code` | query | string | — | — | | `webhook_enabled` | query | boolean | — | — | **200** — The request was processed successfully. `response_code`: `OK` Campos de `data`: | Campo | Tipo | Obligatorio | Descripción | |---|---|---|---| | `items` | array | sí | — | | `items[].event_types` | array | sí | — | | `items[].id` | string | sí | — | **Respuestas de error** | HTTP | response_code | Descripción | |---|---|---| | 401 | `UNAUTHORIZED` | Unauthorized. Verify your session or credentials. | | 403 | `FORBIDDEN` | You do not have permission to perform this action. | | 429 | `TOO_MANY_REQUESTS` | Too many requests. Please retry after a short delay. | | 500 | `INTERNAL_ERROR` | An unexpected error occurred. Please try again later. | | 503 | `SERVICE_UNAVAILABLE` | A required service is temporarily unavailable. Please try again later. | ### Webhook event contract [#get-webhook-event-contracts-event-type] ```http GET /api/public/v1/webhook/event-contracts/{event_type} ``` Host: `https://api-baas-sandbox.tilopay.com` — requiere `Authorization: Bearer `. Returns the outbound webhook payload contract for one public event type (`schema_version` 1.0.0). The envelope object is always `payment` (never `payin`, `payout`, or `transaction`). **When to use each name** - **payment** — resource and envelope. Outcome events: `payment.succeeded`, `payment.failed`, `payment.reversed` (both PAYIN and PAYOUT). Correlate with REST `/transactions/payments`. - **payin / payout** — direction (`PAYIN` inbound, `PAYOUT` outbound). `payin.posted` is inbound-only (ledger posted / funds received). There is no public `payout.posted`. - **transaction** — REST path prefix only. Not used in webhook `event_type` or payload objects. Supported `event_type` values: - `payin.posted` — inbound (PAYIN) payment reached public status `posted`. Envelope field is `payment`. `payment.local_payment` is a JSON boolean (`true`/`false`), not a string. - `payment.succeeded` — the provider confirmed success for a payment (PAYIN or PAYOUT; PIN or SINPE Móvil). Resource-level outcome, not direction-specific. - `payment.failed` — processing ended in a definitive failure (public `status=failed`), with structured `payment.error` (`domain` / `platform`). When the provider rejected the payment, the envelope also includes `rejection`. Not used for later reversals. - `payment.reversed` — subsequent reversal of a payment that already progressed (typically `status=posted` or `confirmed`). REST `result=reversed` and `has_reversal=true`. Processing `status` is unchanged. Not a `payment.failed`. Unknown `event_type` values (including internal-only `payment.status_changed`) return `404`. ## SINPE rejection codes (`rejection`, only on `payment.failed`) When `event_type = payment.failed` and the provider rejected the payment, the envelope includes `rejection` (same object and catalog as `data.rejection` on `POST /accounts/validate`). `rejection.code` is one of a fixed set of normalized semantics (see the `WebhookRejection.code` schema enum). **Most rows in the table below do NOT get a distinct `code`** — only a subset of `reason_code` values has a dedicated semantic; every other `reason_code`, even one listed below with a specific `message`, returns `code = SINPE_REJECTED` (e.g. `reason_code = 21` "fondos insuficientes" still returns `SINPE_REJECTED`). A `reason_code` not listed here at all still produces a response — `message` falls back to a generic text and `code` falls back to `SINPE_REJECTED`. **Cuenta / perfil / límites** | Code | Message | |---|---| | 21 | Cuenta Cliente con fondos insuficientes | | 22 | Cuenta Cliente no admite créditos | | 23 | Cuenta Cliente cerrada | | 24 | Cuenta Cliente inactiva | | 25 | Cuenta Cliente no admite débitos | | 26 | Cuenta Cliente no es de fondos | | 27 | Moneda de la Cuenta Cliente no corresponde | | 28 | Cuenta cliente no existe | | 29 | Cuenta Cliente no registrada en el SINPE | | 30 | Cuenta Cliente no habilitada para el servicio | | 31 | Cuenta Cliente bloqueada | | 32 | Id cliente destino no coincide con registrado en la entidad | | 33 | Nombre del cliente destino no coincide con el registrado en la entidad | | 34 | Cuenta Cliente en proceso de cierre | | 35 | Cuenta Cliente embargada | | 36 | Cuenta Cliente con retención judicial | | 37 | Cuenta de expediente simplificado no permite el monto indicado | | 38 | Límite transaccional de la Cuenta Cliente excedido | | 39 | Cuenta Cliente incorrecta | | 40 | IBAN de la cuenta destino inválido | | 41 | IBAN de la cuenta origen inválido | | 42 | Tipo de cuenta no permite la transacción | | 43 | Cuenta Cliente no pertenece a la entidad indicada | | 44 | Producto de la cuenta no admite el servicio | | 45 | Cuenta Cliente en estado de cancelación | | 46 | Cuenta Cliente restringida por política de la entidad | | 47 | Cuenta Cliente no permite pagos inmediatos | | 48 | Cuenta Cliente no permite SINPE Móvil | | 49 | Titular de la cuenta destino fallecido | | 50 | Cuenta Cliente consolidada o migrada | | 51 | Identificación del cliente origen no coincide | | 52 | Identificación del cliente destino inválida | | 53 | Cliente destino no autorizado para recibir el pago | | 54 | Cliente origen no autorizado para enviar el pago | | 55 | Perfil del cliente origen no permite la transacción | | 56 | Monto inferior al mínimo permitido | | 57 | Monto superior al máximo permitido | | 58 | Cantidad de transacciones diarias excedida | | 59 | Cantidad de transacciones mensuales excedida | | 60 | Límite acumulado diario excedido | | 61 | Límite acumulado mensual excedido | | 62 | Comisión no pudo ser aplicada | | 63 | Tipo de cambio no disponible | | 64 | Transacción rechazada por control de lavado de dinero | | 65 | Transacción rechazada por listas de control | | 66 | Transacción en revisión de cumplimiento | | 67 | Documento de respaldo requerido no presente | | 68 | Firma o autenticación inválida | | 69 | Token o segundo factor inválido | | 70 | Sesión de usuario expirada | | 71 | Usuario no autorizado para el canal | | 72 | Dispositivo no registrado | | 73 | Geolocalización no permitida | | 74 | Operación no soportada en la moneda indicada | | 75 | Operación no soportada para el tipo de cliente | | 76 | Problemas de comunicación | | 77 | Tiempo de espera agotado en la entidad origen | | 78 | Tiempo de espera agotado en el SINPE | | 79 | Error interno de la entidad origen | | 80 | Error interno de la entidad destino | | 81 | Entidad origen no disponible | | 82 | Entidad destino no encontrada | | 83 | Problemas en la respuesta del destino | | 84 | Respuesta de la entidad origen incorrecta | | 85 | Mensaje con formato electrónico inválido | | 86 | Versión del estándar electrónico no soportada | | 87 | Campo obligatorio no informado | | 88 | Campo con valor fuera de catálogo | | 89 | Checksum o integridad del mensaje inválida | | 90 | Referencia SINPE duplicada | | 91 | Moneda no corresponde | | 92 | Transacción no autorizada por entidad destino | | 93 | Transacción no autorizada por cliente destino | | 94 | Transacción no autorizada por entidad origen | | 95 | Transacción no autorizada por cliente origen | | 96 | Reverso no permitido para el estado de la transacción | | 97 | Reverso ya aplicado | | 98 | Confirmación no permitida para el estado de la transacción | | 99 | Liquidación no permitida para el estado de la transacción | | 100 | Entidad Destino no disponible para procesar en tiempo real | | 101 | Entidad origen no disponible para procesar en tiempo real | | 102 | Servicio PIN no habilitado para la entidad destino | | 103 | Servicio PIN no habilitado para la entidad origen | | 104 | Código de entidad destino inválido | | 105 | Código de entidad origen inválido | | 106 | Código de país de la entidad destino inválido | | 107 | Código de país de la entidad origen inválido | | 108 | Número de referencia interna inválido | | 109 | Número de referencia SINPE inválido | | 110 | Transacción no se encuentra en un estado que permita la consulta | **Compensación con entidad destino** | Code | Message | |---|---| | 201 | Tiempo respuesta excedido por la entidad destino | | 202 | Respuesta de la entidad destino incorrecta según el estándar electrónico | | 203 | Se recibió una excepción de la entidad destino | | 204 | Error de comunicación con la entidad destino | | 205 | Falló procesamiento en el SINPE | | 206 | Transacción no autorizada por cliente destino | | 207 | Perfil transaccional del cliente destino no permite recibir el pago | | 208 | Falló la acreditación en la cuenta destino | | 209 | Falló el débito en la cuenta origen | | 210 | Conciliación de la transacción no fue posible | **Identificación** | Code | Message | |---|---| | 801 | Identificación inválida | | 802 | Identificación del cliente origen no encontrada | | 803 | Identificación del cliente destino no encontrada | | 804 | Identificación no vigente | | 805 | Identificación vencida | | 806 | Identificación no corresponde al tipo indicado | | 807 | Tipo de identificación inválido | | 808 | País de la identificación no soportado | | 809 | Identificación de menor de edad no permitida | | 810 | Identificación de persona jurídica no permitida para el servicio | **Validación de formato / Core Bancario** | Code | Message | |---|---| | 1001 | Cuenta cliente activa | | 1002 | El Id de cliente destino no cumple con el formato esperado por el SINPE | | 1003 | El Id de cliente origen no fue informado | | 1004 | El Id de cliente origen no cumple con el formato esperado por el SINPE | | 1005 | Monto con formato inválido | | 1006 | Moneda con formato inválido | | 1007 | Problemas de comunicación con el Core Bancario | | 1008 | Core Bancario no disponible | | 1009 | El valor para el campo no puede ser nulo o infringir su longitud mínima o máxima | | 1010 | El valor para el campo no corresponde al tipo de dato esperado | | 1011 | El valor para el campo no corresponde al catálogo permitido | | 1012 | Fecha con formato inválido | | 1013 | Hora con formato inválido | | 1014 | Número de referencia con formato inválido | | 1015 | IBAN con formato inválido | **Canal / tipo de identificación** | Code | Message | |---|---| | 1040 | Canal no informado | | 1041 | Canal inválido | | 1042 | Canal no corresponde | | 1043 | Canal no habilitado para la entidad | | 1044 | Canal no habilitado para el servicio | | 1045 | El formato de la identificación es inválido | | 1046 | Tipo de identificación no informado | | 1080 | Tipo de identificación no corresponde al cliente origen | | 1081 | Tipo de identificación no corresponde al cliente destino | | 1082 | Tipo de identificación no vigente | | 1083 | Tipo de identificación no soportado por el servicio | | 1084 | Tipo de identificación inválido | | 1085 | Tipo de identificación no soportado por la entidad | **SINPE Móvil (monedero)** | Code | Message | |---|---| | 15300 | El número de teléfono origen indicado es inválido | | 15301 | El número de teléfono origen no tiene activo el Servicio Monedero | | 15302 | El número de teléfono destino indicado es inválido | | 15303 | El número de teléfono destino no está registrado en el padrón móvil del BCCR | | 15304 | No es posible inactivar el monedero indicado pues no existe | | 15305 | El número de teléfono indicado ya se encuentra activo como monedero en el padrón local | ⚠️ This catalog is under review — some entries (notably `208` and `209`) are known to be pending verification against the official SINPE source and may be corrected in a future revision without notice. Delivery body is JSON. `EXTERNAL_WEBHOOK` HTTP body is always `{"data":""}` (AES-256-GCM, key = SHA256(secret_ref)). Decrypt to obtain the event envelope documented per `GET /webhook/event-contracts/{event_type}`. and the decrypted plaintext matches this contract. **Parámetros** | Parámetro | En | Tipo | Obligatorio | Descripción | |---|---|---|---|---| | `X-Correlation-Id` | header | string | — | Optional client-supplied correlation id for end-to-end tracing. Echoed back as `correlation_id` in the response envelope. If omitted, the API generates one and still returns it. | | `event_type` | path | string | sí | Values: payin.posted, payment.succeeded, payment.failed, payment.reversed | **200** — The request was processed successfully. `response_code`: `OK` Campos de `data`: | Campo | Tipo | Obligatorio | Descripción | |---|---|---|---| | `description` | string | sí | — | | `event_type` | string | sí | — | | `example` | object | sí | — | | `schema_version` | string | sí | — | **Respuestas de error** | HTTP | response_code | Descripción | |---|---|---| | 401 | `UNAUTHORIZED` | Unauthorized. Verify your session or credentials. | | 403 | `FORBIDDEN` | You do not have permission to perform this action. | | 404 | `NOT_FOUND` | The requested resource was not found. | | 429 | `TOO_MANY_REQUESTS` | Too many requests. Please retry after a short delay. | | 500 | `INTERNAL_ERROR` | An unexpected error occurred. Please try again later. | | 503 | `SERVICE_UNAVAILABLE` | A required service is temporarily unavailable. Please try again later. | ## Contratos de payload [#contratos] Cada evento tiene su propia estructura de datos. Esto es lo que te enviamos en cada uno: ### payin.posted [#contrato-payin-posted] Datos que te enviamos en `payin.posted`. | Campo | Tipo | Obligatorio | Descripción | |---|---|---|---| | `schema_version` | string | sí | — | | `event` | object | sí | — | | `event.event_id` | string (uuid) | sí | — | | `event.event_type` | string | sí | Values: payin.posted | | `event.occurred_at` | string (date-time) | sí | RFC 3339 timestamp in UTC with second precision and a `Z` suffix. Fractional seconds are never emitted. Example: `2026-01-15T12:00:00Z`. | | `event.correlation_id` | string | sí | — | | `context` | object | sí | — | | `context.country_code` | string | sí | — | | `context.payment_method_code` | string | sí | Public payment method catalog. Same values as REST (`PIN`, `SINPE_MOVIL`). Internal codes such as `PM_PIN` are never exposed. Values: PIN, SINPE_MOVIL | | `payment` | object | sí | — | | `payment.payment_id` | string (uuid) | sí | — | | `payment.public_id` | integer (int64) | sí | — | | `payment.status` | string | sí | Public payment status catalog. Always lowercase. Same values on REST (create, list, get) and webhooks (`payment.status`). Internal lifecycle states are collapsed: - `pending`: initiated, validated, accepted - `processing`: processing, pending_processing, posting - `confirmed`: confirmed by the rail, not yet ledger-posted - `posted`: ledger posted (stays `posted` after a later reversal) - `failed`: failed, rejected, posting_failed, cancelled, expired A reversal is **not** a status. Use REST `result=reversed` / `has_reversal=true` and webhook `payment.reversed`. Operational detail remains in `status_detail` (uppercase internal name) on REST create/list/get. Webhook `payment.failed` uses `error.platform.code` to distinguish posting failures from provider rejections. Values: pending, processing, confirmed, posted, failed | | `payment.amount` | object | sí | — | | `payment.amount.amount` | string | — | — | | `payment.amount.currency` | string | — | — | | `payment.posted_at` | string (date-time) | sí | RFC 3339 timestamp in UTC with second precision and a `Z` suffix. Fractional seconds are never emitted. Example: `2026-01-15T12:00:00Z`. | | `payment.account` | object | sí | — | | `payment.account.type` | string | sí | — | | `payment.account.value` | string | sí | — | | `payment.reference` | object | sí | — | | `payment.reference.client_reference` | string | sí | Partner reference sent at payment creation (`client_reference`), not `detail_reference`. | | `payment.reference.external_reference` | string | sí | — | | `payment.destination_phone_number` | string | — | — | | `payment.local_payment` | boolean | — | JSON boolean (`true`/`false`), not the strings `"true"`/`"false"`. | | `payment.origin_client_name` | string | — | — | | `provider` | object | sí | Shared provider snapshot on REST payment reads and webhook envelopes. Rail reference is only on `payment.external_reference`, not duplicated here. `provider_status_*` match webhook `rejection.reason_code` / `message` / `code` when the provider rejected the operation. `null` when there is no rejection. | | `provider.correlation_id` | string | sí | Transaction correlation UUID (`execution.correlation_id` / `metadata.tx.correlationId`). Sent to GX/SINPE as `correlationId`. Not `channel_reference` (e.g. `MOBILE_APP`). Distinct from webhook `event.correlation_id` (HTTP request id for this delivery). `null` when unknown. | | `provider.occurred_at` | string (date-time) | sí | RFC 3339 timestamp in UTC with second precision and a `Z` suffix. Fractional seconds are never emitted. Example: `2026-01-15T12:00:00Z`. | | `provider.provider_status_code` | string | sí | Raw provider Motivo/code (e.g. `31`). Same meaning as webhook `rejection.reason_code`. `null` when there is no provider rejection. | | `provider.provider_status_desc` | string | sí | Provider Motivo text (prefers Detalle). Same meaning as webhook `rejection.message`. `null` when there is no provider rejection. | | `provider.provider_status_semantic` | string | sí | Normalized platform semantic (e.g. `ACCOUNT_BLOCKED`). Same meaning as webhook `rejection.code`. `null` when there is no provider rejection. | ### payment.succeeded [#contrato-payment-succeeded] Datos que te enviamos en `payment.succeeded`. | Campo | Tipo | Obligatorio | Descripción | |---|---|---|---| | `schema_version` | string | sí | — | | `event` | object | sí | — | | `event.event_id` | string (uuid) | sí | — | | `event.event_type` | string | sí | Values: payment.succeeded | | `event.occurred_at` | string (date-time) | sí | RFC 3339 timestamp in UTC with second precision and a `Z` suffix. Fractional seconds are never emitted. Example: `2026-01-15T12:00:00Z`. | | `event.correlation_id` | string | sí | — | | `context` | object | sí | — | | `context.country_code` | string | sí | — | | `context.payment_method_code` | string | sí | Public payment method catalog. Same values as REST (`PIN`, `SINPE_MOVIL`). Internal codes such as `PM_PIN` are never exposed. Values: PIN, SINPE_MOVIL | | `payment` | object | sí | — | | `payment.payment_id` | string (uuid) | sí | — | | `payment.public_id` | integer (int64) | sí | — | | `payment.status` | string | sí | Public payment status catalog. Always lowercase. Same values on REST (create, list, get) and webhooks (`payment.status`). Internal lifecycle states are collapsed: - `pending`: initiated, validated, accepted - `processing`: processing, pending_processing, posting - `confirmed`: confirmed by the rail, not yet ledger-posted - `posted`: ledger posted (stays `posted` after a later reversal) - `failed`: failed, rejected, posting_failed, cancelled, expired A reversal is **not** a status. Use REST `result=reversed` / `has_reversal=true` and webhook `payment.reversed`. Operational detail remains in `status_detail` (uppercase internal name) on REST create/list/get. Webhook `payment.failed` uses `error.platform.code` to distinguish posting failures from provider rejections. Values: pending, processing, confirmed, posted, failed | | `payment.amount` | object | sí | — | | `payment.amount.amount` | string | — | — | | `payment.amount.currency` | string | — | — | | `payment.client_reference` | string | sí | Partner reference sent at payment creation (`client_reference`), not `detail_reference`. | | `payment.external_reference` | string | sí | — | | `payment.fee_total` | string | sí | Fee total as decimal string (same currency as amount.currency) | | `payment.tax_total` | string | sí | Tax total as decimal string (same currency as amount.currency) | | `payment.net_amount` | string | sí | Net cash impact on the merchant account. PAYIN: amount - fee_total - tax_total (what the merchant receives). PAYOUT: amount + fee_total + tax_total (total debit; fee is charged separately and is not deducted from the transferred amount). | | `payment.succeeded_at` | string | sí | Timestamp when the provider confirmed the payment succeeded. | | `provider` | object | sí | Shared provider snapshot on REST payment reads and webhook envelopes. Rail reference is only on `payment.external_reference`, not duplicated here. `provider_status_*` match webhook `rejection.reason_code` / `message` / `code` when the provider rejected the operation. `null` when there is no rejection. | | `provider.correlation_id` | string | sí | Transaction correlation UUID (`execution.correlation_id` / `metadata.tx.correlationId`). Sent to GX/SINPE as `correlationId`. Not `channel_reference` (e.g. `MOBILE_APP`). Distinct from webhook `event.correlation_id` (HTTP request id for this delivery). `null` when unknown. | | `provider.occurred_at` | string (date-time) | sí | RFC 3339 timestamp in UTC with second precision and a `Z` suffix. Fractional seconds are never emitted. Example: `2026-01-15T12:00:00Z`. | | `provider.provider_status_code` | string | sí | Raw provider Motivo/code (e.g. `31`). Same meaning as webhook `rejection.reason_code`. `null` when there is no provider rejection. | | `provider.provider_status_desc` | string | sí | Provider Motivo text (prefers Detalle). Same meaning as webhook `rejection.message`. `null` when there is no provider rejection. | | `provider.provider_status_semantic` | string | sí | Normalized platform semantic (e.g. `ACCOUNT_BLOCKED`). Same meaning as webhook `rejection.code`. `null` when there is no provider rejection. | ### payment.failed [#contrato-payment-failed] Datos que te enviamos en `payment.failed`. | Campo | Tipo | Obligatorio | Descripción | |---|---|---|---| | `schema_version` | string | sí | — | | `event` | object | sí | — | | `event.event_id` | string (uuid) | sí | — | | `event.event_type` | string | sí | Values: payment.failed | | `event.occurred_at` | string (date-time) | sí | RFC 3339 timestamp in UTC with second precision and a `Z` suffix. Fractional seconds are never emitted. Example: `2026-01-15T12:00:00Z`. | | `event.correlation_id` | string | sí | — | | `context` | object | sí | — | | `context.country_code` | string | sí | — | | `context.payment_method_code` | string | sí | Public payment method catalog. Same values as REST (`PIN`, `SINPE_MOVIL`). Internal codes such as `PM_PIN` are never exposed. Values: PIN, SINPE_MOVIL | | `payment` | object | sí | — | | `payment.payment_id` | string (uuid) | sí | — | | `payment.public_id` | integer (int64) | sí | — | | `payment.status` | string | sí | Public payment status catalog. Always lowercase. Same values on REST (create, list, get) and webhooks (`payment.status`). Internal lifecycle states are collapsed: - `pending`: initiated, validated, accepted - `processing`: processing, pending_processing, posting - `confirmed`: confirmed by the rail, not yet ledger-posted - `posted`: ledger posted (stays `posted` after a later reversal) - `failed`: failed, rejected, posting_failed, cancelled, expired A reversal is **not** a status. Use REST `result=reversed` / `has_reversal=true` and webhook `payment.reversed`. Operational detail remains in `status_detail` (uppercase internal name) on REST create/list/get. Webhook `payment.failed` uses `error.platform.code` to distinguish posting failures from provider rejections. Values: pending, processing, confirmed, posted, failed | | `payment.amount` | object | sí | — | | `payment.amount.amount` | string | — | — | | `payment.amount.currency` | string | — | — | | `payment.client_reference` | string | — | Partner reference sent at payment creation (`client_reference`), not `detail_reference`. | | `payment.external_reference` | string | — | — | | `payment.error` | object | sí | — | | `payment.error.domain` | string | sí | Values: provider_rejection, platform_validation, platform_posting, platform_infra, platform_reversal, sinpe_rejection | | `payment.error.platform` | object | sí | — | | `provider` | object | sí | Shared provider snapshot on REST payment reads and webhook envelopes. Rail reference is only on `payment.external_reference`, not duplicated here. `provider_status_*` match webhook `rejection.reason_code` / `message` / `code` when the provider rejected the operation. `null` when there is no rejection. | | `provider.correlation_id` | string | sí | Transaction correlation UUID (`execution.correlation_id` / `metadata.tx.correlationId`). Sent to GX/SINPE as `correlationId`. Not `channel_reference` (e.g. `MOBILE_APP`). Distinct from webhook `event.correlation_id` (HTTP request id for this delivery). `null` when unknown. | | `provider.occurred_at` | string (date-time) | sí | RFC 3339 timestamp in UTC with second precision and a `Z` suffix. Fractional seconds are never emitted. Example: `2026-01-15T12:00:00Z`. | | `provider.provider_status_code` | string | sí | Raw provider Motivo/code (e.g. `31`). Same meaning as webhook `rejection.reason_code`. `null` when there is no provider rejection. | | `provider.provider_status_desc` | string | sí | Provider Motivo text (prefers Detalle). Same meaning as webhook `rejection.message`. `null` when there is no provider rejection. | | `provider.provider_status_semantic` | string | sí | Normalized platform semantic (e.g. `ACCOUNT_BLOCKED`). Same meaning as webhook `rejection.code`. `null` when there is no provider rejection. | | `rejection` | object | — | Rail-agnostic provider rejection. Shared by `POST /accounts/validate` (`data.rejection`) and the `payment.failed` webhook (`rejection`). Object only when the provider rejected the operation; omitted/`null` otherwise. | | `rejection.code` | string | sí | Normalized platform semantic derived from `reason_code`. Only a subset of `reason_code` values (see the catalog in the description of `POST /accounts/validate` and of the `payment.failed` webhook contract endpoint) has a distinct entry here — for any other numeric `reason_code`, `code` is `SINPE_REJECTED` even when `message` is specific (e.g. `reason_code = 21` "fondos insuficientes" still returns `code = SINPE_REJECTED`, it has no dedicated semantic). `PHONE_NOT_REGISTERED` is the fallback when `reason_code` is non-numeric (SINPE_MOVIL wallet flow). Values: ACCOUNT_CLOSED, ACCOUNT_NOT_FOUND, ACCOUNT_BLOCKED, INVALID_ACCOUNT, IDENT_MISMATCH, IDENT_TYPE_INVALID, INVALID_ID_FORMAT, VALIDATION_ERROR, CURRENCY_MISMATCH, NOT_AUTHORIZED_BY_RECIPIENT, PROFILE_NOT_ALLOWED, CHANNEL_NOT_RECOGNIZED, COMMUNICATION_ERROR, RETRY_LATER, WALLET_PHONE_ORIGIN_INVALID, WALLET_PHONE_ORIGIN_NOT_ENABLED, WALLET_PHONE_DEST_INVALID, WALLET_PHONE_NOT_REGISTERED_BCCR, WALLET_NOT_FOUND, WALLET_PHONE_ALREADY_ACTIVE, PHONE_NOT_REGISTERED, SINPE_REJECTED | | `rejection.reason_code` | string | sí | Raw Motivo/code returned by SINPE. See the endpoint description of `POST /accounts/validate` for the full code catalog (shared by this object wherever it appears, including the `payment.failed` webhook). A code not listed there still produces a response — `message` falls back to a generic text and `code` falls back to `SINPE_REJECTED`. | | `rejection.message` | string | sí | Descriptive Motivo text; prefers provider `Detalle` when present. | ### payment.reversed [#contrato-payment-reversed] Datos que te enviamos en `payment.reversed`. | Campo | Tipo | Obligatorio | Descripción | |---|---|---|---| | `schema_version` | string | sí | — | | `event` | object | sí | — | | `event.event_id` | string (uuid) | sí | — | | `event.event_type` | string | sí | Values: payment.reversed | | `event.occurred_at` | string (date-time) | sí | RFC 3339 timestamp in UTC with second precision and a `Z` suffix. Fractional seconds are never emitted. Example: `2026-01-15T12:00:00Z`. | | `event.correlation_id` | string | sí | — | | `context` | object | sí | — | | `context.country_code` | string | sí | — | | `context.payment_method_code` | string | sí | Public payment method catalog. Same values as REST (`PIN`, `SINPE_MOVIL`). Internal codes such as `PM_PIN` are never exposed. Values: PIN, SINPE_MOVIL | | `payment` | object | sí | — | | `payment.payment_id` | string (uuid) | sí | — | | `payment.public_id` | integer (int64) | sí | — | | `payment.status` | string | sí | Public payment status catalog. Always lowercase. Same values on REST (create, list, get) and webhooks (`payment.status`). Internal lifecycle states are collapsed: - `pending`: initiated, validated, accepted - `processing`: processing, pending_processing, posting - `confirmed`: confirmed by the rail, not yet ledger-posted - `posted`: ledger posted (stays `posted` after a later reversal) - `failed`: failed, rejected, posting_failed, cancelled, expired A reversal is **not** a status. Use REST `result=reversed` / `has_reversal=true` and webhook `payment.reversed`. Operational detail remains in `status_detail` (uppercase internal name) on REST create/list/get. Webhook `payment.failed` uses `error.platform.code` to distinguish posting failures from provider rejections. Values: pending, processing, confirmed, posted, failed | | `payment.result` | string | sí | Values: reversed | | `payment.has_reversal` | boolean | sí | Values: true | | `payment.amount` | object | sí | — | | `payment.amount.amount` | string | — | — | | `payment.amount.currency` | string | — | — | | `payment.client_reference` | string | — | — | | `payment.external_reference` | string | — | — | | `payment.reversed_at` | string (date-time) | sí | RFC 3339 timestamp in UTC with second precision and a `Z` suffix. Fractional seconds are never emitted. Example: `2026-01-15T12:00:00Z`. | | `payment.reason` | object | — | — | | `payment.reason.code` | string | — | — | | `payment.reason.message` | string | — | — | | `provider` | object | sí | Shared provider snapshot on REST payment reads and webhook envelopes. Rail reference is only on `payment.external_reference`, not duplicated here. `provider_status_*` match webhook `rejection.reason_code` / `message` / `code` when the provider rejected the operation. `null` when there is no rejection. | | `provider.correlation_id` | string | sí | Transaction correlation UUID (`execution.correlation_id` / `metadata.tx.correlationId`). Sent to GX/SINPE as `correlationId`. Not `channel_reference` (e.g. `MOBILE_APP`). Distinct from webhook `event.correlation_id` (HTTP request id for this delivery). `null` when unknown. | | `provider.occurred_at` | string (date-time) | sí | RFC 3339 timestamp in UTC with second precision and a `Z` suffix. Fractional seconds are never emitted. Example: `2026-01-15T12:00:00Z`. | | `provider.provider_status_code` | string | sí | Raw provider Motivo/code (e.g. `31`). Same meaning as webhook `rejection.reason_code`. `null` when there is no provider rejection. | | `provider.provider_status_desc` | string | sí | Provider Motivo text (prefers Detalle). Same meaning as webhook `rejection.message`. `null` when there is no provider rejection. | | `provider.provider_status_semantic` | string | sí | Normalized platform semantic (e.g. `ACCOUNT_BLOCKED`). Same meaning as webhook `rejection.code`. `null` when there is no provider rejection. | --- # Catálogos del API Bancario > Catálogo de tipos de identificación de cliente por país en el API Bancario. - kind: api-operation - status: stable - api_version: 1.0.0 - last_verified: 2026-09-02 - url: https://tilopay.com/developers/api-bancario/catalogos El grupo `Catalogs` publica los valores que tu integración debe usar en los campos de identificación de cliente, en vez de codificarlos a mano. ```http GET /api/public/v1/catalogs/customer-identification-types ``` Filtrá por `country_code` de dos letras para obtener los tipos vigentes en ese país. Consultá el catálogo al iniciar la integración y cacheá el resultado; leelo de nuevo antes de agregar un país nuevo. ## Operaciones [#operaciones] ### List customer identification person types [#get-catalogs-customer-identification-types] ```http GET /api/public/v1/catalogs/customer-identification-types ``` Host: `https://api-baas-sandbox.tilopay.com` — requiere `Authorization: Bearer `. Returns the distinct customer person types (`individual`, `business`, `both`) available for the authenticated tenant, optionally filtered by country. This is a person-type classification, not the payment identification-document catalog (`cedula`, `juridica`, `dimex`, ...) used by `identification.type` on `POST /payments`. **Parámetros** | Parámetro | En | Tipo | Obligatorio | Descripción | |---|---|---|---|---| | `X-Correlation-Id` | header | string | — | Optional client-supplied correlation id for end-to-end tracing. Echoed back as `correlation_id` in the response envelope. If omitted, the API generates one and still returns it. | | `country_code` | query | string | — | Optional ISO-2 country code used to filter results. A legacy `country` query parameter is also accepted as an alias when `country_code` is omitted; prefer `country_code`. | **200** — The request was processed successfully. `response_code`: `OK` Campos de `data`: | Campo | Tipo | Obligatorio | Descripción | |---|---|---|---| | `items` | array | sí | — | | `items[].code` | string | sí | — | **Respuestas de error** | HTTP | response_code | Descripción | |---|---|---| | 401 | `UNAUTHORIZED` | Unauthorized. Verify your session or credentials. | | 403 | `FORBIDDEN` | You do not have permission to perform this action. | | 429 | `TOO_MANY_REQUESTS` | Too many requests. Please retry after a short delay. | | 500 | `INTERNAL_ERROR` | An unexpected error occurred. Please try again later. | | 502 | — | Dependency error | | 503 | `SERVICE_UNAVAILABLE` | A required service is temporarily unavailable. Please try again later. | --- # Códigos de respuesta del API Bancario > Catálogo completo de response_code del API Bancario de Tilopay y cómo reaccionar a cada familia. - kind: concept - status: stable - api_version: 1.0.0 - last_verified: 2026-09-02 - url: https://tilopay.com/developers/api-bancario/errores Todo error del API Bancario llega en el [envelope estándar](/developers/api-bancario/convenciones#envelope), con `success: false`, el status HTTP en `http_status_code` y un `response_code` del catálogo. Ramificá por `response_code`. ## Cómo reaccionar por familia [#familias] **`4xx` de request.** El cuerpo o los parámetros no son válidos, o el recurso no existe. Corregí la llamada antes de reenviarla: reintentar igual devuelve el mismo error. Acá caen `INVALID_REQUEST`, `VALIDATION_ERROR`, `NOT_FOUND` y los códigos de negocio como `INSUFFICIENT_FUNDS` o `LIMIT_EXCEEDED`. **`401` y `403`.** El token no viaja, venció o su contexto no autoriza el recurso. Renová el access token con el [intercambio de token](/developers/api-bancario/autenticacion#exchange); si persiste con un token nuevo, el contexto no tiene permiso sobre ese recurso. **`409 IDEMPOTENCY_CONFLICT`.** Reusaste una `Idempotency-Key` con un cuerpo distinto. Usá una llave nueva para la nueva intención; ver [reintentos seguros](/developers/api-bancario/convenciones#reintentos). **`429`.** Superaste el límite de llamadas. Espaciá los envíos y reintentá con backoff. **`5xx`.** Falla del lado del servicio. Reintentá con backoff, y en los `POST` reenviá la **misma** `Idempotency-Key` para no duplicar el registro. Guardá el `correlation_id` antes de escalar a soporte. ## Catálogo completo [#catalogo] Estos son los 28 valores de `ResponseCode` que retorna nuestro API, con los status HTTP en los que aparecen. `OK` es el código de las respuestas exitosas. | response_code | Status HTTP en que se retorna | |---|---| | `OK` | 200 | | `CREATED` | 201 | | `NO_CONTENT` | — | | `UNAUTHORIZED` | 401 | | `FORBIDDEN` | 403 | | `TOO_MANY_REQUESTS` | 429 | | `SERVICE_UNAVAILABLE` | 503 | | `INTERNAL_ERROR` | 500 | | `INVALID_REQUEST` | 400 | | `ACCOUNT_ACCESS_DENIED` | 403 | | `PROVIDER_ERROR` | 502 | | `INVALID_CREDENTIALS` | 401 | | `NOT_FOUND` | 404 | | `ACCOUNT_NOT_FOUND` | 404 | | `ACCOUNT_NOT_CONFIGURED` | 422 | | `UNPROCESSABLE_ENTITY` | 422 | | `PAYMENT_NOT_FOUND` | 404 | | `INVALID_ACCOUNT_TYPE` | 400 | | `INVALID_ACCOUNT_FORMAT` | 400 | | `INVALID_PAYMENT_METHOD` | 400 | | `PAYMENT_INVALID_PAYLOAD` | 400 | | `ACCOUNT_INVALID` | 400 | | `ACCOUNT_HOLDER_MISMATCH` | 400 | | `IDEMPOTENCY_CONFLICT` | 409 | | `PAYMENT_DUPLICATE` | 409 | | `CONFLICT` | 409 | | `INSUFFICIENT_FUNDS` | 422 | | `LIMIT_EXCEEDED` | 422 | Un `response_code` que no esté en esta lista no forma parte del contrato de la versión 1.0.0 del API: tratalo como error genérico según su status HTTP y reportalo con el `correlation_id`. --- # Agentes de IA > Los tres planos que Tilopay le ofrece a un agente de IA: leer la documentación, operar la cuenta por el servidor MCP, e integrar con el API y el SDK. - kind: guide - status: stable - last_verified: 2026-08-29 - url: https://tilopay.com/developers/agentes ## Leer [#leer] Todo el portal está disponible en formato legible por máquina: el índice [`llms.txt`](https://tilopay.com/llms.txt), el Markdown crudo de cualquier URL del sitio agregándole `.md`, el [`openapi.json`](/developers/openapi.json) del API y el [`mcp.json`](/developers/mcp.json) del servidor MCP. ## Automatizá la operativa de tu negocio [#actuar] El [servidor MCP](/developers/agentes/mcp) le permite a tu asistente operar tu cuenta de Tilopay: consultar ventas, crear enlaces de pago, reembolsar. El acceso es autoservicio —iniciás sesión con tus credenciales de Tilopay— y tus credenciales nunca salen del servidor de Tilopay. ## Integrar en producto [#integrar] Cuando lo que se construye es un producto que cobra, el camino son el [SDK JavaScript](/developers/sdk) y el [API Adquirencia](/developers/api/autenticacion), no el MCP. ## Cuál elegir [#cual-elegir] - Operar la cuenta desde un asistente → [servidor MCP](/developers/agentes/mcp). - Construir un producto que cobra → [API](/developers/api/autenticacion) y [SDK](/developers/sdk). - Alimentar un agente con la documentación → [documentación legible](/developers/agentes/documentacion-legible). El acceso al MCP es autoservicio: se instala el conector y se inicia sesión con las credenciales de Tilopay, como explica la [página del servidor MCP](/developers/agentes/mcp). --- # Asistente de Tilopay en WhatsApp > Qué es el Asistente de Tilopay en WhatsApp, cómo se activa, cómo se usa y qué puede hacer: ventas, transacciones, enlaces de pago, catálogo, microtienda y pedidos, comprobantes, suscripciones, tarjetas guardadas, recordatorios y avisos. - kind: guide - status: stable - last_verified: 2026-10-07 - url: https://tilopay.com/developers/agentes/asistente-whatsapp ## Qué es [#que-es] El Asistente de Tilopay en WhatsApp es el mismo servidor MCP de Tilopay conectado a un chat de WhatsApp. En vez de configurar un cliente MCP, el comercio le escribe en lenguaje natural desde el WhatsApp que ya usa y el asistente ejecuta las herramientas sobre su cuenta de Tilopay. Las capacidades son las mismas que expone el MCP: lo que un agente puede hacer por [herramientas de adquirencia](/developers/agentes/mcp/adquirencia) y, bajo solicitud, por [herramientas bancarias](/developers/agentes/mcp/api-bancario), el asistente lo puede hacer desde el chat. No es un chatbot de respuestas armadas: consulta y opera datos reales de la cuenta, y responde en texto plano pensado para leerse en el teléfono. ## Cómo se activa [#activacion] La vinculación se hace desde el mismo chat de WhatsApp y toma alrededor de un minuto. El comercio debe estar afiliado a Tilopay y la persona necesita su correo y contraseña de Tilopay. 1. Escribí cualquier mensaje al número oficial de Tilopay, **+506 7098 2131**, o abrí el chat directo: [Abrir chat en WhatsApp](https://wa.me/50670982131). Si el número todavía no está vinculado, el chat muestra una bienvenida con el botón **Vincular mi cuenta**. También podés escribir «vincular mi cuenta» para pedir el botón de nuevo. 2. Tocá **Vincular mi cuenta**. Las credenciales y los códigos se ingresan en el formulario seguro que se abre, nunca como mensajes dentro del chat. 3. Ingresá el mismo correo y contraseña que usás para entrar al panel de Tilopay. 4. Si tu cuenta tiene verificación en dos pasos, escribí el código que Tilopay envía al método mostrado en pantalla. 5. Escribí el código de 6 dígitos que llega al correo de Tilopay. Este último código se solicita siempre para confirmar la vinculación. 6. Si tu usuario tiene varios comercios, elegí cuál querés usar. Al terminar, cerrá el formulario y ya podés pedirle al asistente que consulte u opere esa cuenta. La vinculación se autentica con el correo, la contraseña y el código que llega al correo, no con el número: el comercio puede escribir desde cualquier teléfono. El +506 7098 2131 es el mismo número desde el que Tilopay envía los códigos de verificación; pedile al comercio que lo guarde como contacto. Un número sin cuenta vinculada no puede ejecutar consultas ni operaciones. La bienvenida de vinculación se envía como máximo una vez al día; aunque no vuelva a aparecer ese día, podés pedir el botón escribiendo «vincular mi cuenta». ## Volver a vincular la cuenta [#revincular] Si la sesión deja de funcionar o cambia la contraseña, escribí «vincular mi cuenta» y completá el mismo proceso. Volver a vincular el mismo número actualiza la conexión existente: no crea otro perfil ni desconecta los clientes MCP que ya estén vinculados. Cada canal conserva su propia sesión, por lo que un problema en WhatsApp no cierra automáticamente las sesiones de Claude, ChatGPT, Cursor u otros clientes MCP. ## Cómo se usa [#uso] No hay comandos ni menús. Se escribe como se le hablaría a alguien del equipo: - «¿cómo van las ventas de los últimos 30 días?» - «cobrale 25 mil colones a Ana por la consulta y mandámelo por WhatsApp» - «buscá la orden 10432» - «todos los días a las 8pm mandame el resumen de ventas de hoy» El asistente recuerda los últimos mensajes del hilo, así que se puede seguir la conversación sin repetir los datos («mandálo también por correo», «eliminá ese enlace»). ## Qué puede hacer [#capacidades] | Área | Qué resuelve desde el chat | | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Ventas | Resumen y tendencias por día, semana o mes, y análisis con ticket promedio, tasa de aprobación, mejores clientes y motivos de rechazo. | | Transacciones | Listar y consultar transacciones, y capturar, reembolsar o reversar un cobro. | | Enlaces de pago | Crear un enlace, compartirlo por WhatsApp o correo, ver su detalle y eliminarlo. | | Catálogo | Listar productos o servicios, ver su detalle, crear, cambiar o eliminar un ítem. | | Microtienda | Armar una tienda con carrito a partir de los productos del catálogo, listar las tiendas activas y desactivar una. | | Pedidos | Activar la gestión de pedidos con nombre y logo de la tienda, ver el resumen, listar pedidos por estado, ver los pagados sin entregar y marcarlos como entregados. | | Comprobantes | Listar los comprobantes de los cobros aprobados y reenviarle a un cliente el comprobante de su pago. | | Contactos | Guardar, listar y eliminar contactos para cobrarles por nombre. | | Cobros recurrentes | Crear, editar y eliminar planes, armarlos paso a paso desde el chat, generar el enlace de suscripción, consultar suscriptores y sus pagos, editar, pausar, reactivar o eliminar un suscriptor, ver cobros fallidos, generar el enlace para poner al día un cobro rechazado y administrar cupones. | | Tarjetas guardadas | Tokenizar la tarjeta de un cliente, listar o eliminar sus tarjetas, consultar métodos de pago y cuotas, cobrar a una tarjeta guardada y ver grupos, afiliados y cobros masivos. | | Recordatorios | Programar recordatorios de una sola vez, diarios, semanales o mensuales, que además pueden ejecutar una consulta del asistente al enviarse; listarlos y cancelarlos. Máximo 20 activos. | | Avisos | Prender, apagar y consultar los avisos del comercio: cobros aprobados, cobros rechazados, pedidos y el resumen diario a la hora que elija. | | Perfil y recetas | Guardar el perfil del negocio y recibir recomendaciones de automatización según lo que vende. | | Soporte | Buscar la guía oficial de un tema, correr el diagnóstico de conexión y revisar un error de integración. | | Bancario (bajo solicitud) | Cuentas, saldos, pagos, estados de cuenta y análisis de movimientos; y, con confirmación por correo, validar una cuenta destino, enviar una transferencia y consultar su estado. Solo con credenciales del API bancario. | Hoy son 117 herramientas en 15 grupos. El detalle de parámetros y el nivel de acceso de cada una vive en las páginas del [servidor MCP](/developers/agentes/mcp). El asistente también recibe **imágenes** por el chat: por ejemplo, la foto de un producto para el catálogo o el logo que se muestra en la microtienda y en los comprobantes. ## Autorización de operaciones sensibles [#autorizacion] Las operaciones que mueven dinero o alteran cobros —reembolsos, capturas, reversiones, cobros a tarjetas guardadas, cambios a suscriptores, eliminación de enlaces, productos o planes y el envío de una transferencia bancaria— piden un código de 6 dígitos que Tilopay envía al correo registrado del usuario. Sin ese código el asistente no las ejecuta. Las llaves del comercio nunca viajan por el chat y el asistente no muestra credenciales, tokens ni identificadores internos. Cada consulta y cada operación queda auditada con usuario, herramienta, fecha y resultado, con límites de uso por cuenta. ## Avisos que el asistente manda solo [#avisos] - **Pago recibido:** cuando un cliente paga un enlace creado desde el asistente, llega un mensaje por WhatsApp con monto, cliente, concepto, referencia y número de orden. - **Reportes programados:** el resumen o la consulta que se haya agendado, con el dato ya consultado al momento del envío. - **Recordatorios:** el recordatorio agendado, con el resultado de la consulta adjunta si se pidió una acción. Los recordatorios de cobros o enlaces siempre llegan al WhatsApp del comercio, nunca al cliente. - **Pedidos por entregar:** el recordatorio diario de los pedidos ya pagados que siguen sin entregar, cuando la gestión de pedidos está activa. ## Si preferís tu propio agente [#mcp] Las mismas herramientas están disponibles por MCP para Claude, ChatGPT, Cursor u otro cliente: empezá por [Conectar tu agente](/developers/agentes/mcp/conectar) y por [Permisos](/developers/agentes/mcp/permisos). --- # Servidor MCP > Cómo conectar un cliente MCP al servidor de Tilopay con OAuth y las mismas credenciales de la cuenta de Tilopay. - kind: mcp-index - status: stable - last_verified: 2026-09-23 - url: https://tilopay.com/developers/agentes/mcp ## Cómo se obtiene el acceso [#acceso] El acceso es autoservicio, el comercio instala el conector con la URL del servidor y, en la ventana de autorización, inicia sesión con las mismas credenciales de su cuenta de Tilopay (correo y contraseña) y confirma el código de verificación que Tilopay envía. Con eso el usuario del asistente se crea solo, queda asociado al comercio y sus credenciales de API se registran cifradas del lado del servidor. Tres cosas que conviene tener claras: 1. La sesión se autoriza con el correo y la contraseña del panel de Tilopay, más el código de verificación. El asistente nunca ve ni guarda esa contraseña: la conexión queda con OAuth 2.0. 2. Como el usuario queda asociado a un comercio, el agente sólo alcanza los datos y las operaciones de ese comercio. 3. El comercio nunca pega su `apiKey`, `apiUser` ni `apiPassword` en el cliente MCP. Las credenciales de API del comercio viven cifradas en el servidor de Tilopay y se descifran en cada llamada. No se pegan en el cliente MCP, ni en el archivo de configuración del asistente, ni se le pasan al modelo. Ese es el argumento de seguridad de todo el diseño. ## Conexión [#conexion] El servidor es `https://mcp.tilopay.com/mcp`. Para conectarlo: 1. Agregar el servidor en el cliente MCP con esa URL. 2. El cliente descubre la autenticación por el 401 con `WWW-Authenticate`, que apunta a `/.well-known/oauth-protected-resource`. 3. El cliente se registra dinámicamente y abre la pantalla de autorización. 4. El usuario inicia sesión con las credenciales de su cuenta de Tilopay, confirma el código de verificación y ve una pantalla de consentimiento con la aplicación que pide acceso, la URL de retorno y los permisos. 5. Al aprobar, el cliente queda conectado. El modelo es OAuth 2.0 con `authorization_code` y `refresh_token`. El cliente descubre los endpoints del proveedor de identidad por sí mismo: lo único que hay que configurar es la URL del servidor. ## Desde los clientes MCP más usados [#clientes] - **Claude** (escritorio y web): agregar un conector remoto con la URL del servidor y completar el inicio de sesión en la ventana que abre. Conectar con Claude - **ChatGPT**: agregar el servidor como conector remoto con esa misma URL; la autorización se completa en el navegador. - **Cursor, VS Code y otros editores**: declarar un servidor MCP remoto de tipo HTTP con la URL, sin token en el archivo de configuración; el editor abre el navegador para autorizar. - **Cliente propio**: usar un cliente MCP con transporte Streamable HTTP y soporte de OAuth 2.0 con registro dinámico. La secuencia es la de arriba: 401, descubrimiento, registro, autorización, conexión. ¿Quieres empezar con casos listos? [Instala una skill](/developers/agentes/mcp/skills). El transporte es Streamable HTTP. Las herramientas disponibles se listan por grupo: [ventas y transacciones](/developers/agentes/mcp/ventas), [enlaces de pago](/developers/agentes/mcp/enlaces-de-pago), [catálogo](/developers/agentes/mcp/catalogo), [contactos](/developers/agentes/mcp/contactos), [cobros recurrentes](/developers/agentes/mcp/recurrentes), [soporte y diagnóstico](/developers/agentes/mcp/soporte). El grupo [API bancario (BaaS)](/developers/agentes/mcp/api-bancario) se activa bajo solicitud y sólo funciona para usuarios con credenciales del API bancario de Tilopay. Antes de conectar un agente, leé [qué puede hacer](/developers/agentes/mcp/permisos). --- # Conectar tu agente de IA > Cómo conectar Claude, ChatGPT, GitHub Copilot, Cursor, Gemini u otro cliente MCP al servidor MCP de Tilopay. - kind: guide - status: stable - last_verified: 2026-09-23 - url: https://tilopay.com/developers/agentes/mcp/conectar Todos los agentes se conectan al mismo servidor y con el mismo flujo: se agrega un servidor MCP remoto con la URL de Tilopay y la sesión se autoriza en el navegador. Lo único que cambia entre agentes es dónde se agrega. ```text https://mcp.tilopay.com/mcp ``` La versión del servidor MCP en producción es **0.3.0**. ## Antes de conectar [#antes] 1. No hay formulario ni aprobación previa: basta tener una cuenta activa de Tilopay. 2. Al autorizar, la sesión se inicia con el correo y la contraseña del panel de Tilopay y se confirma el código de verificación que Tilopay envía. El usuario del asistente se crea solo en ese momento y queda asociado al comercio. 3. Revisá [qué puede hacer un agente](/developers/agentes/mcp/permisos) antes de conectarlo, sobre todo las herramientas marcadas como sensibles. Nunca pegues `apiKey`, `apiUser` ni `apiPassword` del comercio en el agente ni en su archivo de configuración. Las credenciales del comercio viven cifradas en el servidor de Tilopay: el agente sólo maneja su propia sesión OAuth. ## Claude [#claude] Claude soporta conectores remotos, tanto en la app de escritorio como en la web. 1. Agregá un conector personalizado remoto con la URL del servidor. 2. Claude abre la pantalla de autorización de Tilopay: iniciá sesión con tus credenciales de Tilopay y confirmá el código de verificación. 3. Revisá la pantalla de consentimiento (aplicación que pide acceso, URL de retorno y permisos) y aprobá. 4. Al volver a la conversación, las herramientas de Tilopay quedan disponibles. No hay que pegar ningún token: el conector se registra solo. ## ChatGPT [#chatgpt] ChatGPT se conecta como conector remoto usando la misma URL. 1. Agregá el servidor como conector remoto con la URL de arriba. 2. La autorización se completa en el navegador con tus credenciales de Tilopay y el código de verificación. 3. Al aprobar, el conector queda activo y el modelo puede llamar las herramientas. ## GitHub Copilot y VS Code [#copilot] En VS Code (con Copilot en modo agente) se declara un servidor MCP remoto de tipo HTTP. 1. Declará el servidor con la URL, sin token ni credenciales en el archivo de configuración. 2. Al primer uso, el editor abre el navegador para autorizar. 3. Después de aprobar, las herramientas aparecen en la lista de herramientas del agente. ## Cursor y otros editores [#cursor] Cursor y editores equivalentes usan el mismo esquema: un servidor MCP remoto por HTTP. 1. Agregá el servidor remoto con la URL, sin token en la configuración. 2. Autorizá en el navegador cuando el editor lo pida. 3. Habilitá las herramientas para el chat o el agente del editor. ## Gemini [#gemini] Los clientes de Gemini que soportan MCP remoto se conectan igual: se registra la URL del servidor y la autorización ocurre en el navegador. Si el cliente sólo soporta servidores MCP locales por stdio, se requiere un puente que hable Streamable HTTP contra la URL de Tilopay. ## Otros clientes MCP [#otros] Para un cliente propio o cualquier otro agente, el requisito es soportar transporte **Streamable HTTP** y **OAuth 2.0 con registro dinámico de cliente**. La secuencia es: 1. El cliente llama al servidor y recibe un `401` con `WWW-Authenticate`, que apunta a `/.well-known/oauth-protected-resource`. 2. El cliente descubre los endpoints del proveedor de identidad. 3. Se registra dinámicamente y abre la pantalla de autorización. 4. El usuario inicia sesión y aprueba el consentimiento. 5. El cliente queda conectado con `authorization_code` y `refresh_token`. Lo único que se configura es la URL del servidor. ## Verificar la conexión [#verificar] Pedile al agente que liste las herramientas disponibles: deberían aparecer las de Tilopay agrupadas en [ventas y transacciones](/developers/agentes/mcp/ventas), [enlaces de pago](/developers/agentes/mcp/enlaces-de-pago), [catálogo](/developers/agentes/mcp/catalogo), [contactos](/developers/agentes/mcp/contactos), [cobros recurrentes](/developers/agentes/mcp/recurrentes) y [soporte y diagnóstico](/developers/agentes/mcp/soporte). El grupo [API bancario (BaaS)](/developers/agentes/mcp/api-bancario) se activa bajo solicitud y sólo funciona para usuarios con credenciales del API bancario de Tilopay. Una primera prueba segura es una consulta de sólo lectura, por ejemplo pedir las transacciones de un rango de fechas. Para flujos completos mirá las [recetas](/developers/agentes/mcp/recetas). ## Si algo falla [#problemas] - **El cliente no abre la autorización**: revisá que el servidor esté declarado como remoto por HTTP y no como servidor local. - **La autorización no termina**: la sesión se inicia con el correo y la contraseña del panel de Tilopay; además hay que confirmar el código de verificación que llega al correo. - **El agente no ve herramientas**: en varios clientes hay que habilitarlas para la conversación o para el modo agente después de conectar. - **Una herramienta responde vacío**: puede ser el ambiente consultado; varias herramientas trabajan en `production` por defecto. --- # Qué puede hacer un agente > Alcance real de un agente conectado al servidor MCP: qué herramientas leen, qué herramientas modifican estado y qué controles existen. - kind: guide - status: stable - last_verified: 2026-10-07 - url: https://tilopay.com/developers/agentes/mcp/permisos ## Alcance de las herramientas [#alcance] De las 117 herramientas, 63 sólo leen y 54 modifican estado. 20 de esas 54 están marcadas como sensibles. Las marcadas como sensibles, agrupadas por tema. La lista sale del catálogo: son todas las herramientas con nivel de acceso sensible. Enviar mensajes (enlaces, comprobantes o avisos por WhatsApp o correo) cuenta como escritura, no como operación sensible. **Mueven dinero: reembolsos y capturas, cobros a tarjetas guardadas, transferencias bancarias, su confirmación y el doble control** - [`tilopay_modify_transaction`](https://tilopay.com/developers/agentes/mcp/ventas#tilopay-modify-transaction): Capturar, reembolsar o reversar - [`tilopay_charge_saved_card`](https://tilopay.com/developers/agentes/mcp/tarjetas-guardadas#tilopay-charge-saved-card): Cobrar a una tarjeta guardada de un cliente - [`tilopay_saved_cards_create_payments`](https://tilopay.com/developers/agentes/mcp/tarjetas-guardadas#tilopay-saved-cards-create-payments): Cobrar a tarjetas almacenadas - [`baas_send_transfer`](https://tilopay.com/developers/agentes/mcp/api-bancario/send-transfer#baas-send-transfer): Enviar transferencia BaaS - [`baas_confirm_transfer`](https://tilopay.com/developers/agentes/mcp/api-bancario/otras-operaciones#baas-confirm-transfer): Autorizar la transferencia pendiente - [`banca_decide_approval`](https://tilopay.com/developers/agentes/mcp/api-bancario/otras-operaciones#banca-decide-approval): Aprobar o rechazar una operación pendiente **Borran o desactivan: enlaces, productos, planes, cupones, contactos, tarjetas guardadas, recordatorios, tiendas, dominios y pedidos** - [`tilopay_delete_payment_link`](https://tilopay.com/developers/agentes/mcp/enlaces-de-pago#tilopay-delete-payment-link): Eliminar enlace de pago - [`tilopay_catalog_delete_item`](https://tilopay.com/developers/agentes/mcp/catalogo#tilopay-catalog-delete-item): Borrar un producto del catálogo - [`tilopay_delete_contact`](https://tilopay.com/developers/agentes/mcp/contactos#tilopay-delete-contact): Eliminar contacto - [`tilopay_store_delete`](https://tilopay.com/developers/agentes/mcp/microtienda#tilopay-store-delete): Desactivar una microtienda - [`tilopay_store_domain_remove`](https://tilopay.com/developers/agentes/mcp/microtienda#tilopay-store-domain-remove): Quitar un dominio propio - [`tilopay_orders_disable`](https://tilopay.com/developers/agentes/mcp/microtienda#tilopay-orders-disable): Apagar la gestión de pedidos - [`tilopay_cancel_reminder`](https://tilopay.com/developers/agentes/mcp/recordatorios#tilopay-cancel-reminder): Cancelar recordatorio - [`tilopay_recurring_delete_plan`](https://tilopay.com/developers/agentes/mcp/recurrentes#tilopay-recurring-delete-plan): Eliminar plan de suscripción - [`tilopay_recurring_delete_coupon`](https://tilopay.com/developers/agentes/mcp/recurrentes#tilopay-recurring-delete-coupon): Eliminar un cupón - [`tilopay_remove_saved_card`](https://tilopay.com/developers/agentes/mcp/tarjetas-guardadas#tilopay-remove-saved-card): Eliminar una tarjeta guardada de un cliente **Cambian el estado de un suscriptor y sus cobros futuros** - [`tilopay_recurring_manage_subscriber`](https://tilopay.com/developers/agentes/mcp/recurrentes#tilopay-recurring-manage-subscriber): Pausar, reactivar o eliminar un suscriptor - [`tilopay_recurring_edit_subscriber`](https://tilopay.com/developers/agentes/mcp/recurrentes#tilopay-recurring-edit-subscriber): Editar suscriptor de un plan **Cortan el acceso: desvincular la cuenta y quitar a un empleado** - [`tilopay_unlink_account`](https://tilopay.com/developers/agentes/mcp/cuenta#tilopay-unlink-account): Desvincular mi cuenta - [`tilopay_remove_employee`](https://tilopay.com/developers/agentes/mcp/cuenta#tilopay-remove-employee): Quitar acceso a un empleado ## Herencia de permisos [#herencia-de-permisos] El servidor usa las credenciales de API del comercio, así que hereda exactamente sus permisos: no impone barreras adicionales por herramienta. Un usuario activo puede reembolsar y hacer cobros masivos. ## Controles que existen [#controles] - Un interruptor de activación por usuario, que corta el acceso sin borrar la cuenta. - Un rol de administrador separado, que sólo sirve para gestionar usuarios y credenciales. - Un límite de tasa de 60 llamadas por minuto por usuario. ## Confirmación humana [#confirmacion-humana] La confirmación humana antes de una operación sensible depende del cliente MCP, no de Tilopay. Exigila siempre para las herramientas de escritura, y no la negocies en reembolsos ni en cobros masivos. El detalle por herramienta, con parámetros y salida, está en las páginas de cada grupo y en el [`mcp.json`](/developers/mcp.json). --- # Recetas > Catorce flujos de punta a punta con el servidor MCP: dashboard de insights, ventas por WhatsApp, recuperación de cobros recurrentes fallidos, cobranza B2B, proyección de caja con datos bancarios, detección de anomalías, cierre de mes, reembolsos, suscripciones recurrentes, optimización de planes, cobros a tarjetas almacenadas, depuración de integraciones y Tilopay como herramienta de otros agentes. - kind: guide - status: stable - last_verified: 2026-10-07 - url: https://tilopay.com/developers/agentes/mcp/recetas ## Construir un dashboard de insights en tiempo real [#dashboard-insights] 1. `tilopay_sales_summary` trae los totales, costos y neto del período que querés monitorear. 2. `tilopay_analyze_sales` convierte esos números en un resumen narrativo con tendencias y observaciones. 3. `tilopay_list_transactions` lista las transacciones recientes para completar el tablero. 4. `tilopay_get_transaction` abre el detalle de cualquier operación que necesite revisión. El resumen usa UTC, no hora local. Si tenés poco volumen, las tendencias y los clientes destacados pueden venir vacíos. ### Ejemplos de preguntas para el dashboard [#ejemplos-dashboard] - “¿Cómo me fue hoy?” → `tilopay_sales_summary` + `tilopay_analyze_sales`. - “¿Cuáles son mis productos o servicios más vendidos esta semana?” → `tilopay_analyze_sales` sobre el rango de los últimos 7 días. - “¿Tengo transacciones fallidas o sin liquidar?” → `tilopay_list_transactions` filtrando por estado, luego `tilopay_get_transaction` para cada caso. - “¿Cómo evolucionan mis ingresos netos respecto al mes pasado?” → comparar dos llamadas a `tilopay_sales_summary` con ventanas de fechas distintas. ## Vender por WhatsApp desde el catálogo [#cobrar-por-whatsapp] 1. `tilopay_catalog_list_items` lista los productos o servicios del comercio para responder la consulta del cliente con nombres y precios reales. 2. `tilopay_catalog_get_item` abre el detalle del ítem elegido cuando hay que confirmar precio, moneda o descripción antes de armar el pedido. 3. El agente arma el pedido, calcula el total y se lo confirma al cliente antes de cobrar. 4. `tilopay_save_contact` guarda al comprador (nombre, correo, teléfono) para asociarlo al cobro y reutilizarlo en ventas futuras. 5. `tilopay_create_charge` crea el enlace por el total del pedido, con una descripción que identifique la orden. 6. `tilopay_send_payment_link_whatsapp` prepara el envío al cliente. 7. `tilopay_get_payment_link` consulta el estado del enlace para confirmar el pago y cerrar la conversación con el comprobante. `tilopay_send_payment_link_whatsapp` no envía el mensaje: devuelve un enlace `wa.me` con el texto listo para enviar con un toque. Si no hay teléfono ni contacto guardado con ese nombre, la herramienta lo pide. El agente puede quedarse consultando `tilopay_get_payment_link` cada cierto tiempo para avisarle al comercio en cuanto el enlace pase a pagado. Con esta receta un comercio sin tienda en línea vende de punta a punta dentro del chat: catálogo, pedido, cobro y confirmación, sin intervención humana salvo la que el propio comercio quiera exigir. ## Recuperar cobros recurrentes fallidos (dunning inteligente) [#dunning-inteligente] 1. `tilopay_recurring_list_plans` lista los planes activos del comercio. 2. `tilopay_recurring_subscriber_payments` recorre los pagos de los suscriptores de cada plan y separa los cobros rechazados del período. 3. `tilopay_get_transaction` abre cada rechazo para leer el código de respuesta y clasificar la causa: fondos insuficientes, tarjeta vencida, tarjeta bloqueada, sospecha de fraude. 4. Según la causa, el agente decide la acción y se la propone al comercio: esperar el reintento del plan cuando el rechazo es transitorio (fondos insuficientes), o pedirle al cliente un nuevo medio de pago cuando el rechazo es definitivo (tarjeta vencida o bloqueada). 5. `tilopay_create_charge` crea un enlace por el saldo por cobrar cuando hay que pedirle al cliente que pague la cuota con otra tarjeta. 6. `tilopay_send_payment_link_whatsapp` o `tilopay_send_payment_link_email` prepara el mensaje al cliente con un texto adaptado al motivo del rechazo. 7. `tilopay_get_payment_link` confirma cuando el cliente pagó, y `tilopay_recurring_get_subscriber` verifica el estado del suscriptor después de la recuperación. Un agente que corre esta receta cada mañana convierte la lista de rechazos en dos colas: la que se resuelve sola con el reintento del plan y la que necesita un mensaje al cliente. El comercio recibe solo el resumen: cuántos cobros se recuperaron y cuáles siguen sin recuperarse. No uses `tilopay_recurring_manage_subscriber` para "castigar" un rechazo: `pause` y `delete` afectan cobros futuros y `delete` no se deshace. Pausar o dar de baja a un suscriptor es una decisión del comercio, con confirmación humana explícita, nunca una reacción automática a un cobro fallido. ## Cobranza B2B con cuentas por cobrar [#cobranza-b2b] 1. `tilopay_list_contacts` trae los clientes empresariales del comercio; `tilopay_save_contact` registra los que falten con nombre, correo y teléfono de la persona que paga. 2. `tilopay_create_charge` crea un enlace por cada factura sin pagar, con el número de factura en la descripción y una fecha de vencimiento. 3. `tilopay_send_payment_link_email` prepara el primer envío; `tilopay_send_payment_link_whatsapp` prepara el recordatorio cuando la factura sigue sin pagar. 4. `tilopay_get_payment_link` revisa el estado de cada enlace para actualizar la lista de cuentas por cobrar sin entrar al panel. 5. `baas_search_payment` o `baas_list_payments` buscan en las cuentas bancarias del comercio una transferencia directa (SINPE o transferencia bancaria) que coincida con el monto y el cliente, para marcar como pagada una factura que el cliente liquidó fuera del enlace. 6. `tilopay_delete_payment_link` elimina el enlace de una factura que ya se pagó por transferencia, para evitar un cobro doble. Esta receta responde el "¿ya me pagaron?" que consume horas administrativas en negocios que facturan a empresas: una sola lista con facturas, enlaces, estado y pagos recibidos por cualquier vía. Las herramientas `baas_*` son de solo consulta y requieren que soporte haya registrado las credenciales del API bancario del comercio. Si no están configuradas, la herramienta lo indica y la receta sigue funcionando solo con los enlaces de pago. ## Proyectar la caja con datos de la pasarela y del banco (CFO de bolsillo) [#cfo-de-bolsillo] 1. `tilopay_sales_summary` trae las ventas de las últimas semanas para estimar los ingresos esperados del período siguiente. 2. `tilopay_recurring_list_plans` y `tilopay_recurring_get_plan` cuantifican los cobros recurrentes comprometidos y sus fechas. 3. `baas_list_balances` o `baas_get_balance` traen el saldo real de cada cuenta bancaria del comercio. 4. `baas_list_payments` lista las transferencias de los últimos meses para detectar las salidas recurrentes: planilla, alquiler, proveedores. 5. `baas_analyze_payments` resume esos movimientos en lenguaje natural para identificar patrones y fechas pico. 6. El agente combina saldo, entradas previstas y salidas previstas en una proyección diaria, señala los días con saldo mínimo o negativo y propone acciones. 7. `tilopay_create_charge` y `tilopay_send_payment_link_email` ponen a cobro facturas sin pagar cuando el comercio aprueba esa acción. El valor está en cruzar dos fuentes que normalmente viven separadas: la pasarela sabe qué va a entrar y el banco sabe qué hay y qué sale. Una rutina semanal produce un briefing corto con la proyección y las alertas, antes de que abra el negocio. Las herramientas `baas_*` nunca inician, aprueban ni revierten transferencias. Si la proyección sugiere mover fondos entre cuentas, esa acción la ejecuta una persona en el banco; el agente solo la recomienda y la registra. La proyección es una estimación, no un estado financiero. ## Detectar anomalías y actuar [#detector-anomalias] 1. `tilopay_sales_summary` compara la ventana actual (por ejemplo la última hora o el día) contra el mismo período de referencia para detectar caídas de aprobación, picos de rechazos o cambios bruscos en el ticket promedio. 2. `tilopay_list_transactions` filtra por estado para ver si los rechazos se concentran en un método de pago, una moneda o un patrón de intentos repetidos. 3. `tilopay_get_transaction` abre casos representativos para leer los códigos de respuesta. 4. `tilopay_diagnostics` verifica credenciales y disponibilidad de los endpoints para separar un problema de la integración del comercio de un problema de los clientes o del emisor. 5. `tilopay_help_guides` busca en las guías oficiales la explicación y los pasos de corrección que correspondan al código de respuesta o al síntoma. 6. El agente abre la alerta con el diagnóstico ya hecho: qué cambió, desde cuándo, causa probable y acción sugerida. El resumen de ventas usa UTC. Al comparar ventanas cortas, alineá las horas; una "caída" a medianoche local puede ser solo el corte del día en UTC. Muchos intentos rechazados en pocos minutos con montos pequeños y tarjetas distintas pueden indicar pruebas de tarjetas robadas: reportalo a soporte en vez de reintentar. ## Cerrar las ventas del mes [#cierre-de-mes] 1. `tilopay_sales_summary` devuelve los totales, costos y neto del período. 2. `tilopay_analyze_sales` produce el informe en lenguaje natural. 3. `tilopay_get_transaction` trae el detalle de las transacciones que haya que revisar. Las horas y los días del resumen están en UTC, no en hora local. Las tendencias y los clientes destacados vienen vacíos si la muestra es chica. ## Reembolsar con confirmación humana [#reembolso] 1. `tilopay_list_transactions` localiza la transacción en el rango de fechas. 2. `tilopay_get_transaction` muestra el detalle para confirmar que es la correcta. 3. El agente le pide confirmación al usuario. Este paso lo impone el cliente MCP, no Tilopay. 4. `tilopay_modify_transaction` ejecuta la modificación con la acción y el monto. ## Revisar una suscripción recurrente [#suscripcion-recurrente] 1. `tilopay_recurring_list_plans` lista los planes de cobro recurrente del comercio. 2. `tilopay_recurring_get_plan` abre el plan que interesa por su ID. 3. `tilopay_recurring_get_subscriber` muestra el detalle del suscriptor. 4. `tilopay_recurring_subscriber_payments` lista los pagos de ese suscriptor para ver cuáles pasaron y cuáles no. Sirve para responder "¿por qué este cliente aparece sin cobrar este mes?" sin entrar al panel. ## Optimizar los planes de suscripción [#optimizar-planes] 1. `tilopay_recurring_list_plans` lista los planes activos con su precio y periodicidad. 2. `tilopay_recurring_get_plan` abre cada plan para conocer la cantidad de suscriptores y su configuración. 3. `tilopay_recurring_subscriber_payments` recorre los pagos por suscriptor para calcular, por plan, la tasa de cobros exitosos, el mes en que más suscriptores dejan de pagar y la antigüedad promedio. 4. `tilopay_recurring_get_subscriber` revisa los casos atípicos que el análisis señale. 5. El agente presenta el comparativo entre planes: retención, ingreso por suscriptor y punto de abandono, y propone cambios de precio, periodicidad o contenido. 6. `tilopay_create_charge` permite probar una oferta nueva con un segmento pequeño de contactos antes de modificar un plan. Es análisis de precios con datos reales de cobro. El agente no modifica planes: propone, y el comercio decide en el panel. ## Pausar o dar de baja a un suscriptor [#pausar-suscriptor] 1. `tilopay_recurring_get_subscriber` confirma que el suscriptor es el correcto. 2. El agente le pide confirmación al usuario, con el nombre y el plan a la vista. 3. `tilopay_recurring_manage_subscriber` ejecuta `pause`, `reactivate` o `delete`. `tilopay_recurring_manage_subscriber` está marcada como sensible: afecta cobros futuros y `delete` no se deshace. Nunca la ejecutés sin confirmación humana explícita. ## Cobrar a un grupo con tarjetas almacenadas [#cobro-masivo] 1. `tilopay_saved_cards_list_groups` lista los grupos de cobro. 2. `tilopay_saved_cards_list_affiliates` muestra los afiliados del grupo elegido, para saber a cuántas tarjetas se le va a cobrar. 3. El agente resume monto, moneda, motivo y cantidad de afiliados, y pide confirmación. 4. `tilopay_saved_cards_create_payments` crea los cobros. 5. `tilopay_saved_cards_list_collections` y `tilopay_saved_cards_collection_detail` revisan el resultado: la segunda necesita el `code` que devuelve la primera. `tilopay_saved_cards_create_payments` mueve dinero real de las tarjetas almacenadas. Tratala como una operación de un solo intento: confirmá antes, y verificá después con el detalle del cobro. ## Depurar una integración y acompañar a un desarrollador [#depurar-integracion] 1. `tilopay_diagnostics` prueba las credenciales y un endpoint de cada grupo del API, para separar un problema de credenciales de un problema de la petición. 2. `tilopay_debug_code` recibe el fragmento de código, el log o el stack trace y devuelve diagnóstico, causa raíz, corrección y riesgos. 3. `tilopay_help_guides` responde las dudas de uso del panel con las guías oficiales. 4. `tilopay_list_transactions` y `tilopay_get_transaction` confirman si la operación que el desarrollador cree fallida en realidad llegó a Tilopay y con qué resultado. `tilopay_debug_code` no lee el repositorio ni ejecuta el código: analiza sólo lo que le pasás. Antes de mandarlo, quitá credenciales del fragmento; la herramienta oculta lo que reconoce como secreto, pero no reemplaza esa revisión. Con estas cuatro herramientas un agente de soporte atiende el onboarding técnico completo: verifica la cuenta, encuentra la causa del error, entrega la corrección con la guía oficial y confirma contra las transacciones reales. Las preguntas que se repiten son la señal de qué guía o ejemplo debe agregarse al portal. Las tarjetas de prueba del modo sandbox están en la guía de pruebas del portal. El modo sandbox se alterna desde la cuenta; no existe un host separado. ## Tilopay como herramienta de otros agentes [#tilopay-como-herramienta] 1. El acceso es autoservicio: agregás el servidor MCP en tu cliente con la URL `https://mcp.tilopay.com/mcp` y autorizás la sesión con el correo y la contraseña de tu cuenta de Tilopay, más el código de verificación que te enviamos. No hay formulario ni aprobación previa. 2. El agente externo (el asistente de un ERP, un bot de tienda en línea, un agente contable) conecta el servidor MCP con esa sesión OAuth y ejecuta `tilopay_diagnostics` para verificar la conexión. 3. Con el catálogo de herramientas cargado, el agente externo usa las herramientas de consulta (`tilopay_sales_summary`, `tilopay_list_transactions`, `tilopay_recurring_*`, `baas_*`) para responder preguntas del negocio dentro de su propia conversación. 4. Para acciones que crean o mueven dinero (`tilopay_create_charge`, `tilopay_modify_transaction`, `tilopay_saved_cards_create_payments`, `tilopay_recurring_manage_subscriber`) el agente externo aplica la política de confirmación descrita en la página de permisos antes de ejecutar. Esta receta cambia la posición del MCP: no es solo un asistente dentro de Tilopay, es la capa de pagos que cualquier agente puede invocar. Las demás recetas de esta página funcionan igual cuando las ejecuta un agente de terceros. El consumo del MCP puede tener costos adicionales según el volumen; soporte lo detalla al validar el volumen transaccional del comercio. Las herramientas marcadas como sensibles exigen confirmación humana en el cliente MCP que las ejecute, sea de Tilopay o de un tercero. ¿Quieres dejar estas recetas empaquetadas y repetibles? [Instala una skill](/developers/agentes/mcp/skills). --- # Skills para agentes > Paquetes de instrucciones listos para que un agente use el MCP de Tilopay en tareas concretas, como el cierre de caja, cobrar por WhatsApp o recuperar pagos rechazados. - kind: guide - status: stable - last_verified: 2026-10-07 - url: https://tilopay.com/developers/agentes/mcp/skills ## Qué es una skill [#que-es] Una skill es un paquete de instrucciones (un `SKILL.md` más sus referencias) que el agente carga sólo cuando el comercio le pide algo de ese tema. No requiere código ni credenciales: usa el MCP de Tilopay que ya está conectado, y las instrucciones le dicen qué herramientas llamar, en qué orden y cómo validar los números antes de responder. La diferencia con las [recetas](/developers/agentes/mcp/recetas) es que la receta es el ejemplo de prompt; la skill lo deja empaquetado y repetible, con reglas de cálculo y de seguridad. ## Antes de empezar [#antes] Necesitás una cuenta de Tilopay. Si instalás el plugin (opción 2 de abajo), el conector del MCP viene incluido y solo tenés que autorizarlo con tu cuenta la primera vez. Para las demás opciones, primero [conectá el MCP en tu cliente](/developers/agentes/mcp/conectar). Las skills no piden ni guardan credenciales. ## Skills disponibles [#skills] ### Todas las skills en un plugin Las seis skills y el conector del MCP de Tilopay en un solo plugin para Cowork, el chat de claude.ai y Claude Code. Instalalo desde el marketplace de Tilopay con los comandos de abajo. ```text /plugin marketplace add tilopay/claude-plugins /plugin install tilopay-mcp-skills@tilopay ``` - [Ver en GitHub](https://github.com/tilopay/claude-plugins) - Versión: 1.0.1 - Copiar prompt para Claude Code: «Lee el índice de skills de Tilopay en https://tilopay.com/developers/skills/index.md. Para cada skill, crea una carpeta con su nombre dentro de ~/.claude/skills/, guarda ahí su SKILL.md y, si el índice lista archivos de referencia, guárdalos en una subcarpeta references/ con el mismo nombre de archivo. Al final dime qué skills quedaron instaladas.» ### cierre-de-caja Cierre de caja del día, la semana o el mes por moneda: aprobadas, rechazadas, reembolsos, desglose exacto de comisiones y retenciones, neto a liquidar y próximo depósito, con validación de que los números cuadran contra el balance oficial de Tilopay. - Prompt de ejemplo: «Dame el cierre de caja de hoy» - Herramientas del MCP: `tilopay_list_transactions`, `tilopay_sales_summary`, `tilopay_settlement_balance`, `tilopay_settlements_list`, `tilopay_switch_commerce` - Grupos: [Ventas y transacciones](https://tilopay.com/developers/agentes/mcp/ventas) - Versión: 1.0.1 - [SKILL.md](https://tilopay.com/developers/skills/cierre-de-caja/SKILL.md) - Prompt para usarla sin instalar: «Lee https://tilopay.com/developers/skills/cierre-de-caja/SKILL.md y los archivos que referencia, y sigue esas instrucciones usando mi conector de Tilopay. Dame el cierre de caja de hoy» ### cobrar-por-whatsapp Convierte una frase en un cobro real y en el mensaje de WhatsApp listo para enviar; genera el QR si se pide y verifica después si el cliente ya pagó. - Prompt de ejemplo: «Cóbrale 25 mil colones a Ana por el curso de fotografía» - Herramientas del MCP: `tilopay_create_charge`, `tilopay_send_payment_link_whatsapp`, `tilopay_send_payment_link_email`, `tilopay_payment_link_qr`, `tilopay_list_receipts`, `tilopay_find_payment`, `tilopay_list_contacts` - Grupos: [Enlaces de pago](https://tilopay.com/developers/agentes/mcp/enlaces-de-pago), [Comprobantes](https://tilopay.com/developers/agentes/mcp/comprobantes), [Contactos](https://tilopay.com/developers/agentes/mcp/contactos) - Versión: 1.0.1 - [SKILL.md](https://tilopay.com/developers/skills/cobrar-por-whatsapp/SKILL.md) - Prompt para usarla sin instalar: «Lee https://tilopay.com/developers/skills/cobrar-por-whatsapp/SKILL.md y los archivos que referencia, y sigue esas instrucciones usando mi conector de Tilopay. Cóbrale 25 mil colones a Ana por el curso de fotografía» ### rechazos-y-recuperacion Analiza los pagos rechazados, los agrupa por motivo con las etiquetas de la guía oficial «Motivos de rechazo», detecta patrones (mismo cliente reintentando, misma orden recuperada después, canal, horario) y propone acciones concretas, incluido el mensaje al cliente y un enlace nuevo. - Prompt de ejemplo: «¿Por qué me rechazaron pagos este mes y cuáles puedo recuperar?» - Herramientas del MCP: `tilopay_list_transactions`, `tilopay_sales_summary`, `tilopay_create_charge`, `tilopay_send_payment_link_whatsapp`, `tilopay_help_guides` - Grupos: [Ventas y transacciones](https://tilopay.com/developers/agentes/mcp/ventas), [Enlaces de pago](https://tilopay.com/developers/agentes/mcp/enlaces-de-pago), [Soporte y diagnóstico](https://tilopay.com/developers/agentes/mcp/soporte) - Versión: 1.0.1 - [SKILL.md](https://tilopay.com/developers/skills/rechazos-y-recuperacion/SKILL.md) - Prompt para usarla sin instalar: «Lee https://tilopay.com/developers/skills/rechazos-y-recuperacion/SKILL.md y los archivos que referencia, y sigue esas instrucciones usando mi conector de Tilopay. ¿Por qué me rechazaron pagos este mes y cuáles puedo recuperar?» - [Guía «Motivos de rechazo»](https://tilopay.com/guias/panel-transacciones/motivos-de-rechazo) ### conciliacion-mensual Conciliación contable de un mes, quincena o rango: cruza ventas aprobadas, reembolsos y liquidaciones depositadas, con los seis campos de costo etiquetados, y entrega un CSV o Excel para el contador más un resumen de diferencias. - Prompt de ejemplo: «Concíliame septiembre para el contador» - Herramientas del MCP: `tilopay_list_transactions`, `tilopay_refunds_list`, `tilopay_settlements_list`, `tilopay_settlement_transactions`, `tilopay_settlement_balance`, `tilopay_billing_list`, `tilopay_switch_commerce` - Grupos: [Ventas y transacciones](https://tilopay.com/developers/agentes/mcp/ventas), [Liquidaciones, depósitos y facturación](https://tilopay.com/developers/agentes/mcp/liquidaciones), [Cuenta, comercio y equipo](https://tilopay.com/developers/agentes/mcp/cuenta) - Versión: 1.0.0 - [SKILL.md](https://tilopay.com/developers/skills/conciliacion-mensual/SKILL.md) - Prompt para usarla sin instalar: «Lee https://tilopay.com/developers/skills/conciliacion-mensual/SKILL.md y los archivos que referencia, y sigue esas instrucciones usando mi conector de Tilopay. Concíliame septiembre para el contador» ### cfo-de-bolsillo Análisis financiero de ventas: compara períodos del mismo largo, ticket promedio, mejores días y horas, concentración de clientes, costo efectivo de Tilopay como porcentaje de la venta y una proyección simple de cierre de mes y flujo con el próximo depósito, siempre etiquetada como estimación. - Prompt de ejemplo: «¿Cómo voy este mes comparado con el anterior?» - Herramientas del MCP: `tilopay_list_transactions`, `tilopay_sales_summary`, `tilopay_settlement_balance`, `tilopay_settlements_list`, `tilopay_get_business_profile` - Grupos: [Ventas y transacciones](https://tilopay.com/developers/agentes/mcp/ventas), [Liquidaciones, depósitos y facturación](https://tilopay.com/developers/agentes/mcp/liquidaciones), [Perfil del comercio](https://tilopay.com/developers/agentes/mcp/perfil) - Versión: 1.0.0 - [SKILL.md](https://tilopay.com/developers/skills/cfo-de-bolsillo/SKILL.md) - Prompt para usarla sin instalar: «Lee https://tilopay.com/developers/skills/cfo-de-bolsillo/SKILL.md y los archivos que referencia, y sigue esas instrucciones usando mi conector de Tilopay. ¿Cómo voy este mes comparado con el anterior?» ### catalogo-y-cobros-fijos Gestiona el catálogo de productos y servicios: busca productos con su enlace de pago, crea o edita desde una frase o una lista, entrega el QR de un producto o el QR permanente de mostrador, y conecta el catálogo a Facebook/Instagram, Google Shopping, TikTok o Pinterest. - Prompt de ejemplo: «Agregá al catálogo Clase de yoga a 8 mil colones» - Herramientas del MCP: `tilopay_catalog_list_items`, `tilopay_catalog_get_item`, `tilopay_catalog_create_item`, `tilopay_catalog_update_item`, `tilopay_catalog_delete_item`, `tilopay_payment_link_qr`, `tilopay_static_payment_qr`, `tilopay_catalog_feed`, `tilopay_store_list`, `tilopay_send_payment_link_whatsapp` - Grupos: [Catálogo](https://tilopay.com/developers/agentes/mcp/catalogo), [Enlaces de pago](https://tilopay.com/developers/agentes/mcp/enlaces-de-pago), [Microtienda](https://tilopay.com/developers/agentes/mcp/microtienda) - Versión: 1.0.0 - [SKILL.md](https://tilopay.com/developers/skills/catalogo-y-cobros-fijos/SKILL.md) - Prompt para usarla sin instalar: «Lee https://tilopay.com/developers/skills/catalogo-y-cobros-fijos/SKILL.md y los archivos que referencia, y sigue esas instrucciones usando mi conector de Tilopay. Agregá al catálogo Clase de yoga a 8 mil colones» ## Cómo instalar [#instalar] **Opción 1 · Usarla ahora mismo, sin instalar nada (Claude, ChatGPT u otro asistente con el MCP conectado).** 1. Abrí una conversación nueva con el MCP de Tilopay conectado. 2. En la tarjeta de la skill, tocá «Copiar prompt». 3. Pegalo y enviá. El asistente lee las instrucciones desde tilopay.com y las aplica en esa conversación. La próxima vez, volvé a pegar el prompt (o usá la opción 2 para dejarla fija). Por ejemplo, el prompt del cierre de caja: ```text Lee https://tilopay.com/developers/skills/cierre-de-caja/SKILL.md y los archivos que referencia, y sigue esas instrucciones usando mi conector de Tilopay. Dame el cierre de caja de hoy ``` **Opción 2 · Instalar las seis de una vez en Claude (recomendada).** Tilopay publica sus skills como un plugin en GitHub. Se agrega una sola vez y queda guardado en tu cuenta: sirve en Cowork, en el chat de claude.ai y en Claude Code. El plugin incluye el conector del MCP de Tilopay: la primera vez que lo uses, Claude te pide autorizarlo con tu cuenta de Tilopay (en Cowork, desde la pestaña Connectors del plugin). En la app de Claude (Cowork): 1. Abrí la pestaña Cowork y luego Customize en la barra lateral. 2. Entrá a Plugins y hacé clic en Add → Add marketplace → Add from a repository. 3. Escribí `tilopay/claude-plugins` y confirmá. 4. Volvé a Discover, elegí tilopay-mcp-skills y hacé clic en Install. En Claude Code (terminal), dos comandos: ```text /plugin marketplace add tilopay/claude-plugins /plugin install tilopay-mcp-skills@tilopay ``` Desde ese momento, cuando pidas algo del tema («dame el cierre de caja de hoy») con el MCP de Tilopay conectado, Claude carga la skill sola. Para recibir mejoras, en el marketplace usá Check for updates o activá Sync automatically (en Claude Code: `/plugin marketplace update tilopay`).

Los plugins están disponibles en los planes de pago de Claude. Si tu organización limita qué marketplaces se pueden agregar, un Owner debe permitir tilopay/claude-plugins o sincronizarlo para todos desde la configuración de la organización.

**Opción 3 · Dejar una skill fija en un Proyecto de Claude.** La forma más simple sin instalar nada: creá un Proyecto en Claude, abrí el `SKILL.md` de la skill (enlace de la tarjeta), copiá todo el contenido y pegalo en las instrucciones del proyecto. Para que el asistente la use en cualquier conversación, pegá el prompt de la opción 1 cuando lo necesites. **Opción 4 · A mano en Claude Code (sin marketplace).** Pegá este prompt en Claude Code: ```text Lee el índice de skills de Tilopay en https://tilopay.com/developers/skills/index.md. Para cada skill, crea una carpeta con su nombre dentro de ~/.claude/skills/, guarda ahí su SKILL.md y, si el índice lista archivos de referencia, guárdalos en una subcarpeta references/ con el mismo nombre de archivo. Al final dime qué skills quedaron instaladas. ``` El prompt le pide a Claude Code crear una carpeta por skill dentro de `~/.claude/skills/` (o en `.claude/skills/` del proyecto para compartirla con tu equipo), guardando el `SKILL.md` publicado de cada una y, si tiene archivos de referencia, también esos archivos en una subcarpeta `references/`. **Otros clientes MCP.** Usá el `SKILL.md` como instrucciones del sistema o del proyecto, o pegá el prompt de la opción 1. ## Cómo funciona por dentro [#como-funciona] Con el cierre de caja como ejemplo, la secuencia es: 1. El agente convierte "hoy" a la hora local del comercio. 2. Llama `tilopay_list_transactions` con ese rango expresado en UTC. 3. Clasifica cada fila sólo por `code`: `1` es aprobada y `1101` es reembolso. 4. Suma los seis campos de costo con su nombre exacto: `commission`, `iva_commission`, `rent`, `retention_iva`, `cost` e `iva_tilopay`. 5. Valida que bruto − deducciones = neto y lo cruza con `tilopay_settlement_balance` antes de responder. Las skills nunca llaman herramientas que muevan dinero sin confirmación del comercio. ## Crear tu propia skill [#crear] La estructura mínima de un `SKILL.md` es un frontmatter con `name` y `description`, seguido del procedimiento: ```markdown --- name: mi-skill description: Qué hace la skill y cuándo debe usarla el agente. --- 1. Paso del procedimiento, con la herramienta exacta que se llama. 2. Regla de validación antes de responder. ``` Tres consejos: 1. Nombrá las herramientas exactas que el agente tiene que llamar. 2. Poné las reglas de validación de los números. 3. Decí qué NO hacer. Para conocer todas las herramientas disponibles, consultá el manifiesto [`/developers/mcp.json`](/developers/mcp.json). Si armaste una skill útil para otros comercios, enviala a [soporte@tilopay.com](mailto:soporte@tilopay.com). --- # Herramientas de adquirencia > Resumen de los grupos de herramientas del MCP sobre el API de adquirencia: ventas, enlaces de pago, catálogo, contactos, perfil del negocio, microtienda y pedidos, avisos, comprobantes, recordatorios, cobros recurrentes, tarjetas guardadas y soporte. - kind: mcp-index - status: stable - last_verified: 2026-10-07 - url: https://tilopay.com/developers/agentes/mcp/adquirencia ## Qué cubre [#que-cubre] Estas son las herramientas que trabajan sobre el **API de adquirencia** de Tilopay: cobros con tarjeta, enlaces de pago y los datos que los rodean. Vienen activadas con el acceso MCP estándar, sin solicitud adicional, y operan siempre sobre el comercio asociado al usuario del MCP. Las herramientas del [API bancario](/developers/agentes/mcp/api-bancario) son un caso aparte: se activan bajo solicitud y exigen credenciales del API bancario. ## Grupos [#grupos] - [Ventas y transacciones](https://tilopay.com/developers/agentes/mcp/ventas) — 8 herramientas: Consulta de transacciones, métricas de ventas y la modificación de una transacción (captura, reembolso o reversión). - [Enlaces de pago](https://tilopay.com/developers/agentes/mcp/enlaces-de-pago) — 7 herramientas: Creación, consulta y borrado de enlaces de pago, más la preparación del envío por WhatsApp o correo. - [Catálogo de productos](https://tilopay.com/developers/agentes/mcp/catalogo) — 6 herramientas: Lectura del catálogo de productos y servicios que el comercio ya tiene creado en enlaces de pago. - [Contactos](https://tilopay.com/developers/agentes/mcp/contactos) — 3 herramientas: Agenda del comercio: contactos guardados para reutilizar teléfono y correo al enviar un enlace de pago. - [Perfil del negocio y recetas](https://tilopay.com/developers/agentes/mcp/perfil) — 3 herramientas: Perfil del negocio del comercio (a qué se dedica, qué vende, cómo cobra y qué quiere mejorar) y las recetas de automatización que el agente sugiere a partir de ese perfil. - [Microtienda y pedidos](https://tilopay.com/developers/agentes/mcp/microtienda) — 13 herramientas: Microtiendas con carrito armadas desde el catálogo, y la gestión de los pedidos que entran por ahí: activación, resumen, listado, pendientes de entrega y cierre. - [Avisos y notificaciones](https://tilopay.com/developers/agentes/mcp/avisos) — 2 herramientas: Avisos por WhatsApp del comercio: cobros aprobados y rechazados, resumen diario y pedidos. Sólo lee y cambia la configuración; no envía mensajes por su cuenta. - [Comprobantes de cobro](https://tilopay.com/developers/agentes/mcp/comprobantes) — 2 herramientas: Comprobantes de los cobros aprobados: listarlos y reenviarle a un cliente el comprobante de su pago. - [Recordatorios](https://tilopay.com/developers/agentes/mcp/recordatorios) — 3 herramientas: Recordatorios por WhatsApp, de una vez o recurrentes, que pueden ejecutar una acción del agente al enviarse (resumen de ventas, enlaces pendientes, saldos). - [Cobros recurrentes](https://tilopay.com/developers/agentes/mcp/recurrentes) — 23 herramientas: Planes de suscripción y sus suscriptores: consulta, creación y edición de planes, cupones, enlaces de suscripción, cobros fallidos y el paso a paso guiado para armar un plan. - [Tarjetas guardadas y cobros masivos](https://tilopay.com/developers/agentes/mcp/tarjetas-guardadas) — 10 herramientas: Tarjetas guardadas de los clientes y cobros masivos: tokenización, métodos de pago disponibles, cobro a una tarjeta guardada, eliminación de una tarjeta y grupos de cobro. - [Liquidaciones, depósitos y facturación](https://tilopay.com/developers/agentes/mcp/liquidaciones) — 7 herramientas: - [Cuenta, comercio y equipo](https://tilopay.com/developers/agentes/mcp/cuenta) — 8 herramientas: - [Soporte y diagnóstico](https://tilopay.com/developers/agentes/mcp/soporte) — 3 herramientas: Respuestas tomadas de las guías oficiales y una prueba de conexión contra cada grupo del API. El nivel de acceso de cada herramienta y el detalle de sus parámetros está en la página de su grupo; el resumen de permisos está en [Permisos](/developers/agentes/mcp/permisos). --- # Ventas y transacciones > Herramientas del MCP para consultar transacciones, medir ventas y modificar una transacción. - kind: mcp-tool - status: stable - access: destructive - last_verified: 2026-10-07 - url: https://tilopay.com/developers/agentes/mcp/ventas ## Qué cubre [#que-cubre] Este grupo cubre la lectura de transacciones y el análisis de tus ventas, más la modificación de una transacción: captura, reembolso o reversión. La modificación mueve dinero real y está marcada como sensible. ## Herramientas [#herramientas] ### Resumen y tendencias de ventas [#tilopay-sales-summary] - `tilopay_sales_summary` - Acceso: Sólo lectura - Operación del API: `POST /api/v1/consultTransactions (y cálculo local)` — https://tilopay.com/developers/api/procesos-operativos/consult-transactions Calcula métricas de ventas a partir de las transacciones de Tilopay: totales por moneda, ticket promedio, tasa de aprobación, ventas por día, día de la semana y hora, mejores clientes, motivos de rechazo y tendencia. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `startDate` | string | sí | Fecha inicial "YYYY-MM-DD HH:mm:ss" | | `endDate` | string | sí | Fecha final "YYYY-MM-DD HH:mm:ss" | | `includeDeclined` | boolean | — | Incluir transacciones rechazadas para medir tasa de aprobación (por defecto true) | | `environment` | string (production | test) | — | — | | `currency` | array | — | — | **Devuelve** `{ summary, trends, environmentNote }` summary trae range, timezoneNote, totalRows, payments {total, approved, declined, approvalRate}, refunds {total, approved, failed, successRate}, byCurrency por moneda con pagos, costos desglosados (commission, iva_commission, cost, cost_iva, retention_iva, retention_rent, totalDeducted, taxWithholdings, pspCost), netToLiquidate, reconciles y reconciliationDelta; reembolsos; y netForPeriod. Además daily, sample, byWeekday, byHour, topCustomers, declineReasons, refundFailureReasons y transactionTypes. byWeekday, byHour y topCustomers vienen en null si la muestra es insuficiente (menos de 30 filas o menos de 5 días distintos). trends viene en null en ese mismo caso. Las horas y días están en UTC. ### Agente analista de ventas [#tilopay-analyze-sales] - `tilopay_analyze_sales` - Acceso: Sólo lectura - Operación del API: `POST /api/v1/consultTransactions (y análisis con modelo)` — https://tilopay.com/developers/api/procesos-operativos/consult-transactions Agente que analiza las transacciones de Tilopay en un rango de fechas y devuelve un informe en lenguaje natural: desempeño, tendencias, estacionalidad, calidad de aprobación, riesgos y recomendaciones accionables. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `startDate` | string | sí | Fecha inicial "YYYY-MM-DD HH:mm:ss" | | `endDate` | string | sí | Fecha final "YYYY-MM-DD HH:mm:ss" | | `question` | string | — | Pregunta o enfoque específico para el análisis (opcional) | | `environment` | string (production | test) | — | — | | `currency` | array | — | — | **Devuelve** `{ report, summary, trends, environmentNote }` report es el informe en lenguaje natural; summary y trends son los mismos de tilopay_sales_summary. Si no hay transacciones en el rango, devuelve solo un texto avisándolo, sin structuredContent. ### ¿Ya me pagó? [#tilopay-find-payment] - `tilopay_find_payment` - Acceso: Sólo lectura Busca si un cliente ya pagó: revisa los cobros de Tilopay y, si la sesión bancaria está abierta, también las entradas de la cuenta bancaria. Úsala para preguntas como '¿ya me pagó Ana?' o '¿entró el pago de ₡25.000?'. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `name` | string | — | Nombre del cliente (coincidencia parcial) | | `amount` | number | — | Monto del pago esperado | | `currency` | string | — | Moneda del monto, ej. CRC o USD | | `hours` | integer | — | Horas hacia atrás a revisar (por defecto 24) | | `reference` | string | — | Número de orden o referencia | **Devuelve** ### Listar transacciones de Tilopay [#tilopay-list-transactions] - `tilopay_list_transactions` - Acceso: Sólo lectura - Operación del API: `POST /api/v1/consultTransactions` — https://tilopay.com/developers/api/procesos-operativos/consult-transactions Lista transacciones de Tilopay en un rango de fechas. Usa status para aprobadas/rechazadas y sort=newest para 'los últimos N' o 'la última'. Una sola llamada basta: no acortes el rango para buscar filas. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `startDate` | string | sí | Fecha inicial, ej. "2026-08-01 00:00:00" | | `endDate` | string | sí | Fecha final, ej. "2026-08-31 23:59:59" | | `status` | string (approved | declined | all) | — | approved = solo aprobadas, declined = solo rechazadas, all = todas | | `sort` | string (newest | oldest) | — | newest = más recientes primero | | `onlyAproved` | boolean | — | Compatibilidad: false equivale a status: "all" | | `environment` | string (production | test) | — | Ambiente, por defecto production | | `currency` | array | — | Monedas, ej. ["USD","CRC"] | | `orderNumber` | string | — | Filtrar por número de orden | | `email` | string | — | Filtrar por correo del cliente | | `limit` | integer | — | Máximo de filas a devolver | **Devuelve** `{ total, transactions[], environmentNote }` total = filas encontradas antes de aplicar limit; transactions = las filas devueltas; environmentNote avisa si el ambiente consultado no trajo filas. ### Consultar una transacción [#tilopay-get-transaction] - `tilopay_get_transaction` - Acceso: Sólo lectura - Operación del API: `POST /api/v1/consult` — https://tilopay.com/developers/api/procesos-operativos/consult Obtiene el detalle de una transacción específica de Tilopay a partir de tu número de orden. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `orderNumber` | string | sí | Número de orden de la transacción | | `merchantId` | string | — | ID de comercio (opcional) | **Devuelve** `{ result }` Respuesta cruda del API de Tilopay bajo la llave `result`. ### Capturar, reembolsar o reversar [#tilopay-modify-transaction] - `tilopay_modify_transaction` - Acceso: Sensible - Operación del API: `POST /api/v1/processModification` — https://tilopay.com/developers/api/procesos-operativos/process-modification Modifica una transacción de Tilopay: captura (capture), reembolso (refund) o reversión (reversal) por el monto indicado. El monto nunca puede superar el de la venta original: si el usuario pide más, díselo con el monto real de la venta y pregunta si reembolsa ese monto o una parte; no pidas confirmación de un monto mayor. Solo reembolsa ventas aprobadas, nunca una orden que ya es un reembolso (empieza con «Re-»). Cuando Tilopay confirma el reembolso se genera un comprobante en texto listo para reenviar al cliente. Operación sensible: afecta dinero real y requiere segundo factor. Llámala primero sin `confirmation_code`: se envía un código de 6 dígitos al correo del comercio y la respuesta trae `requires_confirmation`. Repite la misma llamada, con los mismos parámetros, agregando `confirmation_code`. Comunica el resultado exactamente como lo devuelve la herramienta (state): si es pendiente o no confirmado, nunca digas que el reembolso ya se hizo. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `orderNumber` | string | sí | Número de orden de la transacción | | `action` | string (capture | refund | reversal) | sí | Tipo de modificación | | `amount` | number | sí | Monto a modificar | | `currency` | string | — | Moneda del movimiento, ej. CRC o USD | | `client_name` | string | — | Nombre del cliente, para el comprobante | | `client_email` | string | — | Correo del cliente, para el comprobante | | `confirmation_code` | string | — | Código de 6 dígitos recibido por correo para autorizar la operación | **Devuelve** `{ result }` Respuesta cruda del API de Tilopay bajo la llave `result`. ### Historial de reembolsos [#tilopay-refunds-list] - `tilopay_refunds_list` - Acceso: Sólo lectura Reembolsos del comercio. pending=true devuelve los reembolsos pendientes de procesar; si no, el historial. Solo consulta: para reembolsar usa tilopay_modify_transaction. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `pending` | boolean | — | Solo pendientes | | `page` | integer | — | Página (por defecto 1) | | `limit` | integer | — | Registros por página (por defecto 20) | | `search` | string | — | Texto a buscar | **Devuelve** ### Cierre de caja programado [#tilopay-cash-close] - `tilopay_cash_close` - Acceso: Escritura Cierre de caja diario por WhatsApp: ventas del día por moneda, rechazos agrupados por motivo y la próxima liquidación de Tilopay. action 'get' muestra la configuración; 'set' la cambia (enabled, time_of_day 'HH:mm' en hora local, days 0=domingo…6=sábado; «de lunes a sábado» = [1,2,3,4,5,6]); 'preview' arma el cierre de hoy ahora. Para «apagá el cierre» usa set con enabled=false. Configurar es solo del dueño. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `action` | string (get | set | preview) | sí | — | | `enabled` | boolean | — | — | | `time_of_day` | string | — | Hora local 'HH:mm' (24 h). 8 pm = '20:00' | | `days` | array | — | 0=domingo … 6=sábado | **Devuelve** --- # Enlaces de pago > Herramientas del MCP para crear, consultar y borrar enlaces de pago, y preparar su envío. - kind: mcp-tool - status: stable - access: destructive - last_verified: 2026-10-07 - url: https://tilopay.com/developers/agentes/mcp/enlaces-de-pago ## Qué cubre [#que-cubre] Con este grupo el agente crea un enlace de cobro, consulta su detalle, lo borra y prepara el envío al cliente por WhatsApp o por correo. El envío por WhatsApp no manda el mensaje: devuelve un enlace listo para enviar. ## Herramientas [#herramientas] ### Crear cobro con enlace [#tilopay-create-charge] - `tilopay_create_charge` - Acceso: Escritura Crea un cobro y devuelve el enlace corto de Tilopay (tilo.co/s/…) que abre directo el formulario seguro de pago; si no está disponible, el enlace propio tilopay.shop/pagar/…. La respuesta trae url (la corta cuando exista) y fallback_url (la propia); ambas sirven. En WhatsApp envía de una vez el QR como imagen junto con el enlace; no llames la herramienta de QR después. Si faltan datos del cliente, la página del enlace los pide antes de cobrar. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `amount` | number | sí | Monto a cobrar | | `currency` | string | — | Moneda, ej. USD o CRC. Si se omite se usa la del país del comercio. | | `reference` | string | sí | Referencia del cobro en texto normal, con espacios. No convertir a slug ni reemplazar espacios por guiones o guiones bajos. | | `description` | string | sí | Concepto visible para el cliente. Conserva literalmente el texto del comercio con espacios, acentos y mayúsculas; por ejemplo 'prueba link', nunca 'prueba_link'. | | `client` | string | — | Nombre del cliente | | `client_email` | string | — | Correo del cliente | | `client_phone` | string | — | Teléfono del cliente | **Devuelve** ### Detalle de un enlace de pago [#tilopay-get-payment-link] - `tilopay_get_payment_link` - Acceso: Sólo lectura - Operación del API: `GET /api/v1/getDetailLinkPayment/{link_payment_id}/{api_key}` — https://tilopay.com/developers/api/links-de-pago/detail-link-payment Obtiene el detalle de un enlace de pago de Tilopay por su ID. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `linkPaymentId` | string | sí | ID del enlace de pago | **Devuelve** `{ result }` Respuesta cruda del API de Tilopay bajo la llave `result`. ### Eliminar enlace de pago [#tilopay-delete-payment-link] - `tilopay_delete_payment_link` - Acceso: Sensible - Operación del API: `POST /api/v1/deleteLinkPayment` — https://tilopay.com/developers/api/links-de-pago/delete-link-payment Elimina un enlace de pago de Tilopay por su ID. Operación sensible: requiere segundo factor. Llámela primero sin `confirmation_code`: se envía un código de 6 dígitos al correo del comercio y la respuesta trae `requires_confirmation`. Repita la misma llamada agregando `confirmation_code`. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `id` | string | sí | ID del enlace de pago a eliminar | | `confirmation_code` | string | — | Código de 6 dígitos recibido por correo para autorizar la operación | **Devuelve** `{ result }` Respuesta cruda del API de Tilopay bajo la llave `result`. ### Enviar enlace de pago por WhatsApp [#tilopay-send-payment-link-whatsapp] - `tilopay_send_payment_link_whatsapp` - Acceso: Escritura Prepara el envío del enlace de pago por WhatsApp a un contacto: devuelve un enlace wa.me con el mensaje listo. Acepta el nombre de un contacto guardado o un teléfono. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `link_url` | string | sí | URL del enlace de pago | | `contact_name` | string | — | Nombre del contacto guardado o del cliente | | `phone` | string | — | Teléfono de WhatsApp, ej. +50688887777 | | `amount` | number | — | — | | `currency` | string | — | — | | `description` | string | — | — | | `message` | string | — | Texto propio del mensaje | | `save_contact` | boolean | — | Guardar el contacto en la agenda | | `send_now` | boolean | — | Obsoleto: se ignora. Siempre se devuelve el enlace wa.me para enviar con un toque. | **Devuelve** `{ to, message, whatsapp_url }` No envía el mensaje: devuelve el teléfono resuelto, el texto ya redactado y un enlace wa.me para enviarlo con un toque. Si no hay teléfono ni contacto guardado con ese nombre, devuelve error pidiéndolo. Guarda el contacto salvo que save_contact sea false. ### Enviar enlace de pago por correo [#tilopay-send-payment-link-email] - `tilopay_send_payment_link_email` - Acceso: Escritura Envía el enlace de pago por correo electrónico al cliente. Acepta el nombre de un contacto guardado o un correo. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `link_url` | string | sí | URL del enlace de pago | | `email` | string | — | Correo del destinatario | | `contact_name` | string | — | Nombre del contacto guardado o del cliente | | `amount` | number | — | — | | `currency` | string | — | — | | `description` | string | — | — | | `message` | string | — | Nota adicional para el cliente | | `save_contact` | boolean | — | Guardar el contacto en la agenda | **Devuelve** `{ sent, to }` sent es true y to el correo al que se envió. Si no hay correo ni contacto guardado con ese nombre, devuelve error pidiéndolo. ### QR de un enlace de pago o producto [#tilopay-payment-link-qr] - `tilopay_payment_link_qr` - Acceso: Sólo lectura Genera el QR de un enlace de pago o de un producto del catálogo y lo envía como imagen (PNG). Úsala cuando el comercio pida el QR para compartir o imprimir. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `link_url` | string | — | Enlace de pago completo (https://...) | | `catalog_id` | string | — | ID del producto del catálogo | | `label` | string | — | Nombre para el pie de la imagen | **Devuelve** ### QR permanente de monto abierto [#tilopay-static-payment-qr] - `tilopay_static_payment_qr` - Acceso: Sólo lectura Devuelve el enlace y el QR permanente de monto abierto del comercio (el cliente escanea, digita el monto y paga). Solo consulta: si el comercio no lo tiene activado, lo explica y no lo activa. **Parámetros** Sin parámetros. **Devuelve** --- # Catálogo > Herramientas del MCP para leer el catálogo de productos y servicios del comercio. - kind: mcp-tool - status: stable - access: read - last_verified: 2026-10-07 - url: https://tilopay.com/developers/agentes/mcp/catalogo ## Qué cubre [#que-cubre] Sólo lectura: lista los productos o servicios que el comercio ya tiene creados en enlaces de pago y devuelve el detalle de uno. ## Herramientas [#herramientas] ### Listar catálogo de productos o servicios [#tilopay-catalog-list-items] - `tilopay_catalog_list_items` - Acceso: Sólo lectura - Operación del API: `GET /api/v1/getLinkPaymentList/{api_key}/{limit}` — https://tilopay.com/developers/api/links-de-pago/payment-item-list Lista los productos o servicios del catálogo de Tilopay (título, precio y enlace corto). Permite buscar por nombre o descripción (sin importar acentos ni mayúsculas). El listado de Tilopay puede tardar unos minutos en reflejar cambios hechos en el panel; lo creado desde aquí aparece de inmediato y la respuesta de tilopay_catalog_create_item ya trae el ítem nuevo. Usa refresh=true para forzar lectura fresca. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `limit` | integer | — | Máximo de ítems (por defecto 50) | | `search` | string | — | Texto a buscar en el nombre del producto | | `page` | integer | — | Página (por defecto 1) | | `refresh` | boolean | — | true para ignorar la memoria corta y leer de nuevo | | `include_qr` | boolean | — | Incluir el QR completo en base64 de cada ítem (por defecto false; el listado devuelve solo el enlace y has_qr) | **Devuelve** `{ result }` Respuesta cruda del API de Tilopay bajo la llave `result`. ### Detalle de un ítem del catálogo [#tilopay-catalog-get-item] - `tilopay_catalog_get_item` - Acceso: Sólo lectura - Operación del API: `GET /api/v1/getLinkPaymentById/{link_payment_id}/{api_key}` — https://tilopay.com/developers/api/links-de-pago/payment-by-id Obtiene el detalle de un producto o servicio del catálogo de Tilopay por su ID. El QR en base64 solo con include_qr=true. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `itemId` | string | sí | ID del ítem del catálogo | | `include_qr` | boolean | — | Incluir el QR en base64 (por defecto false; úsalo solo si el comercio pide el QR) | **Devuelve** `{ result }` Respuesta cruda del API de Tilopay bajo la llave `result`. ### Agregar producto o servicio al catálogo [#tilopay-catalog-create-item] - `tilopay_catalog_create_item` - Acceso: Escritura - Operación del API: `POST /api/v1/createLinkPayment` — https://tilopay.com/developers/api/links-de-pago/create-link-payment Crea un producto o servicio en el catálogo de Tilopay con su precio y devuelve el enlace corto de pago y el QR como imagen. Si el comercio envió una foto por WhatsApp en los últimos 10 minutos, la usa como imagen del producto. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `name` | string | sí | Nombre del producto o servicio (título del enlace) | | `amount` | number | sí | Precio | | `currency` | string | — | Moneda, ej. CRC o USD (por defecto la del comercio) | | `description` | string | — | Descripción corta | | `media_ref` | string | — | Referencia exacta de la imagen recibida por WhatsApp, si la conoce | | `use_last_image` | boolean | — | false para crear el producto sin foto aunque haya una imagen reciente | **Devuelve** `{ result, linkId, url }` result = respuesta del API tal cual; linkId = id del enlace de pago que representa el producto; url = enlace de cobro del producto. ### Editar un producto del catálogo [#tilopay-catalog-update-item] - `tilopay_catalog_update_item` - Acceso: Escritura - Operación del API: `POST /api/v1/createLinkPayment` — https://tilopay.com/developers/api/links-de-pago/create-link-payment Edita un producto del catálogo de Tilopay (nombre, precio, moneda, descripción o foto) sin cambiar su enlace de pago. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `itemId` | string | sí | ID del ítem del catálogo | | `name` | string | — | Nuevo nombre | | `amount` | number | — | Nuevo precio | | `currency` | string | — | Nueva moneda | | `description` | string | — | Nueva descripción corta | | `media_ref` | string | — | Referencia exacta de la imagen recibida por WhatsApp, si la conoce | | `use_last_image` | boolean | — | false para no cambiar la foto aunque haya una imagen reciente | **Devuelve** `{ result, linkId, url, replaced }` El API no permite editar un enlace: la herramienta crea el producto nuevo y borra el anterior. replaced = id del producto que se reemplazó; linkId y url = los del producto nuevo. ### Borrar un producto del catálogo [#tilopay-catalog-delete-item] - `tilopay_catalog_delete_item` - Acceso: Sensible - Operación del API: `POST /api/v1/deleteLinkPayment` — https://tilopay.com/developers/api/links-de-pago/delete-link-payment Borra un producto del catálogo de Tilopay. El enlace de pago del producto deja de funcionar. Requiere código de confirmación enviado al correo. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `itemId` | string | sí | ID del ítem del catálogo | | `confirmation_code` | string | — | Código de 6 dígitos enviado al correo del comercio | **Devuelve** `{ result }` result = respuesta del API al borrar el enlace de pago que representa el producto. ### Sincronizar catálogo con redes y buscadores [#tilopay-catalog-feed] - `tilopay_catalog_feed` - Acceso: Escritura Entrega el enlace del catálogo sincronizado y los pasos para conectarlo en Facebook/Instagram, Google Shopping, TikTok o Pinterest (un canal a la vez, el que pida el comercio). Con send_email=true lo manda al correo del comercio. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `platform` | string (facebook | google | tiktok | pinterest) | — | Canal pedido. Si el comercio no dijo cuál, NO llames: pregúntale primero. | | `send_email` | boolean | — | true si pidió que se lo mandes por correo | **Devuelve** --- # Contactos > Herramientas del MCP para la agenda del comercio: ver, guardar y borrar contactos. - kind: mcp-tool - status: stable - access: destructive - last_verified: 2026-10-07 - url: https://tilopay.com/developers/agentes/mcp/contactos ## Qué cubre [#que-cubre] La agenda le permite al agente reutilizar teléfono y correo al enviar un enlace de pago, sin volver a pedirlos. Borrar un contacto es irreversible. ## Herramientas [#herramientas] ### Guardar contacto [#tilopay-save-contact] - `tilopay_save_contact` - Acceso: Escritura Guarda o actualiza un contacto del comercio (nombre, teléfono de WhatsApp y correo) para reutilizarlo en envíos. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `name` | string | sí | Nombre del contacto | | `phone` | string | — | Teléfono de WhatsApp, ej. +50688887777 | | `email` | string | — | — | | `note` | string | — | — | **Devuelve** `{ contact }` El contacto guardado o actualizado. ### Ver contactos [#tilopay-list-contacts] - `tilopay_list_contacts` - Acceso: Sólo lectura Lista los contactos guardados del comercio; opcionalmente filtra por nombre. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `search` | string | — | Texto a buscar en el nombre | **Devuelve** `{ contacts }` Lista de contactos guardados del comercio. ### Eliminar contacto [#tilopay-delete-contact] - `tilopay_delete_contact` - Acceso: Sensible Elimina un contacto guardado del comercio por su nombre. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `name` | string | sí | Nombre del contacto | **Devuelve** `{ removed }` removed es true. Si no existe un contacto con ese nombre, devuelve error. --- # Perfil del negocio y recetas > Herramientas del MCP para ver y completar el perfil del negocio y obtener recetas de automatización a partir de ese perfil. - kind: mcp-tool - status: stable - access: write - last_verified: 2026-10-07 - url: https://tilopay.com/developers/agentes/mcp/perfil ## Qué cubre [#que-cubre] El agente guarda un perfil corto del negocio: a qué se dedica, qué vende, por dónde vende, cómo son sus cobros y qué quiere mejorar. Con ese perfil arma las recetas de automatización que le propone al comercio, y sabe cuál es la siguiente pregunta que corresponde hacer (el cuestionario es de cuatro preguntas como máximo). El perfil se guarda campo por campo: lo que no se envía se conserva. Las recetas cambian según los módulos que el usuario tenga activos: las recetas bancarias sólo aparecen si tiene habilitado el [API bancario](/developers/agentes/mcp/api-bancario). Estas herramientas no llaman al API de Tilopay: trabajan sobre los datos del propio servidor MCP. ## Herramientas [#herramientas] ### Ver perfil del negocio [#tilopay-get-business-profile] - `tilopay_get_business_profile` - Acceso: Sólo lectura Devuelve el perfil del negocio: los datos que ya trae la cuenta de Tilopay (nombre, giro, ubicación, teléfono, correo de facturación, monedas, logo) y los que faltan por preguntar, con la siguiente pregunta pendiente. **Parámetros** Sin parámetros. **Devuelve** `{ profile, next_question, total_questions, is_complete }` profile = el perfil guardado del negocio (o null si no hay); next_question = la siguiente pregunta pendiente del onboarding; total_questions = cuántas preguntas tiene el cuestionario; is_complete = si el perfil ya está completo. ### Guardar perfil del negocio [#tilopay-save-business-profile] - `tilopay_save_business_profile` - Acceso: Escritura Guarda o completa el perfil del negocio con lo que el comercio respondió o confirmó. Puede guardar un campo a la vez; los campos que no se envían se conservan y lo guardado aquí ya no se sobrescribe con los datos de Tilopay. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `business_type` | string | — | A qué se dedica el negocio | | `main_products` | string | — | Productos o servicios principales | | `sales_channels` | string | — | Canales de venta: local, en línea, redes, WhatsApp | | `ticket_pattern` | string | — | Cómo son los cobros: montos, frecuencia, moneda | | `goals` | string | — | Qué quiere mejorar el comercio | | `notes` | string | — | Detalles adicionales útiles | | `opening_hours` | string | — | Horario de atención | | `tone` | string | — | Tono de comunicación con los clientes | | `short_description` | string | — | Descripción corta del negocio | | `social_links` | string | — | Sitio web y redes sociales | | `refund_policy` | string | — | Política de devoluciones o reembolsos | | `business_name` | string | — | Corrección del nombre del negocio | | `industry` | string | — | Corrección del giro del negocio | | `phone` | string | — | Corrección del teléfono del negocio | | `address` | string | — | Corrección de la dirección | | `invoice_email` | string | — | Corrección del correo de facturación | **Devuelve** `{ profile, next_question, is_complete }` profile = el perfil ya actualizado (los campos que no se envían se conservan); next_question = la siguiente pregunta pendiente; is_complete = si con este guardado el perfil quedó completo. ### Recetas y automatizaciones [#tilopay-recommend-automations] - `tilopay_recommend_automations` - Acceso: Sólo lectura Devuelve recetas y automatizaciones sugeridas para el comercio según su perfil de negocio y los módulos del MCP que tiene activos. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `limit` | integer | — | Cuántas recetas devolver (por defecto 5) | **Devuelve** `{ profile_complete, next_question, recipes }` recipes = recetas y automatizaciones sugeridas según el perfil del negocio y los módulos activos (incluye las bancarias sólo si el usuario tiene BaaS habilitado); profile_complete y next_question indican si falta completar el perfil. --- # Microtienda y pedidos > Herramientas del MCP para armar microtiendas con carrito desde el catálogo y administrar los pedidos que entran por ahí. - kind: mcp-tool - status: stable - access: destructive - last_verified: 2026-10-07 - url: https://tilopay.com/developers/agentes/mcp/microtienda ## Qué cubre [#que-cubre] Con los productos del [catálogo](/developers/agentes/mcp/catalogo) el agente arma una **microtienda con carrito**: una página pública con varios productos donde el cliente elige cantidades y paga todo junto. Cada microtienda tiene su propio enlace. La segunda mitad del grupo es la **gestión de pedidos**: se activa una vez (nombre de la tienda, logo opcional y hora del recordatorio diario), y a partir de ahí el comercio puede ver el resumen, listar pedidos por estado, ver los que están pagados sin entregar y marcarlos como entregados. Los estados de un pedido son `pending` (sin pagar), `paid` (pagado sin entregar) y `delivered` (entregado). Desactivar una microtienda o apagar la gestión de pedidos no borra los productos del catálogo ni los pedidos ya registrados. Estas herramientas no llaman al API de Tilopay: trabajan sobre los datos del propio servidor MCP, salvo el cobro, que sale por el enlace de pago de cada producto. ## Herramientas [#herramientas] ### Crear una microtienda con carrito [#tilopay-store-create] - `tilopay_store_create` - Acceso: Escritura Crea un enlace de microtienda para compartir con un cliente: muestra los productos del catálogo, el cliente arma un carrito y al finalizar paga desde la misma página con un enlace que incluye el detalle del carrito. Por defecto incluye todo el catálogo; se puede limitar a ciertos IDs de productos. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `title` | string | — | Título visible de la tienda | | `item_ids` | array | — | IDs de productos del catálogo a mostrar; si se omite, se muestra todo el catálogo | **Devuelve** `{ slug, url, items }` slug = identificador de la microtienda; url = enlace público de la tienda con carrito; items = cuántos productos del catálogo quedaron incluidos. ### Listar microtiendas activas [#tilopay-store-list] - `tilopay_store_list` - Acceso: Sólo lectura Lista las microtiendas activas del comercio con su enlace para compartir. **Parámetros** Sin parámetros. **Devuelve** `{ stores[] }` stores = microtiendas activas con slug, título, enlace público y los ids de productos que incluye cada una. ### Desactivar una microtienda [#tilopay-store-delete] - `tilopay_store_delete` - Acceso: Sensible Desactiva una microtienda por su slug: el enlace deja de abrir. Confirma con el comercio antes de usarla. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `slug` | string | sí | Slug de la tienda (el final de su enlace) | **Devuelve** `{ slug, active }` Desactiva la microtienda: el enlace deja de mostrar productos. active queda en false; los productos del catálogo no se borran. ### Conectar un dominio propio a la tienda [#tilopay-store-domain-connect] - `tilopay_store_domain_connect` - Acceso: Escritura Conecta un dominio propio del comercio (ej. tienda.minegocio.com) a su microtienda. Lo registra de inmediato y devuelve la instrucción CNAME. Úsala solo cuando el comercio dé el dominio. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `hostname` | string | sí | Dominio, ej. tienda.minegocio.com | | `slug` | string | — | Slug de la tienda; si se omite, la más reciente | **Devuelve** ### Estado de los dominios propios [#tilopay-store-domain-status] - `tilopay_store_domain_status` - Acceso: Sólo lectura Revisa en Cloudflare el estado de los dominios propios de las tiendas del comercio. **Parámetros** Sin parámetros. **Devuelve** ### Quitar un dominio propio [#tilopay-store-domain-remove] - `tilopay_store_domain_remove` - Acceso: Sensible Desconecta un dominio propio de la tienda; la tienda sigue en su dirección tilopay.shop. Confirma con el comercio antes de usarla. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `hostname` | string | sí | — | **Devuelve** ### Activar o configurar la gestión de pedidos [#tilopay-orders-setup] - `tilopay_orders_setup` - Acceso: Escritura Activa el control de pedidos de la microtienda y guarda el nombre de la tienda, el logo y la hora del recordatorio diario de pedidos pagados sin entregar. Sirve también para cambiar cualquiera de esos datos después. El logo puede venir como enlace https de una imagen o como la imagen que el comercio acaba de enviar por WhatsApp (pase la referencia que aparece en el mensaje). **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `store_name` | string | — | Nombre visible de la tienda | | `logo` | string | — | Enlace https de la imagen del logo, o la referencia de la imagen enviada por WhatsApp | | `reminder_time` | string | — | Hora local del recordatorio diario en formato HH:mm (ej. "18:00"); vacío lo desactiva | **Devuelve** `{ orders_enabled, store_name, has_logo, reminder_time }` Deja la gestión de pedidos activa y devuelve la configuración resultante: nombre de la tienda que ven los clientes, si hay logo cargado y la hora del recordatorio diario de pedidos pendientes. ### Ver la configuración de la tienda y los pedidos [#tilopay-orders-settings] - `tilopay_orders_settings` - Acceso: Sólo lectura Muestra si la gestión de pedidos está activa, el nombre de la tienda, si hay logo y la hora del recordatorio diario. **Parámetros** Sin parámetros. **Devuelve** `{ orders_enabled, store_name, has_logo, reminder_time }` Configuración actual de la tienda y de los pedidos, sin cambiar nada. ### Resumen de pedidos [#tilopay-orders-status] - `tilopay_orders_status` - Acceso: Sólo lectura Resumen de los pedidos de las microtiendas: cuántos están pendientes de pago, cuántos pagados sin entregar (con su monto) y cuántos se entregaron hoy. **Parámetros** Sin parámetros. **Devuelve** `{ pending, paid, delivered, ... }` Resumen de pedidos: cuántos están pendientes de pago, pagados sin entregar y entregados, con los montos del período. ### Listar pedidos [#tilopay-orders-list] - `tilopay_orders_list` - Acceso: Sólo lectura Lista los pedidos de las microtiendas con su código, cliente, total y detalle. Se puede filtrar por estado (pending = pendiente de pago, paid = pagado sin entregar, delivered = entregado) y por los últimos días. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `status` | string (pending | paid | delivered | all) | — | Estado del pedido; por defecto todos | | `days` | integer | — | Solo pedidos de los últimos N días | | `limit` | integer | — | — | **Devuelve** `{ orders[] }` orders = pedidos con código, cliente, total, moneda, estado y fecha. Se puede filtrar por estado (pending, paid, delivered, all) y por los últimos días. ### Pedidos pagados sin entregar [#tilopay-orders-pending] - `tilopay_orders_pending` - Acceso: Sólo lectura Lista los pedidos ya pagados que aún no se han entregado. Es la herramienta que usa el recordatorio diario. **Parámetros** Sin parámetros. **Devuelve** `{ pending, orders[] }` pending = cuántos pedidos están pagados y sin entregar; orders = esos pedidos con código, cliente, total y moneda. ### Marcar un pedido como entregado [#tilopay-order-mark-delivered] - `tilopay_order_mark_delivered` - Acceso: Escritura Marca uno o varios pedidos como entregados. Acepta el código del pedido (ej. "#A3F2", incluso varios en el mismo mensaje) o el nombre del cliente. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `code` | string | — | Código del pedido, ej. "#A3F2"; pueden venir varios | | `client` | string | — | Nombre del cliente del pedido | **Devuelve** `{ delivered, missing }` delivered = cuántos pedidos quedaron marcados como entregados; missing = los códigos que no se encontraron. ### Apagar la gestión de pedidos [#tilopay-orders-disable] - `tilopay_orders_disable` - Acceso: Sensible Apaga el control de pedidos y cancela el recordatorio diario. Los pedidos ya registrados se conservan. Pida un sí explícito antes de usarla. **Parámetros** Sin parámetros. **Devuelve** `{ orders_enabled: false }` Apaga la gestión de pedidos. Los pedidos ya registrados se conservan. --- # Avisos y notificaciones > Herramientas del MCP para ver y cambiar los avisos por WhatsApp del comercio: cobros aprobados, cobros fallidos, resumen diario y pedidos. - kind: mcp-tool - status: stable - access: write - last_verified: 2026-10-07 - url: https://tilopay.com/developers/agentes/mcp/avisos ## Qué cubre [#que-cubre] El agente puede avisarle al comercio por WhatsApp cuando entra un cobro, cuando un cobro se rechaza, cuando entra un pedido, y enviarle un resumen diario a la hora que elija. Estas dos herramientas son las que leen y cambian esa configuración. No envían mensajes por su cuenta: solamente prenden, apagan y consultan los avisos. Los campos que no se envían se conservan. ## Herramientas [#herramientas] ### Ver la configuración de avisos [#tilopay-get-notification-settings] - `tilopay_get_notification_settings` - Acceso: Sólo lectura Muestra cómo están configurados los avisos del comercio: si los pagos recibidos se avisan por WhatsApp y/o por correo, a qué correo, desde qué monto y si hay horario de silencio. **Parámetros** Sin parámetros. **Devuelve** `{ settings }` settings = configuración de avisos del comercio: qué avisos por WhatsApp están encendidos (cobros aprobados, cobros fallidos, resumen diario, pedidos) y a qué hora se envía el resumen. ### Configurar los avisos del comercio [#tilopay-set-notification-settings] - `tilopay_set_notification_settings` - Acceso: Escritura Cambia la configuración de avisos del comercio: activar o desactivar el aviso de pago recibido por WhatsApp y por correo, el correo de destino, el monto mínimo para avisar y el horario de silencio (en la hora local del comercio). Solo envíe los campos que el usuario pidió cambiar. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `payment_whatsapp` | boolean | — | Avisar por WhatsApp cuando se recibe un pago | | `payment_email` | boolean | — | Avisar por correo cuando se recibe un pago | | `notify_email` | string | — | Correo que recibe los avisos (si se omite, el de la cuenta) | | `min_amount` | number | — | Monto mínimo para avisar (0 = avisar por cualquier monto) | | `quiet_from` | integer | null | — | Hora local en que empieza el silencio (null para quitarlo) | | `quiet_to` | integer | null | — | Hora local en que termina el silencio (null para quitarlo) | **Devuelve** `{ settings }` settings = la configuración de avisos ya actualizada. Los campos que no se envían se conservan. --- # Comprobantes de cobro > Herramientas del MCP para listar los comprobantes de los cobros aprobados y reenviarle a un cliente el comprobante de su pago. - kind: mcp-tool - status: stable - access: write - last_verified: 2026-10-07 - url: https://tilopay.com/developers/agentes/mcp/comprobantes ## Qué cubre [#que-cubre] Cada cobro aprobado que pasa por el agente genera un comprobante con su propio código, una página para verlo y una imagen para compartir. Con estas dos herramientas el comercio lista los comprobantes de un período y reenvía uno al cliente por WhatsApp. El comprobante es un documento informativo del cobro. No es una factura electrónica. ## Herramientas [#herramientas] ### Listar comprobantes de cobro [#tilopay-list-receipts] - `tilopay_list_receipts` - Acceso: Sólo lectura Lista los últimos comprobantes de cobro del comercio (monto, cliente, orden y código). Cada uno trae un texto listo para reenviar al cliente. No cobra nada. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `limit` | integer | — | Cuántos comprobantes listar (5 por defecto) | **Devuelve** `{ receipts[] }` receipts = comprobantes de cobro con código, monto, moneda, cliente, número de orden, fecha de pago, enlace de la página del comprobante y enlace de la imagen. ### Reenviar el comprobante de un cobro al cliente [#tilopay-send-receipt] - `tilopay_send_receipt` - Acceso: Escritura Envía al cliente el comprobante de un cobro, por WhatsApp (por defecto: enlace wa.me de un toque) o por correo con la marca del comercio (channel=email). Busca por código, número de orden o nombre del cliente; sin datos usa el comprobante más reciente. Si el usuario dice «el último cobro» o «el último comprobante», llámala directamente sin code ni order_number (no consultes transacciones antes). Usa send_now solo si el usuario pide que se envíe directamente por WhatsApp. Nunca inventes el correo ni el teléfono del cliente: si faltan, pídelos. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `code` | string | — | Código del comprobante (8 caracteres) | | `order_number` | string | — | Número de orden del cobro | | `client_name` | string | — | Nombre del cliente del cobro, para buscar el comprobante | | `channel` | string (whatsapp | email) | — | whatsapp (por defecto) o email | | `email` | string | — | Correo del cliente, si se envía por correo | | `contact_name` | string | — | Nombre del contacto guardado o del cliente | | `phone` | string | — | Teléfono de WhatsApp, ej. +50688887777 | | `message` | string | — | Texto propio para acompañar el comprobante | | `save_contact` | boolean | — | Guardar el contacto en la agenda | | `send_now` | boolean | — | true envía el comprobante directamente al cliente; por defecto se entrega el enlace wa.me | **Devuelve** `{ sent | code, page_url, image_url, whatsapp_url }` Reenvía el comprobante al cliente por WhatsApp: devuelve el código del comprobante, el enlace de su página, el de la imagen y, cuando no se envía directo, el enlace de WhatsApp listo para abrir. --- # Recordatorios > Herramientas del MCP para crear, ver y cancelar recordatorios por WhatsApp, con o sin una acción del agente al enviarse. - kind: mcp-tool - status: stable - access: destructive - last_verified: 2026-10-07 - url: https://tilopay.com/developers/agentes/mcp/recordatorios ## Qué cubre [#que-cubre] Un recordatorio es un mensaje de WhatsApp programado: una sola vez, diario, semanal o mensual. Puede ser sólo texto o traer una **acción** que el agente ejecuta al enviarlo, escrita en lenguaje natural ("dame el resumen de ventas de hoy", "listá los enlaces de pago sin cobrar"), y el resultado se adjunta al mensaje. Reglas que conviene tener claras: - Las horas son la hora local del comercio, según el país de su teléfono de WhatsApp. - Hay un máximo de 20 recordatorios activos. - Los recordatorios de enlaces de pago o de cobros **siempre** llegan al WhatsApp del comercio, nunca al cliente. - Para enviar a otro número, primero hay que guardarlo como [contacto](/developers/agentes/mcp/contactos). ## Herramientas [#herramientas] ### Crear recordatorio [#tilopay-create-reminder] - `tilopay_create_reminder` - Acceso: Escritura Crea un recordatorio por WhatsApp, de una sola vez o recurrente (diario, semanal o mensual). Puede ser solo texto o ejecutar una acción del agente al enviarse (con `action`): resumen de ventas, transacciones del día, enlaces pendientes, etc. NO crea recordatorios bancarios (saldo, movimientos, estados de cuenta, transferencias): esos los configura el comercio en el calendario del portal de Banca Cliente. Si el recordatorio es para enviar un enlace de pago o cobro, SIEMPRE llega al WhatsApp del comercio que lo pidió, nunca al cliente. En los demás casos se envía al WhatsApp del comercio o a un contacto ya guardado (contact_name); si el usuario da un teléfono nuevo, hay que guardarlo primero con tilopay_save_contact. Máximo 20 recordatorios activos. El mensaje sale con un prefijo fijo que identifica al comercio. Horas en la hora local del comercio (según el país de su teléfono de WhatsApp). **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `message` | string | sí | Texto del recordatorio (máx. 500 caracteres, sin HTML) | | `action` | string | — | Instrucción que el agente ejecutará al enviarlo, en lenguaje natural, ej. 'dame el resumen de ventas de hoy' o 'lista los enlaces de pago pendientes'. El resultado se adjunta al mensaje. Omítelo si es un recordatorio de solo texto. | | `schedule` | string (once | daily | weekly | monthly) | sí | Frecuencia: once = una sola vez | | `when` | string | — | Solo para once: fecha y hora local 'YYYY-MM-DD HH:mm' | | `time_of_day` | string | — | Para recurrentes: hora local 'HH:mm' | | `weekday` | integer | — | Para weekly: 0 = domingo ... 6 = sábado | | `day_of_month` | integer | — | Para monthly: día del mes (1-28) | | `contact_name` | string | — | Nombre de un contacto ya guardado (mcp_contact) que debe recibirlo. Si se omite, llega al WhatsApp del comercio. No se aceptan teléfonos nuevos: guárdalos primero con tilopay_save_contact. | **Devuelve** `{ id, message, action, phone, contact_name, schedule, when, next_run_local, is_active }` El recordatorio creado: cuándo se envía en la hora local del comercio, a qué número, y qué acción del agente se ejecuta al enviarse. Máximo 20 recordatorios activos; los de enlaces de cobro siempre llegan al WhatsApp del comercio, nunca al cliente. ### Ver recordatorios [#tilopay-list-reminders] - `tilopay_list_reminders` - Acceso: Sólo lectura Lista los recordatorios activos del comercio con su próxima fecha de envío. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `include_inactive` | boolean | — | true para incluir los ya enviados o cancelados | **Devuelve** `{ reminders[] }` reminders = recordatorios del comercio con su mensaje, frecuencia, próxima ejecución en hora local y si están activos. ### Cancelar recordatorio [#tilopay-cancel-reminder] - `tilopay_cancel_reminder` - Acceso: Sensible Cancela un recordatorio por su ID o buscando parte de su texto. No borra el historial, solo deja de enviarse. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `id` | string | — | ID del recordatorio | | `search` | string | — | Parte del texto del recordatorio | **Devuelve** `{ cancelled }` cancelled = el recordatorio que quedó desactivado. --- # Cobros recurrentes > Herramientas del MCP para consultar planes recurrentes, suscriptores y sus pagos, y para pausar, reactivar o eliminar un suscriptor. - kind: mcp-tool - status: stable - access: destructive - last_verified: 2026-10-07 - url: https://tilopay.com/developers/agentes/mcp/recurrentes ## Qué cubre [#que-cubre] Cuatro herramientas de lectura sobre los planes de cobro recurrente y sus suscriptores, y una sensible que pausa, reactiva o elimina un suscriptor. Esa última afecta cobros futuros: pedí confirmación humana antes de ejecutarla. ## Herramientas [#herramientas] ### Listar planes de cobro recurrente [#tilopay-recurring-list-plans] - `tilopay_recurring_list_plans` - Acceso: Sólo lectura - Operación del API: `POST /api/v1/getPlansRepeat` Lista los planes de cobro recurrente configurados en Tilopay. **Parámetros** Sin parámetros. **Devuelve** `{ result }` Respuesta cruda del API de Tilopay bajo la llave `result`. ### Detalle de un plan recurrente [#tilopay-recurring-get-plan] - `tilopay_recurring_get_plan` - Acceso: Sólo lectura - Operación del API: `POST /api/v1/getPlanRepeat` Obtiene el detalle de un plan de cobro recurrente por su ID. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `id` | string | sí | ID del plan | | `include_qr` | boolean | — | Incluir el QR en base64 del plan (por defecto false; úsalo solo si el comercio pide el QR) | **Devuelve** `{ result }` Respuesta cruda del API de Tilopay bajo la llave `result`. ### Detalle de un suscriptor [#tilopay-recurring-get-subscriber] - `tilopay_recurring_get_subscriber` - Acceso: Sólo lectura - Operación del API: `POST /api/v1/getSuscriptorRepeat` Obtiene el detalle de un suscriptor de un plan recurrente por su ID. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `id` | string | sí | ID del suscriptor | **Devuelve** `{ result }` Respuesta cruda del API de Tilopay bajo la llave `result`. ### Buscar suscriptor por nombre o correo [#tilopay-recurring-find-subscriber] - `tilopay_recurring_find_subscriber` - Acceso: Sólo lectura Busca un suscriptor por nombre o correo en todos los planes recurrentes de una sola vez. Úsala antes de pausar, reactivar o editar a alguien cuando no tienes su ID. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `query` | string | sí | Nombre o correo del suscriptor | **Devuelve** ### Pagos de un suscriptor [#tilopay-recurring-subscriber-payments] - `tilopay_recurring_subscriber_payments` - Acceso: Sólo lectura - Operación del API: `POST /api/v1/getSuscriptorPayments` Lista los pagos realizados por un suscriptor recurrente. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `id` | string | sí | ID del suscriptor | **Devuelve** `{ result }` Respuesta cruda del API de Tilopay bajo la llave `result`. ### Cobros recurrentes fallidos [#tilopay-recurring-failed-payments] - `tilopay_recurring_failed_payments` - Acceso: Sólo lectura - Operación del API: `POST /api/v1/getSuscriptorPayments` Lista los últimos cobros recurrentes que fallaron (plan, suscriptor, monto, fecha y motivo en lenguaje simple). Una sola llamada basta. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `limit` | integer | — | Máximo de cobros (por defecto 10) | | `startDate` | string | — | Desde, "YYYY-MM-DD HH:mm:ss" | | `endDate` | string | — | Hasta, "YYYY-MM-DD HH:mm:ss" | **Devuelve** `{ total, source, failures[] }` failures = cobros recurrentes rechazados, con plan, suscriptor, monto, moneda y motivo del rechazo; total = cuántos se encontraron; source = la ruta del API de la que se obtuvieron. Combina la consulta de planes, suscriptores y sus pagos. ### Pausar, reactivar o eliminar un suscriptor [#tilopay-recurring-manage-subscriber] - `tilopay_recurring_manage_subscriber` - Acceso: Sensible - Operación del API: `POST /api/v1/pauseSuscriptorRepeat, /reactiveSuscriptorRepeat o /deleteSuscriptorRepeat` Pausa, reactiva o elimina un suscriptor de un plan recurrente en Tilopay. Operación sensible: afecta cobros futuros y requiere segundo factor. Llámela primero sin `confirmation_code`: se envía un código de 6 dígitos al correo del comercio y la respuesta trae `requires_confirmation`. Repita la misma llamada agregando `confirmation_code`. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `idSubscriber` | string | sí | ID del suscriptor | | `action` | string (pause | reactivate | delete) | sí | Acción a realizar | | `confirmation_code` | string | — | Código de 6 dígitos recibido por correo para autorizar la operación | **Devuelve** `{ result }` Respuesta cruda del endpoint correspondiente a la acción: pause, reactivate o delete. ### Crear plan de suscripción [#tilopay-recurring-create-plan] - `tilopay_recurring_create_plan` - Acceso: Escritura - Operación del API: `POST /api/v1/createPlanRepeat` Crea un plan de cobro recurrente (suscripción) en Tilopay con su título, moneda, frecuencia y modalidades (nombre y monto). Devuelve el ID del plan creado; luego usa tilopay_recurring_subscription_url para obtener el enlace con el que los clientes se suscriben. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `title` | string | sí | Título del plan | | `modality` | array | sí | Modalidades del plan (al menos una): nombre y monto por ciclo | | `frequency` | string (diario | semanal | mensual | anual | quincenal | bimestral | trimestral | cuatrimestral | semestral) | sí | Frecuencia de cobro | | `description` | string | — | Descripción del plan | | `currency` | string | — | Moneda ISO 4217, ej. USD o CRC. Si se omite se usa la del país del comercio. | | `first_amount` | number | — | Monto del pago inicial (0 si no hay) | | `trial_days` | integer | — | Días de prueba gratis (0 si no hay prueba) | | `attempts` | integer | — | Reintentos ante un cobro fallido (1 por defecto) | | `end_at` | string | — | Fecha de fin del plan en formato DD-MM-YYYY (opcional) | | `thanks_url` | string | — | URL de agradecimiento tras suscribirse (opcional) | | `webhook_subscribe` | string | — | Webhook al suscribirse un cliente (opcional) | | `webhook_payment` | string | — | Webhook al cobrarse un pago (opcional) | | `webhook_rejected` | string | — | Webhook al rechazarse un cobro (opcional) | | `webhook_unsubscribe` | string | — | Webhook al cancelarse una suscripción (opcional) | | `webhook_reactive` | string | — | Webhook al reactivarse una suscripción (opcional) | **Devuelve** `{ result, currency, frequency }` result = respuesta del API con el plan creado; currency y frequency = la moneda y la frecuencia con la que quedó el plan. ### Editar plan de suscripción [#tilopay-recurring-edit-plan] - `tilopay_recurring_edit_plan` - Acceso: Escritura - Operación del API: `POST /api/v1/editPlanRepeat` Modifica un plan de cobro recurrente existente: título, descripción, frecuencia, moneda, monto por ciclo (modality), pago inicial, prueba gratis, reintentos, estado o fecha de fin. Consulte primero tilopay_recurring_get_plan para conocer los valores actuales. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `id` | string | sí | ID del plan | | `title` | string | sí | Título del plan | | `frequency` | string (diario | semanal | mensual | anual | quincenal | bimestral | trimestral | cuatrimestral | semestral) | sí | Frecuencia de cobro | | `modality` | array | — | Modalidades con su monto por ciclo; envíelas cuando cambie el precio del plan | | `currency` | string | — | Moneda ISO 4217 | | `description` | string | — | Descripción del plan | | `first_amount` | number | — | Monto del pago inicial | | `trial_days` | integer | — | Días de prueba gratis | | `attempts` | integer | — | Reintentos ante cobro fallido | | `status` | string (inactive | active | closed_to_new) | — | Estado: inactive (inactivo), active (activo) o closed_to_new (activo sin registros nuevos) | | `end_at` | string | — | Fecha de fin del plan en formato DD-MM-YYYY (opcional) | | `thanks_url` | string | — | URL de agradecimiento | | `webhook_subscribe` | string | — | Webhook al suscribirse | | `webhook_payment` | string | — | Webhook al cobrarse un pago | | `webhook_rejected` | string | — | Webhook al rechazarse un cobro | | `webhook_unsubscribe` | string | — | Webhook al cancelarse | | `webhook_reactive` | string | — | Webhook al reactivarse | **Devuelve** `{ result }` result = respuesta del API al editar el plan. Los campos que no se envían se conservan. ### Eliminar plan de suscripción [#tilopay-recurring-delete-plan] - `tilopay_recurring_delete_plan` - Acceso: Sensible - Operación del API: `POST /api/v1/deletePlanRepeat` Elimina un plan de cobro recurrente en Tilopay. Afecta los cobros futuros del plan: confirma con el comercio antes de ejecutarla. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `id` | string | sí | ID del plan | **Devuelve** `{ result }` result = respuesta del API al eliminar el plan. Los suscriptores del plan dejan de cobrarse. ### Enlace de suscripción a un plan [#tilopay-recurring-subscription-url] - `tilopay_recurring_subscription_url` - Acceso: Sólo lectura - Operación del API: `POST /api/v1/recurrentUrl` Devuelve el enlace con el que un cliente se registra en un plan recurrente (o lo renueva si el correo ya está suscrito). Entregue la URL completa, sin recortarla. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `id` | string | sí | ID del plan | | `email` | string | — | Correo del cliente; si ya está suscrito devuelve el enlace de renovación | **Devuelve** `{ url, result }` url = enlace de suscripción al plan, para compartir con el cliente; result = respuesta del API tal cual. ### Editar suscriptor de un plan [#tilopay-recurring-edit-subscriber] - `tilopay_recurring_edit_subscriber` - Acceso: Sensible - Operación del API: `POST /api/v1/editSuscriptorRepeat` Cambia el estado de un suscriptor (activo, pausado o eliminado) y/o su fecha de expiración. Afecta cobros futuros: confirma con el comercio antes de ejecutarla. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `id` | string | sí | ID del suscriptor | | `status` | string (active | paused | deleted) | — | Nuevo estado del suscriptor | | `expire` | string | — | Fecha de expiración del plan para ese suscriptor en formato YYYY-MM-DD | **Devuelve** `{ result }` result = respuesta del API al editar los datos del suscriptor (correo, teléfono, monto o fecha de vencimiento, según el plan). ### Crear cupón de descuento [#tilopay-recurring-create-coupon] - `tilopay_recurring_create_coupon` - Acceso: Escritura - Operación del API: `POST /api/v1/createCoupon` Crea un cupón de descuento para un plan de suscripción: porcentaje o monto fijo, fecha de vencimiento, correos permitidos y límites de uso. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `planId` | string | sí | ID del plan recurrente | | `discount_type` | string (percentage | fixed) | sí | Tipo de descuento: percentage (porcentaje) o fixed (monto fijo) | | `discount` | number | sí | Valor del descuento | | `expire` | string | sí | Fecha de vencimiento del cupón en formato YYYY-MM-DD | | `allow_existing_users` | boolean | — | true si también lo pueden usar clientes ya registrados (false = solo nuevos) | | `emails` | array | — | Correos autorizados; si se omite, cualquier correo puede usarlo | | `usage` | integer | — | Cantidad total de usos | | `renews` | integer | — | Renovaciones válidas con el cupón | | `renews_by_user` | integer | — | Usos por un mismo cliente | **Devuelve** `{ result }` result = respuesta del API con el cupón de descuento creado para el plan. ### Cupones de un plan [#tilopay-recurring-list-coupons] - `tilopay_recurring_list_coupons` - Acceso: Sólo lectura - Operación del API: `POST /api/v1/getRepeatCoupons` Lista los cupones de descuento asociados a un plan de suscripción. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `planId` | string | sí | ID del plan recurrente | **Devuelve** `{ result }` result = cupones del plan tal cual los devuelve el API. ### Detalle de un cupón [#tilopay-recurring-get-coupon] - `tilopay_recurring_get_coupon` - Acceso: Sólo lectura - Operación del API: `POST /api/v1/getCoupon` Obtiene el detalle de un cupón de descuento por su ID. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `id` | string | sí | ID del cupón | **Devuelve** `{ result }` result = detalle de un cupón tal cual lo devuelve el API. ### Eliminar un cupón [#tilopay-recurring-delete-coupon] - `tilopay_recurring_delete_coupon` - Acceso: Sensible - Operación del API: `POST /api/v1/deleteCoupon` Elimina un cupón de descuento de un plan de suscripción. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `id` | string | sí | ID del cupón | **Devuelve** `{ result }` result = respuesta del API al eliminar el cupón. ### Iniciar paso a paso de un plan de suscripción [#tilopay-recurring-plan-wizard-start] - `tilopay_recurring_plan_wizard_start` - Acceso: Escritura Inicia el paso a paso guiado para crear (mode=create) o editar (mode=edit con plan_id) un plan de suscripción. Devuelve la primera pregunta pendiente: entréguela al comercio tal cual y pase su respuesta a tilopay_recurring_plan_wizard_answer. Úselo en vez de tilopay_recurring_create_plan cuando falte algún dato. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `mode` | string (create | edit) | sí | create para un plan nuevo, edit para modificar uno existente | | `plan_id` | string | — | ID del plan (obligatorio en mode=edit) | | `title` | string | — | Título, si el comercio ya lo dijo | | `frequency` | string (diario | semanal | quincenal | mensual | bimestral | trimestral | cuatrimestral | semestral | anual) | — | Frecuencia, si el comercio ya la dijo | | `amount` | number | — | Monto por ciclo, si el comercio ya lo dijo | | `currency` | string | — | Moneda ISO si el comercio la indicó con símbolo o nombre ($ o dólares = USD, ₡ o colones = CRC) | | `description` | string | — | Descripción, si ya la dijo | **Devuelve** `{ draft }` draft = borrador del plan en proceso, con lo que ya se respondió y el siguiente paso pendiente. No crea nada en Tilopay hasta confirmar. ### Responder un paso del plan de suscripción [#tilopay-recurring-plan-wizard-answer] - `tilopay_recurring_plan_wizard_answer` - Acceso: Escritura Guarda la respuesta del comercio al paso actual del plan de suscripción y devuelve la siguiente pregunta o el resumen para confirmar. Entregue el texto devuelto tal cual, sin agregar preguntas propias. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `answer` | string | sí | Lo que respondió el comercio, tal cual | **Devuelve** `{ draft }` draft = el borrador actualizado con la respuesta del paso y el siguiente paso pendiente. ### Confirmar el plan de suscripción [#tilopay-recurring-plan-wizard-confirm] - `tilopay_recurring_plan_wizard_confirm` - Acceso: Escritura - Operación del API: `POST /api/v1/createPlanRepeat` Crea o edita el plan de suscripción con los datos del paso a paso, después de que el comercio dijo sí al resumen. Al crear devuelve además el enlace de suscripción: entréguelo completo, sin recortarlo. **Parámetros** Sin parámetros. **Devuelve** `{ plan_id, subscription_url }` Crea el plan con lo que se armó paso a paso: plan_id = id del plan creado; subscription_url = enlace de suscripción para compartir. ### Cancelar el paso a paso del plan [#tilopay-recurring-plan-wizard-cancel] - `tilopay_recurring_plan_wizard_cancel` - Acceso: Escritura Descarta el plan de suscripción que estaba en proceso sin crear ni cambiar nada. **Parámetros** Sin parámetros. **Devuelve** Descarta el borrador del plan en proceso. No crea ni cambia nada en Tilopay; devuelve sólo la confirmación en texto. ### Enlace de pago para poner al día un cobro recurrente fallido [#tilopay-recurring-settle-link] - `tilopay_recurring_settle_link` - Acceso: Escritura - Operación del API: `POST /api/v1/createLinkPayment` — https://tilopay.com/developers/api/links-de-pago/create-link-payment Crea un enlace de pago por el monto de un cobro recurrente que falló y lo asocia al suscriptor del plan. Cuando el cliente paga ese enlace, la suscripción queda al día automáticamente: el suscriptor se reactiva y su fecha de expiración avanza al siguiente ciclo. Úsala cuando el comercio acepte enviarle el enlace al cliente de un cobro fallido (los datos salen de tilopay_recurring_failed_payments). Devuelve la URL del enlace y, si hay teléfono, un enlace de WhatsApp listo para enviarle al cliente. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `subscriber_id` | string | sí | ID del suscriptor con el cobro fallido | | `amount` | number | sí | Monto pendiente del cobro fallido | | `currency` | string | — | Moneda del cobro. Si se omite se usa la del país del comercio. | | `plan_id` | string | — | ID del plan de suscripción | | `plan_name` | string | — | Nombre del plan, para el concepto del cobro | | `frequency` | string (diario | semanal | quincenal | mensual | bimestral | trimestral | cuatrimestral | semestral | anual) | — | Frecuencia del plan; si se omite se consulta al plan o se asume mensual | | `client_name` | string | — | Nombre del cliente | | `client_email` | string | — | Correo del cliente | | `client_phone` | string | — | Teléfono del cliente en formato internacional, para el enlace de WhatsApp | | `message` | string | — | Mensaje propio para el cliente; si se omite se arma uno | **Devuelve** `{ url, linkId, whatsapp_url, currency, amount, subscriber_id, frequency }` Crea un enlace de pago de un solo uso para que el suscriptor ponga al día un cobro recurrente fallido: url = enlace de pago; whatsapp_url = enlace de WhatsApp listo para enviarlo; linkId = id del enlace creado. ### Enlaces para poner al día varios cobros fallidos [#tilopay-recurring-settle-batch] - `tilopay_recurring_settle_batch` - Acceso: Escritura Envío en tanda (máximo 20) de enlaces para poner al día cobros recurrentes fallidos. Primero llámala SIN confirmar: devuelve el resumen (cantidad, total, quiénes no tienen teléfono) y una huella. Muestra ese resumen TAL CUAL y pide un sí explícito. Solo si el comercio responde sí, llámala de nuevo con confirm=true y la MISMA huella. Úsala cuando pida «mandales a todos»; para un solo cliente usa tilopay_recurring_settle_link. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `confirm` | boolean | — | true solo tras el sí explícito al resumen | | `fingerprint` | string | — | Huella devuelta por el resumen | | `subscriber_ids` | array | — | Limitar a estos suscriptores; si se omite, todos los pendientes (máx. 20) | **Devuelve** ### Poner al día un suscriptor [#tilopay-recurring-mark-settled] - `tilopay_recurring_mark_settled` - Acceso: Escritura - Operación del API: `POST /api/v1/editSuscriptorRepeat` Marca al suscriptor como al día en su plan: lo deja activo y corre su fecha de expiración al siguiente ciclo. Úsala cuando el cobro pendiente ya se pagó por otro medio. Si el pago se hizo con el enlace de tilopay_recurring_settle_link, no hace falta: se actualiza solo. Confirma con el comercio antes de ejecutarla. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `subscriber_id` | string | sí | ID del suscriptor | | `plan_id` | string | — | ID del plan de suscripción | | `frequency` | string (diario | semanal | quincenal | mensual | bimestral | trimestral | cuatrimestral | semestral | anual) | — | Frecuencia del plan; si se omite se consulta al plan o se asume mensual | | `expire` | string | — | Nueva fecha de expiración YYYY-MM-DD; si se omite se calcula el siguiente ciclo | **Devuelve** `{ ok, expire, frequency }` Corre la fecha de vencimiento del suscriptor según la frecuencia del plan, para dejarlo al día después de recuperar un cobro fallido. expire = la nueva fecha de vencimiento. --- # Tarjetas guardadas y cobros masivos > Herramientas del MCP para guardar la tarjeta de un cliente, cobrarle, eliminarla y trabajar con los grupos de cobro masivo. - kind: mcp-tool - status: stable - access: destructive - last_verified: 2026-10-07 - url: https://tilopay.com/developers/agentes/mcp/tarjetas-guardadas ## Qué cubre [#que-cubre] Este grupo trabaja con las tarjetas que los clientes del comercio ya autorizaron guardar (tokenización) y con los cobros masivos a esas tarjetas. Cómo funciona el guardado: el agente genera un **enlace seguro** y lo comparte con el cliente; el cliente digita ahí su tarjeta. Ni el agente, ni el modelo, ni el comercio ven el número completo: las herramientas de consulta devuelven la marca y los últimos dígitos. Las operaciones sensibles del grupo —cobrar a una tarjeta guardada, eliminar una tarjeta y crear cobros masivos— exigen un **código de confirmación** que llega al correo del comercio. Las rutas del API que usan los cobros masivos quedan fuera de la referencia del portal, así que estas páginas no las publican. Lo que sí queda documentado es qué hace cada herramienta, qué recibe y qué devuelve. ## Herramientas [#herramientas] ### Listar grupos de cobro [#tilopay-saved-cards-list-groups] - `tilopay_saved_cards_list_groups` - Acceso: Sólo lectura Lista los grupos de cobro con tarjetas almacenadas (afiliados) en Tilopay. **Parámetros** Sin parámetros. **Devuelve** `{ result }` Respuesta cruda del API de Tilopay bajo la llave `result`. ### Listar afiliados con tarjeta almacenada [#tilopay-saved-cards-list-affiliates] - `tilopay_saved_cards_list_affiliates` - Acceso: Sólo lectura Lista los afiliados (clientes con tarjeta almacenada) de un grupo de cobro. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `group` | integer | — | ID del grupo (0 para todos) | **Devuelve** `{ result }` Respuesta cruda del API de Tilopay bajo la llave `result`. ### Listar cobros masivos [#tilopay-saved-cards-list-collections] - `tilopay_saved_cards_list_collections` - Acceso: Sólo lectura Lista los cobros masivos realizados con tarjetas almacenadas en Tilopay. **Parámetros** Sin parámetros. **Devuelve** `{ result }` Respuesta cruda del API de Tilopay bajo la llave `result`. ### Detalle de un cobro masivo [#tilopay-saved-cards-collection-detail] - `tilopay_saved_cards_collection_detail` - Acceso: Sólo lectura Obtiene el detalle de un cobro masivo. Requiere el `code` del cobro (campo `code` devuelto por tilopay_saved_cards_list_collections). **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `code` | string | sí | Código del cobro masivo (campo `code` de la lista de cobros) | **Devuelve** `{ result }` Respuesta cruda del API de Tilopay bajo la llave `result`. ### Guardar la tarjeta de un cliente (tokenizar) [#tilopay-tokenize-card] - `tilopay_tokenize_card` - Acceso: Escritura - Operación del API: `POST /api/v1/processTokenize` Genera el enlace seguro de Tilopay donde el cliente ingresa su tarjeta para dejarla guardada (tokenizada). El comercio nunca ve ni recibe los datos de la tarjeta. Una vez guardada, se le puede cobrar con tilopay_saved_cards_create_payments (esa sí pide código de confirmación por correo). Si se indica un contacto o teléfono, también devuelve un enlace de WhatsApp con el mensaje listo para enviarle al cliente. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `email` | string | sí | Correo del tarjetahabiente | | `first_name` | string | sí | Nombre del tarjetahabiente | | `last_name` | string | sí | Apellido del tarjetahabiente | | `language` | string (es | en) | — | Idioma del formulario (es por defecto) | | `redirect_url` | string | — | URL a la que vuelve el cliente al terminar (opcional) | | `contact_name` | string | — | Nombre del contacto guardado o del cliente, para armar el mensaje de WhatsApp | | `phone` | string | — | Teléfono de WhatsApp del cliente, ej. +50688887777 | | `message` | string | — | Texto propio para el mensaje al cliente | | `save_contact` | boolean | — | Guardar el contacto en la agenda | **Devuelve** `{ tokenize_url, whatsapp_url, email, contact }` tokenize_url = enlace seguro donde el cliente ingresa su tarjeta para guardarla; whatsapp_url = enlace de WhatsApp listo para enviárselo. La tarjeta la digita el cliente: el agente nunca recibe el número. ### Listar las tarjetas guardadas de un cliente [#tilopay-list-customer-cards] - `tilopay_list_customer_cards` - Acceso: Sólo lectura Lista las tarjetas que un cliente ya tiene guardadas (tokenizadas) en Tilopay, identificadas por tu correo. Devuelve el token de cada tarjeta, que es lo que necesita tilopay_charge_saved_card para cobrarle. Solo se pueden cobrar tarjetas guardadas con el enlace de este asistente o del MCP. No cobra nada. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `email` | string | sí | Correo del cliente dueño de las tarjetas | | `currency` | string | — | Moneda de referencia, ej. CRC o USD. Si se omite se usa la del país del comercio. | **Devuelve** `{ cards, count }` cards = tarjetas ya guardadas de ese cliente, con marca, últimos dígitos y su identificador para cobrar; count = cuántas hay. Nunca devuelve el número completo de la tarjeta. ### Métodos de pago disponibles y cuotas [#tilopay-payment-methods] - `tilopay_payment_methods` - Acceso: Sólo lectura Lista los métodos de pago habilitados para el comercio en el checkout de Tilopay (tarjetas, SINPE Móvil, Yappy, cuotas o tasa cero cuando están activos) y si la cuenta responde en producción o en pruebas. Úsala cuando el comercio pregunte qué puede ofrecerle a su cliente o si tiene cuotas / tasa cero. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `amount` | number | — | Monto de referencia; algunos métodos y cuotas dependen del monto | | `currency` | string | — | Moneda de referencia. Si se omite se usa la del país del comercio. | | `email` | string | — | Correo del cliente (opcional; solo para ver también tus tarjetas guardadas) | **Devuelve** `{ methods, installments, cards, environment, currency }` methods = métodos de pago habilitados para el comercio; installments = cuotas disponibles cuando el método las admite; cards = tarjetas guardadas del cliente si se envió su correo; environment = production o test. ### Cobrar a una tarjeta guardada de un cliente [#tilopay-charge-saved-card] - `tilopay_charge_saved_card` - Acceso: Sensible - Operación del API: `POST /api/v1/processRecurrentPayment` Cobra un monto a una tarjeta ya guardada (tokenizada) de un cliente. Requiere el correo del cliente y el token de la tarjeta (se obtiene con tilopay_list_customer_cards). Operación sensible: mueve dinero real y requiere segundo factor. Llámela primero sin `confirmation_code`: se envía un código de 6 dígitos al correo del comercio y la respuesta trae `requires_confirmation`. Repita la misma llamada, con los mismos parámetros, agregando `confirmation_code`. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `email` | string | sí | Correo del tarjetahabiente | | `card` | string | sí | Token de la tarjeta guardada (versión v2) | | `amount` | number | sí | Monto a cobrar | | `currency` | string | — | Moneda del cobro. Si se omite se usa la del país del comercio. | | `order_number` | string | — | Número de orden; si se omite se genera uno único | | `capture` | boolean | — | Capturar de inmediato (por defecto true) | | `confirmation_code` | string | — | Código de 6 dígitos recibido por correo para autorizar la operación | **Devuelve** `{ result, approved, orderNumber, currency, receipt_code, receipt_url, receipt_image_url }` Cobra a una tarjeta ya guardada del cliente: approved = si el cobro fue aprobado; orderNumber = número de orden generado; receipt_* = comprobante del cobro cuando se generó. Exige segundo factor por correo. ### Eliminar una tarjeta guardada de un cliente [#tilopay-remove-saved-card] - `tilopay_remove_saved_card` - Acceso: Sensible - Operación del API: `POST /api/v1/user/card-remove` Elimina una tarjeta guardada (token) de un cliente en Tilopay. Operación sensible: requiere segundo factor. Llámela primero sin `confirmation_code` y repítala luego con el código de 6 dígitos que llega al correo del comercio. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `email` | string | sí | Correo del cliente dueño de la tarjeta | | `token` | string | sí | Token de la tarjeta a eliminar | | `confirmation_code` | string | — | Código de 6 dígitos recibido por correo para autorizar la operación | **Devuelve** `{ result }` result = respuesta del API al eliminar la tarjeta guardada del cliente. Exige segundo factor por correo. ### Cobrar a tarjetas almacenadas [#tilopay-saved-cards-create-payments] - `tilopay_saved_cards_create_payments` - Acceso: Sensible Crea cobros a afiliados y/o grupos con tarjetas almacenadas en Tilopay. Solo se permiten afiliados cuya tarjeta se guardó con el enlace de este asistente o del MCP (tilopay_tokenize_card); los demás se rechazan. Operación sensible: afecta dinero real y requiere segundo factor. Llámela primero sin `confirmation_code`: se envía un código de 6 dígitos al correo del comercio y la respuesta trae `requires_confirmation`. Repita la misma llamada, con los mismos parámetros, agregando `confirmation_code`. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `reason` | string | sí | Motivo del cobro, ej. "Cobro mensualidad" | | `capture` | boolean | — | Capturar de inmediato (por defecto true) | | `users` | array | — | Afiliados individuales a cobrar | | `groups` | array | — | Grupos a cobrar | | `confirmation_code` | string | — | Código de 6 dígitos recibido por correo para autorizar la operación | **Devuelve** `{ result }` Respuesta cruda del API de Tilopay bajo la llave `result`. --- # Liquidaciones, depósitos y facturación > Herramientas del MCP para consultar la próxima liquidación, el historial de liquidaciones, los depósitos de garantía y las facturas que Tilopay le emite al comercio. - kind: mcp-tool - status: stable - access: write - last_verified: 2026-10-07 - url: https://tilopay.com/developers/agentes/mcp/liquidaciones ## Qué cubre [#que-cubre] Este grupo cubre el dinero que Tilopay le liquida al comercio: el balance por liquidar y la fecha del próximo depósito, las liquidaciones ya procesadas con sus transacciones, los depósitos de garantía (preautorizaciones retenidas a clientes) y las facturas que Tilopay emite por el uso de la plataforma. Todo es de lectura salvo extender un depósito de garantía, que exige un código de seis dígitos que llega por correo. ## Herramientas [#herramientas] ### Próxima liquidación y balance por liquidar [#tilopay-settlement-balance] - `tilopay_settlement_balance` - Acceso: Sólo lectura Dato OFICIAL de Tilopay: fecha del próximo depósito (next_settlement), frecuencia de liquidación, cuenta IBAN destino y, por moneda, el balance acumulado pendiente con su desglose (subtotal, commission, iva_commission, retention, retention_iva, cost, iva_tilopay, transfer, transfer_iva, total neto). Úsala para «¿cuándo me depositan?», «¿cuánto me van a liquidar?», «¿cuánto me cobran de comisión?». **Parámetros** Sin parámetros. **Devuelve** ### Historial de liquidaciones [#tilopay-settlements-list] - `tilopay_settlements_list` - Acceso: Sólo lectura Liquidaciones ya procesadas por Tilopay: fecha de depósito (date_to_report), periodo, monto bruto, deducciones y total transferido. Úsala para «¿ya me depositaron lo del viernes?» o «¿cuánto me depositaron el mes pasado?». **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `page` | integer | — | Página (por defecto 1) | | `limit` | integer | — | Registros por página (por defecto 20) | | `search` | string | — | Texto a buscar | **Devuelve** ### Transacciones de una liquidación [#tilopay-settlement-transactions] - `tilopay_settlement_transactions` - Acceso: Sólo lectura Transacciones incluidas en una liquidación ya procesada (id obtenido de tilopay_settlements_list). **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `settlement_id` | string | sí | Id de la liquidación | **Devuelve** ### Depósitos de garantía (preautorizaciones) [#tilopay-deposits-list] - `tilopay_deposits_list` - Acceso: Sólo lectura Depósitos de garantía o preautorizaciones retenidas a clientes (renta de autos, hotelería, depósitos de seguridad): monto, estado y vencimiento. No confundir con liquidaciones. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `page` | integer | — | Página (por defecto 1) | | `limit` | integer | — | Registros por página (por defecto 20) | | `search` | string | — | Texto a buscar | **Devuelve** ### Detalle de un depósito de garantía [#tilopay-deposit-detail] - `tilopay_deposit_detail` - Acceso: Sólo lectura Detalle de un depósito de garantía (id de tilopay_deposits_list). **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `deposit_id` | string | sí | Id del depósito | **Devuelve** ### Extender un depósito de garantía [#tilopay-deposit-extend] - `tilopay_deposit_extend` - Acceso: Escritura Extiende la vigencia de la autorización de un depósito de garantía. Requiere el código de seis dígitos que llega por correo. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `deposit_id` | string | sí | Id del depósito | **Devuelve** ### Facturas del servicio Tilopay [#tilopay-billing-list] - `tilopay_billing_list` - Acceso: Sólo lectura Facturas que Tilopay le emite al comercio por el uso de la plataforma (no son ventas del comercio). Úsala para «¿cuánto me cobró Tilopay este mes?» o «¿dónde está mi factura de Tilopay?». **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `page` | integer | — | Página (por defecto 1) | | `limit` | integer | — | Registros por página (por defecto 20) | | `search` | string | — | Texto a buscar | **Devuelve** --- # Cuenta, comercio y equipo > Herramientas del MCP para vincular o desvincular la cuenta, elegir el comercio activo, gestionar empleados del asistente y consultar usuarios del panel y métodos de pago habilitados. - kind: mcp-tool - status: stable - access: destructive - last_verified: 2026-10-07 - url: https://tilopay.com/developers/agentes/mcp/cuenta ## Qué cubre [#que-cubre] Este grupo cubre la cuenta de Tilopay vinculada al asistente: vincularla o desvincularla, elegir el comercio activo cuando hay varios, dar o quitar acceso a empleados, y consultar los usuarios del panel web y los métodos de pago y monedas habilitados. Desvincular la cuenta y quitar el acceso a un empleado están marcadas como sensibles y piden confirmación explícita antes de ejecutarse. ## Herramientas [#herramientas] ### Comercio seleccionado [#tilopay-switch-commerce] - `tilopay_switch_commerce` - Acceso: Escritura Muestra el comercio activo de la cuenta de Tilopay vinculada y permite cambiarlo cuando la cuenta tiene varios. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `commerce_id` | string | — | Comercio que se quiere activar. Si se omite, solo se muestra el actual. | **Devuelve** ### Desvincular mi cuenta [#tilopay-unlink-account] - `tilopay_unlink_account` - Acceso: Sensible Desvincula la cuenta de Tilopay del asistente: revoca TODO el acceso (WhatsApp, Claude y otras aplicaciones), borra las claves guardadas (incluidas las del banco) y cierra las sesiones bancarias. Antes de llamarla con confirm=true, repítele al comercio ese alcance y pide confirmación. Úsela cuando el comercio pida desvincular, desconectar o quitar tu cuenta del asistente. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `confirm` | boolean | sí | Debe ser true: el comercio confirmó que quiere desvincular tu cuenta. | | `all_channels` | boolean | — | true solo si el comercio pidió expresamente desvincular también el otro canal (WhatsApp y clientes MCP). | **Devuelve** ### Vincular mi cuenta [#tilopay-send-link-flow] - `tilopay_send_link_flow` - Acceso: Escritura Envía al WhatsApp del comercio el botón para vincular (o volver a vincular) tu cuenta de Tilopay con el asistente. Úsela ante cualquier petición de vincular, conectar o activar el asistente con la cuenta de Tilopay. **Parámetros** Sin parámetros. **Devuelve** ### Dar acceso a un empleado [#tilopay-invite-employee] - `tilopay_invite_employee` - Acceso: Escritura Invita a un empleado a usar el asistente con su propio usuario de Tilopay (solo el dueño). Pide nombre y teléfono de WhatsApp del empleado. Devuelve un enlace wa.me para que el dueño le envíe la invitación. En tu respuesta, repite primero la línea `prerequisito` tal cual y luego entrega el enlace. El empleado puede consultar ventas, crear cobros y enviar comprobantes; no puede reembolsar, cobrar tarjetas guardadas, crear o borrar productos, cambiar precios ni cambiar la configuración. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `name` | string | sí | Nombre del empleado | | `phone` | string | sí | WhatsApp del empleado, ej. 8888-8888 | **Devuelve** ### Ver mis empleados [#tilopay-list-employees] - `tilopay_list_employees` - Acceso: Sólo lectura Lista los empleados con acceso al asistente y las invitaciones pendientes (solo el dueño). **Parámetros** Sin parámetros. **Devuelve** ### Quitar acceso a un empleado [#tilopay-remove-employee] - `tilopay_remove_employee` - Acceso: Sensible Quita el acceso de un empleado al asistente (solo el dueño): revoca toda su sesión, o cancela la invitación si no se había vinculado. Antes de llamarla con confirm=true, confirma con el dueño a quién se quita. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `name` | string | — | Nombre del empleado | | `phone` | string | — | Teléfono del empleado | | `confirm` | boolean | sí | true: el dueño confirmó quitarle el acceso | **Devuelve** ### Métodos de pago y monedas habilitados [#tilopay-accepted-payment-methods] - `tilopay_accepted_payment_methods` - Acceso: Sólo lectura Métodos de pago que el comercio tiene habilitados en Tilopay (marcas de tarjeta, SINPE, etc.), monedas configuradas y configuración PayFac. Úsala para «¿qué tarjetas acepto?», «¿tengo SINPE activo?», «¿puedo cobrar en dólares?». **Parámetros** Sin parámetros. **Devuelve** ### Usuarios del panel de Tilopay [#tilopay-panel-users] - `tilopay_panel_users` - Acceso: Sólo lectura Usuarios que tienen acceso al panel web de Tilopay del comercio y sus módulos. Distinto de los empleados del asistente (tilopay_list_employees). **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `page` | integer | — | Página (por defecto 1) | | `limit` | integer | — | Registros por página (por defecto 20) | | `search` | string | — | Texto a buscar | **Devuelve** --- # Soporte y diagnóstico > Herramientas del MCP para responder con las guías oficiales y probar la conexión con el API. - kind: mcp-tool - status: stable - access: read - last_verified: 2026-10-07 - url: https://tilopay.com/developers/agentes/mcp/soporte ## Qué cubre [#que-cubre] Tres herramientas de lectura: una responde preguntas de uso del panel con las guías oficiales de tilopay.com/guias, otra prueba las credenciales y un endpoint de cada grupo del API para saber qué parte responde cuando algo falla, y la tercera analiza un fragmento de código o un stack trace que le pases y devuelve diagnóstico, causa raíz, corrección y riesgos. Esa última no lee repositorios ni ejecuta código. ## Herramientas [#herramientas] ### Diagnóstico de conexión con Tilopay [#tilopay-diagnostics] - `tilopay_diagnostics` - Acceso: Sólo lectura Verifica las credenciales del usuario y prueba un endpoint de cada grupo (ventas/transacciones, catálogo, recurrentes, tarjetas almacenadas). Úsalo cuando una herramienta falle para saber qué parte del API responde. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `environment` | string (production | test) | — | Ambiente para la prueba de transacciones (por defecto production) | **Devuelve** `{ checks, failed }` checks es una lista con check, ok y detail por cada prueba: credenciales, transacciones, catálogo, recurrentes y tarjetas almacenadas. failed es la cantidad de pruebas con error. Las credenciales se devuelven enmascaradas. ### Ayuda con las guías y tutoriales de Tilopay [#tilopay-help-guides] - `tilopay_help_guides` - Acceso: Sólo lectura Responde dudas de uso del panel de Tilopay (links de pago, catálogo, suscripciones, depósitos de garantía, reembolsos, API/SDK) usando las guías oficiales de tilopay.com/guias. Devuelve extractos y los enlaces a las guías. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `question` | string | sí | Pregunta del comercio, tal como la escribió | **Devuelve** `{ articles }` Hasta 3 artículos con title, url y excerpt, tomados de tilopay.com/guias. Si no hay coincidencia devuelve articles vacío y un texto con las guías disponibles. ### Depurar código [#tilopay-debug-code] - `tilopay_debug_code` - Acceso: Sólo lectura Analiza un fragmento de código o stack trace que envía el usuario y devuelve diagnóstico, causa raíz, corrección concreta y riesgos. No lee repositorios ni ejecuta código. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `code` | string | sí | Fragmento de código, log o stack trace tal como lo envió el usuario | | `error` | string | — | Mensaje de error o comportamiento observado, si lo hay | | `language` | string | — | Lenguaje o stack (ej. typescript, php, react). Si no se indica, se detecta | | `context` | string | — | Qué debería hacer el código o en qué momento falla | **Devuelve** `{ report, truncated, redacted, model }` report es el diagnóstico en texto (diagnóstico, causa raíz, corrección y riesgos). truncated indica si el código se recortó a 12.000 caracteres; redacted, si se ocultaron posibles credenciales antes del análisis; model, el modelo usado. No lee repositorios ni ejecuta el código. --- # Herramientas bancarias > Herramientas del MCP para consultar el API bancario de Tilopay: cuentas, saldos, pagos y estados de cuenta. Se activan bajo solicitud y sólo para usuarios con credenciales del API bancario. - kind: mcp-tool - status: stable - access: write - last_verified: 2026-10-07 - url: https://tilopay.com/developers/agentes/mcp/api-bancario **Estas herramientas no vienen activadas.** Se habilitan **bajo solicitud** y sólo funcionan para usuarios con **credenciales del API bancario de Tilopay** registradas por Tilopay del lado del servidor. Con el acceso MCP estándar el grupo no aparece; y si la herramienta se invoca sin esas credenciales, responde que no existen. Para pedirlo, escribinos desde [contacto](/contacto) e indicá que necesitás el API bancario. ## Qué cubre [#que-cubre] Diecinueve herramientas sobre el [API bancario](/developers/api-bancario): contextos (assignments), diagnóstico de credenciales, cuentas, saldos, número de cuenta completo, pagos, estados de cuenta, un informe analítico de pagos, la validación de una cuenta destino, la transferencia con su autorización, cancelación y aviso de resultado, la aprobación en doble control y el cierre de la sesión bancaria. **Trece de las diecinueve sólo extraen información.** `baas_request_statement` genera un documento de consulta y no mueve dinero. La única que envía dinero es `baas_send_transfer`, y no se ejecuta sola: el portal Banca Cliente envía un código de autorización al correo del comercio, y la transferencia sólo sale cuando el comercio responde ese código y se confirma con `baas_confirm_transfer`. Si la operación queda en doble control, el aprobador la decide con `banca_decide_approval` y un código que llega a su correo. Así, no puede ejecutarse por decisión del modelo. Las cuentas se identifican con `accountType: "IBAN"` más `accountValue`, las fechas son RFC 3339 (`2026-01-01T00:00:00Z`) y `assignmentId` se envía únicamente cuando el usuario tiene varios contextos. ## Herramientas [#herramientas] > Estas herramientas se activan bajo solicitud y sólo funcionan para usuarios con credenciales del API bancario de Tilopay. No forman parte del acceso MCP por defecto: Tilopay habilita el grupo caso por caso. Requiere: Credenciales del API bancario de Tilopay registradas por Tilopay para ese usuario. - [Otras operaciones](https://tilopay.com/developers/agentes/mcp/api-bancario/otras-operaciones) — `baas_list_assignments`, `baas_diagnostics`, `baas_list_accounts`, `baas_get_balance`, `baas_get_account_number`, `baas_get_statement_status`, `baas_confirm_transfer`, `baas_cancel_transfer`, `banca_decide_approval`, `baas_close_session` (Sólo lectura / Sólo lectura / Sólo lectura / Sólo lectura / Sólo lectura / Sólo lectura / Sensible / Escritura / Sensible / Escritura): Contextos (assignments), diagnóstico de credenciales, listado de cuentas, saldo de una cuenta, número de cuenta completo, estado de una solicitud de estado de cuenta, autorización y cancelación de la transferencia pendiente, aprobación en doble control y cierre de la sesión bancaria. - [Saldos de las cuentas BaaS](https://tilopay.com/developers/agentes/mcp/api-bancario/list-balances) — `baas_list_balances` (Sólo lectura): Lista los saldos en tiempo real de las cuentas accesibles del API BaaS (cuenta, montos y fecha de corte). - [Listar pagos BaaS](https://tilopay.com/developers/agentes/mcp/api-bancario/list-payments) — `baas_list_payments` (Sólo lectura): Consulta (solo lectura) los movimientos/pagos de una cuenta bancaria propia. Indica la moneda (CRC/USD) o el número de cuenta de la lista: no escribe el IBAN. Filtros de fecha, estado, moneda, método y dirección, con paginación por cursor. - [Buscar un pago BaaS](https://tilopay.com/developers/agentes/mcp/api-bancario/search-payment) — `baas_search_payment` (Sólo lectura): Busca un pago BaaS dentro de una cuenta por exactamente uno de: paymentId (UUID), publicId (número) o clientReference. Identificadores solo de datos que una herramienta ya devolvió. - [Detalle de un pago BaaS](https://tilopay.com/developers/agentes/mcp/api-bancario/get-payment) — `baas_get_payment` (Sólo lectura): Obtiene el detalle de un pago BaaS por su UUID interno (solo lectura). Usa únicamente identificadores que otra herramienta devolvió en este mismo turno. - [Solicitar estado de cuenta BaaS](https://tilopay.com/developers/agentes/mcp/api-bancario/request-statement) — `baas_request_statement` (Escritura): Solicita la generación de un estado de cuenta (rango máximo 60 días) para una cuenta BaaS. No mueve dinero: solo genera un documento de consulta. Devuelve request_id y status PENDING. - [Analista de pagos BaaS](https://tilopay.com/developers/agentes/mcp/api-bancario/analyze-payments) — `baas_analyze_payments` (Sólo lectura): Analiza (solo lectura) los pagos BaaS de una cuenta en un rango de fechas y devuelve un informe en lenguaje natural: éxito, fallas, reversiones, montos netos y recomendaciones verificables. - [Validar cuenta destino BaaS](https://tilopay.com/developers/agentes/mcp/api-bancario/validate-destination) — `baas_validate_destination` (Sólo lectura): Valida una cuenta destino antes de transferir: PHONE para SINPE Móvil o IBAN para transferencia a cuenta. Devuelve el nombre del titular que el banco confirma. - [Enviar transferencia BaaS](https://tilopay.com/developers/agentes/mcp/api-bancario/send-transfer) — `baas_send_transfer` (Sensible): Envía una transferencia desde la cuenta bancaria del comercio. Método por defecto: SINPE Móvil (destino por teléfono). Para transferencia a cuenta usa accountType=IBAN. El portal Banca Cliente envía el código de autorización al correo del comercio y aplica sus límites; el comercio responde el código y se confirma con baas_confirm_transfer. - [Estado de transferencia BaaS](https://tilopay.com/developers/agentes/mcp/api-bancario/get-transfer-status) — `baas_get_transfer_status` (Sólo lectura): El resultado de una transferencia no se consulta: el banco lo avisa por aquí en cuanto lo tiene (evento del portal). --- # Saldos > Lista los saldos en tiempo real de las cuentas accesibles: cuenta, montos y fecha de corte. - kind: mcp-tool - status: stable - access: read - last_verified: 2026-10-07 - url: https://tilopay.com/developers/agentes/mcp/api-bancario/list-balances > Estas herramientas se activan bajo solicitud y sólo funcionan para usuarios con credenciales del API bancario de Tilopay. No forman parte del acceso MCP por defecto: Tilopay habilita el grupo caso por caso. Requiere: Credenciales del API bancario de Tilopay registradas por Tilopay para ese usuario. - `baas_list_balances` - Acceso: Sólo lectura - Operación del API: `GET /api/public/v1/accounts/balances` — https://tilopay.com/developers/api-bancario/cuentas Lista los saldos en tiempo real de las cuentas accesibles del API BaaS (cuenta, montos y fecha de corte). **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `accountType` | string | — | Filtro por esquema (IBAN) | | `accountValue` | string | — | Filtro por identificador | | `limit` | integer | — | — | | `offset` | integer | — | Desplazamiento de paginación | | `assignmentId` | string | — | Contexto BaaS (opcional) | **Devuelve** `{ result }` result = respuesta del API bancario tal cual. --- # Pagos > Consulta, sólo lectura, los pagos de una cuenta propia identificada por IBAN, con filtros de fecha, estado, moneda, método y dirección. Paginación por cursor. - kind: mcp-tool - status: stable - access: read - last_verified: 2026-10-07 - url: https://tilopay.com/developers/agentes/mcp/api-bancario/list-payments > Estas herramientas se activan bajo solicitud y sólo funcionan para usuarios con credenciales del API bancario de Tilopay. No forman parte del acceso MCP por defecto: Tilopay habilita el grupo caso por caso. Requiere: Credenciales del API bancario de Tilopay registradas por Tilopay para ese usuario. - `baas_list_payments` - Acceso: Sólo lectura - Operación del API: `GET /api/public/v1/transactions/payments` — https://tilopay.com/developers/api-bancario/pagos Consulta (solo lectura) los movimientos/pagos de una cuenta bancaria propia. Indica la moneda (CRC/USD) o el número de cuenta de la lista: no escribe el IBAN. Filtros de fecha, estado, moneda, método y dirección, con paginación por cursor. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `currency` | string | — | Moneda de la cuenta a consultar (CRC o USD). Forma recomendada. | | `accountIndex` | integer | — | Número de la cuenta en la lista de cuentas del usuario | | `accountValue` | string | — | Solo si una herramienta ya lo devolvió. No escribe números de cuenta de memoria: indica la moneda (CRC/USD) o el número de la cuenta en la lista; el sistema resuelve el IBAN real. | | `assignmentId` | string | — | Contexto BaaS (opcional) | | `dateFrom` | string | — | Desde, RFC 3339 (2026-01-01T00:00:00Z) | | `dateTo` | string | — | Hasta, RFC 3339 | | `status` | string (pending | processing | confirmed | posted | failed) | — | Estado público del pago | | `paymentMethodCode` | string (PIN | SINPE_MOVIL) | — | — | | `direction` | string (OUT | IN) | — | OUT = envío, IN = recibido | | `clientReference` | string | — | Referencia del comercio | | `limit` | integer | — | Tamaño de página (máx 50) | | `cursor` | string | — | Cursor de la página anterior | **Devuelve** `{ result }` result = respuesta del API bancario tal cual, con su cursor de paginación. --- # Buscar un pago > Busca un pago dentro de una cuenta por exactamente uno de: paymentId (UUID), publicId (número) o clientReference. Si se envía más de uno, la herramienta devuelve error. - kind: mcp-tool - status: stable - access: read - last_verified: 2026-10-07 - url: https://tilopay.com/developers/agentes/mcp/api-bancario/search-payment > Estas herramientas se activan bajo solicitud y sólo funcionan para usuarios con credenciales del API bancario de Tilopay. No forman parte del acceso MCP por defecto: Tilopay habilita el grupo caso por caso. Requiere: Credenciales del API bancario de Tilopay registradas por Tilopay para ese usuario. - `baas_search_payment` - Acceso: Sólo lectura - Operación del API: `POST /api/public/v1/transactions/payments/search` — https://tilopay.com/developers/api-bancario/pagos Busca un pago BaaS dentro de una cuenta por exactamente uno de: paymentId (UUID), publicId (número) o clientReference. Identificadores solo de datos que una herramienta ya devolvió. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `currency` | string | — | Moneda de la cuenta a consultar (CRC o USD). Forma recomendada. | | `accountIndex` | integer | — | Número de la cuenta en la lista de cuentas del usuario | | `accountValue` | string | — | Solo si una herramienta ya lo devolvió. No escribe números de cuenta de memoria: indica la moneda (CRC/USD) o el número de la cuenta en la lista; el sistema resuelve el IBAN real. | | `assignmentId` | string | — | Contexto BaaS (opcional) | | `paymentId` | string | — | UUID interno del pago | | `publicId` | string | — | Identificador público numérico | | `clientReference` | string | — | Referencia del comercio | **Devuelve** `{ result }` result = respuesta del API bancario tal cual. --- # Detalle de un pago > Obtiene el detalle de un pago del API bancario por su UUID interno, sólo lectura. - kind: mcp-tool - status: stable - access: read - last_verified: 2026-10-07 - url: https://tilopay.com/developers/agentes/mcp/api-bancario/get-payment > Estas herramientas se activan bajo solicitud y sólo funcionan para usuarios con credenciales del API bancario de Tilopay. No forman parte del acceso MCP por defecto: Tilopay habilita el grupo caso por caso. Requiere: Credenciales del API bancario de Tilopay registradas por Tilopay para ese usuario. - `baas_get_payment` - Acceso: Sólo lectura - Operación del API: `GET /api/public/v1/transactions/payments/{payment_id}` — https://tilopay.com/developers/api-bancario/pagos Obtiene el detalle de un pago BaaS por su UUID interno (solo lectura). Usa únicamente identificadores que otra herramienta devolvió en este mismo turno. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `paymentId` | string | sí | UUID interno del pago | | `assignmentId` | string | — | Contexto BaaS (opcional) | **Devuelve** `{ result }` result = respuesta del API bancario tal cual. --- # Estado de cuenta > Solicita la generación de un estado de cuenta para una cuenta del API bancario, con rango máximo de 60 días. No mueve dinero: genera un documento de consulta y devuelve request_id con status PENDING. - kind: mcp-tool - status: stable - access: write - last_verified: 2026-10-07 - url: https://tilopay.com/developers/agentes/mcp/api-bancario/request-statement > Estas herramientas se activan bajo solicitud y sólo funcionan para usuarios con credenciales del API bancario de Tilopay. No forman parte del acceso MCP por defecto: Tilopay habilita el grupo caso por caso. Requiere: Credenciales del API bancario de Tilopay registradas por Tilopay para ese usuario. - `baas_request_statement` - Acceso: Escritura - Operación del API: `POST /api/public/v1/accounts/statements` — https://tilopay.com/developers/api-bancario/cuentas Solicita la generación de un estado de cuenta (rango máximo 60 días) para una cuenta BaaS. No mueve dinero: solo genera un documento de consulta. Devuelve request_id y status PENDING. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `currency` | string | — | Moneda de la cuenta (CRC o USD) | | `accountIndex` | integer | — | Número de la cuenta en la lista | | `accountValue` | string | — | Solo si una herramienta ya lo devolvió. No escribe números de cuenta de memoria: indica la moneda (CRC/USD) o el número de la cuenta en la lista; el sistema resuelve el IBAN real. | | `dateFrom` | string | sí | Desde, RFC 3339 (2026-01-01T00:00:00Z) | | `dateTo` | string | sí | Hasta, RFC 3339 (máx 60 días después) | | `assignmentId` | string | — | Contexto BaaS (opcional) | **Devuelve** `{ result }` result = respuesta del API bancario con request_id y status. La herramienta solicita el documento sin notificación por correo. --- # Analista de pagos > Analiza, sólo lectura, los pagos de una cuenta en un rango de fechas y devuelve un informe en lenguaje natural: éxito, fallas, reversiones, montos netos y recomendaciones. Usa un modelo de lenguaje sobre las cifras calculadas. - kind: mcp-tool - status: stable - access: read - last_verified: 2026-10-07 - url: https://tilopay.com/developers/agentes/mcp/api-bancario/analyze-payments > Estas herramientas se activan bajo solicitud y sólo funcionan para usuarios con credenciales del API bancario de Tilopay. No forman parte del acceso MCP por defecto: Tilopay habilita el grupo caso por caso. Requiere: Credenciales del API bancario de Tilopay registradas por Tilopay para ese usuario. - `baas_analyze_payments` - Acceso: Sólo lectura Analiza (solo lectura) los pagos BaaS de una cuenta en un rango de fechas y devuelve un informe en lenguaje natural: éxito, fallas, reversiones, montos netos y recomendaciones verificables. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `accountIndex` | integer | — | Número de la cuenta en la lista | | `accountValue` | string | — | Solo si una herramienta ya lo devolvió. No escribe números de cuenta de memoria: indica la moneda (CRC/USD) o el número de la cuenta en la lista; el sistema resuelve el IBAN real. | | `dateFrom` | string | sí | Desde, RFC 3339 | | `dateTo` | string | sí | Hasta, RFC 3339 | | `currency` | string | — | Moneda ISO 4217 | | `direction` | string (OUT | IN) | — | — | | `question` | string | — | Enfoque específico del análisis | | `maxItems` | integer | — | Máximo de pagos (por defecto 300) | | `assignmentId` | string | — | Contexto BaaS (opcional) | **Devuelve** `{ summary }` summary trae account, range, totals {count, succeeded, failed, reversed, pending, successRate}, byCurrency con succeededAmount, reversedAmount, netAmount y averageTicket, failureReasons y sample. El informe redactado viene en el texto. Si no hay pagos en el rango, avisa y no analiza. --- # Validar cuenta destino > Consulta los datos de una cuenta destino antes de enviarle una transferencia: titular, tipo de cuenta, moneda y estado. No mueve dinero. - kind: mcp-tool - status: stable - access: read - last_verified: 2026-10-07 - url: https://tilopay.com/developers/agentes/mcp/api-bancario/validate-destination > Estas herramientas se activan bajo solicitud y sólo funcionan para usuarios con credenciales del API bancario de Tilopay. No forman parte del acceso MCP por defecto: Tilopay habilita el grupo caso por caso. Requiere: Credenciales del API bancario de Tilopay registradas por Tilopay para ese usuario. - `baas_validate_destination` - Acceso: Sólo lectura - Operación del API: `POST /api/public/v1/accounts/validate` — https://tilopay.com/developers/api-bancario/cuentas Valida una cuenta destino antes de transferir: PHONE para SINPE Móvil o IBAN para transferencia a cuenta. Devuelve el nombre del titular que el banco confirma. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `accountType` | string (PHONE | IBAN) | sí | Esquema del identificador: PHONE para SINPE Móvil, IBAN para cuenta. | | `accountValue` | string | sí | Número de teléfono E.164 o IBAN | | `assignmentId` | string | — | Contexto BaaS (opcional) | **Devuelve** `{ result }` result = datos que devuelve el API bancario sobre la cuenta destino (titular, tipo de cuenta, moneda y estado) antes de enviar una transferencia. No mueve dinero. --- # Enviar transferencia > Envía una transferencia desde una cuenta bancaria del comercio. Valida la cuenta destino antes y exige un código de confirmación que llega al correo del comercio. - kind: mcp-tool - status: stable - access: destructive - last_verified: 2026-10-07 - url: https://tilopay.com/developers/agentes/mcp/api-bancario/send-transfer **Esta herramienta mueve dinero real.** Antes de enviar, valida la cuenta destino; y para ejecutar la transferencia exige un **código de confirmación** que llega al correo del comercio. Sin ese código la operación no se envía. > Estas herramientas se activan bajo solicitud y sólo funcionan para usuarios con credenciales del API bancario de Tilopay. No forman parte del acceso MCP por defecto: Tilopay habilita el grupo caso por caso. Requiere: Credenciales del API bancario de Tilopay registradas por Tilopay para ese usuario. - `baas_send_transfer` - Acceso: Sensible - Operación del API: `POST /api/public/v1/transactions/payments` — https://tilopay.com/developers/api-bancario/pagos Envía una transferencia desde la cuenta bancaria del comercio. Método por defecto: SINPE Móvil (destino por teléfono). Para transferencia a cuenta usa accountType=IBAN. El portal Banca Cliente envía el código de autorización al correo del comercio y aplica sus límites; el comercio responde el código y se confirma con baas_confirm_transfer. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `amount` | number | sí | Monto a transferir | | `currency` | string | sí | Moneda ISO 4217 (CRC, USD) | | `contactName` | string | — | Nombre del contacto guardado (busca su teléfono/IBAN) | | `destinationAccountType` | string (PHONE | IBAN) | — | PHONE = SINPE Móvil (por defecto), IBAN = transferencia a cuenta | | `destinationAccountValue` | string | — | Teléfono E.164 o IBAN del destino (si no se usa contactName) | | `destinationName` | string | — | Nombre del destinatario (si no se valida via contacto) | | `detailReference` | string | — | Descripción del pago (si se omite, se genera una) | | `assignmentId` | string | — | Contexto BaaS (opcional) | | `allowDuplicate` | boolean | — | Solo true cuando el usuario confirmó literalmente que quiere repetir una transferencia idéntica reciente (por ejemplo 'sí, es otra'). Nunca lo pongas por tu cuenta. | **Devuelve** `{ result: { payment, clientReference, detailReference, destinationName, destinationAccount } }` Envía una transferencia desde una cuenta BaaS del comercio: payment = el pago creado con su payment_id y estado; clientReference y detailReference = referencias para conciliar; destinationName y destinationAccount = a quién y a qué cuenta se envió. Valida la cuenta destino antes y exige código de confirmación por correo. --- # Estado de una transferencia > Consulta el estado actual de una transferencia por su payment_id: estado, resultado, monto, moneda, destino y fecha. - kind: mcp-tool - status: stable - access: read - last_verified: 2026-10-07 - url: https://tilopay.com/developers/agentes/mcp/api-bancario/get-transfer-status > Estas herramientas se activan bajo solicitud y sólo funcionan para usuarios con credenciales del API bancario de Tilopay. No forman parte del acceso MCP por defecto: Tilopay habilita el grupo caso por caso. Requiere: Credenciales del API bancario de Tilopay registradas por Tilopay para ese usuario. - `baas_get_transfer_status` - Acceso: Sólo lectura - Operación del API: `GET /api/public/v1/transactions/payments/{payment_id}` — https://tilopay.com/developers/api-bancario/pagos El resultado de una transferencia no se consulta: el banco lo avisa por aquí en cuanto lo tiene (evento del portal). **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `paymentId` | string | — | Identificador del pago (opcional) | **Devuelve** `{ result }` result = estado actual de la transferencia consultada por su payment_id (estado, resultado, monto, moneda, destino y fecha). --- # Otras operaciones > Contextos (assignments), diagnóstico de credenciales, listado de cuentas, saldo de una cuenta, número de cuenta completo, estado de una solicitud de estado de cuenta, autorización y cancelación de la transferencia pendiente, aprobación en doble control y cierre de la sesión bancaria, en una sola página. - kind: mcp-tool - status: stable - access: read - last_verified: 2026-10-07 - url: https://tilopay.com/developers/agentes/mcp/api-bancario/otras-operaciones > Estas herramientas se activan bajo solicitud y sólo funcionan para usuarios con credenciales del API bancario de Tilopay. No forman parte del acceso MCP por defecto: Tilopay habilita el grupo caso por caso. Requiere: Credenciales del API bancario de Tilopay registradas por Tilopay para ese usuario. ### Contextos (assignments) del API BaaS [#baas-list-assignments] - `baas_list_assignments` - Acceso: Sólo lectura Lista los contextos tenant/cuenta (assignments) disponibles para las credenciales BaaS del usuario. Úsalo cuando otra herramienta pida assignmentId. **Parámetros** Sin parámetros. **Devuelve** `{ assignments[] }` assignments = contextos disponibles con assignment_id, tenant_code, owner_type, country_code y status. ### Diagnóstico del API BaaS [#baas-diagnostics] - `baas_diagnostics` - Acceso: Sólo lectura Verifica las credenciales BaaS del usuario, el login, el intercambio de token y el acceso a cuentas. Úsalo cuando una consulta BaaS falle. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `assignmentId` | string | — | Contexto a probar (opcional) | **Devuelve** `{ checks[], failed }` checks = una fila por verificación (credenciales, login + assignments, cuentas) con ok y detalle; failed = cuántas fallaron. El correo de la credencial se devuelve enmascarado. ### Listar cuentas BaaS [#baas-list-accounts] - `baas_list_accounts` - Acceso: Sólo lectura - Operación del API: `GET /api/public/v1/accounts` — https://tilopay.com/developers/api-bancario/cuentas Lista las cuentas accesibles del API BaaS (sin saldos): tipo de identificador, valor y moneda. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `accountType` | string | — | Filtro por esquema (IBAN) | | `accountValue` | string | — | Filtro por identificador | | `limit` | integer | — | — | | `offset` | integer | — | Desplazamiento de paginación | | `assignmentId` | string | — | Contexto BaaS (opcional) | **Devuelve** `{ result }` result = respuesta del API bancario tal cual. ### Saldo de una cuenta BaaS [#baas-get-balance] - `baas_get_balance` - Acceso: Sólo lectura - Operación del API: `GET /api/public/v1/accounts/balance` — https://tilopay.com/developers/api-bancario/cuentas Obtiene el saldo actual de una cuenta BaaS identificada por IBAN. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `currency` | string | — | Moneda de la cuenta (CRC o USD) | | `accountIndex` | integer | — | Número de la cuenta en la lista | | `accountValue` | string | — | Solo si una herramienta ya lo devolvió. No escribe números de cuenta de memoria: indica la moneda (CRC/USD) o el número de la cuenta en la lista; el sistema resuelve el IBAN real. | | `assignmentId` | string | — | Contexto BaaS (opcional) | **Devuelve** `{ result }` result = respuesta del API bancario tal cual. ### Estado de la solicitud de estado de cuenta [#baas-get-statement-status] - `baas_get_statement_status` - Acceso: Sólo lectura - Operación del API: `GET /api/public/v1/accounts/statements/{request_id}` — https://tilopay.com/developers/api-bancario/cuentas Consulta el estado de una solicitud de estado de cuenta BaaS. Cuando está DONE incluye el enlace de descarga firmado y su vencimiento. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `requestId` | string | sí | request_id devuelto al solicitarlo | | `assignmentId` | string | — | Contexto BaaS (opcional) | **Devuelve** `{ result }` result = respuesta del API bancario tal cual. ### Número de cuenta completo del comercio [#baas-get-account-number] - `baas_get_account_number` - Acceso: Sólo lectura Muestra el IBAN COMPLETO de una cuenta propia del comercio. Úsala SOLO cuando el comercio pide explícitamente tu número de cuenta (por ejemplo para dárselo a un cliente o proveedor) y con confirm=true. Queda registrada en la auditoría. En cualquier otra respuesta se usa el número enmascarado. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `confirm` | boolean | sí | true solo si el comercio pidió explícitamente tu número de cuenta completo | | `currency` | string | — | Moneda de la cuenta (CRC o USD) | | `accountIndex` | integer | — | Número de la cuenta en la lista | | `assignmentId` | string | — | Contexto BaaS (opcional) | **Devuelve** ### Autorizar la transferencia pendiente [#baas-confirm-transfer] - `baas_confirm_transfer` - Acceso: Sensible Autoriza la transferencia pendiente con el código de 6 dígitos que llegó AL CORREO DEL COMERCIO y fue respondido en el chat. Nunca escribas ni repitas el código en la respuesta. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `code` | string | sí | Código de 6 dígitos que respondió el comercio | | `intentId` | string | — | Identificador de la intención (si se omite, se usa la pendiente) | **Devuelve** ### Cancelar la transferencia pendiente [#baas-cancel-transfer] - `baas_cancel_transfer` - Acceso: Escritura Cancela la transferencia que está esperando el código de autorización. Úsala cuando el comercio diga que no la quiere hacer. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `intentId` | string | — | Identificador de la intención (opcional) | **Devuelve** ### Aprobar o rechazar una operación pendiente [#banca-decide-approval] - `banca_decide_approval` - Acceso: Sensible Aprueba o rechaza una transferencia que quedó en doble control, con el código de 6 dígitos que llegó AL CORREO DEL APROBADOR. Nunca escribas el código en la respuesta. **Parámetros** | Parámetro | Tipo | Obligatorio | Descripción | | --- | --- | --- | --- | | `decision` | string (aprobar | rechazar) | sí | Decisión del aprobador | | `code` | string | sí | Código de 6 dígitos del correo del aprobador | | `approvalId` | string | — | Identificador de la aprobación (si se omite, se usa la pendiente) | | `reason` | string | — | Motivo del rechazo (opcional) | **Devuelve** ### Cerrar sesión bancaria [#baas-close-session] - `baas_close_session` - Acceso: Escritura Cierra de inmediato la sesión bancaria activa del asistente de WhatsApp. **Parámetros** Sin parámetros. **Devuelve** --- # Documentación legible por máquina > Los artefactos que el portal publica para agentes: llms.txt, Markdown crudo en cualquier URL, openapi.json y mcp.json. - kind: guide - status: stable - last_verified: 2026-08-29 - url: https://tilopay.com/developers/agentes/documentacion-legible ## Índices para modelos [#llms] - [tilopay.com/llms.txt](https://tilopay.com/llms.txt) — índice del sitio en español, con la URL y una descripción de cada página. - [tilopay.com/llms-full.txt](https://tilopay.com/llms-full.txt) — el mismo índice con el contenido completo. - [tilopay.com/en/llms.txt](https://tilopay.com/en/llms.txt) y [tilopay.com/en/llms-full.txt](https://tilopay.com/en/llms-full.txt) — las versiones en inglés, con las URLs `/en`. ## Markdown crudo [#markdown] Cualquier URL del sitio devuelve su Markdown agregándole `.md`: por ejemplo [tilopay.com/developers/sdk/instalacion.md](https://tilopay.com/developers/sdk/instalacion.md) o [tilopay.com/tarifas.md](https://tilopay.com/tarifas.md). Se sirve como `text/markdown`, con un encabezado de metadatos (tipo de página, estado, versión y fecha de última verificación). Una URL que no existe devuelve 404, no HTML. ## Spec del API [#openapi] - [`openapi.json`](/developers/openapi.json) — spec OpenAPI 3.1 del API de Tilopay: endpoints, parámetros, respuestas y ejemplos. Es la fuente de verdad del API. - [`openapi.yaml`](/developers/openapi.yaml) — el mismo contenido en YAML. Las dos rutas responden con `Access-Control-Allow-Origin: *`, así que se pueden leer desde el navegador. ## Catálogo del MCP [#mcp-json] [`mcp.json`](/developers/mcp.json) describe el servidor MCP: su URL, el modelo de acceso y el catálogo completo de herramientas con parámetros, salida y nivel de acceso. Cuando la herramienta envuelve una operación del API, la entrada incluye ese endpoint. El campo `verified_at` en la raíz trae la fecha (`YYYY-MM-DD`) en que el catálogo se comparó con el servidor. La versión del servidor no cambia cuando se agregan herramientas, así que ésa es la señal que conviene mirar para saber si una copia en caché quedó vieja. ---