# Integración Wompi en GoberData

Estado al 28 de septiembre de 2026 (hora de Colombia): **membresías implementadas y comprobadas en automatización + consulta de comercio Sandbox**. Producción **deshabilitada**. No se declara listo para cobro real.

No hay repositorio git en esta copia de trabajo; los cambios viven en el árbol de `c:\xampp\htdocs\goberdata`.

## Qué está operativo

| Flujo | Estado |
|---|---|
| Membresías de plataforma (planes GoberData) | Checkout alojado Wompi Sandbox, orden local, webhook por ambiente, consulta `GET /v1/transactions/{id}` con llave privada, activación idempotente, correo de acceso. |
| Donaciones de campaña | **No habilitadas con Wompi.** Siguen el recaudo previo de campaña (`BoldDonationController` y pasarelas por `campaign_id`). El catálogo de campaña admite campos Wompi, incluida `integrity_secret`, pero no hay checkout alojado ni webhook de donación Wompi. Una donación no activa membresía ni usa las llaves de la plataforma. |
| Cobro real / producción | Desactivado (`PAYMENTS_ALLOW_LIVE_CHARGES=false` y el perfil sandbox con `allow_live_charges=false`). Tener una llave `pub_prod_` no activa cobros. |

No hay tokenización ni débitos recurrentes automáticos. Un periodo pagado no programa el siguiente cobro.

## Perfiles y precedencia

Fuente canónica: filas cifradas en `platform_payment_gateways` (una por `provider` + `environment`).

Importación controlada de Sandbox:

```bash
php artisan config:clear
php artisan goberdata:wompi:sandbox-sync --activar
```

Lee `WOMPI_PUBLIC_KEY`, `WOMPI_PRIVATE_KEY`, `WOMPI_EVENTS_SECRET` y `WOMPI_INTEGRITY_SECRET` del entorno, valida prefijos `pub_test_` / `prv_test_` / `test_events_` / `test_integrity_` y guarda el perfil **sandbox** cifrado. No borra un perfil de producción.

Precedencia al cobrar: perfil **activo** en BD. Las órdenes copian `gateway`, `gateway_environment`, `platform_gateway_id` y `gateway_credentials` al crearse; un cambio posterior de llaves no reinterpreta órdenes históricas.

## Campos a completar (sin valores)

En `.env` (local o servidor):

- `WOMPI_PUBLIC_KEY`, `WOMPI_PRIVATE_KEY`, `WOMPI_EVENTS_SECRET`, `WOMPI_INTEGRITY_SECRET` — conjunto Sandbox completo, mismos prefijos.
- `PAYMENTS_SANDBOX_EMAILS` — buzones autorizados para compra pública Sandbox y correo de prueba (separados por coma).
- `PAYMENTS_SANDBOX_MAIL_ENABLED=true` para entregar correo de prueba.
- `MEMBERSHIP_MAILER=smtp` (u otro transporte de entrega; no `log` ni `array`).
- `PAYMENTS_ALLOW_LIVE_CHARGES=false` en esta fase.
- SMTP existente (`MAIL_*`) y `MAIL_FROM_ADDRESS` real.
- En el servidor público: `APP_URL=https://goberdata.com` (o el HTTPS de QA). Conservar el mismo `APP_KEY` que cifra la BD.

También se pueden guardar/probar/activar desde `/admin/payment-gateways` (superadministrador, CSRF). Un campo secreto vacío al editar no borra el valor almacenado. Los secretos se muestran enmascarados.

## URLs

Rutas de la aplicación (el host sale de `APP_URL`):

| Uso | Ruta |
|---|---|
| Retorno del checkout | `GET /checkout/retorno` (`checkout.retorno`) |
| Estado del pago (token de seguimiento) | `GET /checkout/estado/{referencia}` |
| Eventos Sandbox | `POST /webhooks/membresia/wompi/sandbox` |
| Eventos producción | `POST /webhooks/membresia/wompi/production` |
| Bold/PayU (membresía legacy) | `POST /webhooks/membresia/{bold\|payu}` |
| Donaciones Bold | `POST /webhooks/bold` |

