# Documentación de QuickPay

Todas las guías de https://docs.pagaconquickpay.com en un solo archivo, en el orden del sitio. Cada página empieza con su título (`#`) y su
dirección. La referencia técnica de la API (OpenAPI) está en https://docs.pagaconquickpay.com/docs.

---

<!-- Sección: Entender QuickPay -->

<!-- https://docs.pagaconquickpay.com/developers/que-es -->

# Qué es QuickPay y cómo llega el dinero

Con QuickPay cobras en bolívares a cualquier persona con cuenta en un banco venezolano. Tu cliente abre un enlace, elige su banco, escribe su teléfono y su cédula, y confirma con la **clave de 8 dígitos que le envía su banco** (por SMS, notificación o correo). No se registra ni instala nada.

| Lo que pasa | Quién lo hace |
|---|---|
| Creas el cobro (un enlace, un QR o un botón) | Tú, desde el portal o desde tu sistema |
| Abre el enlace y paga con la clave de su banco | Tu cliente |
| Confirma el pago con el banco | QuickPay |
| Te avisa (en el portal y, si integraste, por webhook) | QuickPay |
| Te transfiere el dinero a tu cuenta | QuickPay |

## Un pago ocurre en dos momentos

1. **El pago.** El banco confirma el débito y el cobro queda **pagado**. Desde tu sistema te llega el webhook `link.pagado`.
2. **La acreditación.** QuickPay te transfiere el monto, menos la comisión, a tu cuenta. Con la liquidación inmediata (activándose por etapas) te llega además el webhook `link.acreditado` con el desglose.

> **Entrega cuando el cobro esté pagado, no antes.** Que el cliente vuelva a tu web o te mande una captura no prueba nada: la prueba es el estado `pagado` (webhook o consulta).

## Dos formas de usarlo

