Ir al contenido
AppsSDAR

Validar una pasarela de pagos con un cobro real de un sol

actualizada el 9 min de lectura Pagos y normativa peruana

Si tu tienda en Izipay está en la etapa de validación, o el soporte te dice que algo "no está habilitado" y no puedes comprobarlo, la forma más rápida de salir del atolladero es un cobro real de un sol. Lo hicimos en tres sistemas el 9 y 10 de septiembre de 2026, y esta nota cuenta cómo se hace sin perder dinero, qué demuestra un solo pago, y qué nos encontramos por el camino, incluido un bug que ninguna tarjeta de prueba había mostrado.

Por qué las tarjetas de prueba no bastan

Las tarjetas de prueba demuestran que tu código funciona contra el entorno de pruebas de la pasarela. No demuestran que la tienda de producción esté bien configurada, que la pasarela alcance tu servidor con el aviso de pago (el IPN, que va de servidor a servidor) ni que la suscripción recurrente se cree de verdad. Son tres cosas distintas y las tres fallan en silencio: el cliente paga, ve su pantalla de éxito y tú no te enteras de que algo faltó.

En nuestro caso había además un motivo de negocio. El soporte de Izipay nos dijo por WhatsApp que la tienda de wapi "solo es para pagos únicos, no recurrentes". Discutirlo por chat no llevaba a ningún lado. Un cobro real que creara una suscripción sí: se hizo en las tres tiendas (wapi, SortealoPE y Arca) y en las tres la suscripción apareció en el back office. La afirmación del soporte era incorrecta. Si te pasa algo parecido, lleva evidencia, no argumentos.

El cobro que no se cobra

Una transacción con tarjeta no se liquida al instante. Queda "En espera de captura" hasta el cierre de lote. Si antes de ese cierre la anulas, el cargo nunca se completa: el banco libera la retención en uno a siete días hábiles y no hay devolución porque nunca hubo cobro.

En el Back Office de Izipay el camino es Transacciones en curso, clic derecho sobre la operación y Cancelar. El menú trae otras dos opciones que se parecen y que no hay que tocar:

  • Reembolsar mueve dinero de verdad y cobra comisión.
  • Validar fuerza la captura, es decir, convierte la retención en cobro.

La regla práctica: haces el pago y lo cancelas el mismo día, antes del cierre de lote. Si lo dejas pasar, ya no es una cancelación.

Cobrar un sol sin bajarle el precio a todos

El monto de un checkout lo decide el servidor, así que desde la pantalla no hay forma de pagar menos, y está bien que sea así. Para la prueba necesitamos justo una excepción en el servidor. La opción obvia, bajar el precio del plan para todos mientras pruebas, es la peor: si un cliente real paga en esa ventana, queda con un plan de un sol y con una renovación de un sol.

Lo que hicimos fue una variable de entorno temporal con el correo de la cuenta de prueba. Solo el checkout de esa cuenta cobra un sol; el resto sigue pagando el precio de lista. Dicho como lógica, sin secretos:

// al calcular el monto del checkout
const monto = (usuario.correo === process.env.BILLING_CORREO_PRUEBA)
  ? 1.00
  : precioDelPlan(plan, ciclo);

Lo importante es lo que no cambia: la suscripción se crea por el precio real. Eso es exactamente lo que le tienes que demostrar a la pasarela. En SortealoPE el cobro fue de un sol y la suscripción quedó por el precio mensual del plan; en Arca, igual, con el suyo. Ese detalle sale en el back office en Gestión > Suscripciones.

Qué prueba un solo pago

Un pago real en producción cierra tres pendientes de golpe:

  • La tienda cobra de verdad. Ya no depende de la palabra de nadie.
  • El IPN llega. Se comprueba en los registros de acceso de tu servidor: debe aparecer un POST de la pasarela (el agente se identifica como "Lyra-Network Agent", desde el rango 194.50.38.0/24) con respuesta 200. En el cPanel que usamos no hizo falta abrir nada en el firewall, pero en otro hosting conviene mirar el log antes de culpar a la pasarela.
  • La suscripción nativa existe. Aparece con su referencia en Gestión > Suscripciones.

Con esa evidencia le contestamos a Izipay en tres puntos: dónde vive el checkout (dentro de la cuenta del usuario, no en la web pública, y nos ofrecimos a crear un usuario de prueba para que lo vieran), el pago real con su identificador de transacción y el IPN recibido, y la suscripción recurrente generada. Dos datos técnicos que conviene incluir porque ellos los leen: usamos Charge/CreatePayment con formAction: REGISTER_PAY para el cobro inicial y Charge/CreateSubscription para la recurrencia, ambos por la API REST V4.

