Cómo funciona el proyecto
Esta demo resume en un archivo un proyecto de WordPress dividido en dos piezas: el plugin revista-core, con toda la lógica, y el tema revista-tema, con la presentación. Así se puede rediseñar el sitio sin tocar pagos ni permisos.
Requisitos y dónde se resuelven
| Requisito | Solución | Pruébalo |
|---|---|---|
| Zonas públicas y premium por categoría | Nivel por sección y por publicación: público, registrado, básico y premium. Una publicación puede heredar el nivel de su sección. | Cambia de perfil en la barra superior y abre las secciones. |
| YouTube sin salir del sitio | Reproductor youtube-nocookie que se carga al pulsar. | Video premium |
| Podcasts de Spotify | Reproductor oficial embebido desde el enlace. | Podcast |
| Guías y PDFs | Archivos en carpeta bloqueada; se descargan por un endpoint que verifica el acceso. | Guía premium |
| Panel del suscriptor | Plan, estado, tarjeta, historial, cancelar, reactivar y cambiar tarjeta. | Mi cuenta |
| Wompi con tokenización y renovación | Token en el navegador, fuente de pago en el servidor, cobros con firma de integridad, webhook firmado y cron. | Suscríbete |
| Publicar sin código | Campos de ACF registrados en código con instrucciones en cada campo. | Ver el zip del proyecto. |
El flujo de pago
- El navegador envía la tarjeta a
POST /v1/tokens/cardsde Wompi con la llave pública. El servidor de la revista nunca ve el número ni el CVC. - El servidor crea la fuente de pago con
POST /v1/payment_sources, la llave privada y los tokens de aceptación de Habeas Data. - Se cobra con
POST /v1/transactions,payment_source_id,recurrent: truey la firmaSHA256(referencia + centavos + COP + secreto). - Wompi avisa con el evento
transaction.updated. Se verifica su checksum y el pago se aplica una sola vez, aunque el evento llegue repetido. - Cada hora el cron cobra lo que vence en las siguientes 12 horas, reintenta a diario los rechazos (hasta 3) y vence la suscripción al terminar los días de gracia.
Verificación del webhook
function evento_valido(array $body): bool {
$concat = '';
foreach ($body['signature']['properties'] as $ruta) { // p. ej. transaction.id
$v = $body['data'];
foreach (explode('.', $ruta) as $k) { $v = $v[$k]; }
$concat .= $v;
}
$concat .= $body['timestamp'] . SECRETO_EVENTOS;
return hash_equals(hash('sha256', $concat), $body['signature']['checksum']);
}
Lo que queda por hacer en producción
3D Secure en el primer cobro para las tarjetas que lo exijan, facturación electrónica DIAN conectada al evento de pago aprobado, y Vimeo o Bunny Stream si la revista necesita que los videos premium no se puedan ver fuera del sitio.