**En este host local no son accesibles desde Wompi.** `APP_URL` actual es `http://127.0.0.1:9000`. Apache sirve `http://127.0.0.1/goberdata/public`. Ninguna de las dos es HTTPS público.

Cuando el código esté en el dominio canónico, registrar en el panel de comercios Wompi:

- Sandbox: `https://goberdata.com/webhooks/membresia/wompi/sandbox`
- Producción (más adelante): `https://goberdata.com/webhooks/membresia/wompi/production`
- Retorno: `https://goberdata.com/checkout/retorno` (lo arma el backend con referencia y token; no activa la membresía por query string)

Si QA usa otro dominio HTTPS, sustituir el host en la URL Sandbox. `/webhooks/membresia/wompi` ya no elige «las llaves actuales»; hace falta el segmento `sandbox` o `production`.

## Cómo probar un pago aprobado y uno rechazado (Sandbox)

1. Superadministrador: `/admin/payment-gateways` → perfil Wompi sandbox activo y «Probar» en HTTP 200 (comercio accesible, no es un pago completo).
2. Abrir `/planes`. Debe verse **Wompi Sandbox · pagos de prueba**.
3. Visitante: correo listado en `PAYMENTS_SANDBOX_EMAILS`. Si el correo ya existe en `users`, iniciar sesión. Miembros del tenant `qa-juan-villa-aurora` y superadministradores también pueden pagar en Sandbox.
4. Elegir plan → Ir a pagar → **Pagar ahora con Wompi**. El importe y la firma salen del servidor.
5. En Checkout Wompi (solo Sandbox):
   - Aprobado: tarjeta `4242 4242 4242 4242`, fecha futura, CVC de 3 dígitos.
   - Rechazado: tarjeta `4111 1111 1111 1111`.
   - Nequi: `3991111111` aprobado / `3992222222` rechazado.
6. Al volver, el estado lo confirma el servidor (consulta privada). Si el webhook no llega (localhost), ejecutar cuando se conozcan referencia e ID:

```bash
php artisan goberdata:wompi:conciliar REFERENCIA_LOCAL ID_TRANSACCION_WOMPI
php artisan goberdata:pagos:procesar
```

7. Aprobado: membresía de prueba / ambiente `internal_test` privado; correo de acceso al buzón autorizado; cambio de contraseña obligatorio en cuentas nuevas.
8. Rechazado: no crea cuenta, ambiente ni bienvenida.

Evidencia a anotar (sin secretos): referencia local, ID de transacción, ambiente `test`, estado Wompi, estado local, número de activaciones.

## Tenant privado y métricas

Laboratorio persistente: campaña id `6`, slug `qa-juan-villa-aurora`, `environment_type=internal_test`, `is_private_qa=true`.

- Un pago Sandbox no lo convierte a `client`.
- No puede usar el perfil de cobro real.
- `PlatformStatsService` excluye `is_test` e `internal_test` / `is_private_qa` de ingresos, MRR y conversiones comerciales.
- Geografía ficticia (Sierra Clara QA / Villa Aurora QA) no sale en el catálogo público.
- Correos de prueba solo a buzones de `PAYMENTS_SANDBOX_EMAILS` cuando el correo Sandbox está habilitado.

## Transición a producción (no ejecutar ahora)

1. Completar una compra Sandbox real con webhook público y correo recibido.
2. Cargar el conjunto **production** en su fila independiente (`pub_prod_`, `prv_prod_`, `prod_integrity_`, `prod_events_`) sin borrar Sandbox.
3. Probar comercio real desde el backend.
4. Registrar la URL de eventos de producción (HTTPS, TLS, respuesta del endpoint).
5. Confirmar `APP_URL` canónico, scheduler cada minuto (`goberdata:pagos:procesar`) y conciliación.
6. Comprobar que Sandbox no habilita cuentas productivas y que el tenant interno sigue en pruebas.
7. Superadministrador: `PAYMENTS_ALLOW_LIVE_CHARGES=true`, `config:clear`, confirmar `confirm_live` al activar el perfil production. Queda auditoría en el cambio de perfil.
8. Validación posterior con el propietario y reversión: desactivar el perfil production / volver `PAYMENTS_ALLOW_LIVE_CHARGES=false` detiene **nuevos** checkouts reales; no se apagan webhooks ni conciliación de órdenes ya iniciadas. Volver a Sandbox no reembolsa ni reescribe el historial.

