# INDEX_plugin.md — Plugin.php
> **Archivo:** `src/Plugin.php` | 672 líneas | Entry point del plugin UCRM

---

## Propósito
Clase orquestadora principal. UCRM la invoca en cada evento (hook). Detecta si viene de HTTP o CLI y delega al handler correspondiente.

## Namespace & Dependencias
```
namespace SmsNotifier
Depende de: PluginNotifierFacade, PluginOxxoNotifierFacade, TwilioNotifierFacade,
            NotificationDataFactory, Logger, OptionsManager, PluginDataValidator, UcrmApi
```

## Propiedades
| Propiedad | Tipo | Descripción |
|---|---|---|
| `$logger` | Logger | Logger del plugin |
| `$optionsManager` | OptionsManager | Carga config del plugin |
| `$pluginDataValidator` | PluginDataValidator | Valida configuración |
| `$pluginNotifierFacade` | PluginNotifierFacade | Fachada Stripe + Callbell |
| `$pluginOxxoNotifierFacade` | PluginOxxoNotifierFacade | Fachada OXXO |
| `$notifierFacade` | TwilioNotifierFacade | Fachada notificaciones base |
| `$notificationDataFactory` | NotificationDataFactory | Crea objetos NotificationData |
| `$ucrmApi` | UcrmApi (SDK) | Cliente API UCRM |

## Métodos
| Método | Línea | Descripción |
|---|---|---|
| `__construct(...)` | 58 | Inicializa dependencias + UcrmApi con config |
| `run(): void` | 84 | Entry point: detecta SAPI (fpm/cli) y delega |
| `processCli(): void` | 96 | CLI: solo valida config |
| `processHttpRequest(): void` | 104 | HTTP: procesa payload JSON del webhook |

---

## Flujo de `processHttpRequest()` (L.104–670)

### Paso 1 — Detectar tipo de payload (L.111–268)
Lee `php://input`. Si **no tiene `uuid`** → es webhook externo (Stripe/OXXO):

| `type` en JSON | Línea | Acción |
|---|---|---|
| `customer_cash_balance_transaction.created` → `funded` | 133 | `pluginNotifierFacade->createPaymentIntent()` |
| `customer_cash_balance_transaction.created` → `applied_to_payment` | 139 | `pluginNotifierFacade->registerPaymentFromWebhook()` |
| `customer_cash_balance_transaction.created` → `unapplied_from_payment` | 142 | Log de transferencia cancelada |
| `payment_intent.succeeded` | 166 | `pluginNotifierFacade->registerPaymentFromIntent()` |
| `oxxo.retrieve` | 172 | `pluginOxxoNotifierFacade->getOxxoOrderStatus()` → responde JSON |
| `oxxo.request` | 188 | Flujo async: `createStripeReference()` → `createOxxoOrder()` → responde → `generateOxxoVoucher()` en background |
| `payout.failed` | 150 | Solo log |
| `payment_intent.partially_funded` | 155 | Solo log |
| `cash_balance.funds_available` | 163 | Solo log |

### Paso 2 — Payload con `uuid` → Webhook UCRM (L.270–670)
Construye `NotificationData` via factory, luego switch por `eventName`:

| `eventName` | Línea | Acción |
|---|---|---|
| `payment.add` | 297 | Switch por `methodId` UUID → `notifierFacade->verifyPaymentActionToDo()` |
| `payment.delete/unmatch/edit` | 418 | `notifierFacade->verifyClientActionToDo()` |
| `client.edit` | 423 | Detecta cambios de tags/datos → `updatePasswordAntenaIfNeeded()`, `createStripeClient()`, `syncStripeCustomerData()`, `verifyClientActionToDo()` |
| `client.add` | 539 | Solo log |
| `service.edit` | 542 | `notifierFacade->verifyServiceActionToDo()` + `updatePasswordAntenaIfNeeded()` |
| `service.suspend` | 552 | `notifierFacade->verifyServiceActionToDo()` |
| `service.suspend_cancel` | 555 | `notifierFacade->verifyServiceActionToDo()` |
| `service.postpone` | 558 | `notifierFacade->verifyServiceActionToDo()` |
| `invoice.near_due` | 561 | `notifierFacade->notifyOverDue()` |
| `invoice.overdue` | 564 | `notifierFacade->notifyOverDue()` |
| `invoice.add` | 569 | `notifierFacade->verifyInvoiceActionToDo()` |
| `invoice.edit` | 579 | `notifierFacade->verifyInvoiceActionToDo()` |
| `invoice.add_draft` | 582 | `notifierFacade->verifyInvoiceActionToDo()` |
| `invoice.draft_approved` | 585 | `notifierFacade->verifyInvoiceActionToDo()` |
| `invoice.delete` | 588 | `notifierFacade->verifyInvoiceActionToDo()` |
| `job.add` | 591 | PATCH title en UCRM con prefijo `[NOTIFICACION-PENDIENTE]` |
| `job.edit` | 599 | Detecta cambios status/técnico/fecha → `notifierFacade->verifyJobActionToDo()` |

---

## UUIDs de Métodos de Pago (L.309–416)
| UUID | Método |
|---|---|
| `11721cdf-...` | Cheque |
| `6efe0fa8-...` | Efectivo |
| `4145b5f5-...` | Transferencia bancaria |
| `78e84000-...` | PayPal |
| `6da98bb9-...` | Tarjeta de crédito PayPal |
| `1dd098fa-...` | Stripe Credit Card (detecta sub-tipo por metadata) |
| `b9e1e9d1-...` | Suscripción Stripe (tarjeta) |
| `939f7701-...` | Suscripción PayPal |
| `1c963e35-...` | MercadoPago |
| `d8c1eae9-...` | Personalizado |
| `72271b72-...` | Cortesía |
| `b01c0b35-...` | OXXO Pay |
| `93814765-...` | Tarjeta de crédito/débito |

---

## Tags de Cliente que disparan acciones (L.460–492)
| Tag | Acción |
|---|---|
| `CREAR CLABE STRIPE` | `pluginNotifierFacade->createStripeClient(..., true)` |
| `CREAR CLIENTE STRIPE` | `pluginNotifierFacade->createStripeClient(..., false)` |
| `OBTENER PASSWORD ANTENA` | `pluginNotifierFacade->processClientPasswordAntenna()` |
| `isLead: true→false` | Auto-crea cliente en Stripe |

---

## Notas de implementación
- `job.edit` con `statusAfter==1` y `$isPending` en título dispara notificación
- El flujo `oxxo.request` usa `fastcgi_finish_request()` para responder antes de generar el voucher
- `client.edit` refresca datos del cliente vía UCRM API antes de sincronizar con CallBell
