API Storefront (Pública) ======================== El módulo Storefront expone una API pública para embeber formularios de contratación en sitios web externos. Usa autenticación por **X-API-Key** (sin sesión ni JWT). Base URL: ``/storefront/api/`` Autenticación -------------- Todas las peticiones requieren la cabecera ``X-API-Key``: .. code-block:: http GET /storefront/api/plans/ HTTP/1.1 X-API-Key: nxp_a1b2c3d4e5f6... Las API keys se generan desde el dashboard de Storefront (``/storefront/``), accesible solo para superusuarios. Cada key puede tener: - **Dominios permitidos**: lista de dominios CORS autorizados (vacío = todos) - **Rate limit**: peticiones por minuto (default: 60) - **Expiración**: fecha opcional de caducidad Widget ------- ``GET /storefront/api/widget//`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Obtiene la configuración completa de un widget de contratación, incluyendo planes y estilos visuales. **Respuesta** (200): .. code-block:: json { "widget_id": "a1b2c3d4e5f6g7h8", "name": "Widget Hosting", "theme": "auto", "layout": "cards", "primary_color": "#4F46E5", "accent_color": "#10B981", "border_radius": 12, "show_features": true, "cta_text": "Contratar", "show_hosting": true, "show_vps": true, "require_phone": false, "require_company": false, "language": "es", "success_url": "https://ejemplo.com/gracias", "cancel_url": "https://ejemplo.com/cancelado", "plans": [ { "id": 1, "name": "Hosting Basic", "slug": "hosting-basic", "description": "Plan básico de hosting", "resource_type": "hosting", "billing_period": "monthly", "price": "2.99", "effective_price": "2.99", "setup_fee": "0.00", "currency": "EUR", "quota_sites": 1, "quota_databases": 1, "quota_storage_gb": 5, "quota_mailboxes": 5 } ] } Planes ------- ``GET /storefront/api/plans/`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Lista todos los planes de precios activos. Filtrable por tipo de recurso. **Parámetros query**: .. list-table:: :header-rows: 1 :widths: 20 15 65 * - Parámetro - Tipo - Descripción * - ``type`` - string - Filtrar por tipo: ``hosting``, ``vps``, ``saas`` **Respuesta** (200): Array de planes con campos de cuotas según tipo. Campos comunes: .. list-table:: :header-rows: 1 :widths: 25 15 60 * - Campo - Tipo - Descripción * - ``id`` - int - ID del plan * - ``name`` - string - Nombre del plan * - ``slug`` - string - Slug URL-safe * - ``price`` - decimal - Precio mensual (IVA incluido) * - ``effective_price`` - string - Precio redondeado a 2 decimales * - ``setup_fee`` - decimal - Cuota de alta * - ``currency`` - string - Moneda (default: EUR) * - ``billing_period`` - string - ``monthly`` o ``yearly`` * - ``resource_type`` - string - ``hosting``, ``vps`` o ``saas`` Campos adicionales de hosting: ``quota_sites``, ``quota_databases``, ``quota_storage_gb``, ``quota_mailboxes``, ``quota_domains``, ``quota_ftp_users``. Campos adicionales de VPS: ``vps_cpu_cores``, ``vps_memory_mb``, ``vps_disk_gb``, ``vps_bandwidth_tb``, ``vps_default_os``, ``vps_os_options``. Campos adicionales de SaaS: ``saas_max_vms``, ``saas_max_hosting_accounts``, ``saas_max_agents``, ``saas_whitelabel``. Pedidos -------- ``POST /storefront/api/orders/`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Crea un nuevo pedido y redirige al método de pago seleccionado. **Body** (JSON): .. code-block:: json { "plan_id": 1, "customer_email": "cliente@ejemplo.com", "customer_name": "Juan García", "customer_phone": "+34612345678", "customer_company": "Mi Empresa SL", "payment_method": "stripe", "billing_period": "monthly", "domain": "midominio.com", "os_choice": "ubuntu-24.04", "language": "es", "widget_id": "a1b2c3d4e5f6g7h8" } .. list-table:: :header-rows: 1 :widths: 20 10 10 60 * - Campo - Tipo - Requerido - Descripción * - ``plan_id`` - int - Si - ID del plan activo * - ``customer_email`` - email - Si - Email del cliente * - ``customer_name`` - string - Si - Nombre completo * - ``customer_phone`` - string - No - Teléfono (según widget) * - ``customer_company`` - string - No - Empresa (según widget) * - ``payment_method`` - string - Si - ``stripe``, ``paypal`` o ``test`` * - ``billing_period`` - string - No - ``monthly`` (default) o ``yearly`` * - ``domain`` - string - No - Dominio personalizado (FQDN) * - ``os_choice`` - string - No - Sistema operativo (solo VPS) * - ``language`` - string - No - Idioma (default: ``es``) * - ``widget_id`` - string - No - ID del widget de origen **Respuesta** (201): .. code-block:: json { "order_id": "550e8400-e29b-41d4-a716-446655440000", "order_number": "ORD-260219-A3F2", "payment_url": "https://checkout.stripe.com/c/pay/cs_...", "status": "payment_processing" } **Precios anuales**: se aplica un descuento del 20% y se multiplica por 12 meses: ``precio_anual = precio_mensual × 0.8 × 12``. ``GET /storefront/api/orders//`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consulta el estado de un pedido. **Respuesta** (200): .. code-block:: json { "id": "550e8400-e29b-41d4-a716-446655440000", "order_number": "ORD-260219-A3F2", "status": "active", "status_message": "Cuenta de hosting creada correctamente", "plan_name": "Hosting Basic", "price": "2.9900", "setup_fee": "0.0000", "tax_rate": "21.00", "currency": "EUR", "billing_period": "monthly", "subtotal": "2.99", "total": "2.99", "payment_method": "stripe", "created_at": "2026-02-19T15:30:00Z" } Estados del pedido: .. list-table:: :header-rows: 1 :widths: 25 75 * - Estado - Descripción * - ``pending`` - Pedido creado, pendiente de pago * - ``payment_processing`` - Redirigido a pasarela de pago * - ``paid`` - Pago confirmado, pendiente de provisionamiento * - ``provisioning`` - Creando recursos (hosting/VPS/SaaS) * - ``active`` - Recurso activo y funcionando * - ``failed`` - Error en provisionamiento * - ``cancelled`` - Pedido cancelado * - ``refunded`` - Pedido reembolsado Widget Embebible ----------------- El widget JavaScript permite embeber el formulario de contratación en cualquier sitio web externo: .. code-block:: html
El widget: - Carga los planes del widget via API - Renderiza tarjetas/tabla según el layout configurado - Gestiona el formulario de contratación - Redirige a Stripe/PayPal para el pago - Muestra página de resultado (éxito/cancelación) Integración Paso a Paso ~~~~~~~~~~~~~~~~~~~~~~~~~ 1. Crear una **API Key** en ``/storefront/`` 2. Crear un **Order Form** (widget) con los planes deseados 3. Copiar el **snippet de embed** e insertarlo en tu web 4. Configurar **success_url** y **cancel_url** para redirecciones post-pago Guía detallada disponible en ``/storefront/integration/`` (requiere login). Webhooks --------- NoxPanel procesa webhooks de Stripe y PayPal para confirmar pagos: - **Stripe**: ``/storefront/webhooks/stripe/`` — eventos ``checkout.session.completed`` - **PayPal**: ``/storefront/webhooks/paypal/`` — eventos ``CHECKOUT.ORDER.APPROVED`` Tras confirmar el pago, se dispara el provisionamiento automático: 1. Crear usuario Django (si no existe) 2. Crear tenant de hosting / VM / sub-tenant SaaS 3. Crear suscripción y factura 4. Enviar email de bienvenida con credenciales 5. Actualizar estado del pedido a ``active`` CORS ----- El middleware ``StorefrontCORSMiddleware`` gestiona CORS específicamente para las rutas ``/storefront/api/``: - Verifica el header ``Origin`` contra ``allowed_domains`` de la API key - Añade cabeceras ``Access-Control-Allow-*`` apropiadas - Responde a preflight OPTIONS con los métodos permitidos