> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zappway.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# API de facturación y franja

> Referencia interna para la API de facturación: pago de Stripe, portal de clientes, webhooks, precios, prorrateo, créditos de uso y validación de planes.

> **Documentación interna para desarrolladores.** Esta página cubre los patrones de integración de Stripe, el manejo de webhooks, los flujos de pago y la lógica de activación de planes. No está destinado a usuarios finales.

***

## Mapa de ruta

| Método | Punto final                           | Archivo de controlador                    | Descripción                                                         |
| ------ | ------------------------------------- | ----------------------------------------- | ------------------------------------------------------------------- |
| `POST` | `/api/stripe/create-checkout-session` | `stripe/create-checkout-session/route.ts` | Crear una sesión de Stripe Checkout                                 |
| `POST` | `/api/stripe/customer-portal`         | `stripe/customer-portal/route.ts`         | Crear una sesión en el Portal del cliente de Stripe                 |
| `GET`  | `/api/stripe/get-checkout-session`    | `stripe/get-checkout-session/route.ts`    | Recuperar el resultado de una sesión de pago                        |
| `GET`  | `/api/stripe/prices`                  | `stripe/prices/route.ts`                  | Listar precios de planes disponibles                                |
| `POST` | `/api/stripe/proration-preview`       | `stripe/proration-preview/route.ts`       | Vista previa del prorrateo de suscripción antes de la actualización |
| `POST` | `/api/stripe/usage-credits`           | `stripe/usage-credits/route.ts`           | Agregar/administrar créditos de uso                                 |
| `POST` | `/api/stripe/validate-downgrade`      | `stripe/validate-downgrade/route.ts`      | Validar si el downgrade es seguro                                   |
| `POST` | `/api/stripe/referral`                | `stripe/referral/route.ts`                | Aplicar descuento por recomendación                                 |
| `POST` | `/api/stripe/webhook`                 | `stripe/webhook/route.ts`                 | Recibir eventos de webhook de Stripe                                |

***

## Configuración del cliente Stripe

El cliente Stripe se inicializa en `@zappway/lib/stripe` (o similar). La clave API se carga desde la variable de entorno `STRIPE_SECRET_KEY`.

```ts theme={null}
import { stripe } from '@zappway/lib/stripe';
```

***

## Flujo de pago

```
1. User selects a plan in the UI
   POST /api/stripe/create-checkout-session { priceId, successUrl, cancelUrl }
   → Creates Stripe Checkout Session
   → Returns { url } for redirect

2. User completes payment on Stripe-hosted page
   → Stripe redirects to successUrl with ?session_id=...

3. App fetches session result
   GET /api/stripe/get-checkout-session?session_id=...
   → Validates payment success
   → Returns subscription status

4. Stripe fires webhook
   POST /api/stripe/webhook
   → Updates organization subscription in DB
```

***

## Controlador de webhook

El webhook es la **fuente de verdad** para el estado de suscripción. Todos los cambios de plan deben pasar por el webhook, no por la respuesta de la sesión de pago.

```ts theme={null}
// Webhook signature verification (mandatory)
const event = stripe.webhooks.constructEvent(
  body,
  req.headers.get('stripe-signature'),
  process.env.STRIPE_WEBHOOK_SECRET
);
```

**Eventos clave manejados:**

| Evento de rayas                 | Acción                                              |
| ------------------------------- | --------------------------------------------------- |
| `checkout.session.completed`    | Activar suscripción                                 |
| `customer.subscription.updated` | Actualizar características del plan                 |
| `customer.subscription.deleted` | Bajar al nivel gratuito                             |
| `invoice.payment_failed`        | Marcar error en el pago, notificar al usuario       |
| `invoice.paid`                  | Restablecer contadores de uso para un nuevo período |

***

## Planificar puerta

Los planes controlan el acceso a funciones a través de los metadatos de suscripción de la sesión. El patrón utilizado en la aplicación:

```ts theme={null}
// Example: Personal Assistant plan gate
import { assertPersonalAssistantPlan } from '@zappway/lib/personal-assistant';
assertPersonalAssistantPlan(req.session); // throws 403 if plan doesn't include feature
```

Existen `assertXxxPlan` ayudantes similares para otras funciones premium. Leen desde `req.session.organization.subscription` (cargado desde la base de datos a través de devoluciones de llamada de NextAuth).

***

## Vista previa del prorrateo

Antes de actualizar, la interfaz de usuario llama a la vista previa de prorrateo para mostrar al usuario el cargo exacto:

```ts theme={null}
// POST /api/stripe/proration-preview
// Body: { newPriceId: string }
// Returns: Stripe InvoicePreviewParams result
```

***

## Créditos de uso

El terminal `usage-credits` administra créditos prepagos para facturación basada en el uso (por ejemplo, volumen de mensajes). Los créditos se almacenan en la base de datos y se reducen en cada evento facturable.

***

## Validar degradación

Comprueba si el uso de recursos actual de la organización es compatible con un plan inferior:

```ts theme={null}
// POST /api/stripe/validate-downgrade
// Body: { targetPriceId: string }
// Returns: { canDowngrade: boolean, blockers: string[] }
// blockers example: ['You have 15 active agents, plan limit is 5']
```

***

## Variables de entorno necesarias

| Variables                            | Descripción                                                        |
| ------------------------------------ | ------------------------------------------------------------------ |
| `STRIPE_SECRET_KEY`                  | Clave secreta de Stripe (solo del lado del servidor)               |
| `STRIPE_WEBHOOK_SECRET`              | Secreto del punto final del webhook para la verificación de firmas |
| `NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY` | Clave publicable de Stripe (del lado del cliente)                  |

***

## Problemas conocidos / Problemas

* **Idempotencia del webhook:** Stripe puede entregar el mismo evento varias veces. Todos los controladores de webhook deben ser idempotentes: utilice `stripe_event_id` como clave de desduplicación almacenada en la base de datos.
* **Caducidad de la sesión de pago:** Las sesiones caducan después de 24 horas. Si el usuario abandona el pago y regresa más tarde, necesita una nueva sesión.
* **`validate-downgrade`** debe marcar TODOS los tipos de recursos que tienen límites del plan (agentes, habilidades, almacenes de datos, miembros del equipo, etc.). Si un nuevo tipo de recurso obtiene un límite de plan, este punto final debe actualizarse.
* La **URL del portal del cliente** caduca después de 5 minutos: generela a pedido, nunca la almacene en caché.