Una trampa distinta en cada sistema

Los tres comparten el mismo patrón y aun así cada uno escondió un obstáculo propio. Los anoto porque son del tipo que te hace perder una tarde:

  • wapi: el botón de pago se deshabilita cuando el plan está al día, así que el frontend nunca llamaba al checkout. Hubo que marcar un módulo para provocar un cambio de plan. Además, si pones la excepción antes del corte de planes sin cobro, cualquier cambio de plan de esa cuenta abre el formulario de un sol, incluida la baja de un módulo. El orden de limpieza importa: primero bajas el módulo y después cancelas la renovación, porque bajar el módulo vuelve a sincronizar y crearía una suscripción nueva.
  • SortealoPE: el token del formulario que ve el usuario no sale del controlador de pagos sino del manejador de la página aislada que monta el formulario embebido. Cambiar solo el controlador no tenía ningún efecto y el formulario seguía cobrando el precio real. Un cobro "de prueba" que sale por el precio de lista es la clase de sorpresa que hay que descartar antes de teclear la tarjeta.
  • Arca: aquí apareció un bug de verdad, el siguiente.

El bug que encontró la prueba

Al confirmar un pago, Arca tomaba el token de tarjeta guardado del cliente y solo miraba el de la transacción si no había ninguno. Con un token viejo, de una tarjeta ya reemplazada, o simplemente con una tarjeta distinta a la del primer pago, la pasarela respondía PSP_030 ("payment token not found") y la suscripción nunca se creaba.

El efecto para el cliente: paga, se le activa el plan, y la renovación automática no existe. No ve ningún error. Lo descubriría un mes después, cuando su servicio se cortara. Con tarjetas de prueba el bug no sale porque siempre se usa la misma tarjeta desde cero.

La corrección fue invertir la prioridad: el token de la transacción actual manda sobre el guardado, y se persiste si cambió. Revisamos las otras dos implementaciones y las dos ya guardaban siempre el token que llegaba con el pago, así que no lo tenían.

Cuando copies un patrón de pagos de un sistema a otro, compara las implementaciones línea por línea. El mismo diseño puede tener un bug en una copia y no en las otras.

Limpiar al terminar

Una prueba con dinero real que deja residuos en producción es un problema nuevo. El orden que seguimos:

  1. Cancelar la transacción en Transacciones en curso, el mismo día.
  2. Cancelar la suscripción creada (Gestión > Suscripciones), si no quieres que cobre su primera cuota.
  3. Quitar la variable de excepción del servidor.
  4. Revertir cualquier cambio temporal de código y confirmar con un git diff contra el commit anterior que el árbol quedó idéntico.

Un recordatorio que nos costó correos repetidos: las suscripciones creadas en modo prueba siguen vivas y cobran cuotas solas. Cada cuota dispara un IPN contra tu servidor de producción, que solo tiene la clave de producción, así que la firma de prueba no valida, responde 400 y Izipay reintenta avisándote por correo cada vez. No afecta pagos reales, pero llena la bandeja. Al cerrar las pruebas de recurrencia, cancela también las suscripciones de test. Y ten en cuenta cuándo cobra cada modo: en prueba la primera cuota se crea dentro de la hora siguiente; en producción, una vez al día entre las 00:00 y las 05:00 UTC.

Checklist de validación

  • Excepción de un sol solo para la cuenta de prueba. Otra cuenta ve el precio de lista en el checkout.
  • Cobro real hecho. Aparece en Transacciones en curso como "En espera de captura".
  • IPN recibido. POST de la pasarela con 200 en el log de acceso.
  • Suscripción creada por el precio real. Visible en Gestión > Suscripciones, con su referencia.
  • Aviso de lote activo. Regla "al autorizar por lote" activa en el back office.
  • Transacción cancelada, no reembolsada ni validada.
  • Variable de excepción retirada. Revisa las variables del servidor y que el diff de código esté limpio.
  • Suscripciones de test canceladas. Revisa el back office en modo prueba.

La regla de lote merece su línea: los cobros de una recurrencia se autorizan en lote de madrugada, no como pago interactivo. Si solo tienes activo el aviso "al final del pago", el cobro mensual ocurre y tu sistema nunca se entera. Es una de las tres reglas que hay que activar en Configuración > Reglas de notificaciones, junto con "al final del pago" y "al crear una suscripción".

Seguir leyendo

Cómo se arma el checkout y la firma del IPN está en cobrar con Izipay. La lógica de suscripción, con Culqi y con Izipay, en suscripciones recurrentes en Perú. Y la idea de no fiarse de una sola señal se repite en un health check que sirve. Los sistemas que pasaron esta validación son wapi, SortealoPE y Arca.