## Reversión de cobros nuevos

Desactivar el perfil production o `PAYMENTS_ALLOW_LIVE_CHARGES=false` y dejar activo solo sandbox. Conservar workers/scheduler. No borrar credenciales históricas de órdenes pendientes.

## Pruebas ejecutadas en esta instalación

Base de tests: SQLite en memoria (`phpunit.xml`). No usa `RefreshDatabase` contra PostgreSQL de clientes.

```text
php artisan test --filter=Wompi
  50 passed (252 assertions)  — WompiCompraCompletaTest + WompiYQaPrivadoTest

php artisan test --filter=DemoYMembresiaTest
  9 passed (23 assertions)
```

Total coincidente con la entrega del ZIP: 59 pruebas, 275 aserciones (Http::fake y correo aislado).

También:

- `php artisan migrate --force` → `2026_09_28_010000_complete_wompi_checkout` (batch 3).
- `php artisan migrate:status` → todas Ran.
- `php artisan route:list --path=webhooks -v` → sandbox/production parametrizado; Bold/PayU sin Wompi ambiguo.
- `php artisan goberdata:wompi:sandbox-sync --activar`
- `php artisan goberdata:wompi:probar` → `ok=true status=ok detalle=HTTP 200` (en este Windows, TLS del cliente local omitido).
- `php artisan goberdata:wompi:diagnostico --remoto` → comercio Sandbox OK; **falla APP_URL** porque el origen no es HTTPS público.

`npm run build` **no se ejecutó**: no hay `node_modules`. El checkout de membresía usa Blade y `public/js/demo-runtime.js`; no depende de ese bundle Vue.

**No ejecutado:** checkout con tarjeta Sandbox de extremo a extremo, recepción real del webhook desde Wompi, ni comprobación de bandeja SMTP. Localhost no es alcanzable por Wompi.

## Bloqueos concretos

1. **APP_URL local** (`http://127.0.0.1:9000`): el diagnóstico lo marca como incompleto para ensayo público. Además Apache usa `/goberdata/public`; si se prueba el checkout aquí, alinear `APP_URL` con el origen real del navegador.
2. **Webhook público ausente:** Wompi no puede notificar a este PC. Hace falta desplegar a `goberdata.com` (o un túnel HTTPS) y registrar la URL Sandbox en el comercio.
3. **TLS del cliente PHP en Windows:** `cURL 60` al verificar certificados; prueba de comercio y consulta de transacción en `local` reintentan sin verificar. En el VPS debe usarse verificación TLS real.
4. **Scheduler:** en el servidor, cron `* * * * * php artisan schedule:run`. Sin eso, correos y reintentos quedan a `php artisan goberdata:pagos:procesar` manual.
5. **Producción:** no hay perfil production en BD; no activar en esta fase.
6. **Donaciones Wompi:** no implementadas; no usar las llaves de membresía para recaudo de campaña.

## Archivos relevantes

Ver `docs/ARCHIVOS_CAMBIADOS_WOMPI.txt` y `LEEME_WOMPI.md`. Ajustes de esta instalación local:

- Migración `2026_09_28_010000_complete_wompi_checkout.php` hecha idempotente.
- Cliente HTTP local sin verificación TLS en prueba de comercio, diagnóstico `--remoto` y consulta de transacción.
- `.env` conservado (`APP_KEY` intacto); se añadieron banderas de correo Sandbox y `MEMBERSHIP_MAILER` si faltaban.

Fuentes oficiales contrastadas (27–28 sep 2026): ambientes y llaves, widget checkout web, eventos, transacciones, datos de prueba en Sandbox, seguimiento de transacciones.
