154 lines
6.7 KiB
Markdown
Executable File
154 lines
6.7 KiB
Markdown
Executable File
# INDEX_public.md — public.php
|
||
> **Archivo:** `public.php` | 2978 líneas | Portal web administrativo + endpoint público HTTP
|
||
|
||
---
|
||
|
||
## Propósito
|
||
Archivo dual:
|
||
1. **Endpoint REST/webhook** — recibe webhooks de Stripe, solicitudes OXXO, y llamadas AJAX del portal
|
||
2. **SPA PHP** — interfaz web administrativa con 4 módulos (Instaladores, Notificaciones, Stripe, OXXO)
|
||
|
||
---
|
||
|
||
## Variables globales inicializadas (L.1–65)
|
||
| Variable | Descripción |
|
||
|---|---|
|
||
| `$config` | Config del plugin cargada de `data/config.json` |
|
||
| `$ucrmApi` | `UcrmApi` (SDK) con base_uri UCRM y apitoken |
|
||
| `$paymentIntentService` | `PaymentIntentService` con stripeApiKey |
|
||
| `$admins` | Array de admins UCRM `[id, nombre]` |
|
||
| `$defaultStripeAdminId` | ID del admin "stripe" o primero de la lista |
|
||
| `$nmsBaseUrl` | `https://{ipserver}/nms/api/v2.1` |
|
||
| `$installersData` | JSON de instaladores desde config |
|
||
|
||
---
|
||
|
||
## Mapa de Endpoints / Actions
|
||
|
||
### POST con JSON body (L.22–35) — Webhook delegado a Plugin::run()
|
||
| Condición | Acción |
|
||
|---|---|
|
||
| `isset($jsonData['uuid']) || isset($jsonData['eventName']) || isset($jsonData['type'])` | Instancia `Plugin` via DI container y llama `run()` |
|
||
|
||
---
|
||
|
||
### POST `?action=nms_login` (L.80–117) — Login NMS
|
||
- **Body:** `{username, password}`
|
||
- **Respuesta 200:** `{success, token, user}`
|
||
- **Respuesta 201:** `{requires2FA, twoFactorToken}` → sigue con `nms_login_totp`
|
||
- **Guarda token en:** `sessionStorage('nms_auth_token')` (frontend)
|
||
|
||
### POST `?action=nms_login_totp` (L.120–146) — Login TOTP 2FA
|
||
- **Body:** `{twoFactorToken, ..., totpCode}`
|
||
- **Respuesta 200:** `{success, token, user}`
|
||
|
||
### GET `?action=nms_verify_session` (L.148–173) — Verificar sesión NMS
|
||
- **Header:** `x-auth-token`
|
||
- **Llama:** `GET {nmsBaseUrl}/user`
|
||
|
||
---
|
||
|
||
### POST `$_POST['action']` (L.176–291)
|
||
|
||
| action | Línea | Params | Descripción |
|
||
|---|---|---|---|
|
||
| `save_installers` | 177 | `installers_data` (JSON) | Guarda JSON en config.json |
|
||
| `resend_payment` | 191 | `paymentId` | Obtiene pago+cliente UCRM, hace loopback POST a sí mismo simulando webhook |
|
||
| `resend_job_notification` | 238 | `jobId` | Simula webhook `job.edit` con status 0→1 y prefijo `[NOTIFICACION-PENDIENTE]` |
|
||
| `create_intent` | 443 | `clientId, amount, stripeCustomerId, adminId` | `PaymentIntentService->createPaymentIntent()` |
|
||
| `create_oxxo_intent` | 463 | `clientId, amount` | `PluginOxxoNotifierFacade->createOxxoPaymentIntent()` via DI |
|
||
|
||
---
|
||
|
||
### GET `?action=...` (L.293–438)
|
||
|
||
| action | Línea | Params GET | Descripción |
|
||
|---|---|---|---|
|
||
| `search_clients` | 296 | `q` | UCRM `GET clients?query=q&limit=6` |
|
||
| `get_payments` | 307 | `clientId` | UCRM `GET payments?clientId=...&limit=20` + names de métodos |
|
||
| `search_stripe` | 323 | `q` | `PaymentIntentService->searchClients(q)` |
|
||
| `get_stripe_details` | 329 | `id` (clientId UCRM) | `PaymentIntentService->getClientDetails(id)` |
|
||
| `get_stripe_history` | 339 | `stripeCustomerId` | Balance cash + últimos 10 PIs de transferencia |
|
||
| `get_oxxo_history` | 355 | `stripeCustomerId` | Últimos 5 PIs OXXO de Stripe |
|
||
| `get_installer_jobs` | 365 | `installerId` | UCRM `GET scheduling/jobs?assignedUserId=...&statuses=[0,1]&limit=50` |
|
||
| `image` / `get_image` | 413 | `file` o `name` | Sirve imágenes de `/img/`, `/img/webp/`, `/vouchers_oxxo/` |
|
||
|
||
---
|
||
|
||
## HTML/UI — Estructura (L.481–2064)
|
||
|
||
### Variables PHP→JS inyectadas (L.2066–2075)
|
||
```javascript
|
||
NEEDS_LOGIN = true/false // Si sesión UCRM activa
|
||
SYSTEM_USER_ID = null|int // ID usuario actual
|
||
store.installers = [...] // Array de instaladores desde config
|
||
store.crmUrl = 'https://...' // URL base API UCRM
|
||
store.publicUrl = 'https://...'// URL pública CRM
|
||
store.defaultStripeAdminId = '' // ID admin Stripe por defecto
|
||
```
|
||
|
||
### Módulos de la UI (tabs)
|
||
| Tab ID | Sección HTML | Descripción |
|
||
|---|---|---|
|
||
| `instaladores` | `#section-instaladores` | Tabla instaladores + jobs activos del instalador |
|
||
| `notificaciones` | `#section-notificaciones` | Búsqueda cliente + tabla pagos + botón reenviar |
|
||
| `pagos-spei` | `#section-pagos-spei` (en `views/stripe.php`) | Generador Stripe + historial |
|
||
| `pagos-oxxo` | `#section-pagos-oxxo` (en `views/oxxo.php`) | Generador OXXO + historial |
|
||
|
||
### Funciones JS principales (L.2065+)
|
||
| Función | Descripción |
|
||
|---|---|
|
||
| `toggleTheme()` | Cambia light/dark en `data-theme` + localStorage |
|
||
| `showDashboard()` | Muestra menú principal, oculta módulos |
|
||
| `showModule(id)` | Activa módulo por ID (mapea 'stripe'→'pagos-spei', etc.) |
|
||
| `switchTab(tabName)` | Cambia tab activa y sección visible |
|
||
| `showToast(msg, err)` | Toast temporal 3s |
|
||
| `setupSearch(inputId, resultId, action, onSelect)` | Search debounced 300ms → fetch `?action=...` |
|
||
| `renderRichSearchResults(container, data, query, cb)` | Renderiza resultados de búsqueda con highlight |
|
||
| `highlightMatch(text, query)` | Resalta coincidencias en texto |
|
||
| `loadPayments(id)` | Fetch `?action=get_payments&clientId=id` → tabla |
|
||
| `refreshClientPayments()` | Recarga pagos del cliente actual |
|
||
| `resendPayment(id)` | POST `action=resend_payment&paymentId=id` |
|
||
| `loadOxxoHistory(stripeCustomerId)` | Fetch `?action=get_oxxo_history` → tabla |
|
||
| `handleLogin()` | POST `?action=nms_login` → guarda token en sessionStorage |
|
||
| `handleTotpLogin()` | POST `?action=nms_login_totp` |
|
||
| `handleLogout()` | Limpia sessionStorage + reload |
|
||
|
||
### Funciones JS Instaladores
|
||
| Función | Descripción |
|
||
|---|---|
|
||
| `openInstallerModal()` | Abre modal de nuevo instalador |
|
||
| `fillInstallerData(select)` | Rellena campos desde select de admin |
|
||
| `loadInstallerJobs(installerId)` | Fetch `?action=get_installer_jobs&installerId=...` |
|
||
| `resendJobNotification(jobId)` | POST `action=resend_job_notification` |
|
||
| `renderInstallersTable()` | Renderiza tabla desde `store.installers` |
|
||
|
||
---
|
||
|
||
## Includes externos (L.1992–1993)
|
||
```php
|
||
include __DIR__ . '/views/stripe.php'; // Sección y JS del módulo Stripe
|
||
include __DIR__ . '/views/oxxo.php'; // Sección y JS del módulo OXXO
|
||
```
|
||
|
||
---
|
||
|
||
## Archivos que sirve el endpoint `image`
|
||
- `/img/*.{png,webp,jpg}`
|
||
- `/img/webp/*.{webp}`
|
||
- `/vouchers_oxxo/*.{png,webp,jpg}`
|
||
|
||
## Login overlay (L.1711–1750)
|
||
- Se muestra si `NEEDS_LOGIN = true` (usuario sin sesión UCRM activa)
|
||
- Pide credenciales NMS (UISP), no UCRM
|
||
- Soporta 2FA TOTP
|
||
- Token guardado en `sessionStorage('nms_auth_token')`
|
||
|
||
---
|
||
|
||
## Notas de implementación
|
||
- `resend_payment` hace un **loopback cURL** a sí mismo simulando webhook UCRM
|
||
- `create_intent` usa `PaymentIntentService` que llama a Stripe SDK directo
|
||
- El CSS (~1200 líneas) está inline en el archivo, soporta dark/light mode vía `data-theme`
|
||
- Las vistas `stripe.php` y `oxxo.php` tienen su propio JS, leer esos archivos para modificar esos módulos
|