- **Desde el portal:** sin programar. Creas cobros, los mandas por WhatsApp o correo, haces cobranza masiva y suscripciones. → [El portal de comercios](https://docs.pagaconquickpay.com/developers/portal)
- **Desde tu sistema:** lo integras con la API en tu web, tu app o tu bot. → [Cómo se integra](https://docs.pagaconquickpay.com/developers/como-se-integra)

¿No sabes cuál? → [¿Cuál solución necesito?](https://docs.pagaconquickpay.com/developers/cual-solucion)

<!-- https://docs.pagaconquickpay.com/developers/cual-solucion -->

# ¿Cuál solución necesito?

Elegir mal no rompe nada, pero trabajas de más. Ubícate en la primera tabla que te describa.

## Si no programas

| Si… | Usa… | Dónde |
|---|---|---|
| Cobras un monto puntual a una persona | Un cobro con monto (enlace + QR, o por WhatsApp) | [Cobrar](https://docs.pagaconquickpay.com/developers/cobrar-desde-el-portal) |
| Quieres que te paguen el monto que ellos escriban | Tu página de pago `/p/tu-usuario` | [Página de pago](https://docs.pagaconquickpay.com/developers/pagina-de-pago) |
| Cobras a muchos clientes a la vez (condominio, colegio, cartera) | Cobranza masiva desde un Excel | [Clientes y cobranza](https://docs.pagaconquickpay.com/developers/clientes-y-cobranza) |
| Cobras lo mismo cada mes, semana o año | Suscripciones | [Suscripciones](https://docs.pagaconquickpay.com/developers/suscripciones) |
| Tienes una web y quieres un botón "Pagar" | El botón de tu portal (copiar y pegar) | [Botón para tu web](https://docs.pagaconquickpay.com/developers/boton-de-pago) |

## Si programas

| Si… | Usa… | Guía |
|---|---|---|
| Tu web, app o bot crea un cobro por pedido | Un enlace de pago por pedido + webhook | [Enlaces de pago](https://docs.pagaconquickpay.com/developers/enlaces-de-pago) |
| Generas cobros en bloque desde tu sistema | Cobro por lote (hasta 500 por llamada) | [Cobro por lote](https://docs.pagaconquickpay.com/developers/cobro-por-lote) |
| Tu bot de WhatsApp cobra | Enlace en un mensaje con botón + webhook | [Cobrar desde tu bot](https://docs.pagaconquickpay.com/developers/integracion-para-bots) |
| Quieres pedir la clave del banco desde tu propia pantalla | API directa (sólo aliados) | [API directa](https://docs.pagaconquickpay.com/developers/api-directa) |

> **Lo más simple casi siempre gana.** Si dudas entre el portal y la API, empieza por el portal: puedes pasar a la API después sin cambiar nada de tu cuenta.

<!-- https://docs.pagaconquickpay.com/developers/modelo-mental -->

# Cómo funciona un cobro

Todo en QuickPay es un **cobro**: un monto, un concepto y una fecha de vencimiento. Cada cobro tiene un **enlace** (`https://pay.pagaconquickpay.com/l/…`) donde tu cliente paga.

## De principio a fin

1. **Creas el cobro.** Desde el portal o con `POST /switch/v1/links`. Te devolvemos su `id` y su `url`.
2. **Se lo haces llegar.** Por WhatsApp, correo, QR, un botón en tu web o tu bot.
3. **Tu cliente paga.** Elige su banco, escribe su teléfono y su cédula, recibe la clave de 8 dígitos de su banco y la escribe.
4. **Se confirma con el banco.** El cobro pasa a `pagado`. Un cobro se paga **una sola vez**: nadie puede pagarlo dos veces.
5. **Te enteras.** En el portal (Transacciones y el aviso "Recibiste…") y, si integraste, con el webhook `link.pagado`.
6. **Te acreditamos.** El monto, menos la comisión, a tu cuenta. Con la liquidación inmediata (activándose por etapas) llega también `link.acreditado`.

## Lo que conviene saber

- **El monto lo fijas tú.** El cliente no lo puede cambiar (salvo en tu página de pago, donde él lo escribe).
- **Vence.** Por omisión a las 24 horas; tú eliges entre 1 hora y 30 días. Un cobro vencido ya no se puede pagar.
- **Prueba y producción no se mezclan.** Un cobro creado con tu llave de prueba nunca mueve dinero, aunque lo abra alguien de verdad. → [Modo prueba](https://docs.pagaconquickpay.com/developers/datos-de-prueba)
- **Tus datos viajan con el cobro.** Lo que pongas en `metadata` (tu número de pedido, por ejemplo) vuelve en las consultas.

Siguiente: [Estados de un cobro](https://docs.pagaconquickpay.com/developers/ciclo-de-vida)

<!-- https://docs.pagaconquickpay.com/developers/ciclo-de-vida -->

# Estados de un cobro

Un cobro siempre está en uno de estos estados. Los consultas con `GET /switch/v1/links/:id` (campo `estado`).

| Estado | Qué significa | ¿Entregas? |
|---|---|---|
| `pendiente` | Creado, nadie lo ha pagado | No |
| `cobrando` | Un cliente está pagando en este momento | Todavía no |
| `procesando` | El banco recibió el débito y todavía no confirma que el dinero se movió | Todavía no: espera |
| `revision` | Lo estamos verificando con el banco | Todavía no: espera |
| `pagado` | El banco confirmó el pago: el dinero es tuyo | **Sí** |
| `expirado` | Venció sin pagarse | No |
| `cancelado` | Lo cancelaste antes de que lo pagaran | No |

## Cómo se mueve

```
pendiente → cobrando → pagado
                    ↘ procesando / revision → pagado
pendiente → expirado | cancelado
```

- Según el banco de tu cliente, la confirmación puede llegar en el acto (el cobro pasa directo a `pagado`) o el cobro pasa por `procesando` hasta que el banco confirma (suele tardar menos de un minuto, pero a veces bastante más) y entonces queda `pagado` y te llega `link.pagado`.
- Si el banco **rechaza** el pago (clave equivocada, sin saldo), el cobro vuelve a `pendiente` y el cliente puede intentarlo otra vez con una clave nueva. También puede volver a `pendiente` desde `procesando`, si el banco termina rechazándolo.
- `procesando` y `revision` **no son rechazos**: el pago puede terminar aprobado. Nunca le cobres de nuevo a un cliente con un cobro en esos estados.
- `pagado`, `expirado` y `cancelado` son finales: no cambian más.

> **Una regla:** entrega sólo con `pagado`. Todo lo demás es "todavía no".

<!-- https://docs.pagaconquickpay.com/developers/comisiones-y-liquidacion -->

# Comisión y liquidación

## Cuánto cuesta

Cada pago recibido paga una comisión, que se descuenta del pago: tu cliente paga el monto exacto del cobro y a ti te llega el monto menos la comisión. Tu tarifa te la confirmamos al abrir tu cuenta.

## Cuándo llega el dinero

La **liquidación inmediata** te transfiere el neto de cada pago apenas el banco lo confirma. La estamos **activando por etapas**: hoy se aplica a pagos pequeños mientras terminamos las pruebas con dinero real; te avisaremos cuando cubra todos tus cobros. Por cada pago liquidado te llega el webhook `link.acreditado` con el desglose:

| Campo | Qué es |
|---|---|
| `monto_bruto` | Lo que pagó tu cliente |
| `comision` | La comisión descontada |
| `monto_acreditado` | Lo que llegó a tu cuenta |
| `liquidacion_txn_id` | El id de la transferencia |

El neto irá a tu cuenta principal. Si registraste varias cuentas, al cobrar **desde el portal** puedes elegir en cuál cae cada cobro; por la API va siempre a la principal.

> **Las cuentas deben estar a tu nombre.** A nombre de tu cédula si te registraste como persona, o del RIF de tu empresa si te registraste como negocio. Así lo verificamos con un pago de Bs 1 al registrarte.

---

<!-- Sección: Desde el portal -->

<!-- https://docs.pagaconquickpay.com/developers/portal -->

# El portal de comercios

Todo lo que necesitas para cobrar, sin programar. Entras con tu usuario o correo y tu contraseña.

## Cómo se abre la cuenta

1. Eliges **Para mí** (con tu cédula) o **Para mi negocio** (con el RIF de tu empresa).
2. Confirmas tu correo con un código.
3. Subes la foto o el PDF de tu cédula o tu RIF: llenamos tus datos por ti y tú los confirmas.
4. Si abres la cuenta **para tu negocio**, nos dices a qué se dedica: colegios y universidades, condominios, gimnasios y clubes, proveedores de internet, restaurantes y comida, sector salud, tiendas y emprendimientos, veterinarias y mascotas, u otro. Este paso no aparece en las cuentas **para ti**.
5. Registras la cuenta donde quieres recibir el dinero. La verificamos enviándote **Bs 1**: así comprobamos que está a tu nombre.
6. Creas tu usuario y tu contraseña.

Al terminar, tu cuenta queda **aprobada para cobrar dinero real**: la verificación con Bs 1 es la que la habilita. El equipo de QuickPay revisa cada alta después; si algo no cuadra, te escribimos.

> **De 11:45 p. m. a 1:30 a. m. (hora de Venezuela)** los bancos hacen su mantenimiento diario: la verificación con Bs 1 espera a la 1:30 a. m. y no gastas intentos. En esa franja tampoco se pueden hacer pagos: tu portal, tu página de pago y tus enlaces lo avisan desde las 11:30 p. m. Puedes crear y enviar cobros a cualquier hora; tu cliente los paga a partir de la 1:30 a. m.

> **La cuenta debe estar a tu nombre.** Si la cédula o el RIF no coinciden con el titular, el banco rechaza la verificación.

## Qué haces en el portal

| Sección | Para qué |
|---|---|
| Inicio | Lo cobrado hoy y en el mes, lo que ya llegó a tu banco y tus últimos movimientos, en la [divisa de tu panel](#divisa-del-panel) |
| Cobrar | Crear un cobro con monto, tu página de pago o dividir una cuenta |
| Transacciones | Todos tus cobros: filtrar por fecha, estado y más, buscar, ver detalle, cancelar o reenviar uno pendiente, y descargarlos en Excel o CSV → [Filtrar tus transacciones](#filtrar-tus-transacciones) |
| Clientes | Tu base de clientes, a mano o desde Excel, con búsqueda y filtros, segmentos automáticos, etiquetas, estado de pago y acciones en grupo → [Clientes y cobranza](https://docs.pagaconquickpay.com/developers/clientes-y-cobranza). En condominios se llama **Propietarios e inquilinos** |
| Cobranza masiva | Enviar el cobro a muchos clientes, ahora o programado |
| Suscripciones | Planes de cobro recurrente y sus suscriptores, en tres pestañas: **Suscriptores**, **Planes** y **Métricas**, con un resumen arriba (activas, al día, atrasadas, cobrado este mes) → [Suscripciones](https://docs.pagaconquickpay.com/developers/suscripciones). No aparece en restaurantes, que no tienen cobros recurrentes |
| Productos | Tu catálogo: cobras eligiendo el producto (en restaurantes se llama **Menú y productos**; gimnasios, condominios y colegios no lo usan) |
| Sucursales | Restaurantes, gimnasios, sector salud, veterinarias y tiendas: tus locales, para etiquetar cada cobro, elegir a qué cuenta caen sus pagos y filtrar Transacciones |
| Propinas | Restaurantes: activar la pregunta de propina al pagar, sus botones y ver las propinas recibidas → [Propinas](https://docs.pagaconquickpay.com/developers/propinas) |
| Urbanizaciones y complejos | Condominios: cada urbanización o complejo con sus propietarios e inquilinos |
| Integraciones | Botón para tu web, llaves de API y webhooks |
| Ajustes | Tus datos, tu plan, tus cuentas de cobro, tu equipo, la divisa del panel y tus avisos |

**Nombre comercial.** Si tu negocio se conoce con un nombre distinto a su razón social (p. ej. razón social *Inversiones Ejemplo 2023, C.A.* y nombre comercial *Pizzería Ejemplo*), escríbelo al registrarte o en **Ajustes › Tu cuenta** (opcional, hasta 100 caracteres). Quien te paga ve ese nombre en la página de pago ("Estás pagando a…") y en el comprobante del pago. Tu razón social no cambia: es la que usan el banco y la verificación de tu cuenta. Si lo borras, vuelve a mostrarse la razón social.

El portal se adapta al **tipo de negocio** que elegiste al registrarte: el menú y los filtros cambian, pero los cobros, la cobranza masiva y las notificaciones funcionan igual para todos. Si elegiste "Otro", ves el menú estándar.

Cuando entra un pago, el portal te lo muestra al momento: "Recibiste US$ X (Bs Y) de Z", en la divisa de tu panel. Además te enviamos un correo por cada pago.

## Cuentas personales

Si abriste la cuenta con **Para mí**, el portal es más corto, porque una persona recibe pagos pero no administra un negocio. El menú tiene cinco secciones:

| Sección | Para qué |
|---|---|
| Inicio | Lo cobrado hoy y en el mes, lo que ya llegó a tu banco y tus últimos movimientos |
| Cobrar | **Pedir un monto** (enlace o QR para un pago puntual), **Mi enlace** (quien te paga escribe el monto) y **Dividir una cuenta** |
| Movimientos | Cada pago con su referencia del banco: filtrar, buscar, ver detalle y descargarlo. Es la misma pantalla que **Transacciones** en un negocio |
| Contactos | Las personas que te han pagado y eligieron guardar sus datos, y las que agregas tú. Es la misma pantalla que **Clientes** en un negocio, sin carga masiva |
| Ajustes | Tus datos, tu plan, tus cuentas de cobro, la divisa del panel y tus avisos |

Una cuenta personal no tiene Cobranza masiva, Suscripciones, Productos, Sucursales, Integraciones ni Equipo: esas pantallas no aparecen, si abres su dirección vuelves a Inicio y las funciones equivalentes de la API responden `403`. La página de pago de una persona muestra sus iniciales en lugar del ícono de tienda, y en ella quien te paga ve la casilla **"Guardar mis datos para pagarle más rápido a *tu nombre*."** (sin nombre obligatorio). Quien la marca aparece en **Contactos** cuando el pago queda confirmado; esa casilla no es permiso para enviarle novedades.

El estado de tu cuenta se dice igual en Inicio, Cobrar y Ajustes: **cuenta de demostración** (los pagos son simulados), **en revisión** (tus cobros son de prueba hasta que te aprobemos; pasa sólo si la aprobación automática no se pudo completar) o, cuando puedes cobrar, sin aviso. En Inicio, lo cobrado hoy y en el mes suma sólo pagos reales y debajo dice cuántos de prueba quedaron fuera; en una **cuenta de demostración** (todos sus pagos son simulados) los suma, para que se vea cómo luce un negocio cobrando.

## Divisa del panel

En **Ajustes › Divisa del panel** eliges en qué moneda ves tus montos: **dólares (US$)**, que es la que viene por omisión, **euros (€)** o **bolívares (Bs)**. Sólo el Propietario y los Administradores la cambian; el Cobrador ve los montos en esa divisa.

Con dólares o euros, cada monto sale **grande en esa divisa** y, **debajo y pequeño, lo que fue en bolívares**; al lado sigue la cantidad de pagos. Aplica en Inicio (cobrado hoy, este mes, ya en tu banco y lo que está llegando), Últimos movimientos, Transacciones (la lista, el detalle y los totales de lo filtrado), Propinas, el total de cada lote de Cobranza masiva y el aviso de pago recibido. Los planes y productos siguen en la moneda en que fijaste su precio, y el monto que escribes al cobrar (Cobrar, Dividir cuenta, Nueva cobranza) arranca siempre en bolívares (puedes cambiarlo en cada cobro); al crear un producto o un plan, el precio arranca en tu divisa.

**Con qué tasa se convierte.** Cada pago usa la tasa BCV del **día en que se pagó** (día de Venezuela), no la de hoy:

- Si el cobro se creó en esa misma divisa, se usa el monto y la tasa exactos con que se creó.
- Dólares: la última tasa BCV publicada hasta el día del pago (un sábado usa la del viernes).
- Euros: la tasa oficial del euro que guardamos cada día. Si no tenemos la de ese día (pagos anteriores a que empezáramos a guardarla), se usa la más cercana anterior o, en su defecto, la de hoy, y el monto aparece con **≈**.

Los totales suman cada pago ya convertido y se redondean al final; los bolívares de abajo son la suma real en bolívares. Es sólo cómo se muestra: los cobros y lo que llega a tu banco siguen siendo en bolívares.

## Avisos por correo

Cada vez que te pagan, te llega un correo "Recibiste un pago" con el monto, el concepto, la fecha y un enlace a la transacción. Les llega al Propietario y a los Administradores, una sola vez por cobro. Viene encendido; lo apagas en **Ajustes › Avisos**.

## Tu plan

En **Ajustes › Tu plan** ves tu plan, hasta cuándo está pagado, cuántos cobros por WhatsApp enviaste en los últimos 30 días y cuántos te quedan, y los planes disponibles con sus límites. Los cobros por correo no tienen límite. Esta sección la ven el Propietario y los Administradores.

| Plan | Precio | Cobros por WhatsApp |
|---|---|---|
| Gratis | US$ 0 | 20 al mes, hasta 5 por día uno a uno |
| Emprendedor | US$ 3 cada 30 días | 150 al mes, hasta 30 por día uno a uno |
| Negocio | US$ 12 cada 30 días | 600 al mes, hasta 100 por día uno a uno |

**Cambiar de plan:** tocas **Cambiar a …**, ves el monto en US$ y su equivalente en bolívares a la tasa BCV de ese momento, y al continuar se abre el pago de QuickPay en otra pestaña. La tarjeta queda en **Esperando tu pago…** y, cuando el pago se confirma, el plan se activa solo y te llega un correo. Si el pago en línea no está disponible en ese momento, el botón abre el WhatsApp de QuickPay con el mensaje listo.

- Cada pago te da **30 días** del plan y se paga en bolívares a la tasa BCV del momento en que se crea el enlace.
- **Renovar** antes de que venza suma los 30 días al final de tu período.
- **Subir** de plan: empiezas 30 días nuevos desde el pago y los días que te quedaban del plan anterior se suman, convertidos al precio del nuevo (por ejemplo, 20 días de Emprendedor equivalen a 5 días de Negocio).
- **Bajar** de plan: el cambio se aplica cuando termina el período que ya pagaste. No se devuelve dinero. Puedes cancelarlo antes de esa fecha.
- Te avisamos por correo 3 días antes de que venza, el día que vence y el día siguiente, con el enlace para pagar.
- Si no renuevas, tienes **3 días de gracia**; después vuelves al plan Gratis y te avisamos. Los cobros que ya enviaste no se cortan: el cupo sólo se revisa al enviar un cobro nuevo.

## Filtrar tus transacciones

Arriba de la lista siempre ves tres controles: **Fecha**, **Estado** y **Buscar**. El botón **Filtros** abre el resto.

| Filtro | Qué hace |
|---|---|
| Fecha | Hoy, Ayer, Últimos 7 días, Este mes, Mes pasado o **Rango personalizado** (desde–hasta, ambos días incluidos). Los días son de Venezuela: un pago de las 9:00 p. m. entra en ese día. Un cobro cuenta en la fecha en que se pagó; si aún no se paga, en la que se creó |
| Estado | Pagado (en tu banco), Pendiente, Procesando, En revisión, Vencido o Cancelado |
| Buscar | Por concepto, nombre del cliente, referencia del pago o del crédito a tu cuenta, o el identificador del cobro (el final de su enlace) |
| Sucursal | En los tipos de negocio con sucursales. En condominios, urbanización o complejo y propietario o inquilino; en colegios, grado y sección |
| Cuenta donde cae el dinero | Sólo si tienes más de una cuenta de cobro |
| Monto | Mínimo y máximo del cobro, en Bs |
| Propina | Con o sin propina (restaurantes) |
| Cómo se creó | Creado en el portal, página de pago, botón de pago, WhatsApp, API, cobranza masiva o suscripción |
| Etiqueta del cliente | Sólo los cobros enviados a personas con esa [etiqueta](https://docs.pagaconquickpay.com/developers/clientes-y-cobranza#etiquetas). El cobro del switch no trae al cliente, así que se cruza con lo que guardamos al enviarlo: Cobranza masiva, Suscripciones y quienes se registraron al pagar. **Un cobro suelto** (el de Cobrar, o un pago en tu página sin que la persona se registre) **no tiene un cliente asociado y no aparece** con este filtro |
| Modo | Cobros reales o de prueba |
| Pagos rechazados | **Con rechazos:** cobros con al menos un intento de pago rechazado. **Sin rechazos:** los que no tienen ninguno |

Un rechazo no cambia el estado del cobro: vuelve a quedar **Pendiente** y tu cliente puede intentarlo de nuevo; si después paga, sale como pagado y el filtro lo sigue encontrando. Al abrir un cobro con intentos rechazados ves cuántos fueron (por ejemplo **2 intentos rechazados**). Sólo cuentan los intentos en los que tu cliente llegó a escribir la clave de pago de su banco.

Los filtros activos aparecen como etiquetas que quitas con la **x**, y **Limpiar filtros** los quita todos. Quedan en la dirección de la página: puedes recargarla o compartirla y verás lo mismo. Debajo de los filtros ves cuántos cobros salieron, lo **cobrado** (suma de los pagados, sin contar los de prueba; en una cuenta de demostración, que sólo tiene pagos simulados, sí los cuenta) y, en restaurantes, las **propinas**, en la [divisa de tu panel](#divisa-del-panel) y con los bolívares al lado. La lista carga de 50 en 50 con **Ver más**.

Los filtros y los totales cuentan todos tus cobros, en cualquier divisa del panel. En dólares o euros, cada pago se convierte con la tasa BCV de su día de pago, y un cobro que creaste en esa misma divisa cuenta con su monto exacto. Los cobros de suscripción enviados antes del 9 de octubre de 2026 aparecen como cobranza masiva.

## Descargar tus transacciones

En **Transacciones › Descargar** bajas en Excel o CSV **exactamente lo que estás viendo**, con los mismos filtros, y con las fechas en hora de Venezuela. Incluye hasta 5.000 cobros de lo filtrado (los más recientes); si hay más, la pantalla te avisa: acota las fechas para bajar el resto. Las columnas en bolívares (para tu contabilidad) se mantienen; si tu divisa es dólares o euros, se agregan al lado las columnas **Monto**, **Propina** y **Acreditado** en esa divisa, la **Tasa BCV usada** de cada pago y **Tasa aproximada** (Sí cuando no era la tasa exacta de ese día).

<!-- https://docs.pagaconquickpay.com/developers/cobrar-desde-el-portal -->

# Cobrar: enlace, QR y WhatsApp

En **Cobrar › Cobro con monto**:

1. Escribe el monto en **bolívares (Bs), dólares (US$) o euros (€)**; el selector arranca en **bolívares** y puedes cambiarlo en cada cobro. En dólares o euros se convierte a bolívares a la tasa BCV del momento y debajo del monto ves la equivalencia (por ejemplo, «≈ Bs 9.806,15 a tasa BCV del 09/10»): tu cliente siempre paga en bolívares. El dólar usa la tasa BCV de QuickPay; el euro, la tasa oficial del euro, con máximo 36 horas de antigüedad. Si en ese momento no tenemos una tasa del euro confiable, la opción **€** aparece deshabilitada («Tasa del euro no disponible ahora») y no se puede cobrar en euros hasta que haya.
2. Si quieres, agrega un concepto (lo ve tu cliente) o elige productos de tu catálogo.
3. Elige cuándo vence: 1 hora, 24 horas, 3 días, 7 días o 30 días.
4. Si tienes sucursales, elige la sucursal. Si tienes más de una cuenta, en **¿Dónde recibes este pago?** ves la cuenta (banco y teléfono, con parte del número oculto): viene la de la sucursal, o la principal, y la puedes cambiar. Si la cambias, la recordamos para esa sucursal en ese navegador.
5. Pulsa **Crear cobro**.

Te damos el enlace y su **QR** (puedes descargarlo para imprimirlo). Compártelo como quieras.

## Por WhatsApp desde QuickPay

Con **Cobrar por WhatsApp**, le llega a tu cliente un mensaje de QuickPay con tu nombre, el monto y un botón **Pagar** que abre el pago dentro de WhatsApp, sin salir de la conversación.

- Pides el nombre y el WhatsApp sólo después de crear el cobro.
- Las personas a las que ya les cobraste aparecen en **Cobrar de nuevo**: tocas a la persona, pones el monto y el envío sale ya lleno.
- Cada plan incluye un cupo de cobros por WhatsApp (cuenta los de los últimos 30 días). Lo ves en **Ajustes › Tu plan**.

## Dividir una cuenta

En **Cobrar › Dividir cuenta** repartes un total entre varias personas: cada una recibe su propio cobro y en Transacciones los ves juntos. El total lo puedes poner en **Bs, US$ o €**, igual que en un cobro con monto: cada parte se convierte a bolívares a la tasa BCV del momento y ves lo que paga cada persona. Debajo del total aparece su equivalente en bolívares («Total ≈ Bs …») y, junto a cada persona, el de su parte.

## Después

En **Transacciones** ves cada cobro con su estado y lo filtras por fecha, estado, monto y más ([Filtrar tus transacciones](https://docs.pagaconquickpay.com/developers/portal#filtrar-tus-transacciones)). Mientras esté pendiente puedes reenviarlo o cancelarlo.

<!-- https://docs.pagaconquickpay.com/developers/pagina-de-pago -->

# Tu página de pago

Es una dirección fija con tu usuario: `https://portal.pagaconquickpay.com/p/tu-usuario`. Quien la abre escribe el monto y te paga desde cualquier banco. Sirve para:

- Ponerla en tu perfil de Instagram o tu firma de correo.
- Imprimir su QR en el mostrador: cada cliente paga lo que le toca.

La encuentras en **Inicio** y en **Cobrar › Tu página de pago**, lista para copiar o compartir por WhatsApp.

## Bs, US$ o €

Junto al monto, quien paga escoge en qué moneda lo escribe: **Bs**, **US$** o **€**. Si no es Bs, debajo ve la equivalencia, por ejemplo "≈ Bs 1.250,00 a tasa BCV del 09/10". El pago siempre se debita en bolívares, a la tasa BCV del momento en que pulsa **Continuar al pago**; la conversión la hace QuickPay, no el navegador. Si no hay tasa disponible (sobre todo la del euro), esa moneda queda deshabilitada y, si se intenta igual, no se crea el cobro. Con el monto ya puesto en la dirección (abajo) el monto es en Bs y no se puede cambiar.

## Con el monto ya puesto

Puedes agregar el monto y el concepto a la dirección para que el cliente sólo confirme:

```
https://portal.pagaconquickpay.com/p/tu-usuario?monto=150&concepto=Pedido%201024
```

Así funciona también el [botón para tu web](https://docs.pagaconquickpay.com/developers/boton-de-pago).

## Un QR por sucursal o por cuenta

En **Cobrar › Tu página de pago** puedes elegir una **sucursal** y, si tienes más de una cuenta, la **cuenta**. La dirección y el QR cambian: los pagos que entren por ahí quedan en esa sucursal y caen en esa cuenta (o en la de la sucursal). Imprime un QR por local.

```
https://portal.pagaconquickpay.com/p/tu-usuario?sucursal=3
```

El enlace sigue funcionando aunque después archives esa sucursal o quites esa cuenta: lo que ya no exista se ignora y el pago cae en la cuenta que corresponda o, si no, en la principal.

Si activaste [propinas](https://docs.pagaconquickpay.com/developers/propinas), tu cliente puede agregar una antes de pagar.

<!-- https://docs.pagaconquickpay.com/developers/clientes-y-cobranza -->

# Clientes y cobranza masiva

## Tu base de clientes

En **Clientes** guardas a quién le cobras: nombre, WhatsApp o correo (al menos uno), cédula o RIF y una **referencia** (número de contrato, apartamento, socio).

También llegan solos: quien te paga con un enlace y marca **"Quiero ser cliente de *tu comercio* y recibir sus novedades"** aparece aquí cuando el pago queda confirmado, con la etiqueta **Se registró al pagar** y **Acepta novedades**. Usa el filtro **Aceptan novedades** para ver sólo a quienes lo pidieron. En una cuenta en modo prueba, el filtro también muestra a quienes marcaron la casilla con un enlace de prueba, con la etiqueta **Aceptó novedades (prueba)**: se ven para que pruebes el filtro, pero nunca reciben novedades. → [Quiero ser cliente](https://docs.pagaconquickpay.com/developers/enlaces-de-pago#quiero-ser-cliente)

En condominios esta sección se llama **Propietarios e inquilinos**: cada persona se guarda dentro de una urbanización o complejo, con su tipo (propietario o inquilino) y su unidad (apartamento o casa). En colegios puedes anotar el **grado y sección**; en restaurantes, gimnasios, salud, veterinarias y tiendas, la **sucursal**.

### Buscar, filtrar y descargar

La lista de **Clientes** se carga de **50 en 50**: al final pulsas **Ver más**, y el pie dice cuántos hay en total ("Mostrando 50 de 2.500"). Nada se queda fuera por ser muchos: el total es siempre el de lo que coincide con tu búsqueda y tus filtros.

Arriba tienes la **búsqueda** (por nombre, teléfono, correo, cédula o referencia), un selector de **segmento**, uno de **etiqueta** y el botón **Filtros**, que abre una ventana con el resto. Lo que filtras aparece como etiquetas que quitas con la **x**; **Limpiar filtros** las quita todas. Los filtros quedan en la dirección de la página: puedes recargarla o compartirla y verás lo mismo.

| Filtro | Qué muestra |
|---|---|
| Etiquetas | Quienes tengan **cualquiera** de las etiquetas que marques |
| Tiene suscripción / De qué plan | Quienes tienen una suscripción activa o pausada (en cualquier plan o en uno en particular), o ninguna. Las canceladas y las terminadas no cuentan |
| Estado de pago | Al día, pendiente o atrasado, según el último cobro que se le envió ([cómo se calcula](#estado-de-pago-ultimo-pago-y-total-pagado)) |
| Fecha del último pago | Un rango de días de Venezuela, ambos incluidos |
| Total pagado | Mínimo y máximo, en bolívares o en la divisa de tu panel. Quien nunca ha pagado cuenta como 0 |
| Cómo llegó | **A mano**, **Carga masiva** o **Se registró al pagar**. Lo que cargaste antes de que existiera esta distinción aparece como "A mano" |
| Aceptan novedades | Sólo quienes lo pidieron al pagar |
| WhatsApp / Correo | Con o sin ese dato |
| Fecha de alta | Cuándo se agregó a tu lista (días de Venezuela, ambos incluidos) |
| Los de tu tipo de negocio | Urbanización o complejo y propietario o inquilino (condominios), sucursal, grado y sección |

**Descargar** baja en Excel (.xlsx) o CSV **exactamente lo que estás viendo**, con los mismos filtros: contacto, cédula, referencia, etiquetas, suscripciones activas, de dónde llegó, si acepta novedades, fecha de alta y, si tienes los pagos al día, su estado de pago, último pago, cantidad de pagos y total pagado en bolívares (y en tu divisa). Incluye hasta 20.000 clientes; si hay más, la pantalla te avisa para que afines el filtro.

### Segmentos automáticos

Son listas que se arman solas, sin que etiquetes a nadie. Los eliges en el selector de segmento:

| Segmento | Quiénes son |
|---|---|
| **Morosos** | Su último cobro enviado ya venció y no lo pagaron |
| **Nuevos (30 días)** | Se agregaron en los últimos 30 días |
| **Frecuentes** | 3 pagos o más en los últimos 90 días |
| **Aceptan novedades** | Marcaron "quiero recibir novedades" al pagar |
| **Sin pagar hace 60 días** | Llevan más de 60 días en tu lista y no han pagado en ese tiempo (incluye a quien nunca pagó) |

### Etiquetas

Una **etiqueta** es una marca libre, con color, que le pones a tus clientes: VIP, moroso, referido, el grupo que quieras. Se crean en **Clientes › Etiquetas** (hasta 100, con nombre de hasta 40 letras y 8 colores; "VIP" y "vip" son la misma). Una persona puede tener varias.

- **Poner o quitar a uno o a muchos:** marca las casillas de la lista (o elige a todos los que coinciden con tu filtro) y usa **Etiquetar** o **Quitar etiqueta**. Poner una etiqueta que ya tenían no la duplica.
- **Filtrar:** por etiqueta en Clientes, en [Suscripciones](https://docs.pagaconquickpay.com/developers/suscripciones#filtrar-y-trabajar-en-grupo) y en [Transacciones](https://docs.pagaconquickpay.com/developers/portal#filtrar-tus-transacciones), y enviar una cobranza **a una etiqueta**.
- **Borrar una etiqueta** la quita de todas las personas; las personas no se borran.

El **Cobrador** ve las etiquetas de cada cliente y puede filtrar por ellas; crearlas, editarlas, borrarlas y ponerlas es del Propietario y del Administrador.

### Acciones en grupo

Marca las casillas de la lista, o la casilla de arriba para elegir **los de esa página**; entonces aparece **"Elegir los N que coinciden"** para elegir a **todos los que cumplen tu filtro**, aunque no estén cargados en pantalla. Con ellos puedes:

- **Etiquetar** o **quitar una etiqueta**.
- **Enviar cobranza:** te lleva a **Nueva cobranza** con esas personas ya elegidas.
- **Suscribir a un plan.**

El máximo es de **5.000 personas por acción**. Si eliges más, no se hace una parte en silencio: te dice cuántas son y te pide afinar el filtro o hacerlo por partes. Sólo el Propietario y el Administrador eligen y administran; el Cobrador ve la lista pero no administra.

### Estado de pago, último pago y total pagado

En la lista ves, de cada persona, su **estado de pago**, su **último pago** y lo que lleva **pagado** (en la divisa de tu panel, con los bolívares debajo; cada pago se convierte con la tasa BCV de su día de pago). Se calculan así:

- **Estado de pago**, según el **último cobro que se le envió** (por Cobranza masiva o Suscripciones): **al día** si lo pagó; **pendiente** si aún no pagó pero el enlace no ha vencido; **atrasado** si venció sin pagarse (y cuántos días lleva vencido). Los cobros anteriores sin pagar no se acumulan. Quien nunca recibió un cobro no tiene estado.
- **Último pago** y **total pagado** suman sólo los pagos que podemos **ligar a la persona**: los cobros que le enviaste desde Cobranza masiva o Suscripciones, quienes se registraron al pagar y quienes se suscribieron por enlace. Un cobro suelto (el que creas en **Cobrar**, o un pago en tu página sin que la persona se registre) no trae un cliente y **no cuenta**: no adivinamos quién pagó por su nombre o su teléfono.
- Los pagos de prueba sólo cuentan si tu cuenta está en modo prueba.
- Se actualiza solo, a los pocos minutos de cada pago.

### Carga masiva desde Excel

Pulsa **Carga masiva** y sube un Excel (.xlsx) o un CSV de hasta 2.000 filas. Reconocemos estas columnas por su nombre:

| Columna | Obligatoria | También se puede llamar |
|---|---|---|
| nombre | Sí | cliente, razón social, socio |
| whatsapp | Uno de los dos | teléfono, celular |
| correo | Uno de los dos | email |
| cedula | No | documento, rif |
| referencia | No | contrato, apartamento, código |
| monto | No | deuda, saldo, total |
| moneda | No | divisa. Bs (o VES), US$ (USD, dólares) o € (EUR, euros); si falta, Bs |
| concepto | No | descripción, detalle |

Pulsa **Descargar plantilla** para bajar un Excel con las columnas exactas de tu tipo de negocio y una fila de ejemplo. Según el negocio se agregan: **tipo** (propietario o inquilino) y **complejo** en condominios, que debe existir ya en Urbanizaciones y complejos; **sucursal** donde hay sucursales; **grado** en colegios.

Antes de guardar ves cada fila con su error, si lo tiene. Si vuelves a subir la planilla, los clientes que ya existen (mismo WhatsApp, correo o referencia) **se actualizan, no se duplican**.

## Cobranza masiva

En **Cobranza masiva** le envías el cobro a muchos clientes de una vez:

- **Desde un Excel:** cada fila con su monto (o un monto general para las que no traen).
- **A tus clientes:** los eliges de la lista (con búsqueda y de 50 en 50; **Elegir todos los que coinciden** toma a todos los de tu búsqueda, no sólo los que ves) y pones el monto o un producto del catálogo.
- **A una etiqueta:** el envío sale a todos los que tengan esa etiqueta **en el momento de enviar**.
- **Desde Clientes:** elige a las personas allá (o a todos los de un filtro) y pulsa **Enviar cobranza**: la ventana se abre con ellas elegidas.

La ventana **Nueva cobranza** tiene dos pasos. **Paso 1, qué cobras:** el monto (en **Bs, US$ o €**; en dólares o euros se convierte a bolívares a la tasa BCV del momento del envío), el concepto, cuándo sale y cuándo vence; en **Más opciones** van el nombre del envío, la sucursal y la cuenta. **Paso 2, a quién:** tus clientes, una etiqueta o el Excel, el canal y un resumen antes de enviar. Un envío a clientes admite hasta **5.000 personas**; con más, te pide dividirlo en lugar de dejar a alguien fuera. El paso 1 debe estar completo para pasar al 2.

Eliges el canal (**WhatsApp, correo o los dos**), cuándo sale (**ahora o en una fecha y hora**) y cuándo vence. En el detalle de cada envío ves por dónde le llegó a cada cliente y **quién ya pagó**.

Puedes filtrar a quién enviar por urbanización o complejo y por propietario o inquilino (condominios), y asignar el envío a una sucursal. En **Transacciones** filtras luego por esos mismos datos.

Si tienes más de una cuenta, en **¿Dónde recibes estos pagos?** eliges una para todo el envío. Si dejas **Según la sucursal**, cada cobro cae en la cuenta de la sucursal del envío (o de la sucursal de cada cliente) y, si no tiene, en la principal. Las suscripciones siguen la misma regla con la sucursal de cada suscriptor.

En la lista de cobranzas, el total de cada lote sale en la [divisa de tu panel](https://docs.pagaconquickpay.com/developers/portal#divisa-del-panel) con los bolívares debajo (con «≈» cuando incluye precios en otra moneda o el lote aún no sale, porque se cobra a la tasa del envío).

> **WhatsApp usa el cupo de tu plan.** Si se acaba y el cliente tiene correo, el cobro le llega por correo. El correo no tiene límite. Tu cupo y los planes están en **Ajustes › Tu plan**.

<!-- https://docs.pagaconquickpay.com/developers/suscripciones -->

# Suscripciones

Para lo que cobras siempre igual: el plan de internet, la mensualidad del gimnasio, la cuota del condominio.

> **Restaurantes:** esta sección no está disponible en el portal de un restaurante, porque no tiene cobros recurrentes.

1. Crea un **plan**: nombre, monto (en bolívares, dólares o euros; en dólares o euros, cada período se cobra en bolívares a la tasa BCV de ese día) y cada cuánto se cobra (semanal, quincenal, mensual, trimestral o anual).
2. Agrega **suscriptores** desde tus clientes, eliges por dónde les llega (WhatsApp, correo o los dos) y la fecha del primer cobro.

En cada fecha, a partir de las 8:00 a. m. (hora de Venezuela), le enviamos el cobro a cada suscriptor y paga desde cualquier banco con la clave del suyo.

> **No es un débito automático.** Nadie le debita a tu cliente sin que él lo apruebe: en cada período le llega el cobro y él lo paga.

## Cuándo termina

Una suscripción puede terminar en una **fecha** o tras una **cantidad de cobros** (por ejemplo, mensual por 6 meses). En la lista ves "Termina el …". Después del último cobro queda **Finalizada**: no se genera ningún cobro más ni se envía ningún recordatorio. Para volver a cobrarle, agrégalo otra vez al plan.

Los suscriptores y los planes están en dos pestañas: **Suscriptores** y **Planes**.

## Recordatorios

Cada plan trae **Recordatorios** encendidos (los apagas en la tarjeta del plan):

- **3 días antes del cobro**, un correo: "Tu próximo cobro de <plan> es el <fecha>". No aplica a planes semanales.
- **Si a las 24 horas no ha pagado**, le reenviamos el mismo enlace; si al cobro le queda menos de un día, le enviamos un último recordatorio.
- **Como mucho dos recordatorios** después del cobro, sólo entre las 8:00 a. m. y las 8:00 p. m. (hora de Venezuela), y se detienen en cuanto paga.

Llegan por correo a quien eligió recibir el cobro por correo. Si activas **WhatsApp** en el plan (viene apagado), también se reenvía el cobro pendiente por WhatsApp, y cada mensaje cuenta en tu cupo. En la lista de suscriptores ves el último recordatorio de cada uno.

## Lo que puedes hacer

- Pausar, reanudar o cancelar una suscripción.
- Editar el plan: el cambio aplica desde el próximo cobro.
- Ver los envíos de cada fecha en **Cobranza masiva** (con quién pagó).
- Todo lo de abajo: [resumen y métricas](#resumen-y-metricas), [estado de pago](#estado-de-pago), [filtros y acciones en grupo](#filtrar-y-trabajar-en-grupo), [editar a un suscriptor](#editar-a-un-suscriptor), [su historial](#historial-de-cobros) y [el enlace para que se suscriban solos](#enlace-para-que-se-suscriban-solos).

Si un cliente no paga un período, el siguiente le llega igual: los cobros no se acumulan en uno.

## Resumen y métricas

Arriba de la pantalla ves cuatro tarjetas: **Activas** (con cuántas están pausadas y finalizadas), **Al día**, **Atrasadas** y **Cobrado este mes**, en la [divisa de tu panel](https://docs.pagaconquickpay.com/developers/portal#divisa-del-panel) con los bolívares debajo. "Cobrado este mes" suma lo pagado en el mes (días de Venezuela) por cobros de suscripciones.

La pestaña **Métricas** agrega, para el mes en curso:

- **Ingreso mensual recurrente:** lo que cobran en un mes típico tus suscripciones **activas**, con el precio que de verdad se les cobra (descuentos incluidos). Cada frecuencia se lleva a mes: semanal ×4,35, quincenal ×2,03, mensual ×1, trimestral ÷3, anual ÷12. Es una proyección: se convierte a tu divisa con la tasa BCV de **hoy** (por eso lleva «≈»).
- **Morosidad:** las suscripciones atrasadas entre las activas, en porcentaje.
- **Altas y bajas:** las suscripciones nuevas del mes y las **canceladas**. Las bajas se cuentan desde que se empezó a llevar el historial de cambios; la pantalla dice desde cuándo.
- **Cobrado vs esperado:** *esperado* es lo que salió en cobros este mes (convertido a la tasa del día del envío, con «≈»); *cobrado* es lo que ya pagaron de esos mismos cobros.

## Estado de pago

Cada suscriptor tiene un estado de pago, según el **último cobro que se le envió**:

- **Al día:** lo pagó.
- **Pendiente:** aún no lo paga pero su enlace no ha vencido, o todavía no le ha tocado ningún cobro.
- **Atrasado (N días):** el enlace venció sin pagarse; N son los días que lleva vencido.

Los cobros anteriores que no pagó no se acumulan: si pagó el último, está al día. El estado sale de los pagos que confirma el banco y se actualiza solo, a los pocos minutos de cada pago.

## Filtrar y trabajar en grupo

La lista de suscriptores se carga de **50 en 50** (**Ver más**) con el total exacto de lo filtrado. Filtras por **estado** (activas, pausadas, finalizadas), **plan**, **estado de pago**, **etiqueta** del cliente y **con descuento**, y buscas por nombre, teléfono, correo, referencia o plan. Los filtros quedan en la dirección de la página. Las [etiquetas](https://docs.pagaconquickpay.com/developers/clientes-y-cobranza#etiquetas) son las de Clientes: se ponen a la persona, no a la suscripción.

Marca las casillas, o elige **todos los que coinciden** con tu filtro, y puedes: **pausar**, **reanudar**, **cambiar de plan**, **etiquetar** o **quitar una etiqueta**. Cada acción dice cuántos se cambiaron y cuántos no (por ejemplo, a quien no estaba activa no se le puede pausar). **Descargar** baja en Excel o CSV lo que estás viendo, con su estado de pago y su descuento, hasta 20.000 filas.

Las suscripciones las administran el Propietario y el Administrador; el Cobrador no las ve.

## Editar a un suscriptor

El lápiz de cada fila abre **Editar suscriptor**, con tres bloques que se guardan por separado:

- **Cambiar de plan.** La suscripción pasa al plan nuevo **desde su próximo cobro**: ese cobro sale con el precio del plan nuevo. **No hay prorrateo:** no se cobra ni se acredita ninguna diferencia del período en curso, y el cobro que ya salió queda como salió. Se conservan la fecha del próximo cobro, el fin y la cuenta de cobros. Si la persona **ya está** en el plan nuevo, o ya estuvo y se canceló o terminó, no se puede cambiar: cancela esta suscripción y agrégala al plan nuevo desde **Agregar suscriptores** (si ya tuvo ese plan, se reactiva). Un descuento fijo o un precio especial se quitan al cambiar (se fijaron con el precio del plan anterior); un descuento en % se conserva.
- **Precio especial o descuento.** Para un suscriptor en particular: un **descuento en %**, un **descuento fijo** (en la moneda del plan) o un **precio especial** que reemplaza al del plan, con un **motivo** opcional. Se aplica a **cada cobro que se genere desde ese momento**, y el monto final nunca baja de 0,01: el descuento en % va hasta 99,99 y el fijo tiene que ser menor que el precio del plan. Si después bajas el precio del plan y el cobro de un suscriptor quedaría en cero, ese período no se envía. Ves el descuento en la lista, y puedes quitarlo en cualquier momento.
- **Envío y fechas:** por dónde le llega el cobro (WhatsApp, correo o los dos) y la fecha del próximo cobro.

Cada cambio queda en el [historial](#historial-de-cobros) del suscriptor.

## Historial de cobros

El botón del reloj abre el **historial** de un suscriptor: cada cobro que se le generó, con su **fecha**, **monto**, **estado** (pagado, esperando pago, vencido, cancelado…), **referencia** del pago y **código de verificación QP**. Debajo, los cambios de su suscripción: pausas, cambios de plan y de descuento. El estado de cada cobro lo dice el switch; si no responde en ese momento, el estado se deduce de lo que ya sabemos y se marca como tal.

## Agregar suscriptores a un plan

**Agregar suscriptores** abre una lista de tus clientes con búsqueda y de 50 en 50 (también puedes filtrar por etiqueta). Para el plan que elegiste:

- Quien **ya está en ese plan** sale deshabilitado, con **Ya suscrito**.
- Quien está en **otro plan** sale con ese plan (**En Plan 50mb**) y se puede elegir.
- **Elegir todos** toma a todos los que coinciden con tu búsqueda, menos los que ya están en el plan. Admite hasta 5.000 por vez.

Si cancelaste a alguien o terminó su plan, al agregarlo de nuevo se reactiva con la fecha y el fin nuevos.

## Enlace para que se suscriban solos

Cada plan puede tener un **enlace de suscripción** (en la tarjeta del plan, pestaña **Planes**, interruptor **Enlace para suscribirse solo**). Lo copias y lo compartes por donde quieras. Quien lo abre:

1. **Elige su plan** entre los que tienen el enlace encendido, y deja su **nombre**, su **WhatsApp o correo** (al menos uno) y, si quiere, su cédula o RIF.
2. **Paga el primer cobro** desde su banco. Si el plan está en dólares o euros, se cobra en bolívares a la tasa BCV del día. El enlace de pago dura 24 horas.
3. **Queda suscrito sólo cuando el pago se confirma.** Al volver del banco, la misma página espera la confirmación y se lo dice, con la fecha de su próximo cobro. Si no paga, no queda suscrito ni se crea nada. Si ya estaba en tus clientes (mismo WhatsApp o correo y sin una cédula distinta), se usa su ficha y no se duplica; si no, se crea y aparece como **Se registró al pagar**.

Enviar el formulario dos veces no crea dos cobros. El primer cobro cuenta como el primero del plan, y el siguiente le llega en la fecha que toca. Si el pago confirmado no cuadra con el cobro (otro monto), la suscripción no se activa por su cuenta. Un pago de prueba nunca suscribe a nadie en una cuenta que ya cobra de verdad.

**Cambiar por un enlace nuevo** deja de servir el anterior; apagar el interruptor deja el plan fuera del enlace.

<!-- https://docs.pagaconquickpay.com/developers/productos -->

# Productos

Tu catálogo: lo que vendes con su precio, en bolívares, dólares o euros.

- Lo creas en **Productos** (nombre, precio y una descripción opcional).
- Al crear un cobro, **Elegir del catálogo** te deja tomar varios productos con su cantidad: el monto y el concepto se llenan solos.
- También los usas en la cobranza masiva.

Un producto no se borra: se **archiva**, para que los cobros viejos lo sigan nombrando. Un cobro va en una sola moneda: no mezcla productos en monedas distintas. Al cobrar un producto en dólares o euros se convierte a bolívares a la tasa BCV del momento.

## Importar el menú con IA (restaurantes)

En **Menú y productos**, **Importar menú con IA** lee una foto (JPG, PNG o HEIC), un PDF o un Excel o CSV de tu menú y arma la lista con nombre, descripción, precio y moneda. Antes de guardar revisas todo: corriges o descartas filas. Si un producto ya está en tu catálogo con el mismo nombre y precio, no se repite. Hasta 5 archivos de 9 MB.

<!-- https://docs.pagaconquickpay.com/developers/propinas -->

# Propinas

Para **restaurantes y comida**. Tu cliente puede agregar propina al pagar: se suma al pago y se debita **en un solo débito**, a la misma cuenta que el pago.

## Activarlas

En el portal, ve a **Propinas** y enciende **Pedir propina al pagar**. Eliges:

- **Dónde se pregunta:** en la página de pago (enlace, QR y botón web), en el pago por WhatsApp, o en los dos.
- **Los botones:** hasta 4. Cada uno en dólares, en euros, en bolívares o en porcentaje del pago. Vienen **US$ 1, US$ 2 y US$ 5**; los montos en dólares se convierten a bolívares a la tasa BCV del dólar del momento del pago, y los montos en euros a la tasa BCV del euro. Si el cobro se creó en dólares o en euros, los botones en esa misma divisa usan la tasa con que se creó el cobro. Al lado de cada botón ves cuánto es hoy en bolívares.
- **El tope:** nadie puede agregar más que ese porcentaje del pago (10 %, 20 %, 30 %, 50 % o 100 %).

**Otro** (tu cliente escribe el monto) y **Sin propina** siempre aparecen.

## Qué ve tu cliente

Antes de elegir su banco ve **¿Quieres agregar propina?** con tus botones (por ejemplo **US$ 1 · Bs 36,50** o **€ 1 · Bs 39,80**), **Otro** y **Sin propina**. Si elige una, el monto a pagar pasa a ser el del cobro más la propina, y su comprobante muestra las dos líneas: **Monto** y **Propina**.

Si en ese momento no tenemos la tasa BCV del dólar, los botones en dólares no aparecen; si no tenemos una tasa del euro confiable, los de euros tampoco. Los de bolívares, los de porcentaje, **Otro** y **Sin propina** siempre aparecen.

## Qué recibes

- En **Propinas** ves las propinas recibidas por fecha y sucursal, con el total y el promedio.
- En **Transacciones**, el detalle de cada pago muestra la **Propina** y el **Total pagado por el cliente**. La descarga en Excel o CSV trae la columna **Propina (Bs)** y, si tu divisa es dólares o euros, también la propina en esa divisa. En la pestaña **Recibidas** los montos salen en la [divisa de tu panel](https://docs.pagaconquickpay.com/developers/portal#divisa-del-panel) con los bolívares debajo.
- Desde tu sistema, el enlace y el aviso `link.pagado` traen `propina` y `total` (`monto` sigue siendo el del cobro). → [Glosario](https://docs.pagaconquickpay.com/developers/glosario)

La comisión de QuickPay se calcula sobre lo debitado (pago más propina) y, con liquidación inmediata, la propina te llega junto con el resto del pago.

## Reglas

- **El monto del cobro no cambia.** La propina va aparte.
- **La propina la valida QuickPay**, no la página: no puede ser negativa, lleva hasta dos decimales y no pasa del tope. Si apagas las propinas, nadie puede agregar una, ni con un enlace viejo.
- Sólo en cobros en bolívares.

<!-- https://docs.pagaconquickpay.com/developers/boton-de-pago -->

# Botón para tu web

Un botón **Pagar con QuickPay** que pegas en cualquier página, sin programar.

1. En el portal, ve a **Integraciones › Configura tu botón**.
2. Elige el texto del botón y, si quieres, un monto fijo, un concepto, una sucursal y la cuenta donde caen sus pagos (si tienes más de una). Sin elegir, la de la sucursal o la principal.
3. Copia el código y pégalo en tu web (WordPress, Wix, una tienda o HTML propio).

El botón lleva a tu [página de pago](https://docs.pagaconquickpay.com/developers/pagina-de-pago) con el monto y el concepto que elegiste. Si no fijas monto, tu cliente escribe cuánto paga.

> **¿Necesitas un monto distinto por pedido?** Entonces crea un enlace por pedido desde tu sistema: → [Enlaces de pago](https://docs.pagaconquickpay.com/developers/enlaces-de-pago).

## Botón en una sola línea: `boton.js`

Si ya tienes el enlace de cobro (el `id` que devuelve `POST /links`, o el `slug` de tu comercio), pega esto donde quieras que aparezca el botón:

```html
<script src="https://pay.pagaconquickpay.com/boton.js" data-link="ID_O_SLUG"></script>
```

Cambia `ID_O_SLUG` por el `id` del enlace (por ejemplo `3f2c9a1e-5b7d-4e21-9c0a-8d4f6b1a2e37`) o por el slug de tu comercio (por ejemplo `mi-comercio`). El botón **Pagar con QuickPay** aparece justo ahí y abre el pago en una pestaña nueva:

- Con un `id`, abre la [página de pago](https://docs.pagaconquickpay.com/developers/pagina-de-pago) de ese enlace, `https://pay.pagaconquickpay.com/l/<id>`.
- Con un `slug`, abre la página de cobro de tu comercio, `https://pagaconquickpay.com/pay/<slug>`.

Atributos opcionales:

| Atributo | Para qué | Valores |
|---|---|---|
| `data-texto` | Cambiar el texto del botón | Texto plano, hasta 40 caracteres. Por omisión, `Pagar con QuickPay` |
| `data-abrir` | Abrir en una ventana emergente en vez de una pestaña | `ventana`. Si el navegador la bloquea, se abre la pestaña de siempre |

Un botón por etiqueta `<script>`: para varios cobros en la misma página, pega una etiqueta por cada uno.

**Qué garantiza.**

- **Sin llaves en el navegador.** El `id` de un enlace sirve para pagar ese cobro y nada más; nunca pegues una llave (`sk_…`) en tu página. Si `data-link` no es un `id` ni un slug válido (incluida cualquier llave), el botón no se pinta.
- **No ejecuta nada que venga de los atributos.** El script no usa `eval` ni arma HTML con tus atributos: el texto del botón es texto, no código, y la dirección sólo se forma con un `id` o un `slug` validados.
- **No hace peticiones ni guarda datos** en tu página. El botón es un enlace normal: también funciona con clic derecho o clic central.
- **El botón no confirma el pago.** Que alguien abra el enlace no prueba que haya pagado: confirma con el webhook `link.pagado` o consultando el cobro. → [Volver a tu web y verificar](https://docs.pagaconquickpay.com/developers/volver-a-tu-web)

**Si tu sitio usa una política de seguridad de contenido (CSP)**, permite el script con `script-src https://pay.pagaconquickpay.com`. El botón no hace peticiones, así que no necesita `connect-src`, y sus estilos los aplica por código, sin `style-src 'unsafe-inline'`. El archivo se sirve con CORS abierto sólo para lectura (`GET`), porque es público y no usa credenciales.

> **Prueba primero con un enlace de prueba.** Crea el enlace con tu llave `sk_test_…` y usa su `id` en `data-link`: pagas sin dinero real. → [Modo prueba](https://docs.pagaconquickpay.com/developers/datos-de-prueba)

<!-- https://docs.pagaconquickpay.com/developers/equipo-y-cuentas -->

# Equipo y cuentas

## Tus cuentas de cobro

En **Ajustes › Dónde recibes tu dinero** registras una o varias cuentas, todas a tu nombre (tu cédula o el RIF de tu empresa). Cada una se verifica con un pago de Bs 1. Una es la **principal**; al crear un cobro puedes elegir otra.

### Una cuenta por sucursal

Si tienes sucursales, en **Sucursales** editas cada una y eliges **Cuenta donde caen sus pagos** (sólo el Propietario). Una sucursal sin cuenta usa la principal.

A qué cuenta cae un pago, en este orden:

1. La que elijas en ese cobro (en **Cobrar**, **Cobranza masiva**, el botón web o el enlace de tu página).
2. La de la sucursal del cobro.
3. La principal.

Si la cuenta de una sucursal se quita, el pago cae en la principal. Todas tienen que estar a tu nombre: QuickPay lo vuelve a revisar en cada cobro.

## Tu equipo

En **Ajustes › Equipo** invitas personas por correo. Les llega un enlace para crear su contraseña y entran con su correo.

| Rol | Puede |
|---|---|
| Propietario | Todo, incluido el equipo y las cuentas de cobro |
| Administrador | Todo menos el equipo y las cuentas de cobro |
| Cobrador | Cobrar y ver transacciones, clientes y productos |

Sólo el Propietario invita y cambia roles. Si desactivas a alguien o le cambias el rol, su sesión se cierra en su siguiente acción; con el rol nuevo vuelve a entrar. Cambiar la contraseña también cierra sus sesiones abiertas.

---

<!-- Sección: Desde tu sistema -->

<!-- https://docs.pagaconquickpay.com/developers/como-se-integra -->

# Cómo se integra

Integrar QuickPay son dos decisiones.

## 1. ¿Dónde paga tu cliente?

| Opción | Cómo | Para |
|---|---|---|
| **En la página de pago de QuickPay** (recomendado) | Creas un enlace y llevas al cliente a su `url` | Webs, apps, bots, correos: casi todo |
| **En tu propia pantalla** | Pides tú la clave del banco con la API directa | Sólo aliados con contrato → [API directa](https://docs.pagaconquickpay.com/developers/api-directa) |

Con la página de QuickPay no manejas datos bancarios ni la clave del banco: sólo un `id` y una `url`.

## 2. ¿Cómo te enteras del pago?

| Opción | Cómo | Cuándo |
|---|---|---|
| **Webhook** (recomendado) | Te enviamos `link.pagado` a tu servidor, firmado | Siempre que puedas recibir un POST |
| **Consulta** | `GET /switch/v1/links/:id` hasta ver `pagado` | Como respaldo, o si no puedes recibir webhooks |

## El camino completo

```
Tu servidor ──POST /links──▶ QuickPay      (te devuelve id y url)
Tu cliente  ──abre la url──▶ página de pago (paga con la clave de su banco)
QuickPay    ──link.pagado──▶ tu servidor    (entregas el pedido)
```

> **La llave va sólo en tu servidor.** Nunca en el navegador, en una app móvil ni en un bot del lado del cliente: con ella cualquiera crearía cobros a tu nombre.

Empieza aquí: [Tu primer cobro en 5 minutos](https://docs.pagaconquickpay.com/developers/quickstart)

<!-- https://docs.pagaconquickpay.com/developers/quickstart -->

# Tu primer cobro en 5 minutos

Cuatro pasos con tu **llave de prueba**: no se mueve dinero real.

## 1. Saca tu llave de prueba

En tu portal ve a **Integraciones › Llaves de API › Crear llave**, elige **Prueba** y copia el valor. Tiene esta forma:

```
tu-comercio:sk_test_…
```

Guárdala en una variable:

```bash
export QP_KEY="tu-comercio:sk_test_…"
```

## 2. Crea un enlace de pago

```bash
curl -s https://pay.pagaconquickpay.com/switch/v1/links \
  -H "x-switch-key: $QP_KEY" \
  -H "content-type: application/json" \
  -d '{ "monto": 150, "concepto": "Pedido #1024", "metadata": { "pedido": "1024" } }'
```

Te devuelve, entre otros campos:

```json
{
  "id": "3f6c2a9e-8b1d-4c7a-9e2f-5a1b7c3d9e40",
  "url": "https://pay.pagaconquickpay.com/l/3f6c2a9e-8b1d-4c7a-9e2f-5a1b7c3d9e40",
  "estado": "pendiente",
  "mode": "test"
}
```

## 3. Págalo

Abre la `url`. Como es un cobro de prueba, la página te lo indica y acepta **cualquier clave de 8 dígitos** (para forzar un rechazo o un pago en proceso: [Modo prueba](https://docs.pagaconquickpay.com/developers/datos-de-prueba)): elige un banco, escribe un teléfono y una cédula de ejemplo (`04141234567`, `V12345678`) y paga.

## 4. Confirma que está pagado

```bash
curl -s https://pay.pagaconquickpay.com/switch/v1/links/3f6c2a9e-8b1d-4c7a-9e2f-5a1b7c3d9e40 \
  -H "x-switch-key: $QP_KEY"
```

`"estado": "pagado"`. Listo: ese es el ciclo completo.

## Y ahora, el porqué

- Qué significa cada estado → [Estados de un cobro](https://docs.pagaconquickpay.com/developers/ciclo-de-vida)
- Enterarte sin consultar → [Webhooks](https://docs.pagaconquickpay.com/developers/webhooks-referencia)
- Todos los campos del enlace → [Enlaces de pago](https://docs.pagaconquickpay.com/developers/enlaces-de-pago)
- Cuando quieras cobrar de verdad → [Pasar a producción](https://docs.pagaconquickpay.com/developers/pasar-a-produccion)

<!-- https://docs.pagaconquickpay.com/developers/llaves-y-entornos -->

# Llaves y entornos

Toda llamada lleva la cabecera:

```
x-switch-key: <tu-comercio>:<llave>
```

## Dos tipos de llave

| Llave | Empieza con | Qué hace |
|---|---|---|
| Prueba | `sk_test_` | Simula todo de punta a punta. **Nunca mueve dinero** |
| Producción | `sk_live_` | Cobra de verdad |

**El modo lo decide la llave, no tu código.** No hay ningún campo `test=true`: la misma petición con `sk_test_` es de prueba y con `sk_live_` es real. Un cobro creado en prueba queda de prueba para siempre, aunque lo abra alguien de verdad.

**Cada llave sólo ve y toca lo de su modo.** Con `sk_test_` no se consulta, lista, edita ni cancela nada creado con `sk_live_` (enlaces, lotes, órdenes, suscripciones, productos, propinas y equipo): responde `404` como si no existiera. Y una `idempotency_key` usada en prueba no se cruza con producción.

**Hay dos cosas del comercio que no tienen modo y por eso exigen `sk_live_`:** los webhooks (`POST`, `PATCH` y `DELETE /switch/v1/webhooks`, porque reciben también los avisos de producción) y la configuración de tus Flows de WhatsApp (`POST /switch/v1/flow/config`, `PUT /switch/v1/flows/definicion`). Con `sk_test_` responden `403` con `{ "error": "requiere_llave_live" }`; listar y ver webhooks sí funciona con cualquier llave. Si aún no tienes llave de producción, registra tu URL desde el portal (Integraciones › Webhooks).

## Dónde se sacan

En tu portal, **Integraciones › Llaves de API**:

- La de prueba la creas cuando quieras.
- La de producción se activa cuando tu cuenta está aprobada.
- La llave se muestra **una sola vez**. Si la pierdes, revócala y crea otra.
- Puedes tener varias (una por sistema) y revocar cada una por separado: lo que use una llave revocada recibe `401` de inmediato.
- Por API (`POST /switch/v1/api-keys` y `POST /switch/v1/api-keys/:id/revoke`), **una llave de prueba sólo crea y revoca llaves de prueba**. Para crear o revocar una de producción, llama con una `sk_live_`; con una `sk_test_` responde `403` con `{ "error": "requiere_llave_live" }`.
- El `label` de una llave nueva (1 a 120 caracteres) es libre, salvo que no puede empezar por `service-key:` ni `partner:` (son de uso interno): responde `400` con `{ "error": "label_reservado" }`.

## Dónde se guardan

> **Sólo en tu servidor**, en una variable de entorno o un gestor de secretos. Nunca en el código del navegador, en una app móvil ni en un repositorio.

## URL base

| | URL |
|---|---|
| API | `https://pay.pagaconquickpay.com/switch/v1` |
| Página de pago | `https://pay.pagaconquickpay.com/l/<id>` |

Es la misma para prueba y producción: cambia sólo la llave.

<!-- https://docs.pagaconquickpay.com/developers/enlaces-de-pago -->

# Enlaces de pago

Un enlace de pago es un cobro con su propia dirección (`https://pay.pagaconquickpay.com/l/…`). Tu cliente lo abre, elige su banco y autoriza con la clave de 8 dígitos que le manda su banco (por SMS, notificación o correo). La página la aloja QuickPay: tú no manejas datos bancarios.

Sirve para cobrar por WhatsApp, correo, SMS o QR: creas el enlace, lo envías y te enteras cuando lo pagan.

## 1. Crear un enlace

```http
POST https://pay.pagaconquickpay.com/switch/v1/links
x-switch-key: tu-comercio:sk_test_…
Content-Type: application/json

{
  "monto": 450.00,
  "concepto": "Servicio de consultoría",
  "expira_horas": 72,
  "success_url": "https://tu-dominio.com/gracias?pedido=100",
  "metadata": { "cliente_id": "CLI-001", "factura": "FAC-2026-100" },
  "idempotency_key": "factura-FAC-2026-100"
}
```

Respuesta `201`:

```json
{
  "id": "3f6c2a9e-8b1d-4c7a-9e2f-5a1b7c3d9e40",
  "url": "https://pay.pagaconquickpay.com/l/3f6c2a9e-8b1d-4c7a-9e2f-5a1b7c3d9e40",
  "wa_deeplink": null,
  "qr_png": null,
  "monto": 450,
  "moneda": "VES",
  "concepto": "Servicio de consultoría",
  "estado": "pendiente",
  "expires_at": "2026-10-11T14:00:00.000Z",
  "success_url": "https://tu-dominio.com/gracias?pedido=100",
  "failure_url": null,
  "metadata": { "cliente_id": "CLI-001", "factura": "FAC-2026-100" },
  "mode": "test"
}
```

Guarda el `id` junto a tu pedido: con él consultas el cobro y reconoces su webhook. Para mandarle el cobro a tu cliente usa `url`.

### Campos que puedes enviar

| Campo | Tipo | Obligatorio | Notas |
|---|---|---|---|
| `monto` | número | Sí | Mayor que cero, en bolívares. |
| `concepto` | texto | Sí | Lo que ve tu cliente al pagar. Hasta 140 caracteres. |
| `moneda` | texto | No | `VES` (la única hoy). |
| `expira_horas` | número entero | No | De 1 a 720 (30 días). Por omisión, 24. |
| `expira_en` | fecha ISO 8601 | No | Vencimiento exacto; si lo envías, manda sobre `expira_horas`. Tiene que ser futuro. |
| `success_url` | texto | No | A dónde vuelve tu cliente al pagar. Empieza con `https://`, hasta 400 caracteres. → [Volver a tu web](https://docs.pagaconquickpay.com/developers/volver-a-tu-web) |
| `failure_url` | texto | No | A dónde vuelve tu cliente si el pago no puede continuar. Empieza con `https://`, hasta 400 caracteres. → [Volver a tu web](https://docs.pagaconquickpay.com/developers/volver-a-tu-web) |
| `metadata` | objeto | No | Tus datos: hasta 20 claves (nombre ≤ 40, valor ≤ 200 caracteres). Te los devuelve la respuesta de crear; **no viajan en el webhook**, así que guarda la relación `id` ↔ pedido en tu sistema. |
| `idempotency_key` | texto | No | Hasta 64 caracteres. Ver abajo. |

> Si el banco rechaza, tu cliente **no** sale de la página de pago: puede intentarlo otra vez con una clave nueva. Sólo vuelve a tu `failure_url` si el cobro ya no se puede pagar (venció o lo cancelaste) o si él elige **Cancelar y volver**.

## 2. No duplicar cobros: `idempotency_key`

Va **en el cuerpo** de la petición. Si repites la creación con la misma `idempotency_key` (por ejemplo, porque se cortó la red y no sabes si llegó), recibes el **mismo** enlace en vez de uno nuevo:

- Primera vez: `201` y el enlace nuevo.
- Repetición: `200`, el mismo enlace y `"idempotent_replay": true`.

La llave vale **dentro del modo**: la misma `idempotency_key` con tu llave de prueba y con la de producción son dos enlaces distintos (uno `test` y otro `live`); nunca recibes con `sk_live_` un enlace creado con `sk_test_`. Si recibes `409` con `"error": "idempotency_key_en_uso"`, esa llave ya la usaste en el otro modo: usa otra.

Usa algo que identifique tu pedido (`factura-FAC-2026-100`), no un valor al azar por intento.

## 3. Compartir el enlace

Mándale `url` a tu cliente. En WhatsApp, lo mejor es un mensaje con botón (`cta_url` en la API de WhatsApp Cloud): abre la página de pago con un toque.

```json
{
  "messaging_product": "whatsapp",
  "to": "584141234567",
  "type": "interactive",
  "interactive": {
    "type": "cta_url",
    "body": { "text": "Tienes un pago de Bs 450 pendiente. Puedes pagarlo desde cualquier banco." },
    "action": {
      "name": "cta_url",
      "parameters": { "display_text": "Pagar ahora", "url": "https://pay.pagaconquickpay.com/l/3f6c2a9e-8b1d-4c7a-9e2f-5a1b7c3d9e40" }
    }
  }
}
```

El mensaje sale de **tu** número de WhatsApp, y su costo en Meta es tuyo.

## 4. Lo que hace tu cliente

1. Abre el enlace. Ve tu nombre, el concepto y el monto.
2. Elige su banco y escribe el teléfono y la cédula afiliados a ese banco. Si quiere, escribe su nombre.
3. Escribe la clave de 8 dígitos que le manda su banco.
4. Mientras el banco confirma, la página muestra **Procesando tu pago** y no deja reenviar el pago. Si tu cliente intenta salir o recargar, el navegador le pregunta antes; si recarga igual, vuelve a esa misma pantalla, no al formulario. Si el banco tarda más de lo normal (90 segundos), se lo dice sin invitarlo a pagar de nuevo, y la página se actualiza sola cuando el banco responde.
5. Ve la confirmación. Si enviaste `success_url`, vuelve a tu web.

Un enlace se paga **una sola vez**. Sólo tras un rechazo del banco puede intentarlo otra vez, con una clave nueva.

### Cierre diario de los bancos

Todas las noches, de **11:45 p. m. a 1:30 a. m.** (hora de Venezuela), los bancos hacen su cierre diario y no atienden pagos. En esa franja la página de pago:

- Muestra arriba el aviso **Bancos en mantenimiento** con el texto "Los bancos están en su mantenimiento diario y no se pueden hacer pagos. Podrás pagar a partir de la 1:30 a. m. (hora de Venezuela)." y no deja pedir la clave de pago. No se le cobra nada a tu cliente.
- Desde **15 minutos antes** (11:30 p. m.) muestra un aviso que no bloquea: "En 12 minutos los bancos entran en mantenimiento (de 11:45 p. m. a 1:30 a. m.). Si vas a pagar, hazlo ahora." Los minutos se actualizan solos.
- Se actualiza sola cada 30 segundos: una página abierta antes de la franja se bloquea al empezar y se desbloquea a la 1:30 a. m. sin recargar.

Si alguien pide la clave dentro de la franja, la página recibe `503` con `{ "error": "cierre_bancario", "motivo": "Los bancos están en su mantenimiento diario y no se pueden hacer pagos. Podrás pagar a partir de la 1:30 a. m. (hora de Venezuela).", "reintentar_en": 5400 }` (`reintentar_en`, en segundos, y la cabecera `Retry-After` dicen cuánto falta para que termine) y muestra el mismo aviso.

Lo que ya estaba en curso no se corta: un pago con la clave ya pedida sigue su camino y los avisos `link.pagado` y `link.acreditado` llegan como siempre. El enlace sigue `pendiente` y tu cliente lo paga después de la 1:30 a. m. con el mismo enlace, si no vence antes. Los enlaces de **prueba** no tienen esta franja: no pasan por el banco.

### Pagar con tarjeta (piloto)

Está en **piloto** y apagado: QuickPay lo enciende por comercio. Si no está activo para tu cuenta, tu página de pago se ve exactamente como arriba.

Con el piloto activo, debajo de los bancos tu cliente ve **Paga con tarjeta de débito o crédito**: se aceptan tarjetas de crédito y las tarjetas de débito de Banco de Venezuela, Bancaribe, Bancrecer, Banco del Tesoro, Bancamiga, Banco Digital de los Trabajadores, BANFANB, Banco Fondo Común, Banco Plaza y R4. Antes del botón **Pagar con tarjeta** ve cuánto pagará: «Con tarjeta pagas Bs 103,00 (incluye recargo de 3 % por pago con tarjeta)» para un cobro de Bs 100. Al tocarlo pasa a la página de pago de Credicard, que es donde escribe su tarjeta: QuickPay no ve ni guarda los datos de la tarjeta. Ese formulario dura 6 minutos.

- **El recargo lo paga tu cliente**, no tú: se cobra a la tarjeta el monto (con la propina, si agregó una) más el recargo. A ti se te liquida lo mismo que si te hubiera pagado con débito inmediato: el monto (con propina) menos tu comisión de siempre.
- Sólo en cobros en bolívares de **producción**, desde Bs 5 (el mínimo de Credicard) y hasta el tope del piloto, contando el recargo. No aparece en enlaces de prueba ni en enlaces con [pago dividido](https://docs.pagaconquickpay.com/developers/pago-dividido).
- El enlace se sigue pagando **una sola vez**: mientras el formulario de la tarjeta está abierto, el enlace queda `cobrando` y no se puede pagar con débito inmediato (ni abrir otro formulario); mientras un pago con débito inmediato está en curso, no se puede pagar con tarjeta.
- El enlace pasa a `pagado` sólo cuando Credicard confirma el cobro aprobado. Si lo rechaza o el formulario vence sin pago, el enlace vuelve a `pendiente` y tu cliente puede pagarlo otra vez (con tarjeta o con débito inmediato).
- Te llega el mismo aviso `link.pagado`: `monto`, `propina` y `total` son los del cobro (sin el recargo), con `"metodo": "tarjeta"`, `recargo_tarjeta` (lo que pagó de más tu cliente), en `referencia` la referencia del recibo de la tarjeta y en `txn_id` el id del pago con tarjeta. → [Webhooks](https://docs.pagaconquickpay.com/developers/webhooks-referencia)
- **La liquidación de los pagos con tarjeta no es inmediata**: Credicard abona los pagos con tarjeta en su cierre nocturno. Cuando el abono llega, QuickPay te liquida ese pago y te llega `link.acreditado`, como con cualquier otro pago.

### Quiero ser cliente

Debajo de la cédula, tu cliente ve el campo **Tu nombre** (opcional) y la casilla **"Quiero ser cliente de *tu comercio* y recibir sus novedades."** La casilla viene **desmarcada**: sólo la marca quien quiere. Si la marca, el nombre es obligatorio.

Cuando el cobro queda `pagado` (no antes), esa persona aparece en **Clientes** del portal con la etiqueta **Se registró al pagar** y **Acepta novedades**. Si ya la tenías (misma cédula, o mismo WhatsApp sin cédula), no se duplica ni se le cambia el nombre que le pusiste: sólo se marca que acepta novedades. En **Clientes** puedes filtrar por **Aceptan novedades**.

Si quien paga ya está registrado en QuickPay por WhatsApp con esa cédula, se usa el nombre de su registro: no tiene que registrarse dos veces.

Si quien cobra es una **cuenta personal**, la casilla dice **"Guardar mis datos para pagarle más rápido a *su nombre*."** y marcarla no vuelve obligatorio el nombre; sin nombre, el contacto se guarda con el teléfono de quien pagó. Esa casilla no es permiso para enviarle novedades.

Con un enlace de **prueba** se ve igual, pero el cliente queda marcado **Se registró al pagar (prueba)** y no cuenta como permiso para enviarle novedades.

Por la API sólo te llega si lo pidió: `pagador.alta_cliente` al consultar el enlace y en el aviso `link.pagado`. Nunca su cédula, teléfono ni nombre.

## 5. Enterarte del pago

- **Webhook `link.pagado`** (recomendado): registra tu URL en el portal (**Integraciones › Webhooks**) o con `POST /switch/v1/webhooks`. → [Webhooks](https://docs.pagaconquickpay.com/developers/webhooks-referencia)
- **Consultar el enlace**:

```bash
curl -s https://pay.pagaconquickpay.com/switch/v1/links/3f6c2a9e-8b1d-4c7a-9e2f-5a1b7c3d9e40 \
  -H "x-switch-key: $QP_KEY"
```

```json
{
  "id": "3f6c2a9e-8b1d-4c7a-9e2f-5a1b7c3d9e40",
  "url": "https://pay.pagaconquickpay.com/l/3f6c2a9e-8b1d-4c7a-9e2f-5a1b7c3d9e40",
  "wa_deeplink": null,
  "qr_png": null,
  "comercio": "tu-comercio",
  "monto": 450,
  "moneda": "VES",
  "concepto": "Servicio de consultoría",
  "estado": "pagado",
  "expires_at": "2026-10-11T14:00:00.000Z",
  "txn_id": "b639fac6-1d2e-4f00-9a1b-3c4d5e6f7a8b",
  "created_at": "2026-10-08T14:00:00.000Z",
  "paid_at": "2026-10-08T14:03:22.000Z",
  "propina": 0,
  "total": 450,
  "pagador": { "alta_cliente": false },
  "codigo_verificacion": "QP-7K3M9-XQ4TA"
}
```

`pagador.alta_cliente` es `true` si quien pagó marcó "Quiero ser cliente de *tu comercio* y recibir sus novedades" en la página de pago. → [Página de pago](https://docs.pagaconquickpay.com/developers/enlaces-de-pago#quiero-ser-cliente)

`propina` y `total` vienen siempre: si activaste [propinas](https://docs.pagaconquickpay.com/developers/propinas) y tu cliente agregó una, `total` = `monto` + `propina` es lo que se le debitó. `monto` no cambia.

Cuando el enlace está `pagado`, la respuesta trae `codigo_verificacion`: el mismo código que ve tu cliente en su comprobante. Cualquiera puede [verificarlo](https://docs.pagaconquickpay.com/developers/enlaces-de-pago#verificar-un-comprobante).

Sólo consultas los enlaces del modo de tu llave: un enlace real consultado con `sk_test_` (o uno de prueba con `sk_live_`) responde `404`.

Qué significa cada `estado`: → [Estados de un cobro](https://docs.pagaconquickpay.com/developers/ciclo-de-vida)

## 6. Listar tus enlaces

```bash
curl -s "https://pay.pagaconquickpay.com/switch/v1/links?estado=pagado&limit=20" \
  -H "x-switch-key: $QP_KEY"
```

Devuelve una **lista** de enlaces (cada uno con la forma de la consulta, incluido `codigo_verificacion` si está pagado), del más nuevo al más viejo.

Los filtros se combinan entre sí (todos tienen que cumplirse). Por ejemplo, los pagados o en proceso del 8 de octubre en Venezuela que digan "mensualidad":

```bash
curl -s "https://pay.pagaconquickpay.com/switch/v1/links?estado=pagado,procesando&desde=2026-10-08T04:00:00Z&hasta=2026-10-09T04:00:00Z&q=mensualidad" \
  -H "x-switch-key: $QP_KEY"
```

| Parámetro | Notas |
|---|---|
| `estado` | Opcional. Uno o varios separados por coma: `pendiente`, `cobrando`, `procesando`, `revision`, `pagado`, `expirado`, `cancelado`. Un valor que no es un estado se ignora. |
| `desde` · `hasta` | Opcionales. Fecha ISO 8601 (`2026-10-08T04:00:00Z`) o milisegundos desde 1970. Se compara con la fecha del pago o, si aún no se pagó, con la de creación. `desde` entra y `hasta` no. Un día de Venezuela va de las 04:00 Z de ese día a las 04:00 Z del siguiente. |
| `q` | Opcional. Texto a buscar en el concepto, el nombre de quien pagó, la referencia bancaria del pago, el `id` del enlace o su `codigo_verificacion`. Con varias palabras, cada una tiene que aparecer en alguno de esos campos. No distingue mayúsculas ni tildes. |
| `min` · `max` | Opcionales. Monto del enlace en Bs (sin propina), ambos incluidos. |
| `con_propina` | Opcional. `true`: sólo los que tienen propina. `false`: sólo los que no. |
| `mode` | Opcional. `test` o `live`. Sólo ves los enlaces del modo de tu llave: con `sk_test_`, los de prueba; con `sk_live_`, los reales. Si pides el otro modo, la lista viene vacía. |
| `origen` | Opcional. Cómo se creó: `api`, `panel`, `mi_pagina`, `boton` o `whatsapp`. |
| `limit` | Cuántos traer. Por omisión 50, máximo 200. |
| `offset` | Cuántos saltar, para paginar. |

Si `desde`, `hasta`, `min`, `max`, `con_propina`, `mode` u `origen` traen un valor que no se entiende, responde `400` con `{ "error": "validation", "parametro": "…", "detail": "…" }` en lugar de ignorarlo.

## 7. Cancelar un enlace

Si el pedido ya no va (el cliente se arrepintió, te equivocaste en el monto), cancela el enlace:

```bash
curl -s -X POST https://pay.pagaconquickpay.com/switch/v1/links/3f6c2a9e-8b1d-4c7a-9e2f-5a1b7c3d9e40/cancelar \
  -H "x-switch-key: $QP_KEY"
```

```json
{ "id": "3f6c2a9e-8b1d-4c7a-9e2f-5a1b7c3d9e40", "estado": "cancelado" }
```

Sólo se puede cancelar un enlace **`pendiente`**. Si tu cliente ya está pagando (`cobrando`, `procesando`, `revision`) o ya pagó, responde `409` con `{ "error": "no_cancelable", "estado": "…" }` y no se toca nada: cancelar a mitad de un pago dejaría el dinero sin dueño. Si el `id` no es tuyo, no existe o es del otro modo (un enlace real con tu llave de prueba, o al revés), `404`. Cuando alguien abre un enlace cancelado ve que fue cancelado (y, si pusiste `failure_url`, vuelve a tu web).

## 8. Muchos cobros de una vez

Si le cobras a una lista de personas (mensualidades, cuotas), crea hasta 500 enlaces en una sola petición: → [Cobro por lote](https://docs.pagaconquickpay.com/developers/cobro-por-lote)

## Verificar un comprobante

El comprobante de un pago exitoso lleva un **código de verificación** (por ejemplo `QP-7K3M9-XQ4TA`) y la línea "Verifícalo en pagaconquickpay.com/verificar". Con ese código, tú o cualquier persona pueden comprobar que el comprobante es auténtico. Una captura con el monto editado no pasa la verificación, porque el código depende del monto, la moneda y la fecha del pago.

- **En la web:** `https://docs.pagaconquickpay.com/verificar` (también acepta `?codigo=QP-…`, para ponerlo en un QR o un enlace).
- **Por API, sin llave:**

```bash
curl -s "https://pay.pagaconquickpay.com/switch/v1/verificar/QP-7K3M9-XQ4TA"
```

```json
{
  "valido": true,
  "estado": "válido",
  "monto": 150,
  "moneda": "VES",
  "comercio": "Tu Comercio",
  "fecha_hora": "2026-10-09T18:03:22.000Z",
  "fecha_hora_caracas": "09/10/2026, 02:03 p. m.",
  "referencia_bancaria": "****2808",
  "prueba": false,
  "mensaje": "Comprobante auténtico emitido por QuickPay.",
  "concepto": "Mensualidad de octubre",
  "referencia_externa": null,
  "verificaciones": 1,
  "primera_verificacion": "2026-10-09T18:05:10.000Z",
  "primera_verificacion_caracas": "09/10/2026, 02:05 p. m."
}
```

- `concepto` es el del enlace que se pagó y `referencia_externa` la referencia de tu pedido si el enlace vino de un [lote](https://docs.pagaconquickpay.com/developers/cobro-por-lote) (`null` si no). Sirven para comprobar que el comprobante es del pedido que te están presentando, y no de otro del mismo monto.
- `verificaciones` dice cuántas veces se ha verificado ese código, **contando esta consulta**, y `primera_verificacion` cuándo fue la primera (en UTC y en hora de Caracas). Si te presentan un comprobante que ya se verificó antes, lo verás aquí. Pueden venir `null` si por ahora no se pudo registrar la consulta.

- Si el código no existe responde `404` con `"estado": "no_encontrado"` y el mensaje "No encontramos un comprobante con ese código.".
- Los pagos de **prueba** también tienen código, y la verificación los marca con `"prueba": true` y el mensaje "Pago de prueba (no movió dinero).".
- Nunca se muestran datos de quien pagó (teléfono, cédula ni nombre). La referencia bancaria sale enmascarada, con sólo los últimos 4 dígitos.
- Límite: 20 consultas por minuto por IP (`429` si te pasas).
- Tu servidor recibe el mismo código en `codigo_verificacion`, al consultar el enlace `pagado` y en el aviso `link.pagado`.

<!-- https://docs.pagaconquickpay.com/developers/cobro-por-lote -->

# Cobro por lote — botón de pago para tu bot de WhatsApp

Sirve para cobrarle a una lista de personas (una mensualidad, una cuota, una factura por cliente) desde el
bot que **ya tienes**, sin construir integración bancaria. Tú mandas la lista, QuickPay te devuelve un link
de pago por persona, tu bot envía cada link con un botón, y tú te enteras de cada pago por webhook o
consultando el lote.

Funciona con cualquier plataforma que pueda hacer una petición HTTP y mandar un mensaje con botón de URL
(software propio, n8n, Make, ManyChat, Wati, Landbot, Builderbot, Take Blip).

## 1. Crea el lote

```http
POST https://pay.pagaconquickpay.com/switch/v1/lotes
x-switch-key: <tu API key>
Content-Type: application/json

{
  "nombre": "Mensualidad septiembre",
  "idempotency_key": "mensualidad-2026-09",
  "expira_horas": 72,
  "items": [
    { "monto": 450.00, "concepto": "Mensualidad septiembre", "referencia_externa": "CLI-001",
      "cliente": { "nombre": "Cliente Uno", "telefono": "04141234567" } },
    { "monto": 450.00, "concepto": "Mensualidad septiembre", "referencia_externa": "CLI-002",
      "cliente": { "nombre": "Cliente Dos", "telefono": "04241234567" } }
  ]
}
```

Respuesta `201`: el lote con un item por persona. Lo que necesitas de cada item es `url` (para el botón) y
`link_id` (para reconciliar):

```json
{
  "id": "…", "total": 2, "mode": "test",
  "resumen": { "total": 2, "pagados": 0, "abiertos": 2, "monto_total": 900, "monto_pagado": 0, "completo": false },
  "items": [
    { "n": 1, "link_id": "…", "url": "https://pay.pagaconquickpay.com/l/…", "wa_deeplink": null,
      "referencia_externa": "CLI-001", "monto": 450, "estado": "pendiente" }
  ]
}
```

Reglas:
- **Hasta 500 items** por lote. Si un item no valida, no se crea ninguno.
- **`idempotency_key` del lote**: si repites la petición con la misma llave, recibes el mismo lote. Nunca se
  duplica un cobro por reintentar. Vale dentro del modo: la misma llave con `sk_test…` y con `sk_live…` son dos
  lotes distintos (lo mismo la `idempotency_key` de cada item).
- **Cada llave ve sólo los lotes de su modo**: con `sk_test…` no se listan, consultan ni cancelan los lotes
  creados con `sk_live…` (responde `404`), y al revés.
- **`referencia_externa`** es tu identificador (número de factura, fila del Excel). Vuelve en cada consulta.
- Con una API key de prueba (`sk_test…`) el lote nace en modo `test`: el checkout simula y **no cobra**.
  Con una `sk_live…` cobra de verdad.
- Si tienes la lista en Excel o CSV, conviértela a JSON en tu herramienta (n8n y Make lo hacen con un nodo).

## 2. Manda el botón desde tu bot

Envía a cada persona un mensaje con **botón de URL** (`cta_url` en la API de WhatsApp Cloud, o el bloque
"botón con enlace" de tu plataforma) apuntando a la `url` del item. El botón abre el checkout **dentro de
WhatsApp**; un enlace pegado como texto no siempre lo hace.

El checkout le pide a la persona su banco, teléfono o cuenta, cédula y el código OTP que le manda su banco.
QuickPay cobra por débito inmediato. Cada link se paga **exactamente una vez**.

El mensaje sale desde **tu** número, así que su costo en Meta es tuyo.

Si tu bot manda el cobro **fuera** de las 24 horas desde el último mensaje del cliente, WhatsApp exige una
**plantilla aprobada** (categoría *utility*). Ejemplo de plantilla que puedes registrar en tu WABA y ajustar
a tu tono (el botón es de tipo URL con sufijo dinámico, que rellenas con el `link_id` del item):

```
Hola {{1}}, tienes un pago pendiente de {{2}} por {{3}}.
Puedes pagarlo con débito inmediato desde tu banco, en un minuto.
[Botón URL]  Pagar ahora  →  https://pay.pagaconquickpay.com/l/{{1}}
```

Variables del cuerpo: `{{1}}` nombre del cliente, `{{2}}` concepto, `{{3}}` monto con "Bs". Variable del
botón: el `link_id`. Dentro de las 24 horas puedes mandar un mensaje interactivo `cta_url` sin plantilla.

## 3. Entérate de los pagos

Dos formas, y puedes usar las dos:

- **Webhook** (recomendado): registra tu URL en `/switch/v1/webhooks` y recibirás el evento `link.pagado`
  con el `link_id` en cuanto se confirme el pago.
- **Consulta del lote**: `GET /switch/v1/lotes/{id}` devuelve cada item con su `estado`
  (`pendiente`, `cobrando`, `procesando`, `revision`, `pagado`, `expirado`, `cancelado`) y el resumen
  (`pagados`, `abiertos`, `monto_pagado`, `completo`).

Un `pagado` es un pago confirmado por el banco. `procesando` y `revision` son estados intermedios: no los
trates como pagados ni como fallidos; espera el webhook o vuelve a consultar.

## 4. Cancela lo que no se cobró

`POST /switch/v1/lotes/{id}/cancelar` cancela **sólo** los items que siguen `pendiente`. Un item que está en
`cobrando`, `procesando` o `revision` no se cancela porque puede haber un OTP o un débito en curso; espera a
que termine.

## Prueba sin dinero real

1. En tu portal, **Integraciones › Llaves de API**, crea una llave de prueba.
2. Crea un lote con 2 items y manda los links a tu propio teléfono.
3. Abre uno, completa el checkout: en modo `test` el banco se simula y el item pasa a `pagado`.
4. Consulta el lote y verifica que el webhook llegó.

Referencia completa de la API: [Referencia de la API](https://docs.pagaconquickpay.com/docs) y la [colección Postman](https://docs.pagaconquickpay.com/developers/postman).

<!-- https://docs.pagaconquickpay.com/developers/pago-dividido -->

# Pago dividido

> **En piloto.** El pago dividido está detrás de una bandera y todavía no está activo para todos los comercios. Si lo pides y no está activo para tu cuenta, crear el enlace responde `400` con `{ "error": "split_no_disponible" }` y no se crea nada. Escríbenos para entrar al piloto.

Un enlace de pago puede repartir lo que te llega de ese pago entre **hasta 5 cuentas además de la tuya**: por porcentaje o por monto fijo. Lo que sobra es tuyo.

El reparto se hace **sobre el neto**: lo que pagó tu cliente (con la propina, si agregó una) menos la comisión. Corre con la [liquidación inmediata](https://docs.pagaconquickpay.com/developers/comisiones-y-liquidacion): tu cuenta necesita tenerla activa.

## Antes de empezar: aprueba las cuentas

Sólo se reparte a cuentas que **tú aprobaste en el portal**, en **Ajustes → Cuentas para pago dividido** (hasta 20). Una cuenta que no esté ahí se rechaza al crear el enlace con `400` `split_cuenta_no_preaprobada`.

Es una protección: las cuentas aprobadas sólo se cambian desde el portal, no con tu llave. Si alguien llegara a tener tu llave, no podría mandar tu dinero a una cuenta suya.

La cuenta del enlace tiene que coincidir con la aprobada en tipo, banco, número y cédula o RIF del titular.

## Crear un enlace con reparto

Agrega `split` al crear el enlace (`POST /switch/v1/links`):

```bash
curl -s https://pay.pagaconquickpay.com/switch/v1/links \
  -H "x-switch-key: $QP_KEY" -H "content-type: application/json" \
  -d '{
    "monto": 100,
    "concepto": "Pedido 1234",
    "split": [
      { "cuenta": { "tipo": "cuenta", "valor": "01020000000000000001", "banco": "0102", "identificacion": "V00000000", "nombre": "Socio Uno" }, "porcentaje": 30 },
      { "cuenta": { "tipo": "cuenta", "valor": "01020000000000000002", "banco": "0102", "identificacion": "V00000000", "nombre": "Socio Dos" }, "monto": 10 }
    ]
  }'
```

Cada elemento de `split` lleva:

| Campo | Qué es |
|---|---|
| `cuenta` | La cuenta que recibe: `tipo` (`cuenta` o `telefono`), `valor`, `banco` (código de 4 dígitos), `identificacion` y `nombre` (hasta 40 caracteres) |
| `porcentaje` | Porcentaje del neto, mayor que 0 y hasta 100, con 2 decimales como máximo |
| `monto` | Monto fijo en la moneda del enlace, con 2 decimales como máximo |

Cada beneficiario lleva `porcentaje` **o** `monto`, no los dos. La respuesta de crear trae el mismo `split` que guardamos.

Todo se valida al crear el enlace y queda fijo: un enlace no se edita, así que para cambiar el reparto se cancela y se crea otro.

| HTTP | `error` | Cuándo |
|---|---|---|
| 400 | `split_no_disponible` | El pago dividido no está activo para tu cuenta |
| 400 | `split_invalido` | Falta un dato de la cuenta, viene `porcentaje` y `monto` a la vez (o ninguno), o un campo desconocido. `detail` dice cuál |
| 400 | `split_max_beneficiarios` | Más de 5 beneficiarios |
| 400 o 422 | `split_excede_neto` | Los porcentajes suman más de 100 (400), o el reparto pasa del neto de ese monto después de la comisión (422) |
| 422 | `split_requiere_liquidacion_inmediata` | Tu cuenta no tiene liquidación inmediata |
| 400 | `split_cuenta_no_preaprobada` | Una de las cuentas no está entre las que aprobaste en el portal. `detail` dice cuál (`split[1]: …`) |
| 400 | `split_beneficiario_bloqueado` | Un control de seguridad no permite pagarle a una de las cuentas, o esa cuenta pasa el tope diario por beneficiario. `detail` dice cuál |
| 503 | `split_no_disponible_ahora` | No pudimos revisar las cuentas en ese momento. No se creó nada: intenta de nuevo en unos minutos |

## Cómo se reparte

En el ejemplo, con una comisión del 1 %, el neto de Bs 100 es Bs 99:

| Quién | Regla | Recibe |
|---|---|---|
| Socio Uno | 30 % | Bs 29,70 |
| Socio Dos | Bs 10 fijos | Bs 10,00 |
| Tú | el resto | Bs 59,30 |

- **Los montos se fijan con el neto de ese pago.** Si cuando se liquida el neto no alcanza para el reparto (por ejemplo, porque la comisión cambió después de crear el enlace), no se le paga a nadie: el pago queda en revisión y lo resolvemos contigo.
- **Redondeo:** cada porcentaje se calcula en céntimos y se redondea hacia abajo. El céntimo que sobra es tuyo. Si un porcentaje da menos de un céntimo, esa parte no se paga.
- **Cuándo:** sólo cuando el banco confirma que el pago de tu cliente entró, igual que tu liquidación. Mientras tanto, nadie recibe nada.
- **Una sola vez:** cada pago del reparto tiene su propio identificador y no se repite. Si un pago a un beneficiario no tiene una respuesta clara del banco, queda en revisión y no se reintenta solo.
- **Se revisa otra vez antes de pagar:** entre que creas el enlace y que el pago se liquida pueden pasar horas. Justo antes de pagarle a cada cuenta volvemos a revisar que siga aprobada, que ningún control de seguridad la frene y que no pase el tope diario por beneficiario. Si algo falla, esa parte queda en revisión y no se paga sola; las demás siguen.
- **En revisión:** una persona de nuestro equipo la resuelve con el banco: la paga, la da por pagada con la referencia bancaria o la cierra sin pagar (con una nota). Si se cierra sin pagar, ese monto no sale de nuestra cuenta y lo resolvemos contigo.

## Ver el reparto

`GET /switch/v1/links/:id` de un enlace con reparto trae, además de lo de siempre:

- `split`: las reglas que mandaste al crearlo.
- `reparto`: `null` hasta que el pago se liquida; después, el detalle de lo que se llevó cada cuenta.

```json
{
  "split": [ "…las reglas…" ],
  "reparto": {
    "estado": "repartido",
    "moneda": "VES",
    "monto_comercio": 59.3,
    "monto_repartido": 39.7,
    "beneficiarios": [
      { "banco": "0102", "tipo": "cuenta", "ultimos4": "0001", "nombre": "Socio Uno", "porcentaje": 30, "monto_fijo": null,
        "monto": 29.7, "estado": "pagado", "referencia_bancaria": "70000001", "liquidacion_txn_id": "…" }
    ]
  }
}
```

`reparto.estado` es `pendiente` (falta pagar alguna parte), `repartido` (todo pagado), `en_revision` (algo lo está revisando una persona) o `cerrado` (terminó, pero alguna parte se cerró sin pagar). Cada beneficiario tiene `estado` `pendiente`, `pagado`, `en_revision`, `sin_monto` (su parte dio menos de un céntimo) o `descartado` (se cerró sin pagarle). Las cuentas van enmascaradas: banco, tipo, últimos 4 dígitos y nombre.

En el portal, el detalle de cada transacción con reparto muestra lo mismo.

## El aviso `link.acreditado`

Con reparto, `link.acreditado` llega **cuando todo el reparto terminó** (no antes): cada parte pagada, o cerrada sin pagar por una persona. Trae:

- `monto_acreditado`: lo que llegó a **tu** cuenta (el resto).
- `reparto`: el mismo detalle de arriba.

Si el reparto se llevó todo el neto, no hay transferencia a tu cuenta: `monto_acreditado` es `0` y `liquidacion_txn_id` es el id del pago de tu cliente. → [Webhooks](https://docs.pagaconquickpay.com/developers/webhooks-referencia)

## Reintegros

Con tu llave en vivo (`sk_live`), `POST /switch/v1/reintegro` responde **403 `reintegro_no_habilitado`**. Con tu llave de prueba (`sk_test`) funciona como se describe aquí.

Si el reparto ya le pagó (o está pagándole) a algún beneficiario, `POST /switch/v1/reintegro` de ese pago responde **409 `cobro_con_split_repartido`**: devolverle todo a tu cliente sería pagar dos veces. Escríbenos y lo resolvemos.

Si el reintegro se hace antes de que se reparta, el reparto se detiene y queda en revisión.

## En modo prueba

Con una `sk_test_` el reparto se simula: no se transfiere nada, y el aviso `link.acreditado` (con `mode: "test"`) trae el `reparto` calculado igual que en producción. Las cuentas también tienen que estar aprobadas en el portal, así ves el mismo rechazo que verás en producción.

<!-- https://docs.pagaconquickpay.com/developers/integracion-para-bots -->

# Integración para bots de terceros — cómo un bot cobra con QuickPay

¿Tienes un bot de WhatsApp, Telegram o tu propia app? Integra QuickPay en 3 pasos y **cobra a tus clientes sin construir infraestructura bancaria**.

El flujo es simple: tu bot crea un link de pago, lo envía en un mensaje con botón, QuickPay cobra, y te avisa por webhook.

## Flujo de pago del usuario final

```
1. Cliente abre WhatsApp → ve mensaje de tu bot con botón "Pagar"
2. Toca el botón → abre en WhatsApp el checkout hosteado de QuickPay
3. Selecciona su banco, autoriza con la clave de 8 dígitos que le envía su banco (SMS, notificación o correo)
4. QuickPay cobra y, si enviaste `success_url`, lo devuelve a tu web
5. Tu bot se entera por webhook → entrega el servicio
```

## Paso 1: Obtén tu llave

1. Abre tu cuenta de comercio en el portal (con tu cédula o el RIF de tu empresa).
2. En **Integraciones › Llaves de API**, crea una llave de **prueba**. Tiene la forma `tu-comercio:sk_test_…` y se muestra una sola vez.
3. Guárdala en una variable de entorno de tu servidor (nunca en el código del bot que corre en el teléfono del cliente).

Cuando todo funcione en prueba, crea la de producción: → [Pasar a producción](https://docs.pagaconquickpay.com/developers/pasar-a-produccion)

## Paso 2: Crea un link de pago desde tu bot

**Cuando un cliente quiera pagar**, crea un link:

### Ejemplo: bot de Node.js

```js
const axios = require('axios');

async function crearLinkDePago(monto, concepto, metaDatos) {
  const response = await axios.post(
    'https://pay.pagaconquickpay.com/switch/v1/links',
    {
      monto,
      concepto,
      expira_horas: 24,
      metadata: metaDatos,          // tus datos; vuelven al crear, no en el webhook
      idempotency_key: metaDatos.orden, // reintentar no duplica el cobro
    },
    {
      headers: {
        'x-switch-key': process.env.QUICKPAY_KEY,
        'content-type': 'application/json'
      }
    }
  );

  return response.data;
}

// Uso
const link = await crearLinkDePago(
  450.00,
  'Crédito bot de consultoría',
  { cliente_id: 'CLI-001', orden: 'ORD-2026-100' }
);

console.log('Link de pago:', link.url);
// Guarda link.id junto a la orden: el webhook te dirá ese id cuando la paguen.
```

### Ejemplo: bot de Python

```python
import requests
import os

def crear_link_de_pago(monto, concepto, metadatos):
    response = requests.post(
        'https://pay.pagaconquickpay.com/switch/v1/links',
        json={
            'monto': monto,
            'concepto': concepto,
            'expira_horas': 24,
            'metadata': metadatos,
            'idempotency_key': metadatos['orden'],
        },
        headers={
            'x-switch-key': os.environ['QUICKPAY_KEY'],
            'content-type': 'application/json'
        }
    )
    
    return response.json()

# Uso
link = crear_link_de_pago(
    450.00,
    'Crédito bot de consultoría',
    {'cliente_id': 'CLI-001', 'orden': 'ORD-2026-100'}
)

print(f"Link: {link['url']}")
```

### Ejemplo: bot de Make/n8n (sin código)

**Make.com:**

1. **HTTP Request** a `POST https://pay.pagaconquickpay.com/switch/v1/links`
   - Headers: `x-switch-key: {{QUICKPAY_KEY}}`
   - Body (JSON):
     ```json
     {
       "monto": {{monto}},
       "concepto": "{{concepto}}",
       "expira_horas": 24,
       "metadata": {
         "cliente_id": "{{cliente_id}}"
       }
     }
     ```

2. **Extrae** `data.url` de la respuesta.

3. **Continúa** con el resto de tu flow (enviar a WhatsApp, etc.).

## Paso 3: Envía el link por WhatsApp con botón

Una vez tienes la URL, envía un mensaje **interactivo** con botón al cliente.

### 3.1 Si usas WhatsApp Cloud API

```js
const axios = require('axios');

async function enviarPagoWhatsApp(numeroCliente, urlPago, monto) {
  await axios.post(
    `https://graph.facebook.com/v18.0/${process.env.WA_PHONE_ID}/messages`,
    {
      messaging_product: 'whatsapp',
      to: numeroCliente,
      type: 'interactive',
      interactive: {
        type: 'cta_url',
        body: {
          text: `Hola, tienes un pago de Bs ${monto.toFixed(2)} pendiente. Puedes pagarlo desde cualquier banco.`
        },
        footer: {
          text: 'Powered by QuickPay'
        },
        action: {
          name: 'cta_url',
          parameters: { display_text: 'Pagar ahora', url: urlPago }
        }
      }
    },
    {
      headers: {
        'Authorization': `Bearer ${process.env.WA_TOKEN}`
      }
    }
  );
}
```

### 3.2 Si usas Make/n8n/Zapier

- **Module**: WhatsApp / Send Interactive Message
- **Text**: "Tienes un pago de Bs XXX pendiente"
- **Button type**: URL
- **Button text**: "Pagar ahora"
- **Button URL**: `{{link.url}}`

## Paso 4: Recibe la confirmación de pago (webhook)

Registra la URL de tu bot en **Integraciones › Webhooks** (o con `POST /switch/v1/webhooks`). Cuando tu cliente paga, te llega `link.pagado` con el `link_id`: búscalo en tu base, verifica la firma v2 y confírmale al cliente por WhatsApp. → [Webhooks](https://docs.pagaconquickpay.com/developers/webhooks-referencia)

## Paso 5: Entrega el servicio/producto

El aviso trae el `link_id`, no tus `metadata`: busca la orden que guardaste con ese id.

```js
// En tu handler del webhook (después de verificar la firma)
if (event.type === 'link.pagado') {
  const orden = await BD.buscarOrden({ link_id: event.data.link_id });
  if (!orden || orden.estado === 'pagado') return; // ya entregada: el aviso puede llegar dos veces

  await BD.actualizar({ link_id: event.data.link_id }, { estado: 'pagado', pagado_en: new Date() });
  await entregarServicio(orden.cliente_id, orden.id);
  await enviarConfirmacion(orden.cliente_id);
}
```

## Flujo completo (ejemplo real)

**Bot de créditos educativos:**

```js
const express = require('express');
const axios = require('axios');

const app = express();
app.use(express.json());

// Cliente envía: "/pagar 450 Matricula"
app.post('/api/iniciar-pago', async (req, res) => {
  const { cliente_id, monto, concepto } = req.body;

  // 1. Crear link de pago
  const link = await axios.post(
    'https://pay.pagaconquickpay.com/switch/v1/links',
    {
      monto,
      concepto,
      metadata: { cliente_id }
    },
    { headers: { 'x-switch-key': process.env.QUICKPAY_KEY } }
  );

  // 2. Guardar orden pendiente
  await BD.insertOne({
    cliente_id,
    link_id: link.data.id,
    monto,
    concepto,
    estado: 'pendiente'
  });

  // 3. Enviar botón a WhatsApp
  await axios.post(`https://graph.facebook.com/v18.0/${process.env.WA_PHONE_ID}/messages`, {
    messaging_product: 'whatsapp',
    to: cliente_id,
    type: 'interactive',
    interactive: {
      type: 'cta_url',
      body: { text: `Hola, tienes un pago de Bs ${monto} por ${concepto}.` },
      action: {
        name: 'cta_url',
        parameters: { display_text: 'Pagar ahora', url: link.data.url }
      }
    }
  }, {
    headers: { 'Authorization': `Bearer ${process.env.WA_TOKEN}` }
  });

  res.json({ link: link.data.url });
});

// 4. Webhook de confirmación (verifica la firma v2 antes: ver Webhooks)
app.post('/webhooks/quickpay', async (req, res) => {
  const event = req.body;

  if (event.type === 'link.pagado') {
    // El aviso trae link_id: con él encuentras la orden que guardaste en el paso 2
    const orden = await BD.findOne({ link_id: event.data.link_id, estado: 'pendiente' });
    if (!orden) return res.status(200).send('OK'); // repetido o desconocido
    const cliente_id = orden.cliente_id;

    await BD.updateOne({ link_id: event.data.link_id }, { estado: 'pagado', pagado_en: new Date() });

    // Envía confirmación a WhatsApp
    axios.post(`https://graph.facebook.com/v18.0/${process.env.WA_PHONE_ID}/messages`, {
      messaging_product: 'whatsapp',
      to: cliente_id,
      type: 'text',
      text: { body: '✓ Pago confirmado. Tu matrícula está activa.' }
    }, {
      headers: { 'Authorization': `Bearer ${process.env.WA_TOKEN}` }
    });
  }

  res.status(200).send('OK');
});

app.listen(3000);
```

## Checklist de implementación

- ✅ Tengo `x-switch-key` y `QUICKPAY_WEBHOOK_SECRET` en `.env`.
- ✅ Mi bot crea links con `POST /switch/v1/links`.
- ✅ Envío el link en un botón de WhatsApp (o mi plataforma).
- ✅ Registré el webhook en `/switch/v1/webhooks`.
- ✅ Mi endpoint verifica firmas HMAC-SHA256.
- ✅ Respondo `200` en menos de 8 segundos desde el webhook.
- ✅ Deduplico eventos por `(type, data.link_id)`.
- ✅ Entrego el servicio cuando recibo `link.pagado`.
- ✅ Probé con la llave de prueba (`sk_test_…`) antes de producción.

## Troubleshooting

| Problema | Solución |
|---|---|
| "unauthorized" (401) | Verifica que `x-switch-key` está en formato `comercio:sk_test_xxx` |
| Link devuelve estado "pendiente" | Normal, espera el webhook. Cliente aún no pagó. |
| No recibo webhook | Verifica que tu URL es HTTPS, responde `200` y tu firewall no bloquea. |
| "Invalid signature" | Asegúrate de capturar el **raw body** antes de parsear JSON. |
| Cliente se sale del checkout | Normal, espera a que intente de nuevo o el link expire (24h default). |

## Seguridad

- **Guarda `sk_live_…` en variables de entorno**, nunca en código.
- **Verifica siempre el webhook** — no confíes en un `link.pagado` sin firma.
- **Sé idempotente** — un webhook puede llegar dos veces.
- **No des acceso** a `QUICKPAY_WEBHOOK_SECRET` a código cliente.
- **Usa HTTPS** en tu endpoint de webhook.

## Próximos pasos

- Prueba el ciclo completo con tu llave de prueba → [Modo prueba](https://docs.pagaconquickpay.com/developers/datos-de-prueba)
- Cuando funcione, cambia a la llave de producción → [Pasar a producción](https://docs.pagaconquickpay.com/developers/pasar-a-produccion)

## Soporte

Escríbenos por WhatsApp desde el enlace **Soporte** al pie de esta página.

<!-- https://docs.pagaconquickpay.com/developers/volver-a-tu-web -->

# Volver a tu web y verificar

Al crear el enlace puedes indicar a dónde vuelve tu cliente cuando termina de pagar:

```json
{ "monto": 150, "concepto": "Pedido #1024", "success_url": "https://tu-tienda.com/gracias?pedido=1024" }
```

`success_url` debe empezar con `https://`. Cuando el enlace tiene `success_url`, la página de pago se abre con una pantalla de 2,5 segundos que muestra el nombre de tu comercio, el concepto y el monto, y avisa que el pago lo procesa QuickPay. Tu cliente puede saltarla con **Continuar**; si recarga la página, no se repite.

Al confirmarse el pago, la página muestra arriba "Volviendo a <tu comercio> en 3 s" con la cuenta regresiva y el botón **Volver ahora**, y abre tu dirección con dos datos agregados:

```
https://tu-tienda.com/gracias?pedido=1024&estado=pagado&referencia=10242808
```

Si tu cliente pagó con [tarjeta](https://docs.pagaconquickpay.com/developers/enlaces-de-pago#pagar-con-tarjeta-piloto) (piloto), vuelve igual: `referencia` es la operación QuickPay (8 caracteres) en lugar de la referencia bancaria.

## Cuando el pago no puede continuar: `failure_url`

```json
{ "monto": 150, "concepto": "Pedido #1024", "success_url": "https://tu-tienda.com/gracias?pedido=1024", "failure_url": "https://tu-tienda.com/pago-fallido?pedido=1024" }
```

También debe empezar con `https://`. Tu cliente vuelve a esa dirección, con `estado` agregado, en estos casos:

| `estado` | Cuándo |
|---|---|
| `expirado` | Abre el enlace cuando ya venció, o vence mientras tu cliente está pagando |
| `cancelado` | Abre el enlace cuando ya lo cancelaste, o lo cancelas mientras tu cliente está pagando |
| `rechazado` | El banco rechazó el pago y tu cliente elige **Cancelar y volver** |

```
https://tu-tienda.com/pago-fallido?pedido=1024&estado=rechazado
```

Si el banco rechaza, tu cliente **no** vuelve solo: se queda en la página de pago para intentarlo otra vez, y ahí aparece el botón **Cancelar y volver**. Si no pones `failure_url`, el botón no aparece y un enlace vencido o cancelado sólo muestra su aviso.

> **`failure_url` tampoco es prueba de nada.** Que tu cliente llegue ahí no significa que no haya pagado (por ejemplo, pudo pagar en otra pestaña). Antes de cancelar un pedido, consulta el cobro.

> **Volver a tu web no prueba el pago.** Cualquiera puede escribir esa dirección en su navegador. Antes de entregar, confirma que el cobro está `pagado`: con el webhook `link.pagado` o con una consulta.

## Verificar desde tu página de "gracias"

Cuando el cliente llega a tu `success_url`, tu servidor consulta el cobro:

```bash
curl -s https://pay.pagaconquickpay.com/switch/v1/links/<id> -H "x-switch-key: $QP_KEY"
```

| `estado` | Qué muestras |
|---|---|
| `pagado` | "¡Gracias! Tu pago fue confirmado." |
| `procesando` o `revision` | "Tu banco está confirmando el pago. Te avisaremos." (no le pidas pagar otra vez) |
| `pendiente` | "Todavía no recibimos tu pago." con un enlace para intentarlo |

Guarda el `id` del cobro junto a tu pedido al crearlo: así sabes cuál consultar.

<!-- https://docs.pagaconquickpay.com/developers/webhooks-referencia -->

# Webhooks

Un webhook es un aviso que QuickPay le manda a tu servidor (un `POST` con JSON) cuando pasa algo con tus cobros. Es la forma recomendada de enterarte de un pago: no tienes que consultar.

## Eventos

| Evento | Cuándo llega |
|---|---|
| `link.pagado` | El banco confirmó el pago de un cobro: ya puedes entregar |
| `link.acreditado` | Te transferimos el neto de ese pago a tu cuenta. Llega con la liquidación inmediata, que se está activando por etapas |
| `link.devuelto` | Una devolución que hiciste desde el portal llegó a tu cliente. Las devoluciones están en piloto: si no están activas para tu cuenta, este aviso no llega |
| `transaccion.aprobada` | [API directa](https://docs.pagaconquickpay.com/developers/api-directa): el banco confirmó la operación (`LIQUIDADA`). Llega una sola vez por operación, junto con `transaccion.liquidada` |
| `transaccion.liquidada` | API directa: la operación quedó `LIQUIDADA` (confirmada por el banco) |
| `transaccion.rechazada` | API directa: el banco rechazó la operación (`RECHAZADA`) |

`link.pagado` sale cuando el banco **confirma** que el dinero se movió, no cuando recibe la orden de débito. Según el banco de tu cliente, la confirmación puede llegar en el mismo momento del pago o el cobro pasa primero por `procesando` y el aviso llega cuando el banco lo confirma: suele tardar menos de un minuto, pero a veces tarda bastante más. Si el banco no lo aprueba, el cobro vuelve a `pendiente` y no llega ningún `link.pagado`. Llega una sola vez por cobro. → [Estados de un cobro](https://docs.pagaconquickpay.com/developers/ciclo-de-vida)

`transaccion.aprobada` sigue la misma regla: sale cuando el banco **confirma** la operación (`LIQUIDADA`), no cuando recibe la orden de débito (`ACEPTADA`, "enviada a BCV"). Por eso llega junto con `transaccion.liquidada` y su `data.estado` es `"LIQUIDADA"`. Con una llave de prueba, el cobro simulado avisa `transaccion.aprobada` en el acto con `data.estado: "ACEPTADA"` y `referencia: "SIMULADO"`. El cuerpo de los avisos `transaccion.*` es `{ "type", "sentAt", "data": { "id", "estado", "monto", "moneda", "concepto", "referencia", "operacion" } }`, donde `data.id` es el `id` que te devolvió la operación.

`data.operacion` dice de qué es la transacción, para que un envío de dinero no se confunda con un pago que recibiste: `cobro` (te pagaron), `pago` (salió dinero: por ejemplo, la transferencia del neto a tu cuenta o un reintegro), `reverso`, y las tres de una devolución: `devolucion_debito` (el débito a tu cuenta, con la clave de tu banco, para devolverle a tu cliente), `devolucion` (el dinero que le llega a tu cliente) y `devolucion_retorno` (si el banco de tu cliente rechazó la devolución, te regresamos lo que te debitamos). Entrega mercancía sólo con `operacion: "cobro"`.

## 1. Registra tu URL

Lo más fácil: en tu portal, **Integraciones › Webhooks › Agregar URL** (sirve aunque todavía no tengas llave de producción). O por API, **con una llave `sk_live_`**:

```bash
curl -s https://pay.pagaconquickpay.com/switch/v1/webhooks \
  -H "x-switch-key: $QP_KEY" -H "content-type: application/json" \
  -d '{ "url": "https://tu-dominio.com/webhooks/quickpay", "eventos": ["link.pagado", "link.acreditado"] }'
```

El webhook recibe también los avisos de producción, así que crear, cambiar o borrar webhooks por API exige una `sk_live_`: con una `sk_test_` responde `403` con `{ "error": "requiere_llave_live" }`. Con la llave de prueba sí puedes listarlos y ver sus entregas. La URL debe empezar con `https://`. La respuesta trae el **`secret`** con el que verificas la firma: **se muestra una sola vez**, guárdalo.

Reglas de la URL:

- Tiene que llegar a una **dirección pública de Internet**. Si apunta (o su nombre resuelve) a una red interna —`localhost`, `127.x`, `10.x`, `172.16–31.x`, `192.168.x`, `100.64–127.x`, `169.254.x` o sus equivalentes IPv6— el registro responde `422` con `{ "error": "destino_bloqueado" }`. Lo mismo al cambiar la URL con `PATCH`.
- **No seguimos redirecciones.** Si tu servidor responde `301`, `302`, `307` o `308`, el aviso cuenta como no entregado y se reintenta: registra la URL final.
- Hasta **10 webhooks por comercio**. Con 10, registrar otro responde `409` con `{ "error": "limite_webhooks" }`: borra uno que no uses.

## 2. Lo que te llega

Cabeceras:

| Cabecera | Qué es |
|---|---|
| `x-quicklink-event` | El evento, p. ej. `link.pagado` |
| `x-quicklink-timestamp` | Segundos desde 1970 (UTC) en que se firmó |
| `x-quicklink-signature-v2` | `v2=<hex>`: HMAC-SHA256 de `timestamp + "." + cuerpo` |
| `x-quicklink-signature` | `sha256=<hex>`: HMAC-SHA256 del cuerpo (firma anterior, se mantiene por compatibilidad) |

Cuerpo de `link.pagado`:

```json
{
  "type": "link.pagado",
  "sentAt": "2026-10-08T14:03:22.000Z",
  "data": {
    "link_id": "3f6c2a9e-8b1d-4c7a-9e2f-5a1b7c3d9e40",
    "txn_id": "b639fac6-1d2e-4f00-9a1b-3c4d5e6f7a8b",
    "estado": "pagado",
    "monto": 150,
    "moneda": "VES",
    "concepto": "Pedido #1024",
    "referencia": "10242808",
    "mode": "live",
    "codigo_verificacion": "QP-7K3M9-XQ4TA",
    "propina": 0,
    "total": 150,
    "pagador": { "alta_cliente": false }
  }
}
```

`monto` es lo que pidió el cobro. Si activaste propinas y tu cliente agregó una, viene en `propina` y `total` es lo que se le debitó (`monto` + `propina`, en un solo débito). Sin propina, `propina` es `0` y `total` es igual a `monto`.

`codigo_verificacion` es el código que lleva el comprobante de tu cliente: sirve para [verificar que es auténtico](https://docs.pagaconquickpay.com/developers/enlaces-de-pago#verificar-un-comprobante). Puede venir `null`; ignóralo en ese caso.

`pagador.alta_cliente` es `true` si quien pagó marcó en la página de pago "Quiero ser cliente de *tu comercio* y recibir sus novedades". Esa persona ya aparece en **Clientes** del portal; el aviso no trae su cédula, teléfono ni nombre. → [Página de pago](https://docs.pagaconquickpay.com/developers/enlaces-de-pago#quiero-ser-cliente)

`mode` dice si el aviso es de un cobro de **producción** (`live`) o de **prueba** (`test`). En `link.acreditado` viene igual.

`metodo` sólo viene cuando tu cliente pagó con [tarjeta](https://docs.pagaconquickpay.com/developers/enlaces-de-pago#pagar-con-tarjeta-piloto) (piloto): `"metodo": "tarjeta"`, `recargo_tarjeta` es el recargo por pago con tarjeta que pagó tu cliente (no se te liquida) y `referencia` es la del recibo de la tarjeta. `monto`, `propina` y `total` son los del cobro, sin el recargo. Con débito inmediato el aviso no trae `metodo` ni `recargo_tarjeta`.

Cuerpo de `link.devuelto` (piloto):

```json
{
  "type": "link.devuelto",
  "sentAt": "2026-10-14T21:33:59.304Z",
  "data": {
    "link_id": "4e38874a-eb60-457b-ba53-371a74dbaff4",
    "devolucion_id": "786d2085-00d3-4f61-95c4-b7509cfb5276",
    "estado": "completada",
    "monto": 1,
    "monto_devuelto": 1,
    "moneda": "VES",
    "referencia_bancaria": "SIMULADO",
    "mode": "test"
  }
}
```

Con una llave de prueba `referencia_bancaria` llega como `"SIMULADO"`; en producción es la referencia del crédito a tu cliente.

`monto` es lo que se devolvió en esta devolución y `monto_devuelto` lo devuelto en total de ese cobro (una devolución puede ser parcial y un cobro puede tener varias). Llega una vez por devolución, cuando el dinero ya salió hacia tu cliente.

`link.acreditado` trae además `liquidacion_txn_id`, `monto_bruto`, `comision` y `monto_acreditado`. Con [pago dividido](https://docs.pagaconquickpay.com/developers/pago-dividido) (piloto) llega cuando todo el reparto terminó (cada parte pagada o cerrada sin pagar) y trae además `reparto`; `monto_acreditado` es sólo tu parte. Con propina, `monto_bruto` es el `total` (la comisión se calcula sobre lo debitado y la propina te llega con el resto del pago). Si devolviste parte de ese pago desde el portal antes de que te lo acreditáramos (piloto de devoluciones), `monto_acreditado` llega ya descontado: lo devuelto y el costo del banco de la devolución. En ese caso `monto_acreditado` es menor que `monto_bruto − comision`. Si devolviste todo lo que te tocaba, no llega `link.acreditado`. → [Glosario](https://docs.pagaconquickpay.com/developers/glosario)

## 3. Verifica la firma (siempre)

Usa la firma **v2** y rechaza avisos con más de 5 minutos: así nadie te reenvía uno viejo. Calcula sobre el cuerpo **exacto** que llegó, antes de parsearlo.

### Node.js

```js
import { createHmac, timingSafeEqual } from 'node:crypto';

function verificar(cuerpo, firma, timestamp, secreto) {
  if (!firma || !timestamp || Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;
  const esperado = Buffer.from('v2=' + createHmac('sha256', secreto).update(`${timestamp}.${cuerpo}`).digest('hex'));
  const recibido = Buffer.from(String(firma));
  return esperado.length === recibido.length && timingSafeEqual(esperado, recibido);
}

// Express: app.post('/webhooks/quickpay', express.text({ type: '*/*' }), (req, res) => { … })
//   verificar(req.body, req.get('x-quicklink-signature-v2'), req.get('x-quicklink-timestamp'), process.env.QUICKPAY_WEBHOOK_SECRET)
```

El [SDK](https://docs.pagaconquickpay.com/developers/sdk/node) trae esto listo: `verificarWebhook({ cuerpo, firma, timestamp, secreto })`.

### PHP

```php
$cuerpo = file_get_contents('php://input');
$ts = $_SERVER['HTTP_X_QUICKLINK_TIMESTAMP'] ?? '';
$firma = $_SERVER['HTTP_X_QUICKLINK_SIGNATURE_V2'] ?? '';
$esperado = 'v2=' . hash_hmac('sha256', $ts . '.' . $cuerpo, getenv('QUICKPAY_WEBHOOK_SECRET'));
if (!$ts || abs(time() - (int)$ts) > 300 || !hash_equals($esperado, $firma)) { http_response_code(401); exit; }
```

## 4. Responde rápido

Responde `200` en menos de 8 segundos y procesa después. Si no respondemos con `2xx`, **reintentamos hasta 6 veces**: de inmediato, a los 30 segundos, 2 minutos, 5 minutos, 15 minutos y 1 hora.

## 5. No entregues dos veces

Un aviso puede llegar más de una vez (por los reintentos). Guarda qué `link_id` (en los avisos `transaccion.*`, `data.id`; en `link.devuelto`, `devolucion_id`) ya procesaste para cada evento y, si llega repetido, responde `200` sin volver a entregar.

## 6. Prueba y revisa las entregas

- **Probar:** en el portal, **Integraciones › Webhooks › Probar** envía a tu URL un aviso `webhook.test` firmado igual que los reales (mismas cabeceras, firma v2) y te dice si respondió `2xx`. Ese aviso no trae `data`: respóndele `200` sin procesarlo.
- **Eliminar:** en el portal, **Integraciones › Webhooks › Eliminar** borra la URL aunque todavía no tengas llave de producción (por API, `DELETE /switch/v1/webhooks/:id` exige una `sk_live_`).
- **Historial:** `GET /switch/v1/webhooks/:id/deliveries` te da las últimas entregas con su estado, el HTTP que respondió tu servidor y los intentos. Si en el momento de entregar tu URL resolvía a una red interna, la entrega queda `fallido` sin reintentos, con `status: null` y `error: "destino_bloqueado"`; en las demás, `error` viene `null`. Con una `sk_test_` sólo salen las entregas de avisos de prueba (`data.mode: "test"`); las de producción, y los avisos `transaccion.*`, se ven con una `sk_live_`.

## 7. Administrar por API

| Método | Ruta | Para |
|---|---|---|
| GET | `/webhooks` | Listar (sin el secreto). Sirve con cualquier llave |
| GET | `/webhooks/:id` | Ver uno |
| PATCH | `/webhooks/:id` | Cambiar `url`, `eventos` o `estado` (`activo` / `inactivo`). Sólo `sk_live_` |
| DELETE | `/webhooks/:id` | Borrar. Sólo `sk_live_` |

> **Revisa `data.mode` antes de entregar.** Llegan los avisos de prueba y los de producción al mismo webhook: si `mode` es `test`, el pago fue simulado y no debes entregar nada de verdad. → [Modo prueba](https://docs.pagaconquickpay.com/developers/datos-de-prueba)

<!-- https://docs.pagaconquickpay.com/developers/errores -->

# Errores y rechazos

## Cuando la API responde con error

El cuerpo siempre trae `error` y, a veces, `detail`:

```json
{ "error": "validation", "detail": { "fieldErrors": { "monto": ["Number must be greater than 0"] } } }
```

| HTTP | `error` | Qué pasó | Qué haces |
|---|---|---|---|
| 400 | `validation` | Un campo falta o no es válido. Al listar enlaces con un filtro que no se entiende, viene además `parametro` con su nombre y `detail` es un texto | Revisa `detail` (y `parametro`) |
| 401 | `unauthorized` | Falta la llave, está mal escrita o fue revocada | Revisa `x-switch-key` |
| 403 | `comercio_suspendido` | Tu comercio está suspendido: no se pueden crear enlaces ni lotes (ni de prueba ni de producción) | Escríbenos para reactivarlo |
| 403 | `requiere_llave_live` | Con una llave de prueba intentaste crear o revocar una llave de producción | Usa una `sk_live_` → [Llaves](https://docs.pagaconquickpay.com/developers/llaves-y-entornos) |
| 404 | `not_found` | Ese cobro no existe o no es de tu comercio | Revisa el `id` |
| 409 | p. ej. `item_duplicado` | Conflicto: en un lote, una `idempotency_key` de ítem ya usada | Revisa `detail` |
| 409 | `limite_webhooks` | Ya tienes 10 webhooks registrados | Borra uno que no uses → [Webhooks](https://docs.pagaconquickpay.com/developers/webhooks-referencia) |
| 422 | `destino_bloqueado` | La URL del webhook apunta a una red interna | Usa una URL pública → [Webhooks](https://docs.pagaconquickpay.com/developers/webhooks-referencia) |
| 400 / 422 / 503 | `split_…` | El pago dividido no está activo, el reparto no es válido, una cuenta no está aprobada en el portal o un control de seguridad la frena | → [Pago dividido](https://docs.pagaconquickpay.com/developers/pago-dividido) |
| 409 | `idempotency_key_en_uso` | Esa `idempotency_key` ya la usaste con una llave del otro modo (prueba o producción) | Usa otra llave de idempotencia |
| 409 | `tope_diario_excedido` / `tope_acumulado_excedido` | Al pedir la clave de pago (página de pago, WhatsApp Flow o `POST /cobrar/token`): ese cobro pasaría el tope de lo que tu cuenta puede recibir hoy o en total. Trae `motivo` (el texto para tu cliente); con tu llave, además `tope` y `usado` (en Bs) y, si tu tope está en dólares, `topes_moneda`, `tope_usd` y `tasa_bcv` | Tu cliente no paga ahora; escríbenos si necesitas más tope → [Límites](https://docs.pagaconquickpay.com/developers/limites-y-reglas) |
| 429 | — | Pasaste el límite de peticiones | Espera y reintenta → [Límites](https://docs.pagaconquickpay.com/developers/limites-y-reglas) |
| 503 | `cierre_bancario` | En la página de pago, al pedir la clave entre las 11:45 p. m. y la 1:30 a. m. (hora de Venezuela): los bancos están en su cierre diario. Trae `motivo` (el texto para tu cliente) y `reintentar_en` (segundos hasta que termine) | Tu cliente paga después de la 1:30 a. m. con el mismo enlace → [Cierre diario](https://docs.pagaconquickpay.com/developers/enlaces-de-pago#cierre-diario-de-los-bancos) |
| 5xx | — | Falla nuestra | Reintenta con la misma `idempotency_key` |

## Cuando el banco rechaza el pago

Eso no te llega como error de la API: tu cliente lo ve en la página de pago ("El banco no aprobó el pago") y puede intentarlo otra vez con una clave nueva. El cobro sigue `pendiente` hasta que lo pague o venza.

## Si tu comercio está suspendido

Mientras dure la suspensión:

- Crear enlaces (`POST /links`) o lotes (`POST /lotes`) responde `403` con `{ "error": "comercio_suspendido" }`.
- Un enlace que estaba `pendiente` no se puede empezar a pagar: tu cliente ve "Este comercio no está recibiendo pagos" y no se le cobra nada.
- Lo que ya se estaba pagando (`cobrando`, `procesando`, `revision`) termina normalmente, y el dinero de lo ya pagado se te sigue liquidando.
- Consultar y listar tus enlaces sigue funcionando.

## Reintentar sin duplicar

Si una creación falla por red o por un `5xx`, reintenta con la **misma** `idempotency_key`: si el primer intento sí llegó, recibes el mismo enlace en vez de uno nuevo.

```json
{ "monto": 150, "concepto": "Pedido #1024", "idempotency_key": "pedido-1024" }
```

<!-- https://docs.pagaconquickpay.com/developers/datos-de-prueba -->

# Modo prueba

Con tu **llave de prueba** (`sk_test_…`) haces el ciclo completo sin mover dinero: creas cobros, los pagas, te llegan los webhooks firmados y los ves en tu portal.

## Cómo se paga un cobro de prueba

Abre su `url`: la página muestra **"Modo prueba"**. Llénala con datos de ejemplo:

| Campo | Ejemplo |
|---|---|
| Banco | Cualquiera de la lista |
| Teléfono | `0414` + `1234567` |
| Cédula | `V` + `12345678` |
| Clave de pago | Cualquier número de 8 dígitos, p. ej. `12345678` (o una de las claves de la tabla de abajo, para forzar un resultado) |

No se le pide nada a ningún banco ni llega ningún mensaje: con una clave cualquiera el pago se aprueba y el cobro pasa a `pagado`.

## Forzar un resultado

El modo prueba te deja provocar los casos difíciles para que pruebes tu manejo de cada uno. Sólo funciona en cobros creados con una llave `sk_test_…`; en un cobro de producción estas claves no hacen nada especial (se tratan como cualquier clave y las valida el banco).

### Con la clave de pago

En el paso de la clave, escribe una de estas para provocar cada desenlace. Cualquier otra clave de 8 dígitos aprueba. El **monto** y el banco elegido no cambian el resultado: lo decide sólo la clave.

| Clave de pago | Desenlace | Qué ves | Qué te llega |
|---|---|---|---|
| Cualquier otra de 8 dígitos | **Aprobado** | El cobro pasa a `pagado` y la página muestra el comprobante. | `link.pagado` |
| `11111111` | **Rechazado** (rechazo genérico) | El cobro sigue `pendiente`, la página muestra el rechazo y tu cliente puede intentarlo con otra clave. | Nada |
| `11111112` | **Rechazado por fondos** | Igual que el anterior, con el aviso "Saldo insuficiente". Motivo `SALDO_INSUFICIENTE`. | Nada |
| `11111113` | **Rechazado por clave inválida** | Igual, con el aviso "La clave de pago no es válida". Motivo `OTP_INVALIDO`. | Nada |
| `11111114` | **Banco no disponible** | Igual, con el aviso "El banco no está disponible en este momento". Motivo `BANCO_NO_DISPONIBLE`. | Nada |
| `22222222` | **Pendiente y luego aprueba** | El pago queda `procesando`. A los 30 segundos más o menos pasa solo a `pagado`. Mientras tanto no se puede volver a pagar. | `link.pagado`, recién a los 30 s |
| `33333333` | **Tarda en confirmar** | La página se queda en "Procesando tu pago" unos 8 segundos y luego aprueba. | `link.pagado`, al aprobar |

En producción, según el banco de quien paga, un pago puede pasar primero por `procesando` y `link.pagado` llega cuando el banco lo confirma. En modo prueba, "Cualquier otra" aprueba en el acto; para probar cómo maneja tu sistema la espera, usa `22222222`.

Los rechazos siguen el mismo camino que un rechazo real del banco: el cobro se libera, el intento queda registrado como rechazado y no sale ningún webhook (un cobro rechazado no tiene aviso). Las dos formas de aprobar sí disparan los mismos webhooks que en producción, con `"mode": "test"`.

**Solo funcionan en modo prueba.** Se aplican únicamente a un cobro creado con una llave `sk_test_…`. Con una llave `sk_live_…`, y en cualquier cobro de producción, estas claves no hacen nada especial: se tratan como cualquier clave y las valida el banco. Ninguna llave ni dato de la petición puede encenderlas: lo decide el modo con que se creó el cobro, y ese modo no cambia.

### Sin abrir la página: `POST /links/:id/simular`

Para que tu servidor maneje un cobro de punta a punta sin abrir la página de pago:

```bash
curl -s -X POST https://pay.pagaconquickpay.com/switch/v1/links/<id>/simular \
  -H "x-switch-key: $QP_TEST_KEY" -H "content-type: application/json" \
  -d '{ "resultado": "pagado" }'
```

| `resultado` | Qué hace | Respuesta |
|---|---|---|
| `pagado` | Marca el cobro `pagado` y dispara los mismos avisos que un pago real. Te llega `link.pagado` (con `"referencia": "SIMULADO"`). Si tu comercio tiene liquidación inmediata activa, también te llega un `link.acreditado` simulado. | `200` con `"estado": "pagado"` |
| `rechazado` | Simula que el banco rechazó: el cobro queda `pendiente`, sin cambios y sin webhook. Sirve para confirmar que tu sistema sigue esperando. | `200` con `"estado": "pendiente"` |
| `expirado` | Vence el cobro al instante (`expirado`). | `200` con `"estado": "expirado"` |

La respuesta incluye `"simulado": true`. Si el cobro no es de prueba, recibes `403` (`solo_modo_prueba`). Si ya no está `pendiente` (o está vencido por tiempo), `409` (`no_simulable`). Un cobro en `procesando` por la clave `22222222` se puede adelantar con `pagado`.

Todos los avisos de prueba traen `"mode": "test"` dentro de `data`. → [Webhooks](https://docs.pagaconquickpay.com/developers/webhooks-referencia)

## Qué pasa igual que en producción

- Los estados del cobro y su consulta (`GET /links/:id`).
- El webhook `link.pagado`, firmado igual que en producción, con `"mode": "test"`.
- El cobro aparece en tu portal marcado como prueba.

## Lo que el modo prueba no hace

- **No cobra dinero ni consulta a ningún banco.** La referencia de un pago de prueba es `SIMULADO`.
- **No simula todos los rechazos del banco** (cuenta bloqueada, por ejemplo): sólo los de la tabla de arriba. Los estados exactos que puede devolver un cobro real están en [Estados de un cobro](https://docs.pagaconquickpay.com/developers/ciclo-de-vida).

> **Un cobro de prueba nunca se vuelve real**, aunque lo abra alguien de verdad con su clave del banco. Y uno de producción nunca es de prueba: no mezcles llaves en el mismo pedido.

## Si algo no funciona en producción

La [página de estado](https://docs.pagaconquickpay.com/estado) muestra si el servicio y los cobros con débito inmediato están operativos, y los incidentes recientes. Los mismos datos están en [`/estado.json`](https://docs.pagaconquickpay.com/estado.json), sin llave.

<!-- https://docs.pagaconquickpay.com/developers/pasar-a-produccion -->

# Pasar a producción

## Antes de cobrar de verdad, comprueba en prueba

- [ ] Creas un enlace y guardas su `id` junto a tu pedido.
- [ ] Pagas el enlace de prueba y tu sistema lo ve `pagado`.
- [ ] Tu webhook recibe `link.pagado`, **verifica la firma** y responde `200`.
- [ ] Si llega el mismo aviso dos veces, no entregas dos veces.
- [ ] Entregas sólo con `pagado`, nunca por volver a tu `success_url`.
- [ ] Un cobro en `procesando` o `revision` no le pide al cliente pagar otra vez.
- [ ] Probaste los casos difíciles con las claves de prueba: `11111111` (rechazo) y `22222222` (procesando), o `POST /links/:id/simular`. → [Modo prueba](https://docs.pagaconquickpay.com/developers/datos-de-prueba)
- [ ] Tu webhook ignora (no entrega) los avisos con `"mode": "test"`.
- [ ] Tu llave está sólo en tu servidor.

## El día que pasas

Lo único que cambia es **la llave**:

1. Tu cuenta debe estar aprobada (el portal te muestra "Puede cobrar" en Ajustes).
2. En **Integraciones › Llaves de API**, crea una llave de **Producción** (`sk_live_…`).
3. Cámbiala en tu servidor.
4. Haz un cobro real pequeño y confírmalo de punta a punta.

> **Los avisos de prueba y de producción llegan al mismo webhook** (por eso crearlo o cambiarlo por API exige `sk_live_`; desde el portal puedes registrarlo antes de tener la llave de producción), pero cada uno trae `data.mode` (`test` o `live`). Si es `test`, el pago fue simulado: no entregues de verdad.

<!-- https://docs.pagaconquickpay.com/developers/api-directa -->

# API directa (aliados)

> **Para aliados con contrato.** Si eres un comercio, no necesitas esto: usa [enlaces de pago](https://docs.pagaconquickpay.com/developers/enlaces-de-pago), donde QuickPay pide la clave del banco por ti. La API directa es para quien muestra su propia pantalla de pago (por ejemplo, un bot que pide la clave dentro de su conversación) o envía pagos.

Una sola integración para **cobrar** y **pagar** sobre todos los rieles bancarios del país. Tú dices *qué* quieres (cobrar/pagar Bs X a Y); QuickPay decide *cómo* y *por cuál banco*.

En esta guía vas a, con `curl` puro y copy-paste:

1. Conseguir tu API key y autenticarte.
2. Hacer tu **primer cobro** (débito inmediato con OTP).
3. **Enviar un pago** a un beneficiario.
4. **Consultar** el estado de una operación.
5. Recibir **webhooks** de cambios de estado.
6. Manejar **errores y rechazos**.

> **Convención.** A lo largo de la guía usamos la variable `{{base_url}}` como host del API. Sustitúyela por la URL que te entregamos (producción: `https://pay.pagaconquickpay.com`). Define una variable de entorno para copiar-pegar sin editar:
>
> ```bash
> export base_url="https://pay.pagaconquickpay.com"
> ```

---

## 1. Obtén tu API key

Toda llamada se autentica con la cabecera **`x-switch-key`** en formato:

```
x-switch-key: <comercio>:<api_key>
```

- `<comercio>` es el identificador de tu comercio (p. ej. `acme`).
- `<api_key>` es la llave secreta. Tienes dos tipos:

| Llave | Prefijo | Qué hace |
|---|---|---|
| **Prueba** | `sk_test_…` | Ambiente de ensayo. **No mueve dinero real** (sandbox simulado en QA). |
| **Producción** | `sk_live_…` | Mueve dinero real sobre los bancos. |

> **El modo lo fija la llave, no tu código.** No envías ningún campo `mode` ni `test=true`: el servidor deriva el modo (`test`/`live`) del prefijo de la API key. La misma petición, con `sk_test_…` corre simulada y con `sk_live_…` mueve dinero. Cambias de ambiente cambiando una sola cosa: la llave.

Guarda tu llave en una variable para el resto de la guía. Empieza siempre en **test**:

```bash
export SWITCH_KEY="acme:sk_test_xxxxxxxxxxxxxxxxxxxxxxxx"
```

Verifica que tu llave funciona pidiendo tus transacciones (no mueve dinero):

```bash
curl -s "$base_url/switch/v1/transacciones?limit=1" \
  -H "x-switch-key: $SWITCH_KEY"
```

Respuesta esperada (HTTP 200): un arreglo con tus transacciones (`[]` si todavía no tienes ninguna).

Si recibes `401 {"error":"unauthorized"}`, revisa el formato `<comercio>:<api_key>` y que la llave esté activa.

### Conceptos que vas a usar en todas las llamadas

- **`idempotency_key` (UUID).** Obligatorio en cada operación de dinero. Reintentar con **la misma** llave **nunca** duplica el cobro/pago: te devuelve el resultado original. Genera uno por operación:
  ```bash
  uuidgen | tr 'A-Z' 'a-z'   # o cualquier generador de UUID v4
  ```
- **`Instrumento`.** Origen o destino del dinero. Se expresa igual sea cuenta o teléfono:
  ```jsonc
  {
    "tipo": "cuenta",            // "cuenta" | "telefono"
    "valor": "01020000...",      // nº cuenta (20 díg) o teléfono
    "banco": "0102",             // código BCV de 4 dígitos
    "identificacion": "V12345678", // cédula/RIF con prefijo (V/E/J/P…)
    "nombre": "Ana Pérez"        // ≤ 40 caracteres
  }
  ```
- **Montos en VES.** `{ "valor": 320.00, "moneda": "VES" }` (la moneda es ISO-4217 y por defecto `VES`).
- **El estado se lee del cuerpo, no del HTTP.** Un `200 OK` significa que el banco respondió; el campo `estado` (`ACEPTADA`/`PENDIENTE`/`RECHAZADA`/…) te dice qué pasó con el dinero.

---

## 2. Tu primer cobro (débito inmediato / C2P)

`cobrar` **debita al pagador** (le cobras a una persona). Es un **débito inmediato** y suele requerir un **OTP** que el banco del pagador le envía. El flujo son **2 pasos**:

```
POST /cobrar/token   →   (el pagador recibe un OTP de su banco, ~120s de validez)
POST /cobrar         →   (envías ese OTP y se ejecuta el cobro)
```

### Paso 2.1 — Solicitar el OTP

`POST /switch/v1/cobrar/token` con el mismo cuerpo del cobro **sin** el `otp`. `cobrador` eres tú (recibes el dinero); `pagador` es quien paga.

```bash
IDEM=$(uuidgen | tr 'A-Z' 'a-z')

curl -s -X POST "$base_url/switch/v1/cobrar/token" \
  -H "x-switch-key: $SWITCH_KEY" \
  -H "content-type: application/json" \
  -d "{
    \"idempotency_key\": \"$IDEM\",
    \"monto\": { \"valor\": 320.00, \"moneda\": \"VES\" },
    \"concepto\": \"Matricula 2026-1\",
    \"canal\": \"boton_pago\",
    \"cobrador\": {
      \"tipo\": \"cuenta\", \"valor\": \"01020000011234567890\", \"banco\": \"0102\",
      \"identificacion\": \"J123456789\", \"nombre\": \"ACME C.A.\"
    },
    \"pagador\": {
      \"tipo\": \"telefono\", \"valor\": \"04125551234\", \"banco\": \"0105\",
      \"identificacion\": \"V12345678\", \"nombre\": \"Ana Perez\"
    }
  }"
```

Respuesta (`Resultado`):

```json
{
  "id": "qp_txn_018f3a...",
  "estado": "ACEPTADA",
  "referencia_banco": "12345678",
  "endtoend": null,
  "motivo_rechazo": null,
  "intentos": 1
}
```

`ACEPTADA` aquí significa "OTP solicitado": el pagador ya recibió el código en su teléfono. **El token vive ~120 segundos.**

Si tu cuenta tiene tope de lo que recibe (por día o en total) y este cobro lo pasaría, no se pide el OTP: responde `409` con `{ "error": "tope_diario_excedido", "motivo": "…", "tope": 50000, "usado": 49500 }` (o `tope_acumulado_excedido`). `tope` y `usado` van siempre en Bs. Si tu tope está en dólares, se agregan `"topes_moneda": "USD"`, `"tope_usd"` (el tope tal como está fijado) y `"tasa_bcv"` (los Bs por dólar con que se convirtió); `tope` es `tope_usd × tasa_bcv`. Sólo frena aquí: un `/cobrar` con un OTP ya pedido no se frena por el tope. → [Límites](https://docs.pagaconquickpay.com/developers/limites-y-reglas)

> En modo **test** el OTP es simulado; usa `12345678` en el paso siguiente.

### Paso 2.2 — Ejecutar el cobro con el OTP

Toma el OTP que te da el pagador y llama a `POST /switch/v1/cobrar`. Es el **mismo cuerpo** del paso anterior **más** el campo `otp`. Reutiliza el **mismo `idempotency_key`** del flujo de cobro:

```bash
curl -s -X POST "$base_url/switch/v1/cobrar" \
  -H "x-switch-key: $SWITCH_KEY" \
  -H "content-type: application/json" \
  -d "{
    \"idempotency_key\": \"$IDEM\",
    \"monto\": { \"valor\": 320.00, \"moneda\": \"VES\" },
    \"concepto\": \"Matricula 2026-1\",
    \"canal\": \"boton_pago\",
    \"otp\": \"12345678\",
    \"cobrador\": {
      \"tipo\": \"cuenta\", \"valor\": \"01020000011234567890\", \"banco\": \"0102\",
      \"identificacion\": \"J123456789\", \"nombre\": \"ACME C.A.\"
    },
    \"pagador\": {
      \"tipo\": \"telefono\", \"valor\": \"04125551234\", \"banco\": \"0105\",
      \"identificacion\": \"V12345678\", \"nombre\": \"Ana Perez\"
    }
  }"
```

Respuesta:

```json
{
  "id": "qp_txn_018f3a...",
  "estado": "LIQUIDADA",
  "referencia_banco": "98765432",
  "endtoend": "0000001234567890",
  "motivo_rechazo": null,
  "intentos": 1
}
```

- Si `estado` es `LIQUIDADA`, el banco confirmó el cobro: el dinero entró.
- Si es `ACEPTADA`, el banco recibió el débito ("enviada a BCV") pero todavía no lo confirma: **no entregues todavía**. Consulta (sección 4) o espera el webhook `transaccion.liquidada`.
- Si es `RECHAZADA`, mira `motivo_rechazo` (sección 6). El error típico aquí es `OTP_INVALIDO` (código vencido o mal escrito → pide un token nuevo en 2.1).

> **Atajo:** si ya capturaste el OTP por tu cuenta (p. ej. el banco del pagador lo entrega in-band), puedes llamar directo a `/cobrar` con el `otp`, sin el paso 2.1.

---

## 3. Envía un pago (payout)

`pagar` **envía dinero** desde tu tesorería a un beneficiario. Aquí `ordenante` eres tú (de dónde sale el dinero) y `beneficiario` es quien recibe.

> **Quién puede usarlo:** `pagar` debita una cuenta de QuickPay, no un saldo tuyo en QuickPay. Por eso sólo lo usan las integraciones que QuickPay habilita. Con una llave de comercio (`sk_test` o `sk_live`) sin esa habilitación responde `403` con `{ "error": "pagar_no_habilitado" }`, y lo mismo `POST /switch/v1/dispersiones`.

La pieza clave es **`via`**, que elige el riel de envío:

| `via` | Riel | Cuándo | Destino | Resultado |
|---|---|---|---|---|
| `credito_inmediato` *(default)* | Crédito Inmediato (CCE) | Predominante | **teléfono o cuenta** | Liquida en BCV de forma **asíncrona** → `ACEPTADA`, luego `LIQUIDADA` por consulta/webhook |
| `pago_movil` | Pago entre teléfonos (P2P) | Alterno (p. ej. reintegros) | **solo teléfono** | Instantáneo → `LIQUIDADA` |

Reglas de oro:

- A **cuenta** siempre es `credito_inmediato` (aunque envíes `via: "pago_movil"`, a cuenta va por CCE).
- A **teléfono** es `credito_inmediato` por defecto; usa `pago_movil` solo si quieres el riel P2P instantáneo.

```bash
IDEM=$(uuidgen | tr 'A-Z' 'a-z')

curl -s -X POST "$base_url/switch/v1/pagar" \
  -H "x-switch-key: $SWITCH_KEY" \
  -H "content-type: application/json" \
  -d "{
    \"idempotency_key\": \"$IDEM\",
    \"monto\": { \"valor\": 250.00, \"moneda\": \"VES\" },
    \"concepto\": \"Reintegro\",
    \"proposito\": \"transferencia\",
    \"via\": \"credito_inmediato\",
    \"canal\": \"billetera_digital\",
    \"ordenante\": {
      \"tipo\": \"cuenta\", \"valor\": \"01020000011234567890\", \"banco\": \"0102\",
      \"identificacion\": \"J123456789\", \"nombre\": \"ACME C.A.\"
    },
    \"beneficiario\": {
      \"tipo\": \"telefono\", \"valor\": \"04145556677\", \"banco\": \"0134\",
      \"identificacion\": \"V87654321\", \"nombre\": \"Maria Gomez\"
    }
  }"
```

Respuesta:

```json
{
  "id": "qp_txn_018f4b...",
  "estado": "ACEPTADA",
  "referencia_banco": "55512345",
  "endtoend": "0000009876543210",
  "motivo_rechazo": null,
  "intentos": 1
}
```

Por `credito_inmediato` lo normal es recibir **`ACEPTADA`** (enviada a BCV) y que confirme a **`LIQUIDADA`** poco después. Para enterarte de ese cambio: consulta (sección 4) o suscríbete a webhooks (sección 5).

> Campos opcionales de `pagar`: `proposito` (`transferencia` | `nomina` | `proveedor`, default `transferencia`) y `via` (default `credito_inmediato`). Para un pago entre teléfonos (P2P) usa `"via": "pago_movil"`.

---

## 4. Consulta el estado (ACEPTADA → LIQUIDADA)

La liquidación interbancaria es **asíncrona**. Una operación puede quedar `PENDIENTE`/`ACEPTADA` y confirmarse después. Usa `POST /switch/v1/consultar` con el `id` que te devolvió `cobrar`/`pagar`:

```bash
curl -s -X POST "$base_url/switch/v1/consultar" \
  -H "x-switch-key: $SWITCH_KEY" \
  -H "content-type: application/json" \
  -d '{ "id": "qp_txn_018f4b..." }'
```

Respuesta (estado **actualizado**):

```json
{
  "id": "qp_txn_018f4b...",
  "estado": "LIQUIDADA",
  "referencia_banco": "55512345",
  "endtoend": "0000009876543210",
  "motivo_rechazo": null,
  "intentos": 1
}
```

### Ciclo de vida de los estados

| Estado | Significado | ¿Final? |
|---|---|---|
| `ACEPTADA` | El banco recibió y aprobó (síncrono o "enviada a BCV") | No (espera liquidación) |
| `PENDIENTE` | Aceptada, en liquidación interbancaria; **consulta** o espera webhook | No |
| `LIQUIDADA` | Confirmada y liquidada | **Sí (OK)** |
| `RECHAZADA` | Rechazo de negocio (ver `motivo_rechazo`) | **Sí (fallo)** |
| `ERROR` | Fallo técnico interno (reintentable) | No |
| `DESCONOCIDA` | Sin respuesta / timeout post-envío | No |

El camino feliz típico es **`ACEPTADA` → `LIQUIDADA`**.

> **Regla de seguridad.** Ante `DESCONOCIDA`, **consulta antes de reintegrar**: el banco pudo haber movido el dinero. **Nunca** reenvíes la operación original a ciegas (por eso existe `idempotency_key`: reintentar la misma operación es seguro y no duplica).

No necesitas hacer polling agresivo: configura un webhook (siguiente sección) y QuickPay te avisa cuando el estado cambie.

---

## 5. Webhooks salientes

Las operaciones de la API directa también avisan por webhook (`transaccion.aprobada`, `transaccion.rechazada`, `transaccion.liquidada`). `transaccion.aprobada` llega cuando el banco **confirma** la operación (`LIQUIDADA`), junto con `transaccion.liquidada`; un cobro `ACEPTADA` (enviado a BCV, sin confirmar) no avisa nada todavía. Cómo registrarlo, verificar la firma v2 y manejar los reintentos: → [Webhooks](https://docs.pagaconquickpay.com/developers/webhooks-referencia).

## 6. Manejo de errores y rechazos

Distingue dos planos:

### 6.1 Errores de protocolo (código HTTP)

| HTTP | Significado | Qué hacer |
|---|---|---|
| `400` | Validación del cuerpo. Devuelve `{ "error": "VALIDATION", "detail": {...} }` con los campos inválidos | Corrige el payload |
| `401` | `x-switch-key` ausente o inválida | Revisa formato `<comercio>:<api_key>` y que la llave esté activa |
| `404` | `id` no encontrado (en `/consultar`), o la operación es de otro modo que tu llave: una llave de prueba no ve operaciones reales y una real no ve las de prueba | Verifica el `id`, el comercio y el modo de la llave |
| `200` | El banco respondió | **Lee `estado`** del cuerpo para saber qué pasó con el dinero |

### 6.2 Rechazos de negocio (`motivo_rechazo`)

Cuando `estado` es `RECHAZADA`, el campo **`motivo_rechazo`** te dice por qué, con un enum **normalizado igual para todos los bancos**.

```json
{
  "id": "qp_txn_018f5c...",
  "estado": "RECHAZADA",
  "referencia_banco": null,
  "motivo_rechazo": "SALDO_INSUFICIENTE",
  "intentos": 1
}
```

Valores de `motivo_rechazo` y cómo reaccionar:

| `motivo_rechazo` | Qué pasó | Acción sugerida |
|---|---|---|
| `SALDO_INSUFICIENTE` | El pagador/ordenante no tiene fondos | Avisa y reintenta luego |
| `OTP_INVALIDO` | OTP vencido o incorrecto | Pide token nuevo (`/cobrar/token`) y reintenta |
| `CUENTA_NO_EXISTE` | Cuenta destino/origen inexistente | Corrige el instrumento |
| `CUENTA_BLOQUEADA` | Cuenta bloqueada | No reintentable; contacta al titular |
| `CUENTA_NO_DEBITO` / `CUENTA_NO_CREDITO` | La cuenta no admite débito/crédito | Usa otro instrumento |
| `MONTO_INVALIDO` | Monto fuera de rango/formato | Corrige el monto |
| `EXCEDE_LIMITE` | Supera un tope (banco o riesgo) | Reduce monto o revisa límites |
| `BENEFICIARIO_NO_COINCIDE` | Nombre/ID no coincide con la cuenta | Verifica datos del destino |
| `NO_AFILIADO_SERVICIO` | No afiliado al servicio de pago | El titular debe afiliarse |
| `BANCO_NO_DISPONIBLE` | Banco caído o no procesó | Reintenta más tarde (QuickPay puede reenrutar en `pagar`) |
| `DUPLICADA` | Operación ya procesada | Consulta el estado de la original |
| `FUERA_DE_HORARIO` | Fuera de ventana operativa | Reintenta en horario |
| `CANCELADA_POR_PAGADOR` | El pagador canceló | No reintentable |
| `PENDIENTE_BCV` | En liquidación BCV | Consulta más tarde |
| `RECHAZO_TECNICO` | Fallo técnico del banco | Reintentable con backoff |
| `FIRMA_AUTH` | Credencial/config del banco | No reintentable; reportar (no reenrutar dinero) |
| `NO_SOPORTADO` | Operación no soportada (p. ej. reverso) | Maneja por flujo alterno |
| `BLOQUEO_RIESGO` | Bloqueado por el motor de riesgo/fraude | Revisa listas/velocidad; no reintentar a ciegas |
| `SIN_DEBITO_EN_EXTRACTO` | Sólo en `pagar`: el banco no respondió al envío y, horas después, el débito no aparece en el estado de cuenta de QuickPay | No reenvíes con otra `idempotency_key` sin revisarlo antes con QuickPay |
| `DESCONOCIDO` | Sin clasificar | Consulta el estado y, si sigue sin aclararse, escríbenos con el `id` |

> **Reintentos seguros.** Para reintentar una operación, usa el **mismo `idempotency_key`**: si la original sí se ejecutó, recibes su resultado en vez de un cobro/pago duplicado. Ante `DESCONOCIDA` o un timeout, **consulta primero** — nunca reenvíes con una llave nueva.

---

## Recapitulando

- **Una cabecera:** `x-switch-key: <comercio>:<api_key>`. El **modo lo fija la llave** (`sk_test_…` vs `sk_live_…`).
- **Cobrar** = débito inmediato en 2 pasos: `/cobrar/token` → OTP → `/cobrar`.
- **Pagar** = payout; `via` elige el riel (`credito_inmediato` por defecto; `pago_movil` P2P por teléfono).
- **Estados asíncronos:** `ACEPTADA` → `LIQUIDADA`. Confírmalos con `/consultar` o webhooks.
- **`idempotency_key` (UUID)** en cada operación: reintentar nunca duplica.
- **Rechazos** normalizados en `motivo_rechazo`, iguales para todos los bancos.

¿Listo para producción? Cambia tu `sk_test_…` por `sk_live_…` — nada más en tu código cambia.

**Documentación interactiva:** `{{base_url}}/docs` (Scalar) · **OpenAPI:** `{{base_url}}/openapi.json`

---

<!-- Sección: Referencia -->

<!-- https://docs.pagaconquickpay.com/developers/referencia -->

# Entornos y URLs

## URLs

| | |
|---|---|
| API | `https://pay.pagaconquickpay.com/switch/v1` |
| Página de pago de un cobro | `https://pay.pagaconquickpay.com/l/<id>` |
| Referencia completa (OpenAPI) | [docs.pagaconquickpay.com/docs](https://docs.pagaconquickpay.com/docs) · [openapi.json](https://docs.pagaconquickpay.com/openapi.json) |

Prueba y producción usan las mismas URLs: el modo lo decide la llave (`sk_test_` o `sk_live_`). → [Llaves y entornos](https://docs.pagaconquickpay.com/developers/llaves-y-entornos)

## Endpoints para comercios

Todos con `x-switch-key: <tu-comercio>:<llave>`.

| Método | Ruta | Para |
|---|---|---|
| POST | `/links` | Crear un enlace de pago |
| GET | `/links` | Listar tus enlaces |
| GET | `/links/:id` | Consultar un enlace |
| POST | `/links/:id/cancelar` | Cancelar un enlace que sigue pendiente |
| POST | `/links/:id/simular` | Forzar el resultado de un enlace de prueba (`pagado`, `rechazado` o `expirado`); sólo con llave `sk_test_` |
| POST | `/lotes` | Crear hasta 500 enlaces |
| GET | `/lotes` | Listar tus lotes |
| GET | `/lotes/:id` | Consultar un lote y cada enlace |
| POST | `/lotes/:id/cancelar` | Cancelar los enlaces pendientes de un lote |
| GET · POST | `/webhooks` | Listar o registrar webhooks |
| GET · PATCH · DELETE | `/webhooks/:id` | Ver, cambiar (`url`, `eventos`, `estado`) o borrar un webhook |
| GET | `/webhooks/:id/deliveries` | Últimas entregas de un webhook |
| GET · POST | `/api-keys` | Listar o crear llaves |
| POST | `/api-keys/:id/revoke` | Revocar una llave |

Las llaves y los webhooks también se manejan desde el portal, en **Integraciones**.

## Endpoint público (sin llave)

| Método | Ruta | Para |
|---|---|---|
| GET | `/verificar/:codigo` | Comprobar que un comprobante es auténtico a partir de su código de verificación (`QP-XXXXX-XXXXX`). Límite: 20 consultas por minuto por IP. → [Verificar un comprobante](https://docs.pagaconquickpay.com/developers/enlaces-de-pago#verificar-un-comprobante) |

<!-- https://docs.pagaconquickpay.com/developers/limites-y-reglas -->

# Límites y reglas

| Qué | Límite |
|---|---|
| Peticiones a la API | 120 por minuto por comercio (al pasarlo: `429`) |
| Ítems por lote | 500 |
| Vigencia de un enlace | De 1 hora a 30 días (`expira_horas` 1–720); por omisión 24 horas |
| `concepto` | 140 caracteres |
| `metadata` | Hasta 20 claves; nombre de hasta 40 caracteres y valor de hasta 200 |
| `idempotency_key` | Hasta 64 caracteres |
| `success_url` y `failure_url` | Deben empezar con `https://`; hasta 400 caracteres |
| Pago de prueba en `procesando` (clave `22222222`) | Pasa a `pagado` a los 30 segundos más o menos |
| Moneda | Bolívares (`VES`). Si cobras en dólares desde el portal, se convierte a la tasa BCV del momento |
| Webhooks | URL `https://`; hasta 6 intentos de entrega |
| Pedir la clave de pago en la página de pago | 5 por hora por cobro. En producción, además, con la misma cédula y el mismo teléfono: 3 cada 10 minutos y una por minuto, y 10 cada 10 minutos desde una misma conexión (IP). Las solicitudes que el banco rechaza (por ejemplo, una cédula mal escrita) no cuentan. Al pasarlo, tu cliente ve cuánto debe esperar |
| Cierre diario de los bancos | De 11:45 p. m. a 1:30 a. m. (hora de Venezuela) no se puede pedir la clave de pago; aviso previo desde las 11:30 p. m. → [Cierre diario](https://docs.pagaconquickpay.com/developers/enlaces-de-pago#cierre-diario-de-los-bancos) |
| Monto por cobro y por día | Tu cuenta puede tener un monto mínimo y uno máximo por cobro, y un máximo por día. Los fija QuickPay; si no tienes, no hay. Pueden estar en bolívares o en dólares: si están en dólares, se convierten a bolívares con la tasa oficial del BCV en el momento de cada operación. Un cobro que pasa el máximo se rechaza con `EXCEDE_LIMITE` (por debajo del mínimo, `MONTO_INVALIDO`) sin debitar a tu cliente. Si necesitas más, escríbenos |
| Tope de lo que recibes | Tu cuenta puede tener un tope por día (hora de Venezuela) y otro en total. Los fija QuickPay; si no tienes, no hay tope. Pueden estar en bolívares o en dólares: si están en dólares, se convierten a bolívares con la tasa oficial del BCV en el momento de cada cobro (así el tope no pierde valor cuando sube el dólar). Cuentan los cobros pagados y los que el banco está procesando; los rechazados no. Con el tope lleno, tu cliente no puede pedir la clave de pago (`409` `tope_diario_excedido` o `tope_acumulado_excedido`, con el mensaje en `motivo`; con tu llave, `POST /cobrar/token` trae además `tope` y `usado` en Bs y, si tu tope está en dólares, `topes_moneda`, `tope_usd` y `tasa_bcv`); quien ya la tenía termina su pago. Las cuentas nuevas que se aprueban automáticamente, sin revisión previa, nacen con un tope de US$ 300 por día y US$ 1.000 en total hasta que QuickPay las revisa. Si necesitas más, escríbenos |
| Propina | Hasta el tope que elijas (máximo el 100 % del cobro) y nunca más de Bs 100.000; dos decimales; sólo en bolívares → [Propinas](https://docs.pagaconquickpay.com/developers/propinas) |

## Reglas que no cambian

- **Un cobro se paga una sola vez.** Nadie puede pagar dos veces el mismo enlace.
- **El monto no lo cambia el pagador** (salvo en tu página de pago, donde él lo escribe). La propina, si la activaste, va aparte en `propina`.
- **Prueba nunca mueve dinero**, aunque alguien abra el enlace de verdad. Las claves mágicas y `POST /links/:id/simular` sólo funcionan en cobros de prueba; en producción responden `403` o se tratan como una clave cualquiera.
- **Sólo se cancela un cobro `pendiente`.** Si alguien ya está pagando o ya pagó, `POST /links/:id/cancelar` responde `409`.
- **Las cuentas donde recibes deben estar a tu nombre** (tu cédula o el RIF de tu empresa). Vale también para la cuenta de cada sucursal y la que elijas en un cobro.
- **Cierre bancario diario:** de 11:45 p. m. a 1:30 a. m. (hora de Venezuela) los bancos hacen su cierre. En esa franja la página de pago lo avisa y no deja pedir la clave (al intentarlo responde `503` `cierre_bancario`); desde 15 minutos antes avisa sin bloquear. Lo que ya estaba en curso termina normalmente y los enlaces de prueba no se afectan. → [Cierre diario](https://docs.pagaconquickpay.com/developers/enlaces-de-pago#cierre-diario-de-los-bancos)

<!-- https://docs.pagaconquickpay.com/developers/glosario -->

# Glosario de campos

## Enlace de pago

| Campo | Tipo | Qué es |
|---|---|---|
| `id` | texto (UUID) | Identificador del cobro. Guárdalo junto a tu pedido |
| `url` | texto | Dónde paga tu cliente |
| `wa_deeplink` | texto o `null` | Reservado para abrir el cobro en el WhatsApp de QuickPay. **Hoy llega en `null`**: para mandarle el cobro a tu cliente usa `url` |
| `qr_png` | texto o `null` | QR de `wa_deeplink` (imagen PNG en `data:` URL). **Hoy llega en `null`** |
| `comercio` | texto | El código de tu comercio |
| `monto` | número | Monto en bolívares que pide el cobro. No cambia aunque tu cliente agregue propina |
| `propina` | número | Propina que agregó tu cliente al pagar, en bolívares (`0` si no agregó). Sólo aparece si activaste propinas en el portal → [Propinas](https://docs.pagaconquickpay.com/developers/propinas) |
| `total` | número | Lo que se le debitó a tu cliente: `monto` + `propina`. Sin propina es igual a `monto` |
| `moneda` | texto | `VES` |
| `concepto` | texto | Lo que ve tu cliente al pagar |
| `estado` | texto | `pendiente`, `cobrando`, `procesando`, `revision`, `pagado`, `expirado` o `cancelado` → [Estados](https://docs.pagaconquickpay.com/developers/ciclo-de-vida) |
| `expires_at` | fecha (ISO, UTC) | Cuándo vence |
| `paid_at` | fecha (ISO, UTC) | Cuándo se pagó |
| `txn_id` | texto | Id de la transacción del pago |
| `created_at` | fecha (ISO, UTC) | Cuándo se creó |
| `metadata` | objeto | Tus datos (al crear) |
| `success_url` | texto | A dónde vuelve el cliente (al crear) |
| `failure_url` | texto | A dónde vuelve el cliente si el pago no puede continuar: el cobro venció, lo cancelaste o él elige "Cancelar y volver" tras un rechazo (al crear). → [Volver a tu web](https://docs.pagaconquickpay.com/developers/volver-a-tu-web) |
| `idempotency_key` | texto | Tu llave para no duplicar (al crear) |
| `mode` | texto | `test` o `live`: el ambiente del cobro. Viene en la respuesta de crear y dentro de `data` en los avisos `link.pagado` y `link.acreditado` |
| `codigo_verificacion` | texto | Código del comprobante (`QP-XXXXX-XXXXX`) de un cobro `pagado`. Quien lo reciba puede comprobar en [pagaconquickpay.com/verificar](https://docs.pagaconquickpay.com/developers/enlaces-de-pago#verificar-un-comprobante) que el comprobante es auténtico. Viene al consultar o listar un enlace pagado (`null` en los demás estados) y dentro de `data` en el aviso `link.pagado`. Es `null` si por ahora no se pudo generar |
| `pagador` | objeto | Lo que sabemos de quien pagó. Hoy trae sólo `alta_cliente` |
| `alta_cliente` | sí/no | Dentro de `pagador`. `true` si quien paga marcó en la página de pago "Quiero ser cliente de *tu comercio* y recibir sus novedades" (la casilla viene desmarcada). Con el cobro `pagado`, esa persona aparece en **Clientes** del portal → [Página de pago](https://docs.pagaconquickpay.com/developers/enlaces-de-pago#quiero-ser-cliente). No trae su cédula, teléfono ni nombre |
| `idempotent_replay` | sí/no | `true` cuando repetiste la creación con la misma `idempotency_key` y te devolvemos el enlace que ya existía |
| `split` | lista | Sólo en enlaces con [pago dividido](https://docs.pagaconquickpay.com/developers/pago-dividido) (piloto): las reglas del reparto que mandaste al crearlo. Viene al crear y al consultar el enlace |
| `reparto` | objeto o `null` | Sólo en enlaces con pago dividido: al consultar el enlace, `null` hasta que el pago se liquida y después lo que se llevó cada cuenta (`estado`: `pendiente`, `repartido`, `en_revision` o `cerrado`; `monto_comercio`, `monto_repartido`, `beneficiarios`). También dentro de `data` en el aviso `link.acreditado` → [Pago dividido](https://docs.pagaconquickpay.com/developers/pago-dividido#ver-el-reparto) |

## Respuesta de `POST /links/:id/simular` (sólo cobros de prueba)

| Campo | Qué es |
|---|---|
| `id` | El `id` del cobro |
| `estado` | Estado en que queda el cobro: `pagado`, `pendiente` o `expirado` |
| `resultado` | Lo que pediste simular: `pagado`, `rechazado` o `expirado` |
| `simulado` | Siempre `true` |

## Respuesta de `POST /links/:id/cancelar`

| Campo | Qué es |
|---|---|
| `id` | El `id` del cobro |
| `estado` | `cancelado` |

## Aviso `link.pagado` (campo `data`)

| Campo | Qué es |
|---|---|
| `link_id` | El `id` del cobro |
| `txn_id` | Id de la transacción |
| `estado` | `pagado` |
| `monto`, `moneda`, `concepto` | Del cobro (`monto` es el del enlace, sin propina) |
| `propina` | Propina que agregó tu cliente (`0` si no agregó) |
| `total` | Lo debitado: `monto` + `propina` |
| `referencia` | Referencia del banco (`SIMULADO` en un cobro de prueba) |
| `mode` | `live` o `test`: si el pago fue de producción o simulado |
| `codigo_verificacion` | Código del comprobante, para que tu cliente (o tú) lo verifique en pagaconquickpay.com/verificar |
| `pagador` | `{ "alta_cliente": true }` si quien pagó pidió ser tu cliente y recibir tus novedades; `false` si no |
| `metodo` | Sólo viene si tu cliente pagó con tarjeta (piloto): `"tarjeta"`. Sin este campo, el pago fue con débito inmediato → [Pagar con tarjeta](https://docs.pagaconquickpay.com/developers/enlaces-de-pago#pagar-con-tarjeta-piloto) |
| `recargo_tarjeta` | Sólo con `metodo: "tarjeta"`: recargo por pago con tarjeta que pagó tu cliente además del `total`. No es tuyo ni se te liquida |

## Aviso `link.acreditado` (campo `data`)

| Campo | Qué es |
|---|---|
| `link_id` | El `id` del cobro |
| `txn_id` | Id del pago del cliente |
| `liquidacion_txn_id` | Id de la transferencia a tu cuenta |
| `monto_bruto` | Lo que pagó tu cliente (con la propina, si agregó una) |
| `comision` | Comisión descontada |
| `monto_acreditado` | Lo que llegó a tu cuenta |
| `estado` | `acreditado` |
| `moneda` | `VES` |
| `referencia_bancaria` | Referencia del banco de la transferencia a tu cuenta |
| `banco_destino` | Código del banco de tu cuenta |
| `referencia_cobro` | Referencia del banco del pago de tu cliente |
| `mode` | `live` o `test`: si la acreditación fue real o simulada |
| `reparto` | Sólo con [pago dividido](https://docs.pagaconquickpay.com/developers/pago-dividido): lo que se llevó cada cuenta. En ese caso `monto_acreditado` es sólo tu parte |

## Aviso `link.devuelto` (campo `data`, piloto)

| Campo | Qué es |
|---|---|
| `link_id` | El `id` del cobro que se devolvió |
| `devolucion_id` | Id de la devolución (un cobro puede tener varias devoluciones parciales) |
| `estado` | `completada`: el dinero salió hacia tu cliente |
| `monto` | Lo que se le devolvió a tu cliente en esta devolución |
| `monto_devuelto` | Lo devuelto en total de ese cobro, contando las devoluciones anteriores |
| `moneda` | `VES` |
| `referencia_bancaria` | Referencia del banco de la transferencia a tu cliente. Puede venir `null` |
| `mode` | `live` o `test`: si la devolución fue real o simulada |

## Avisos `transaccion.*` (campo `data`)

| Campo | Qué es |
|---|---|
| `id` | El `id` de la operación |
| `estado` | `LIQUIDADA` o `RECHAZADA` (con una llave de prueba, `ACEPTADA`) |
| `monto`, `moneda`, `concepto` | De la operación |
| `referencia` | Referencia del banco |
| `operacion` | De qué es: `cobro`, `pago`, `reverso`, `devolucion_debito`, `devolucion` o `devolucion_retorno` → [Webhooks](https://docs.pagaconquickpay.com/developers/webhooks-referencia) |

<!-- https://docs.pagaconquickpay.com/developers/changelog -->

# Novedades

## 16 de octubre de 2026

- **Conecta QuickPay a tu IA, sin copiar llaves.** Agrega `https://mcp.pagaconquickpay.com/mcp` en Claude, ChatGPT, Claude Code o Cursor, entra con el correo de tu comercio (el del portal) y autoriza. Empiezas en modo prueba; producción se elige al autorizar si tu cuenta está aprobada. Tu IA puede crear, listar, ver y cancelar enlaces de cobro, consultar una transacción y ver tus liquidaciones y los bancos; no puede enviar, devolver ni sacar dinero. Quien ya usaba el MCP con su llave en el header `x-switch-key` no tiene que cambiar nada. → [Conectar por MCP](https://docs.pagaconquickpay.com/developers/mcp) · [Guía del MCP en PDF](https://docs.pagaconquickpay.com/developers/mcp.pdf)
- **Menú «IA y MCP»** en la documentación, con el MCP, la documentación para tu IA, las guías en PDF y `llms.txt`.
- **Respuestas sin datos internos.** Con tu llave, `POST /switch/v1/cobrar`, `/cobrar/token`, `/pagar`, `/consultar` y `/reverso` ya no traen `banco_usado` ni `raw`. Para saber qué pasó sigue `estado`, y si fue rechazada, `motivo_rechazo`, que es igual para todos los bancos. El listado y la exportación de `GET /switch/v1/transacciones` ya no traen la columna `banco`, `GET /switch/v1/config` ya no trae `rieles` y los avisos `transaccion.*` ya no traen `banco`. Si leías alguno de esos campos, deja de hacerlo; lo demás no cambia. → [API directa](https://docs.pagaconquickpay.com/developers/api-directa)
- **`GET /switch/v1/bancos` y `GET /switch/v1/politica-dinero` pasan a uso interno:** responden `403` `solo_uso_interno` a las llaves de comercio. Para comprobar que tu llave funciona usa `GET /switch/v1/transacciones?limit=1`. La referencia interactiva (`/docs`, `/openapi.json`) ya no lista rutas de uso interno.
- **Toda la documentación en un archivo.** Descarga la [guía esencial en PDF](https://docs.pagaconquickpay.com/developers/quickpay-docs.pdf) (portada, índice y lo necesario para empezar), lee todo [en una sola página](https://docs.pagaconquickpay.com/developers/todo) o baja el [.md para tu IA](https://docs.pagaconquickpay.com/developers/quickpay-docs.md) (Claude, ChatGPT, Cursor). También publicamos `llms.txt` y `llms-full.txt`. → [Con tu IA o en PDF](https://docs.pagaconquickpay.com/developers/con-tu-ia)

## 14 de octubre de 2026

- **Página de pago con `success_url`: llegada y vuelta más claras.** Al abrir el enlace, una pantalla de 2,5 segundos muestra tu comercio, el concepto y el monto, y avisa que el pago lo procesa QuickPay (se salta con **Continuar**). Al pagar, en vez de un aviso pequeño al final del comprobante, aparece arriba "Volviendo a <tu comercio> en 3 s" con la cuenta regresiva y el botón **Volver ahora**. Los datos que llegan a tu `success_url` no cambian. Quien paga con **tarjeta** (piloto) ahora también vuelve a tu `success_url`: Credicard lo regresa a la página de pago y de ahí a tu web, con la operación QuickPay como `referencia`. → [Volver a tu web](https://docs.pagaconquickpay.com/developers/volver-a-tu-web)
- **Avisos `transaccion.*`: campo nuevo `operacion`.** Dice de qué es la transacción: `cobro`, `pago`, `reverso`, `devolucion_debito`, `devolucion` o `devolucion_retorno`. Así un envío de dinero (la transferencia del neto a tu cuenta, un reintegro o una devolución) ya no llega con la misma forma que un pago que recibiste. Los demás campos no cambian; si entregas con `transaccion.liquidada`, entrega sólo cuando `operacion` sea `cobro`. → [Webhooks](https://docs.pagaconquickpay.com/developers/webhooks-referencia)
- **Aviso nuevo `link.devuelto` (piloto).** Devoluciones de cobros desde el portal: llega cuando una devolución llegó a tu cliente, con `monto` (esta devolución) y `monto_devuelto` (el total devuelto de ese cobro). Las devoluciones están en piloto con algunas cuentas; si no están activas para la tuya, este aviso no llega. → [Webhooks](https://docs.pagaconquickpay.com/developers/webhooks-referencia)
- **Reintegro con llave en vivo.** `POST /switch/v1/reintegro` con una llave de comercio en vivo (`sk_live`) responde **403 `reintegro_no_habilitado`**: el reintegro sale de la cuenta de QuickPay, no de la tuya. Con tu llave de prueba (`sk_test`) sigue funcionando igual.
- **Página de pago, «Pedir otra clave»:** después de pedir una clave nueva, la página le dice a tu cliente que escriba sólo la última que le llegó, porque las anteriores pueden no servir.

## 13 de octubre de 2026

- **Cuentas nuevas con aprobación automática nacen con tope.** Mientras una persona de QuickPay no revisa el alta, la cuenta puede recibir hasta US$ 300 por día y US$ 1.000 en total (en bolívares, con la tasa oficial del BCV en el momento de cada cobro). Cuando la revisamos, subimos o quitamos el tope. Las cuentas que ya tenían topes, o que aprobó una persona, no cambian. → [Límites](https://docs.pagaconquickpay.com/developers/limites-y-reglas)
- **Máximo diario por cuenta:** cuenta sólo lo que recibes en cobros (antes sumaba también los pagos que te hacemos a tu cuenta, así que el tope se llenaba a la mitad) y el día va de medianoche a medianoche hora de Venezuela (antes cortaba a las 8:00 p. m.). → [Límites](https://docs.pagaconquickpay.com/developers/limites-y-reglas)
- **Monto máximo por cobro y por día, también en dólares.** El monto mínimo y máximo por cobro y el máximo por día que QuickPay le fija a una cuenta pueden estar en dólares; en ese caso se convierten a bolívares con la tasa oficial del BCV en el momento de cada operación. Los que están en bolívares no cambian, y el error sigue siendo `EXCEDE_LIMITE` (o `MONTO_INVALIDO` por debajo del mínimo). → [Límites](https://docs.pagaconquickpay.com/developers/limites-y-reglas)
- **Topes en dólares.** El tope de lo que recibes por día y en total también puede estar en dólares. En ese caso se convierte a bolívares con la tasa oficial del BCV en el momento de cada cobro, así que no pierde valor cuando sube el dólar. Los errores y mensajes son los mismos; con tu llave, el `409` de `POST /cobrar/token` sigue trayendo `tope` y `usado` en Bs y agrega `topes_moneda`, `tope_usd` y `tasa_bcv`. Los topes en bolívares no cambian. → [Límites](https://docs.pagaconquickpay.com/developers/limites-y-reglas)
- **Tope de lo que recibes, por día y en total.** QuickPay puede fijarle a una cuenta un tope de lo que recibe por día (hora de Venezuela) y otro en total. Si no tienes, nada cambia. Con el tope lleno, tu cliente no puede pedir la clave de pago: la página de pago y el WhatsApp Flow le muestran el mensaje, y `POST /cobrar/token` responde `409` `tope_diario_excedido` o `tope_acumulado_excedido`. Quien ya tenía su clave termina su pago. → [Límites](https://docs.pagaconquickpay.com/developers/limites-y-reglas)
- **`link.pagado` sólo con el pago confirmado por el banco.** Antes, un cobro pasaba a `pagado` y te llegaba `link.pagado` apenas el banco recibía la orden de débito, aunque todavía no confirmara que el dinero se movió. Ahora espera la confirmación: según el banco de tu cliente, puede llegar en el mismo momento del pago, como antes, o el cobro queda en `procesando` y `link.pagado` llega cuando el banco confirma (suele tardar menos de un minuto, pero a veces bastante más). Si el banco termina rechazándolo, el cobro vuelve a `pendiente` y no llega aviso. Sigue llegando una sola vez por cobro y con los mismos campos. Si tu sistema entrega con `link.pagado` o con el estado `pagado`, no tienes que cambiar nada; no entregues con `procesando`. Los cobros de prueba no cambian. → [Estados de un cobro](https://docs.pagaconquickpay.com/developers/ciclo-de-vida)
- **Página de pago:** quien paga desde otro banco ve "Procesando tu pago" hasta que el banco confirma, y luego el comprobante con la referencia bancaria.
- **`transaccion.aprobada` sólo con la operación confirmada por el banco.** Antes llegaba con `ACEPTADA`, cuando el banco recibía la orden de débito ("enviada a BCV") y todavía no confirmaba que el dinero se movió. Ahora llega cuando la operación queda `LIQUIDADA`, una sola vez, junto con `transaccion.liquidada`, y su `data.estado` es `"LIQUIDADA"` (antes `"ACEPTADA"`). Si entregabas con `transaccion.aprobada`, ahora entregas con la confirmación del banco; si comparabas `data.estado` con `"ACEPTADA"`, compáralo con `"LIQUIDADA"`. Con llave de prueba no cambia: el cobro simulado avisa en el acto. → [Webhooks](https://docs.pagaconquickpay.com/developers/webhooks-referencia)
- **WhatsApp Flow del switch:** el mismo cambio. El Flow ya no muestra el pago como hecho apenas el banco recibe la orden: según el banco de quien paga, se confirma en ese momento o ve "Tu pago se está procesando" y el pago se confirma cuando el banco lo liquida. Los Flows de prueba no cambian.
- **API directa:** la guía decía que un cobro `ACEPTADA` ya era exitoso. No lo es: `ACEPTADA` es "enviada a BCV"; el cobro está confirmado con `LIQUIDADA`. → [API directa](https://docs.pagaconquickpay.com/developers/api-directa)

## 12 de octubre de 2026

- **Portal y página de pago:** un cobro pagado dice siempre **Pagado** (antes, si ya se había acreditado, decía «En tu banco»); el detalle del pago sigue indicando si está acreditado o por acreditar. Abrir el enlace de un cobro ya pagado muestra el comprobante con el mismo diseño de cuando se paga, sin datos de quien pagó.
- **Pago con tarjeta, «No completé el pago»:** si la tarjeta fue rechazada o la persona cerró la página de Credicard, en la pantalla «Estamos confirmando tu pago con tarjeta» puede tocar **No completé el pago: pagar de otra forma**. QuickPay le pregunta a Credicard: si no cobró, el enlace vuelve a estar disponible al instante (antes había que esperar unos minutos); si sí cobró, el enlace queda pagado.
- **La página de pago recuerda a quien paga:** después del primer pago, el teléfono, la cédula y el nombre quedan guardados sólo en el navegador de esa persona, y la próxima vez vienen llenos. Si ya marcó «Quiero ser cliente» de ese comercio, en vez de la casilla ve «Ya eres cliente». «No soy yo» borra los datos guardados (por si el teléfono es compartido). Nada de esto se busca en el servidor.
- **Pagar con tarjeta (piloto, apagado):** la página de pago de un enlace puede ofrecer, además del débito inmediato, **Pagar con tarjeta** de débito o crédito por Credicard, con la lista de bancos de débito aceptados y el total con el recargo por pago con tarjeta (lo paga tu cliente) antes del botón. Se enciende por comercio; si no está activo para tu cuenta, nada cambia. El enlace sigue pagándose una sola vez y queda `pagado` sólo cuando Credicard confirma el cobro. El aviso `link.pagado` de esos pagos trae `"metodo": "tarjeta"` y `recargo_tarjeta`; se te liquida lo mismo que con débito inmediato, cuando Credicard abona el pago. → [Pagar con tarjeta](https://docs.pagaconquickpay.com/developers/enlaces-de-pago#pagar-con-tarjeta-piloto)
- **Cuenta aprobada al registrarte:** al terminar el registro y la verificación con Bs 1, la cuenta queda lista para cobrar dinero real, sin esperar revisión. El equipo de QuickPay revisa cada alta después.
- **Portal:** aviso de mantenimiento de los bancos en el encabezado (desde las 11:30 p. m.); en Estadísticas, tu mejor día y bloque pico en porcentaje y el ticket promedio por horario según tu tipo de negocio.
- **Bancos en mantenimiento en la página de pago:** de 11:45 p. m. a 1:30 a. m. (hora de Venezuela) la página muestra arriba **Bancos en mantenimiento** y no deja pedir la clave de pago, en vez de dejar que tu cliente llene todo y falle al final. Desde 15 minutos antes avisa, sin bloquear, cuántos minutos faltan. La página se actualiza sola cada 30 segundos. Pedir la clave dentro de la franja responde `503` con `{ "error": "cierre_bancario", "motivo": "…", "reintentar_en": <segundos> }`. Lo que ya estaba en curso termina normalmente y los enlaces de prueba no se afectan. → [Cierre diario](https://docs.pagaconquickpay.com/developers/enlaces-de-pago#cierre-diario-de-los-bancos)
- **Cobro por WhatsApp Flow:** en esa misma franja, pedir la clave desde tu Flow de producción vuelve a la pantalla de datos con el mismo mensaje y no le pide nada al banco. Confirmar un pago con una clave ya pedida sigue igual.

## 11 de octubre de 2026

- **Nombre comercial en la página de pago:** si escribes un nombre comercial en el portal (**Ajustes › Tu cuenta**), quien te paga lo ve en la página de pago y en el comprobante en lugar de la razón social. La razón social sigue siendo la que usan el banco y la verificación. → [Portal](https://docs.pagaconquickpay.com/developers/portal)
- **Webhooks, Probar:** el aviso de prueba del portal (`webhook.test`) ahora va firmado igual que los reales: `x-quicklink-event`, `x-quicklink-timestamp` y `x-quicklink-signature-v2`. Antes llevaba sólo la firma anterior, así que un servidor que verifica la v2 como indica esta guía lo rechazaba y el portal decía que no llegó. → [Webhooks](https://docs.pagaconquickpay.com/developers/webhooks-referencia)
- **Webhooks, Eliminar:** el portal permite borrar un webhook (**Integraciones › Webhooks › Eliminar**) sin llave de producción. → [Webhooks](https://docs.pagaconquickpay.com/developers/webhooks-referencia)
- **Pago dividido:** un enlace puede repartir el neto de su pago entre hasta 5 cuentas además de la tuya, por porcentaje o monto fijo; el resto es tuyo. Se configura con `split` al crear el enlace, corre con la liquidación inmediata y sólo reparte cuando el banco confirma que el pago entró. Está en piloto detrás de una bandera: si no está activo para tu cuenta, `split` responde `400` `split_no_disponible`. → [Pago dividido](https://docs.pagaconquickpay.com/developers/pago-dividido)
- **`GET /links/:id`** de un enlace con reparto trae `split` y `reparto`; el aviso `link.acreditado` trae `reparto` y llega cuando todo el reparto terminó. Los enlaces sin `split` no cambian.
- **Reintegro:** si el reparto de un pago ya le pagó a algún beneficiario, responde **409 `cobro_con_split_repartido`**.
- **Pago dividido, cuentas aprobadas:** sólo se reparte a cuentas que apruebas en el portal (**Ajustes → Cuentas para pago dividido**); las cuentas aprobadas no se cambian con tu llave. Una cuenta sin aprobar responde `400` `split_cuenta_no_preaprobada`; una que un control de seguridad frena o que pasa el tope diario por beneficiario, `400` `split_beneficiario_bloqueado`. Antes de pagarle a cada cuenta se revisa otra vez: si ya no pasa, esa parte queda en revisión y no se paga sola. `reparto.estado` suma `cerrado` y cada beneficiario puede quedar `descartado` (se cerró sin pagarle, con una nota). → [Pago dividido](https://docs.pagaconquickpay.com/developers/pago-dividido)
- **Modo prueba: más desenlaces forzados.** Además de `11111111` (rechazo) y `22222222` (pendiente y luego aprueba), ahora `11111112` rechaza por fondos insuficientes, `11111113` por clave inválida, `11111114` simula banco no disponible y `33333333` tarda unos 8 segundos en confirmar y luego aprueba. Los rechazos no envían webhook y las aprobaciones envían `link.pagado` con `"mode": "test"`, igual que en producción. Sólo existen con una llave `sk_test_`; en producción no hacen nada especial. → [Modo prueba](https://docs.pagaconquickpay.com/developers/datos-de-prueba)
- **Botón de pago en una línea:** `<script src="https://pay.pagaconquickpay.com/boton.js" data-link="ID_O_SLUG"></script>` pinta el botón **Pagar con QuickPay** y abre el pago en una pestaña (o en una ventana con `data-abrir="ventana"`). No usa llaves ni ejecuta nada de lo que escribas en los atributos. → [Botón para tu web](https://docs.pagaconquickpay.com/developers/boton-de-pago)
- **Página de estado de los cobros:** [/estado](https://docs.pagaconquickpay.com/estado) y [/estado.json](https://docs.pagaconquickpay.com/estado.json) ahora muestran el estado de los cobros con débito inmediato (operativo, degradado, caído o sin datos recientes), con la hora de actualización, y los incidentes de los últimos 7 días. No se nombra a los bancos. Sin llave.
- **`failure_url`:** la guía [Volver a tu web](https://docs.pagaconquickpay.com/developers/volver-a-tu-web) ya describe exactamente los tres casos (`expirado`, `cancelado` y `rechazado`), también cuando el cobro vence o se cancela mientras tu cliente está pagando.

## 10 de octubre de 2026 (segunda auditoría de seguridad)

- **Un cobro `ACEPTADA` se confirma con el banco antes de devolverlo.** `POST /switch/v1/reintegro` sobre un cobro en `ACEPTADA` consulta al banco en ese momento y sólo devuelve si queda `LIQUIDADA`. Si el banco todavía no lo confirma, responde **409 `cobro_no_confirmado_banco`**: no es definitivo, vuelve a intentarlo más tarde.
- **Un reintento a la vez por cobro:** si llega un `retry_nonce` mientras otro intento de reintegro del mismo cobro está en curso, responde **409 `reintegro_en_curso`** y no emite otro pago.
- **Liquidación en revisión:** si el pago de ese cobro a tu cuenta quedó en revisión después de enviarse, el reintegro también responde **409 `cobro_ya_liquidado_al_comercio`**.
- **Pedir la clave de pago:** las solicitudes que el banco rechaza (cédula o teléfono mal escritos) ya no cuentan para los topes, y el tope por pagador se aplica al par cédula + teléfono (antes, a cualquiera de los dos). En producción se suma un tope de 10 solicitudes cada 10 minutos por conexión. El conteo es atómico: varias solicitudes simultáneas no se saltan el tope. → [Límites](https://docs.pagaconquickpay.com/developers/limites-y-reglas)
- **Enviar dos veces el pago:** el segundo envío espera al primero durante todo el plazo de respuesta del banco (antes, 90 s fijos) y responde `procesando` sin mandar el cobro a revisión.
- **Webhooks:** `POST`, `PATCH` y `DELETE /switch/v1/webhooks` exigen una `sk_live_` (con `sk_test_`, `403` `requiere_llave_live`): el webhook recibe también los avisos de producción. Listar y ver los webhooks sigue funcionando con cualquier llave, y el portal permite registrar la URL sin llave de producción. → [Webhooks](https://docs.pagaconquickpay.com/developers/webhooks-referencia)
- **Historial de entregas con `sk_test_`:** `GET /switch/v1/webhooks/:id/deliveries` sólo lista las entregas de avisos de prueba (`data.mode: "test"`). Las de producción, y los avisos `transaccion.*`, sólo se ven con una `sk_live_`. → [Webhooks](https://docs.pagaconquickpay.com/developers/webhooks-referencia)
- **Flows:** `POST /switch/v1/flow/config` y `PUT /switch/v1/flows/definicion` exigen siempre `sk_live_` (antes sólo si ya tenías un Flow de producción). → [Llaves y entornos](https://docs.pagaconquickpay.com/developers/llaves-y-entornos)
- **Lotes de dispersión:** `GET /switch/v1/dispersiones/:id` y `POST /switch/v1/dispersiones/:id/cancelar` responden **404** si el lote es de otro modo que tu llave.
- **Llaves:** al crear una llave por API, el `label` no puede empezar por `service-key:` ni `partner:`; responde `400` con `label_reservado`. → [Llaves y entornos](https://docs.pagaconquickpay.com/developers/llaves-y-entornos)
- **Cobro por WhatsApp Flow:** un binding con `monto_fijo` ya no cobra si el Flow manda otro monto (antes cobraba el fijo sin avisar). Nuevo modo opcional `exigir_monto_firmado`: tu bot firma el monto de cada orden en el `flow_token` con un `monto_secret` que sólo vive en tu servidor. Sin estas opciones nada cambia.

## 10 de octubre de 2026 (operaciones sobre una transacción)

- **El modo de la llave manda:** `POST /switch/v1/consultar` y `POST /switch/v1/reintegro` responden **404** si el `id` es de otro modo que tu llave (una llave de prueba no consulta ni devuelve un cobro real, y al revés).
- **`retry_nonce` del reintegro sólo reintenta lo que el banco rechazó sin mover dinero.** Si un intento anterior quedó sin respuesta clara (`DESCONOCIDA`, `PENDIENTE`, `ERROR` o un código técnico), responde **409 `reintegro_intento_ambiguo`** y no se emite otro pago hasta conciliarlo. Si ningún intento anterior existe, **409 `reintegro_sin_intento_previo`**: el primer intento va sin `retry_nonce`. Si alguno ya pagó, sigue siendo **409 `reintegro_ya_pagado`**.
- **No se reintegra un cobro que ya se te liquidó:** con liquidación inmediata, si el pago de ese cobro a tu cuenta está en curso o hecho, el reintegro responde **409 `cobro_ya_liquidado_al_comercio`**.

## 10 de octubre de 2026 (seguridad)

- **`POST /switch/v1/pagar` y `POST /switch/v1/dispersiones`** debitan una cuenta de QuickPay: con una llave de comercio sin habilitación responden `403` con `{ "error": "pagar_no_habilitado" }`. → [API directa](https://docs.pagaconquickpay.com/developers/api-directa)
- **`GET /switch/v1/saldo` y `GET /switch/v1/movimientos` pasan a uso interno**: responden `403` `cuenta_no_permitida` a las llaves de comercio. Lo tuyo lo ves en Transacciones y Cartera.
- **Verificar un comprobante** trae `concepto`, `referencia_externa` y cuántas veces se ha verificado el código (`verificaciones`, `primera_verificacion`). Lo que ya leías no cambia. → [Verificar un comprobante](https://docs.pagaconquickpay.com/developers/enlaces-de-pago#verificar-un-comprobante)
- **Límite de peticiones:** las peticiones sin llave, o con una llave que no es válida, se cuentan por la IP de quien llama, y nunca contra el cupo de un comercio.
- **Errores `500`** responden `{ "error": "error_interno" }`, sin el detalle interno.

## 10 de octubre de 2026 (seguridad de llaves y webhooks)

- **Llaves:** una llave de prueba (`sk_test_`) sólo crea y revoca llaves de prueba. Crear o revocar una de producción exige una `sk_live_`; si no, `403` con `requiere_llave_live`. → [Llaves y entornos](https://docs.pagaconquickpay.com/developers/llaves-y-entornos)
- **Webhooks:** la URL tiene que llegar a una dirección pública (una de red interna responde `422` con `destino_bloqueado`), no seguimos redirecciones (una `3xx` cuenta como no entregada) y hay un máximo de 10 webhooks por comercio (`409` con `limite_webhooks`). El historial de entregas trae el campo `error`. → [Webhooks](https://docs.pagaconquickpay.com/developers/webhooks-referencia)

## 10 de octubre de 2026 (prueba y producción separadas)

- **Cada llave sólo ve y toca lo de su modo.** Con `sk_test_` ya no se consultan, listan, editan ni cancelan enlaces, lotes, órdenes, suscripciones, productos, propinas ni miembros del equipo creados con `sk_live_` (responde `404`), y al revés. `GET /links` sin `mode` trae sólo los del modo de tu llave. → [Llaves y entornos](https://docs.pagaconquickpay.com/developers/llaves-y-entornos)
- **`idempotency_key` por modo:** la misma llave en prueba y en producción crea dos objetos distintos; con `sk_live_` nunca recibes un enlace, lote u orden de prueba. Nuevo `409 idempotency_key_en_uso` si la llave choca con una usada en el otro modo. → [No duplicar cobros](https://docs.pagaconquickpay.com/developers/enlaces-de-pago)
- **Página de pago:** pedir la clave de pago tiene tope (5 por hora por cobro; en producción, con los mismos datos, 3 cada 10 minutos y una por minuto). Si tu cliente envía dos veces el pago, el segundo envío espera al primero en vez de dejar el cobro en revisión; y un cobro en `revision` que el banco termina de confirmar o rechazar se cierra solo. → [Límites](https://docs.pagaconquickpay.com/developers/limites-y-reglas)

## 9 de octubre de 2026 (conciliación de pagos entrantes)

- **`POST /switch/v1/conciliar`, `/conciliar/saliente` y `/conciliar/multiple` pasan a uso interno**: responden 403 a las llaves de comercio. Para saber si te pagaron, usa el estado del enlace o el aviso `link.pagado`.
- **`ya_conciliado: true` ya no cuenta como pagado**: el banco la responde aunque el monto no coincida. Sólo `conciliado: true` autoriza entregar, y exige el monto exacto y una referencia que no se haya usado antes. Nuevo campo `revision` para los casos que revisa una persona.

## 9 de octubre de 2026 (cuentas demo)

- **Inicio y Transacciones en las cuentas de demostración:** lo cobrado (hoy, en el mes y en lo filtrado) suma los pagos simulados, que son los únicos que tiene una demo. En las demás cuentas sigue igual: sólo pagos reales, con «Sin contar N de prueba». → [Portal](https://docs.pagaconquickpay.com/developers/portal#cuentas-personales)

## 9 de octubre de 2026 (Clientes y Suscripciones a escala)

- **Clientes y Suscripciones se cargan de 50 en 50** con el total exacto de lo filtrado y **Ver más**. Antes mostraban sólo los primeros 1.000 clientes y 2.000 suscriptores y el resto no aparecía; ahora nada se queda fuera. → [Clientes y cobranza](https://docs.pagaconquickpay.com/developers/clientes-y-cobranza#buscar-filtrar-y-descargar)
- **Filtros de Clientes** en la dirección de la página, con etiquetas que se quitan con la **x**: etiqueta, suscripción y plan, estado de pago, último pago, total pagado (en Bs o en tu divisa), cómo llegó, aceptan novedades, WhatsApp, correo, fecha de alta y los de tu tipo de negocio.
- **Etiquetas de clientes** con color (se ponen a uno o a muchos) y **segmentos automáticos**: morosos, nuevos (30 días), frecuentes, aceptan novedades y sin pagar hace 60 días. Se pueden usar para filtrar Clientes, Suscripciones y Transacciones, y para enviar una cobranza **a una etiqueta**. El Cobrador las ve y filtra; no las administra. → [Etiquetas](https://docs.pagaconquickpay.com/developers/clientes-y-cobranza#etiquetas)
- **Estado de pago, último pago y total pagado** por cliente y por suscriptor, a partir de los pagos confirmados. Cuentan los pagos que se pueden ligar a la persona; un cobro suelto no. → [Estado de pago](https://docs.pagaconquickpay.com/developers/clientes-y-cobranza#estado-de-pago-ultimo-pago-y-total-pagado)
- **Acciones en grupo** sobre lo elegido o sobre **todo lo filtrado** (máximo 5.000 por acción; con más, se pide afinar en vez de dejar a alguien fuera): etiquetar, quitar etiqueta, enviar cobranza y suscribir; en Suscripciones, también pausar, reanudar y cambiar de plan. **Descargar** en Excel o CSV lo filtrado.
- **Suscripciones:** resumen arriba, pestaña **Métricas** (ingreso mensual recurrente, morosidad, altas y bajas, cobrado vs esperado), **historial de cobros** por suscriptor y **Editar suscriptor**: cambiar de plan **desde el próximo cobro y sin prorrateo**, y **precio especial o descuento** (en %, fijo o precio fijo) con motivo, aplicado a cada cobro que se genere. → [Suscripciones](https://docs.pagaconquickpay.com/developers/suscripciones#editar-a-un-suscriptor)
- **Agregar suscriptores:** quien ya está en el plan sale deshabilitado ("Ya suscrito"), quien está en otro lleva su plan como etiqueta y "Elegir todos" respeta eso. Ya no se le pisa el canal a quien ya estaba suscrito.
- **Enlace para suscribirse solo:** cada plan puede tener un enlace público donde la persona elige el plan, deja sus datos y paga el primer cobro; **queda suscrita sólo cuando el pago se confirma**. → [Enlace para que se suscriban solos](https://docs.pagaconquickpay.com/developers/suscripciones#enlace-para-que-se-suscriban-solos)

## 9 de octubre de 2026 (cuentas personales)

- **Cuentas personales:** quien abre su cuenta con **Para mí** ve un portal más corto: Inicio, Cobrar, Movimientos, Contactos y Ajustes, sin Cobranza masiva, Suscripciones, Productos, Sucursales, Integraciones ni Equipo. → [Cuentas personales](https://docs.pagaconquickpay.com/developers/portal#cuentas-personales)
- **Página de pago:** si quien cobra es una persona, la casilla dice «Guardar mis datos para pagarle más rápido a *su nombre*.» y no exige el nombre. En los negocios queda igual. → [Quiero ser cliente](https://docs.pagaconquickpay.com/developers/enlaces-de-pago#quiero-ser-cliente)
- **Estado de la cuenta:** Inicio, Cobrar y Ajustes dicen lo mismo: cuenta de demostración, en revisión o, si puedes cobrar, sin aviso.
- **Inicio:** las tarjetas dicen «Sin contar N de prueba» cuando hay pagos de prueba. En el detalle de un movimiento, una comisión menor a un centavo se muestra como «< US$ 0,01 (Bs 3,00)».
- **Dirección de tu página de pago:** es la misma en todas las pantallas, incluido el registro.
## 9 de octubre de 2026 (comisión general)

- **Comisión por cobro:** la comisión general por omisión es **1 %** (antes 2 %). Las cuentas que no tienen una comisión acordada usan la general; las que tienen una acordada la conservan. Tu comisión vigente se ve en **Ajustes › Comisión**.

## 9 de octubre de 2026 (revisión de QA)

- **Comisión real:** **Ajustes › Comisión** muestra la comisión que el switch aplica a tu cuenta; si no se puede leer, te pide consultarla con soporte en lugar de mostrar una cifra. En el switch, la comisión acordada por debajo del piso ya no se vuelve a subir al piso (2 %) al verificar o aprobar la cuenta.
- **Clientes › Aceptan novedades** en una cuenta de prueba incluye a quienes marcaron la casilla con un enlace de prueba (etiqueta «Aceptó novedades (prueba)»); nunca entran a envíos reales. → [Clientes y cobranza](https://docs.pagaconquickpay.com/developers/clientes-y-cobranza)
- **Dividir cuenta:** el total muestra «Total ≈ Bs …» y cada persona su equivalente en bolívares. En tu página de pago, con US$ o €, el pagador ve «Pagarás ≈ Bs … a tasa BCV del …».
- **Transacciones:** los pagos de prueba dicen «Pago de prueba» (no «En tu banco») también en Inicio; el detalle muestra el nombre del banco del cliente y el código de verificación; el filtro de monto acepta Bs o tu divisa (se convierte con la tasa de hoy). Propinas › Recibidas sigue el mismo criterio que Transacciones con los pagos de prueba.
- **Página de pago:** la lista «Otro banco» muestra el código junto al nombre y la pantalla «Procesando» ya no parpadea cuando el pago se resuelve en menos de un segundo.
## 9 de octubre de 2026 (planes de WhatsApp)

- **Tu plan se paga desde el portal:** en **Ajustes › Tu plan**, **Cambiar a …** muestra el precio en US$ y en bolívares a la tasa BCV, abre el pago de QuickPay y el plan se activa solo cuando el pago se confirma. Cada pago da 30 días; al subir de plan los días que te quedaban se suman convertidos al precio del nuevo; bajar de plan se aplica al terminar el período; si no renuevas hay 3 días de gracia antes de volver a Gratis. Te avisamos 3 días antes, el día del vencimiento y el día siguiente. → [Tu plan](https://docs.pagaconquickpay.com/developers/portal#tu-plan)

## 9 de octubre de 2026 (noche, propinas en euros)

- **Propinas en euros:** en **Propinas › Ajustes** cada botón puede ser en **€**, además de US$, Bs o %. Tu cliente lo ve como **€ 1 · Bs 39,80**, convertido a la tasa BCV del euro. Si en ese momento no hay una tasa del euro confiable, los botones en € no aparecen; los demás sí. → [Propinas](https://docs.pagaconquickpay.com/developers/propinas)
- **Transacciones › Filtros › Pagos rechazados:** muestra los cobros con al menos un intento de pago rechazado (o los que no tienen ninguno), y el detalle del cobro dice cuántos intentos se rechazaron. Un rechazo deja el cobro pendiente para que tu cliente lo intente de nuevo. → [Filtrar tus transacciones](https://docs.pagaconquickpay.com/developers/portal#filtrar-tus-transacciones)

## 9 de octubre de 2026 (tarde)

- **Transacciones en dólares o euros:** los filtros y los totales cuentan todos tus cobros, no sólo los últimos 5.000. Cada pago se sigue convirtiendo con la tasa BCV de su día de pago (con «≈» si la tasa es aproximada) y un cobro creado en esa misma divisa cuenta con su monto exacto. → [Filtrar tus transacciones](https://docs.pagaconquickpay.com/developers/portal#filtrar-tus-transacciones)

## 9 de octubre de 2026 (mediodía)

- **Divisa del panel:** en **Ajustes › Divisa del panel** eliges ver tus montos en **dólares (por omisión), euros o bolívares**. Inicio (cobrado hoy, este mes, ya en tu banco), Transacciones, Propinas, los lotes de Cobranza y el aviso de pago salen en esa divisa con **los bolívares debajo, en pequeño**. Cada pago se convierte con la tasa BCV de **su día de pago**, no la de hoy; si la tasa es aproximada (euros de días anteriores) se muestra con «≈». El monto que escribes al cobrar arranca en tu divisa. → [Divisa del panel](https://docs.pagaconquickpay.com/developers/portal#divisa-del-panel)
- **Descarga de transacciones:** conserva las columnas en bolívares y agrega las de tu divisa con la **tasa usada** de cada pago.
- **Inicio:** «Cobrado este mes» y «Ya en tu banco» ahora suman todos los cobros del mes; antes podían quedarse cortos con más de 200 cobros.

## 9 de octubre de 2026

- **Listar enlaces con filtros:** `GET /links` ahora acepta varios estados separados por coma (`estado=pagado,procesando`), `desde` y `hasta` (fecha del pago o, si no se pagó, de creación), `q` (concepto, nombre de quien pagó, referencia, `id` o código de verificación), `min` y `max` en Bs, `con_propina`, `mode` y `origen`. Sigue devolviendo una lista y lo que ya usabas no cambia. Un valor que no se entiende en uno de los filtros nuevos responde `400` con `parametro`. → [Listar tus enlaces](https://docs.pagaconquickpay.com/developers/enlaces-de-pago#6-listar-tus-enlaces)
- **`codigo_verificacion` también al listar** (antes sólo al consultar un enlace). Es `null` si el enlace no está pagado. El SDK trae `listarEnlaces`.
- **Pago confirmado más rápido:** cuando el banco nos notifica que un pago en `procesando` se completó, el enlace pasa a `pagado` y sale `link.pagado` en ese mismo momento (antes esperaba la siguiente revisión, hasta 15 segundos después).
- **Transacciones en el portal:** con la divisa del panel en bolívares, los filtros se aplican sobre todos tus cobros (ya no sólo sobre los últimos 5.000); en dólares o euros siguen contando tus últimos 5.000. **Cómo se creó** incluye **Suscripción**. → [Filtrar tus transacciones](https://docs.pagaconquickpay.com/developers/portal#filtrar-tus-transacciones)

## 9 de octubre de 2026 (mañana)

- **Página de pago en Bs, US$ o €:** quien paga escoge la moneda en que escribe el monto y ve la equivalencia en bolívares a la tasa BCV. El cobro se hace en bolívares con la tasa del momento. → [Tu página de pago](https://docs.pagaconquickpay.com/developers/pagina-de-pago)
- **Referencia en €:** si el cobro se hizo con precio en euros, la página de pago muestra el monto en € y la tasa BCV, igual que con US$.

## 9 de octubre de 2026 (madrugada)

- **Transacciones con filtros:** por **fecha** (Hoy, Ayer, Últimos 7 días, Este mes, Mes pasado o un rango, en días de Venezuela), **estado**, **búsqueda** (concepto, cliente o referencia), sucursal, cuenta donde cae el dinero, **monto** mínimo y máximo, propina, cómo se creó el cobro y cobros de prueba. Los filtros quedan en la dirección de la página, se quitan con la **x** y muestran cuántos cobros salieron y cuánto suman. **Descargar** baja exactamente lo filtrado. → [Filtrar tus transacciones](https://docs.pagaconquickpay.com/developers/portal#filtrar-tus-transacciones)
- Un cobro que el banco está revisando se muestra como **En revisión** (antes decía Procesando).
- **Restaurantes sin Suscripciones:** el portal de un restaurante ya no trae planes ni suscripciones, porque no tiene cobros recurrentes. Los demás tipos de negocio no cambian.

## 9 de octubre de 2026 (noche)

- **Página de pago, elegir banco:** cinco bancos a la vista (Venezuela, Banesco, Mercantil, Plaza y Bancaribe) y un botón **Otro banco** que abre la lista con el resto, ordenada por código.
- **Euros en el portal:** donde pones un monto (Cobrar, Dividir cuenta, Nueva cobranza, planes y productos) ahora eliges **Bs, US$ o €** y ves la equivalencia en bolívares a la tasa BCV. Tu cliente sigue pagando en bolívares. Si no hay una tasa del euro confiable en ese momento, la opción € se deshabilita. → [Cobrar desde el portal](https://docs.pagaconquickpay.com/developers/cobrar-desde-el-portal)
- **Dividir cuenta** ahora acepta el total en Bs, US$ o € (antes sólo bolívares).
- **Nueva cobranza** en dos pasos: qué cobras y a quién, con resumen antes de enviar. → [Clientes y cobranza](https://docs.pagaconquickpay.com/developers/clientes-y-cobranza)
- **"Quiero ser cliente" en la página de pago:** tu cliente puede escribir su nombre y marcar "Quiero ser cliente de *tu comercio* y recibir sus novedades" (desmarcada por omisión). Cuando el pago queda confirmado aparece en **Clientes** con **Se registró al pagar** y **Acepta novedades**, sin duplicar a quien ya tenías. Nuevo filtro **Aceptan novedades** en Clientes. → [Quiero ser cliente](https://docs.pagaconquickpay.com/developers/enlaces-de-pago#quiero-ser-cliente)
- **Campo nuevo `pagador.alta_cliente`** (sí/no) al consultar o listar un enlace y en `data` del aviso `link.pagado`. No trae cédula, teléfono ni nombre. Lo que ya leías no cambia.
- **Procesando tu pago:** mientras el banco confirma, la página de pago muestra una pantalla de carga en lugar del formulario, no deja reenviar el pago y pregunta antes de salir. Si se recarga, vuelve a esa pantalla.
- Si tu cliente escribe su nombre al pagar, lo ves en **Transacciones** y en el correo "Recibiste un pago".

## 9 de octubre de 2026 (tarde)

- **Propinas** (restaurantes): tu cliente puede agregar propina al pagar, en la página de pago y en WhatsApp, con tus botones (por omisión US$ 1, 2 y 5 a tasa BCV), **Otro** y **Sin propina**. Se debita junto con el pago en un solo débito. Nueva sección **Propinas** en el portal. → [Propinas](https://docs.pagaconquickpay.com/developers/propinas)
- **Campos nuevos `propina` y `total`** al consultar o listar un enlace y en `data` del aviso `link.pagado`. `monto` no cambia: es el del cobro. Sin propina, `propina` es `0` y `total` es igual a `monto`. Lo que ya leías no cambia.
- **Una cuenta por sucursal:** cada sucursal puede tener su cuenta; al cobrar con esa sucursal el pago cae ahí (y se puede cambiar en cada cobro). También en cobranza masiva, suscripciones, el botón web y el enlace de tu página (`?sucursal=` y `?cuenta=`). → [Equipo y cuentas](https://docs.pagaconquickpay.com/developers/equipo-y-cuentas)
- **Descarga de transacciones:** columna nueva **Propina (Bs)**.

## 9 de octubre de 2026 (mañana)

- **Código de verificación en cada comprobante:** el comprobante de un pago exitoso trae un código (`QP-XXXXX-XXXXX`) y la línea "Verifícalo en pagaconquickpay.com/verificar". Cualquiera puede comprobar ahí que el comprobante es auténtico: así una captura editada no pasa. Para ti es un campo nuevo, `codigo_verificacion`, al consultar un enlace `pagado` y en `data` del aviso `link.pagado`; lo que ya leías no cambia. Nuevo `GET /verificar/:codigo` (público, 20 consultas por minuto por IP). Los pagos de prueba también tienen código y la verificación los marca como "Pago de prueba (no movió dinero)".
- **Registro de negocios:** ahora pregunta a qué se dedica el negocio (o "Otro").
- **Portal por tipo de negocio:** menú con importación por IA en restaurantes, sucursales, urbanizaciones y complejos en condominios, y filtros por cada uno en Transacciones.
- **Suscripciones:** fecha de fin o cantidad de cobros, y pestañas Suscriptores y Planes.
- **Carga masiva:** plantilla de Excel para descargar.

## 8 de octubre de 2026 (noche)

- **Comercio suspendido:** crear enlaces o lotes responde `403` con `comercio_suspendido`, y un enlace `pendiente` muestra "Este comercio no está recibiendo pagos" sin cobrarle nada a tu cliente. Lo que ya se estaba pagando termina normalmente y lo ya pagado se te sigue liquidando. Detalle en [Errores](https://docs.pagaconquickpay.com/developers/errores).

## 8 de octubre de 2026 (tarde)

- **Aviso "Recibiste un pago" por correo** al Propietario y a los Administradores, uno por cobro. Se apaga en **Ajustes › Avisos**.
- **Descargar transacciones** en Excel o CSV desde Transacciones, con el filtro que estás viendo.
- **Recordatorios de suscripción** por plan: 3 días antes, a las 24 horas y un último aviso; por correo, y por WhatsApp si lo activas.
- **Ajustes › Tu plan:** tu plan, tu uso de WhatsApp y los planes disponibles.
- **Equipo:** desactivar a alguien o cambiarle el rol cierra su sesión en su siguiente acción.
- **Liquidación inmediata activada por etapas:** hoy se aplica a pagos pequeños mientras terminamos las pruebas con dinero real.
- **Modo prueba con simulador:** en un cobro de prueba, la clave `11111111` simula un rechazo del banco y `22222222` un pago `procesando` que se aprueba solo a los 30 segundos. Cualquier otra clave de 8 dígitos sigue aprobando.
- **Nuevo `POST /links/:id/simular`** (sólo llave `sk_test_`): fuerza `pagado`, `rechazado` o `expirado` sin abrir la página de pago. En producción responde `403`.
- **Los avisos `link.pagado` y `link.acreditado` traen `data.mode`** (`test` o `live`), para que tu servidor distinga un pago simulado de uno real. Es un campo nuevo: lo que ya leías no cambia.
- **`failure_url` ya funciona:** tu cliente vuelve a esa dirección, con `?estado=expirado`, `cancelado` o `rechazado`, cuando el cobro venció, lo cancelaste o él elige **Cancelar y volver** después de un rechazo del banco.
- **Nuevo `POST /links/:id/cancelar`** con tu llave: cancela un enlace sólo si sigue `pendiente` (si alguien ya está pagando, `409`). El SDK trae `cancelarEnlace` y `simularEnlace`.
- **Página de estado pública:** [/estado](https://docs.pagaconquickpay.com/estado) muestra en vivo la API, la base de datos, la página de pago, las operaciones con el banco de la última hora y la liquidación inmediata.

## 8 de octubre de 2026 (mañana)

- **Portal de comercios renovado:** cobro con monto, página de pago, cobranza masiva, suscripciones, productos, equipo con roles.
- **Llaves de API y webhooks desde el portal** (Integraciones): la llave y el secreto se muestran una sola vez.
- **Liquidación inmediata (construida, todavía sin activar):** el neto de cada pago irá a tu cuenta y te avisaremos con `link.acreditado`.
- **Firma v2 de los webhooks** con marca de tiempo (`x-quicklink-signature-v2` y `x-quicklink-timestamp`) para rechazar avisos reenviados. La firma anterior sigue llegando.
- **Enlaces:** `success_url` (con `estado` y `referencia` al volver), `metadata` e `idempotency_key`.
- **Documentación verificada contra el código:** se corrigieron "Enlaces de pago" y "Cobrar desde tu bot" (la idempotencia va en el cuerpo, el aviso trae `link_id` y no tus `metadata`, el listado devuelve una lista) y el glosario ahora explica todos los campos.
- **Página de pago nueva:** iconos de los bancos, teléfono por prefijo, clave de 8 dígitos y comprobante para guardar o compartir.
- **Documentación nueva** con este esquema y el SDK renombrado a `QuickPay` (el nombre `QuickLink` sigue funcionando).

## 16 de septiembre de 2026

- Dominio propio: `pay.pagaconquickpay.com` y `docs.pagaconquickpay.com`.

## 6 de septiembre de 2026

- **Cobro por lote:** hasta 500 enlaces en una llamada, con estado por ítem y cancelación de los pendientes.

---

<!-- Sección: IA y MCP -->

<!-- https://docs.pagaconquickpay.com/developers/mcp -->

# Conecta QuickPay a tu IA (MCP)

Con el servidor MCP de QuickPay, tu asistente de IA (Claude, ChatGPT, Claude Code, Cursor u otro compatible con MCP) crea y consulta tus enlaces de cobro cuando se lo pides con tus palabras: *"Cobra Bs 1.500 por el pedido 1024"*, *"¿Qué cobros tengo pendientes?"*.

No copias ninguna llave: pegas la dirección del servidor, entras con el correo de tu comercio y autorizas.

```text
https://mcp.pagaconquickpay.com/mcp
```

Para leerlo o compartirlo: [Guía esencial del MCP en PDF](https://docs.pagaconquickpay.com/developers/mcp.pdf).

## Qué puede hacer tu IA

Casi todo lo de la [API pública](https://docs.pagaconquickpay.com/developers/referencia): lo que no puede está en la sección siguiente.

| Herramienta | Qué hace | Prueba | Producción |
|---|---|---|---|
| `crear_link_cobro` | Crea un enlace de cobro con monto y concepto (opcional: `moneda`, `expira_horas`, `expira_en`, `idempotency_key`, `success_url`, `metadata`). Crearlo no mueve dinero: el cobro ocurre sólo si alguien lo paga. | Sí | Sí |
| `listar_cobros` | Lista tus enlaces, los más recientes primero (20 por omisión, hasta 50 por página). Filtra por estado, fechas, montos o texto (concepto, nombre de quien pagó, referencia bancaria o id). | Sí | Sí |
| `ver_cobro` | Muestra un enlace por su id: monto, estado, cuándo se pagó y el código del comprobante. | Sí | Sí |
| `cancelar_link` | Cancela un enlace que sigue pendiente. Uno pagado o en proceso de pago no se cancela. | Sí | Sí |
| `simular_cobro` | Fuerza el resultado de un enlace de prueba (`pagado`, `rechazado` o `expirado`). → [Modo prueba](https://docs.pagaconquickpay.com/developers/datos-de-prueba) | Sí | No |
| `crear_lote` | Crea hasta 500 enlaces de una vez. → [Cobro por lote](https://docs.pagaconquickpay.com/developers/cobro-por-lote) | Sí | Sí |
| `listar_lotes` · `ver_lote` | Tus lotes con su resumen, o uno con el estado de cada enlace. | Sí | Sí |
| `cancelar_lote` | Cancela los enlaces de un lote que siguen pendientes. | Sí | Sí |
| `verificar_comprobante` | Comprueba un comprobante por su código `QP-XXXXX-XXXXX`. | Sí | Sí |
| `consultar_estado` | Dice si un pago está confirmado, por el id de la transacción (el `txn_id` de un enlace pagado): `LIQUIDADA`, `ACEPTADA` (en proceso) o `RECHAZADA`. | Sí | Sí |
| `listar_liquidaciones` | Tus liquidaciones. | Sí | Sí |
| `listar_bancos` | Los bancos desde los que tus clientes pueden pagarte (código y nombre). | Sí | Sí |
| `mi_conexion` | Con qué comercio y en qué modo está conectada. | Sí | Sí |
| `listar_llaves` | Tus llaves de API, enmascaradas. | Sí | Sí |
| `crear_llave` · `revocar_llave` | Crea o revoca una llave de prueba (`sk_test`). La llave completa se muestra una sola vez. → [Llaves y entornos](https://docs.pagaconquickpay.com/developers/llaves-y-entornos) | Sí | No: desde el portal |
| `listar_webhooks` · `ver_webhook` · `ver_entregas_webhook` | Tus webhooks (sin el secreto) y sus últimas entregas. | Sí | Sí |

**Webhooks: tu IA sólo los ve.** Registrarlos, cambiarlos o borrarlos se hace desde el portal › Integraciones. → [Webhooks](https://docs.pagaconquickpay.com/developers/webhooks-referencia)

**En producción, las llaves también sólo se ven:** crearlas o revocarlas se hace desde el portal › Integraciones. Si se lo pides a tu IA, QuickPay responde `403` `solo_desde_el_portal` y tu IA te lo dice.

Las herramientas que cambian algo (cancelar, simular, llaves) van marcadas para que tu IA te pida confirmación antes de usarlas.

## Qué no puede hacer

**Tu IA no puede enviar, pagar, transferir ni devolver dinero**, ni sacar dinero de ninguna cuenta. Tampoco puede ver tus movimientos o tu saldo, cambiar tus datos o tu cuenta bancaria, registrar o cambiar webhooks, ni, en producción, crear o revocar llaves (eso se hace en el portal). Esas herramientas no existen en el servidor MCP y, además, QuickPay rechaza (`403`) cualquier otra operación hecha con el acceso de una IA, aunque alguien intente usarlo fuera del MCP.

## Cómo se conecta

1. Agregas QuickPay en tu IA con la dirección de arriba (los pasos de cada una están más abajo).
2. Tu IA abre una página de QuickPay en el navegador. Escribe el **correo de tu comercio**, el mismo con el que entras al portal, y te llega un enlace de acceso.
3. Abre el enlace **en el mismo navegador** donde empezaste. Expira en 15 minutos y es de un solo uso.
4. Revisa qué podrá hacer la IA, elige el comercio (si tienes varios) y el modo, y toca **Autorizar**.

### Modo prueba o producción

| Modo | Qué pasa |
|---|---|
| **Prueba** (por omisión) | Los enlaces son de prueba: nadie paga dinero real. Igual que con tu llave `sk_test`. → [Modo prueba](https://docs.pagaconquickpay.com/developers/datos-de-prueba) |
| **Producción** | Los enlaces cobran dinero real a quien los pague. Llaves y webhooks sólo se ven (se manejan desde el portal). Sólo se puede elegir si tu cuenta ya está aprobada y la aplicación es conocida (Claude, ChatGPT, Cursor o una de línea de comandos como Claude Code). |

Si la página dice **Aplicación no verificada**, la aplicación que pidió el acceso no vuelve a una de las conocidas: sólo se puede conectar en modo prueba. Autoriza sólo si reconoces la dirección que aparece en "Volverá a".

Para cambiar de modo, quita el conector y vuelve a conectarlo eligiendo el otro.

## Claude

En Claude (web o escritorio), agrega un **conector personalizado** con la dirección `https://mcp.pagaconquickpay.com/mcp`, ponle de nombre *QuickPay* y conéctalo: se abre la página de QuickPay para entrar y autorizar.

## ChatGPT

En la configuración de ChatGPT, en **Conectores**, crea un conector con la dirección `https://mcp.pagaconquickpay.com/mcp` y autenticación **OAuth**. Al conectarlo se abre la página de QuickPay para entrar y autorizar. Los conectores personalizados dependen de tu plan de ChatGPT.

## Claude Code

```bash
claude mcp add --transport http quickpay https://mcp.pagaconquickpay.com/mcp
```

Luego, dentro de Claude Code, escribe `/mcp`, elige **quickpay** y autentícate: se abre el navegador para entrar y autorizar.

## Cursor

Agrega esto a `~/.cursor/mcp.json` (si ya tienes otros servidores, suma sólo `quickpay` dentro de `mcpServers`):

```json
{
  "mcpServers": {
    "quickpay": { "url": "https://mcp.pagaconquickpay.com/mcp" }
  }
}
```

Cuando Cursor lo pida, entra y autoriza en el navegador.

## Ejemplos

Lo que le pides a tu IA y lo que hace. Tu IA redacta la respuesta a su manera; los datos salen de QuickPay.

| Le dices | Usa | Te responde |
|---|---|---|
| *"Cobra Bs 1.500 por el pedido 1024"* | `crear_link_cobro` | El enlace (`https://pay.pagaconquickpay.com/l/…`) para mandárselo a tu cliente, con el monto, el concepto y hasta cuándo vale (24 horas si no le dices otra cosa). |
| *"¿Qué cobros tengo pendientes?"* | `listar_cobros` | Tus enlaces pendientes, del más reciente al más viejo, con monto y concepto. |
| *"¿Ya pagaron el pedido 1024?"* | `listar_cobros` / `ver_cobro` | Busca el enlace por el concepto y te dice su estado: `pendiente`, `procesando`, `pagado`, `expirado` o `cancelado`; si está pagado, cuándo. |
| *"Cancela el enlace del pedido 1024"* | `cancelar_link` | Que quedó `cancelado` y ya no se puede pagar. Si alguien ya lo pagó o lo está pagando, te dice que no se puede. |
| *"¿Con qué bancos me pueden pagar?"* | `listar_bancos` | La lista de bancos desde los que tus clientes pueden pagarte. |
| *"¿Qué liquidaciones tengo?"* | `listar_liquidaciones` | Tus liquidaciones con su estado y monto. |
| *"¿Estás en modo prueba?"* | `mi_conexion` | Tu comercio y si la conexión es de prueba o de producción. |
| *"Crea un lote con estas 3 facturas: …"* | `crear_lote` | El lote con un enlace por factura. |
| *"Simula que pagaron el enlace de prueba"* | `simular_cobro` | Que el enlace de prueba quedó `pagado` (en producción no se puede). |
| *"¿Qué webhooks tengo?"* | `listar_webhooks` | Tus webhooks con su URL, eventos y estado. |
| *"Crea una llave de prueba para mi servidor"* | `crear_llave` | La llave `sk_test_…` completa, una sola vez. |
| *"¿Es auténtico el comprobante QP-…?"* | `verificar_comprobante` | Si es válido, con el monto y la fecha del pago. |

## Seguridad

- **Para quitarle el acceso a tu IA**, quita el conector en tu IA (en Claude Code: `claude mcp remove quickpay`). Para volver a conectarla tienes que entrar y autorizar de nuevo.
- El acceso de la IA vale para un solo comercio y un solo modo, los que elegiste al autorizar.
- **Una llave de prueba creada desde tu IA sigue funcionando aunque quites el conector.** Revócala con `revocar_llave` o en tu portal › Integraciones › Llaves de API cuando ya no la uses.
- QuickPay no guarda los accesos en claro: guarda una huella que sólo sirve para comprobarlos.
- Si tu comercio se suspende, o el correo deja de ser el contacto verificado del comercio, el acceso se corta en el acto.
- Si alguien intenta conectarse con tu correo, el enlace te llega a ti y sólo funciona en el navegador donde se empezó la conexión: abierto en el tuyo, no le da acceso a nadie. Si no fuiste tú, ignora el correo.

## Con tu llave, sin iniciar sesión

Si tu herramienta no soporta el inicio de sesión de MCP (OAuth), puedes mandar tu llave en un header. La IA tiene entonces el modo de la llave (`sk_test` = prueba, `sk_live` = producción) y las mismas herramientas de arriba.

```bash
claude mcp add --transport http quickpay https://mcp.pagaconquickpay.com/mcp --header "x-switch-key: <comercio>:<tu_llave>"
```

> Con este método la llave queda guardada en la configuración de tu herramienta. Usa la de prueba mientras pruebas y revócala en tu portal › Integraciones › Llaves de API si se expone. Con el inicio de sesión no hay llave que cuidar.

## Detalles técnicos

Para quien construye su propio cliente MCP. El servidor sigue la especificación de autorización de MCP (2025-06-18):

| | |
|---|---|
| Recurso protegido (RFC 9728) | `https://mcp.pagaconquickpay.com/.well-known/oauth-protected-resource` |
| Servidor de autorización (RFC 8414) | `https://mcp.pagaconquickpay.com/.well-known/oauth-authorization-server` |
| Registro de clientes (RFC 7591) | `POST /oauth/register` |
| Autorización | `GET /oauth/authorize`: código de autorización con PKCE `S256` **obligatorio** |
| Tokens | `POST /oauth/token`: `authorization_code` y `refresh_token` |
| Revocación (RFC 7009) | `POST /oauth/revoke` |

- `/mcp` sin token responde `401` con `WWW-Authenticate: Bearer resource_metadata="…"`.
- Las `redirect_uri` tienen que ser `https://`, o `http://localhost` / `http://127.0.0.1` para aplicaciones de línea de comandos (en esas el puerto puede cambiar). Sin fragmento. Con una que no sea de `claude.ai`, `claude.com`, `chatgpt.com`, Cursor o loopback, sólo se autoriza modo prueba.
- Scope: `cobros` (el único).
- El token de acceso dura **1 hora**; el `refresh_token` dura 30 días y cambia en cada uso. Si un `refresh_token` ya usado se presenta otra vez, se revoca la autorización completa.
- Si tu comercio se suspende, o el correo deja de ser el contacto verificado del comercio, el acceso se corta en el acto. Si el correo deja de ser el contacto verificado del comercio, se corta al vencer el token de acceso (a más tardar en una hora).
- Un enlace de acceso por intento de conexión, y hasta 5 por correo cada 10 minutos.
- Hasta 60 llamadas a herramientas por minuto por conexión y 120 por comercio; los listados devuelven hasta 50 resultados por página.
- Las herramientas devuelven sólo los campos documentados de cada respuesta ([glosario](https://docs.pagaconquickpay.com/developers/glosario)); un error llega como `error` (código) y `mensaje`.

<!-- https://docs.pagaconquickpay.com/developers/con-tu-ia -->

# Usar la documentación con tu IA o sin conexión

Si prefieres no navegar página por página, descarga toda la documentación en un solo archivo. Son las mismas guías de este sitio, en el mismo orden, y se actualizan con ellas.

| Para | Descarga |
|---|---|
| Lo esencial, con índice, para leer o compartir | [Guía esencial en PDF](https://docs.pagaconquickpay.com/developers/quickpay-docs.pdf) (unas 30 páginas) |
| Toda la documentación junta | [En una sola página](https://docs.pagaconquickpay.com/developers/todo) (se puede imprimir) |
| Dársela a Claude, ChatGPT, Cursor u otra IA | [quickpay-docs.md](https://docs.pagaconquickpay.com/developers/quickpay-docs.md) |
| Herramientas que leen el estándar `llms.txt` | `https://docs.pagaconquickpay.com/llms.txt` (índice) y `https://docs.pagaconquickpay.com/llms-full.txt` (todo el texto) |

Cada guía tiene además su propio botón **Descargar .md** arriba a la derecha.

## Cómo usarla con una IA

1. Descarga `quickpay-docs.md`.
2. Súbelo a la conversación (o a tu proyecto) y pídele lo que necesitas, por ejemplo: *"Con esta documentación, escribe en Node el endpoint que recibe el webhook `link.pagado` y verifica la firma"*.
3. Prueba lo que te entregue con tu llave de prueba `sk_test_…` antes de pasar a producción. → [Modo prueba](https://docs.pagaconquickpay.com/developers/datos-de-prueba)

> **Tu llave no va en la conversación.** La IA no la necesita para escribir el código: déjala en tu servidor, en una variable de entorno. Si alguna vez la pegaste en un chat, revócala en tu portal › Integraciones › Llaves de API y crea otra.

La referencia técnica de cada endpoint (OpenAPI) está en [Referencia de la API](https://docs.pagaconquickpay.com/docs).
