Facturación de suscripciones
Los planes y sus límites, la página de facturación, los cambios a un plan superior cobrados al instante y los cambios a uno inferior programados para la renovación, el pago de prueba integrado y Stripe, las pruebas y las renovaciones, los correos de facturación, las facturas en PDF, y qué cambia un pago fallido o una suspensión.
Para el paquete Full Stack
Planes y sus límites
Cada espacio de trabajo está en uno de tres planes mensuales, en dólares estadounidenses:
| Plan | Precio | Puestos | Solicitudes de API | Almacenamiento |
|---|---|---|---|---|
| Starter | $29 al mes | 3 | 10,000 | 5 GB |
| Pro | $99 al mes | 10 | 100,000 | 20 GB |
| Scale | $249 al mes | 30 | 500,000 | 100 GB |
- Un espacio de trabajo creado en el alta inicial empieza con una Trial de Starter, durante el ajuste Trial length de la plataforma (
trial_days, 14 días tal como se carga). Los datos de ejemplo ponen a Forma Studio en Pro, con tres facturas pagadas. - Cuando una prueba llega a su fin sin un plan de pago, el espacio de trabajo pasa a Past due desde ese momento, y empieza el periodo de gracia de un pago fallido (consulta Un pago fallido más abajo). La página de facturación dice "The trial has ended. Choose a paid plan before" el fin del periodo de gracia, y el rastro de actividad registra "The trial ended without a paid plan".
- Los Seats se hacen cumplir: una invitación, y aceptar una, se rechaza con
seat_limit_reachedcuando todos los puestos están ocupados. - Las API requests cuentan las llamadas hechas con las claves de API del espacio de trabajo, y el Storage los archivos de proyecto que contiene. Ambos se muestran frente al plan y se comprueban antes de un cambio a un plan inferior; la API no rechaza una llamada ni un archivo subido por encima del límite. El recuento de solicitudes vuelve a cero con cada nuevo periodo de facturación, incluido el de una prueba.
La página de facturación
Billing, en /en/dashboard/billing, muestra la suscripción del espacio de trabajo:
- El plan con su estado (Trial, Active, Past due, Ending, Canceled o Suspended), su precio mensual y la siguiente fecha que importa, como "Renews" o "Trial ends".
- Change plan (Choose a paid plan durante una prueba, después de que haya terminado, y cuando el espacio de trabajo está cancelado) y Manage payment method, o Resume subscription mientras el plan está terminando.
- Mientras un cambio a un plan inferior espera la renovación, "Moves to Starter on" la fecha, con Keep Pro (el nombre del plan actual) para deshacerlo.
- Usage: solicitudes de API, puestos y almacenamiento frente a los límites del plan.
- Invoice history, con un botón Download en cada factura.
- Billing email, con Edit: "Payment notices go to this address, and it is printed on every invoice." Stripe Checkout también lo rellena.
- Cancel subscription, mientras el plan está en prueba, activo o con el pago vencido.
Un miembro que puede leer la facturación pero no cambiarla ve la misma página con "Only the owner and billing members change the plan." en lugar de los botones.
Cambiar de plan
Elige un plan
Pulsa Change plan y elige un plan. Bajo "What changes" el cuadro de diálogo muestra lo que se Charged today y la Next invoice, ambos de la API. Durante una prueba, después de que haya terminado y cuando el espacio de trabajo está cancelado, el botón es Choose a paid plan, y se puede elegir cualquier plan, incluido el actual ("Your trial plan" durante una prueba).
Un cambio a un plan superior: cobrado al instante
Un plan más caro surte efecto al instante, y la fecha de renovación se mantiene. En una suscripción de Stripe en marcha el cuadro de diálogo dice "Takes effect at once. The card on file is charged the prorated difference today, and the renewal date stays.", Charged today es la cifra propia de Stripe, y Upgrade and pay now la cobra al método de pago guardado sin página de pago. En el pago de prueba dice "Takes effect at once, prorated for the rest of this period." y Continue to payment abre el pago. Un primer pago (una prueba, una prueba terminada o un espacio de trabajo cancelado) cobra el mes completo del plan y empieza un nuevo periodo de 30 días: "The paid plan starts at once. The first month is charged in full.", con "and ends the trial" durante una prueba.
Pagar y volver
El pago es el pago de prueba integrado, o la propia página de Stripe una vez configurado Stripe. Un cambio a un plan superior cobrado a la tarjeta guardada termina al instante con "The workspace is on the Pro plan." De vuelta en la página de facturación desde un pago dice "Confirming the payment...", luego "Payment received. The workspace is on the Pro plan." con el plan nuevo, sus límites y una factura pagada. Un pago que se dejó sin terminar muestra "A checkout for the Pro plan was started and not finished." hasta que se descarta.
Un cambio a un plan inferior: programado, sin cobrar nada
Un plan más barato "Takes effect on" la fecha de renovación, "Nothing is charged today.", y Schedule the change lo registra; el panel del plan dice entonces "Moves to Starter on" esa fecha. Keep Pro a su lado deshace el cambio: "The workspace stays on the Pro plan." Mientras los puestos, las solicitudes de API o el almacenamiento superan los límites del plan más pequeño, el cuadro de diálogo lista cada uno y rechaza con "Bring usage under the new plan's limits first."
Un plan comprado mediante un pago cambia solo cuando el proveedor de pago lo confirma: desde el webhook firmado de Stripe, o cuando la página de facturación consulta a la API al volver el visitante y la API lee la sesión directamente de Stripe. La dirección de retorno por sí sola nunca cambia un plan.
- Con Stripe, un cambio a un plan superior modifica la suscripción en marcha sobre la marcha: Stripe factura al instante la diferencia prorrateada y la cobra al método de pago guardado. El precio mostrado vale 30 minutos; después el cambio se rechaza ("The price shown is out of date. Check the new price, then confirm again.") y el cuadro de diálogo muestra la nueva cifra. Una tarjeta rechazada, un banco que quiere confirmar el pago, o la falta de método de pago guardado se rechazan con una frase que dice cuál, y el plan se queda como estaba.
- Con Stripe, un cambio a un plan inferior es un calendario de suscripción: el periodo actual conserva el precio que se pagó, la renovación factura el precio menor, y no se prorratea nada. Cuando se paga esa renovación, el espacio de trabajo pasa al plan nuevo. Keep libera el calendario, y un cambio a un plan superior en medio lo descarta (y lo restablece si el cobro falla).
- Con el pago de prueba, el periodo se renueva por sí solo al terminar: una factura pagada al precio del plan, el siguiente periodo de 30 días, el recuento de uso a cero, y se aplica un cambio a un plan inferior programado para entonces.
El pago de prueba integrado
Sin clave de Stripe, cada cambio de plan pasa por el propio pago de prueba del panel en /en/dashboard/billing/checkout/<session>. Muestra el espacio de trabajo, el plan actual y el nuevo, el importe y a quién se factura, dice "This is the built-in test checkout. It asks for no card and charges nothing.", y ofrece Test payment y Cancel.
- Test payment cambia el plan al instante y escribe una factura pagada, exactamente como lo hace un pago de Stripe confirmado. Cancel no cobra nada: "Checkout canceled. Nothing was charged."
- Solo un miembro con permiso para gestionar la facturación en ese espacio de trabajo puede abrir la página.
BILLING_PROVIDER=simulatoren el.envde la API mantiene el pago de prueba incluso con claves de Stripe definidas.- Manage payment method dice "The test checkout keeps no card, so there is no payment method to manage."
Aceptar pagos reales con Stripe
Define STRIPE_SECRET_KEY en el .env de la API y reiníciala. El registro de la API dice entonces "Stripe is set up in test mode." para una clave sk_test_, o que cobra tarjetas reales para una clave sk_live_.
- Un primer pago abre Stripe Checkout en modo suscripción para el precio mensual del plan, a nombre del correo de facturación. Stripe devuelve al comprador a la página de facturación, que confirma el pago con la API antes de mostrar el plan nuevo.
- No hace falta crear nada antes en Stripe: el precio de cada plan se crea la primera vez que se necesita, con un producto que lleva el nombre del plan (
Northstack Pro) y la clave de búsquedanorthstack_<plan>_usd_<cents>_month(northstack_pro_usd_9900_month), y después se encuentra por esa clave. Un precio de plan nuevo recibe una clave nueva, y las suscripciones con el precio antiguo lo conservan. - Después, un cambio a un plan superior modifica la suscripción en marcha y cobra la tarjeta guardada, y un cambio a uno inferior se programa para la renovación, como en Cambiar de plan más arriba. Stripe renueva la suscripción por sí mismo, y su
invoice.paidlleva el espacio de trabajo al siguiente periodo. - Si un nuevo pago de Stripe sustituye una suscripción que el espacio de trabajo aún tiene, la API cancela la antigua, con su tiempo sin usar abonado en la siguiente factura del cliente. Si Stripe rechaza esa cancelación, el registro de la API lo indica y nombra la suscripción que hay que cancelar en el panel de Stripe.
- Cuando un espacio de trabajo ya ha pagado con Stripe, Manage payment method abre el portal de clientes de Stripe y vuelve a la página de facturación.
- Cancel subscription indica a Stripe que termine la suscripción al final del periodo, descartando un cambio a un plan inferior programado para la renovación, y Resume subscription deshace la cancelación.
- Con claves de prueba no se mueve dinero: en la página de Stripe paga con la tarjeta
4242 4242 4242 4242, cualquier fecha futura y cualquier CVC.
El webhook de Stripe
Antes de salir en vivo, añade un webhook en Stripe con la dirección pública de tu API y pon su secreto de firma en STRIPE_WEBHOOK_SECRET. Las suscripciones y los pedidos de licencias del sitio web comparten este único endpoint.
| Dirección | Eventos |
|---|---|
https://<your-api>/api/billing/webhooks/stripe | checkout.session.completed, checkout.session.expired, invoice.paid, invoice.payment_failed, customer.subscription.deleted |
- Cada entrega se comprueba primero con la firma de Stripe, y una firma incorrecta se rechaza con un 400. Cada id de evento se aplica una sola vez, por muchas veces que Stripe lo envíe.
- Con
STRIPE_SECRET_KEYdefinido ySTRIPE_WEBHOOK_SECRETvacío, el registro de la API lo indica al iniciar, y cada entrega se rechaza con un 400 cuyo mensaje nombraSTRIPE_WEBHOOK_SECRET. Hasta que se define, las renovaciones, los pagos fallidos y las cancelaciones no se registran, y un pago solo cuenta cuando el comprador vuelve a la página de facturación. checkout.session.completedcambia el plan.invoice.paidguarda la factura de Stripe una sola vez, con su importe y el periodo que paga, y vuelve a poner el espacio de trabajo en Active (o en Ending si estaba cancelado). Una factura que inicia un periodo lleva la fecha de renovación a su fin y pone el recuento de uso a cero, y una renovación aplica un cambio a un plan inferior programado para ella; la factura prorrateada de un cambio a un plan superior no mueve nada.invoice.payment_failedmarca el espacio de trabajo como Past due, ycustomer.subscription.deletedlo marca como Canceled.- En tu propio equipo Stripe no puede llegar a la API, y un pago de prueba se completa igualmente, porque la página de facturación pide a la API que lea la sesión de Stripe cuando vuelve el comprador.
Cancelar y reanudar
Cancel subscription pregunta "Cancel the subscription?": el plan sigue activo hasta la fecha de renovación, y después el espacio de trabajo conserva sus datos pero deja de facturar. El estado pasa a Ending, el panel dice "Ends" con la fecha, y Resume subscription mantiene el plan después de todo. Un cambio a un plan inferior programado para la renovación se descarta, ya que no hay renovación en la que ocurra.
Con Stripe, Stripe termina la suscripción en esa fecha y su webhook marca el espacio de trabajo como Canceled. En el pago de prueba el espacio de trabajo pasa a Canceled al final del periodo. Un espacio de trabajo cancelado conserva toda lectura, y no puede crear proyectos, invitaciones ni claves de API nuevos hasta que vuelva a estar en un plan de pago: Choose a paid plan compra cualquier plan a su precio completo, desde ese día.
Eliminar un espacio de trabajo (su propietario, en Settings, Danger zone) termina su suscripción de Stripe al instante, sin abono por el resto del periodo. Si no se puede contactar con Stripe, la eliminación se rechaza con un 409, "The subscription could not be canceled with the payment provider, so the workspace was kept. Try again in a few minutes.", de modo que un espacio de trabajo eliminado nunca se factura.
Facturas
- Se escribe una factura, numerada
INV-con el año y un número correlativo, cada vez que se paga un cambio de plan, por el importe cobrado entonces, en cada renovación del pago de prueba, y con Stripe por cada factura que Stripe informa como pagada, renovaciones incluidas, con el importe y el periodo de Stripe. Una factura de Stripe se guarda una sola vez, por muchas veces que se informe. Invoice history lista las últimas 36, con su fecha, importe y estado (Paid, Open o Void). - Download abre la factura como PDF: el plan, el periodo, a quién se factura y el total. El enlace está firmado y funciona cinco minutos, sin iniciar sesión, así que se puede abrir en una pestaña nueva.
- El correo de facturación de la página es la dirección que nombra la factura y la que rellena Stripe Checkout.
Pruebas y renovaciones con el tiempo
Lo que el calendario hace vencer lo aplica la propia API, una vez cada cosa: una prueba que llega a su fin, un periodo del pago de prueba que se renueva y una suscripción configurada para terminar con su periodo. Se ejecuta cada vez que se lee la facturación de un espacio de trabajo, y una vez por hora para cada espacio (la primera pasada un minuto después de iniciar la API), así que un servidor que estuvo apagado se pone al día cuando vuelve.
- Stripe renueva sus propias suscripciones; para esas, la API sigue los
invoice.paidyinvoice.payment_failedde Stripe. - Cada cambio se hace una sola vez aunque dos peticiones, o dos servidores de API, resuelvan el mismo espacio de trabajo en el mismo momento.
- El rastro de actividad registra una prueba terminada (
billing.trial_ended), un cambio de plan (billing.plan_changed, incluido uno aplicado en una renovación) y un cambio programado deshecho (billing.schedule_canceled).
Correos de facturación
Cuatro eventos de facturación se envían por correo al propietario y a los miembros de facturación del espacio de trabajo, cada uno en su propio idioma, o en el del espacio cuando no han elegido ninguno, y al correo de facturación en el idioma del espacio cuando no es ya uno de los suyos, con un enlace a la página de facturación:
- un pago fallido, con el fin del periodo de gracia;
- una prueba que terminó sin un plan de pago, con la misma fecha;
- un cambio de plan que se pagó;
- un cambio programado aplicado en la renovación.
El interruptor Email notifications del espacio de trabajo (Settings, Notifications) desactiva estos cuatro para todos los del espacio. Las invitaciones, los restablecimientos de contraseña y los recibos de licencia se envían siempre. Sin ajustes SMTP, cada mensaje se escribe en el registro de la API.
Un pago fallido
Cuando Stripe informa de un pago fallido, el espacio de trabajo pasa a Past due, y la página de facturación dice "The last payment failed. Update the payment method before" el fin de su periodo de gracia. Una prueba que terminó sin un plan de pago está vencida del mismo modo, desde su fecha de fin.
- Durante el periodo de gracia,
BILLING_GRACE_DAYSen el.envde la API (7 por defecto), todo sigue funcionando. - Después, el espacio de trabajo no puede crear proyectos, invitaciones ni claves de API nuevos; la API los rechaza con
billing_grace_expired. Toda lectura y todo registro existente siguen funcionando, y nunca se elimina nada por un pago fallido. - La siguiente factura pagada vuelve a poner el espacio de trabajo en Active; tras una prueba terminada, lo hace el primer pago.
Un espacio de trabajo suspendido
El personal de la plataforma puede suspender un espacio de trabajo desde la administración de la plataforma. Sus miembros aún pueden iniciar sesión y leerlo todo, todo cambio se rechaza con workspace_suspended, las claves de API solo pueden leer, y la página de facturación dice "Suspended. Contact support to restore the workspace."
Quién puede hacer qué
| Permiso | Permite | Roles de ejemplo |
|---|---|---|
billing.read | Abrir la página de facturación, sus facturas y sus descargas | Owner, Billing |
billing.manage | Cambiar de plan, conservar el plan en lugar de un cambio programado, el pago de prueba, el portal de pagos, cancelar, reanudar y el correo de facturación | Owner, Billing |
Ambos están en la matriz de roles de cada espacio de trabajo, así que el propietario puede concederlos a otro rol. Un rol que no tiene ninguno recibe el espacio de trabajo sin su correo de facturación (billingEmail: null) de todas las rutas de espacio; el personal de la plataforma aún lo ve en la página de la organización.
Las rutas que hay detrás
GET /api/workspaces/:workspaceId/billingresponde con la suscripción, los planes, el uso y cualquier pago pendiente;.../billing/invoicescon las últimas 36 facturas.POST .../billing/previewcon{ "planId": "pro" }responde cuánto cuesta el cambio y cuándo se aplica. Para un cambio a un plan superior de una suscripción de Stripe en marcha llevachargesCardOnFile: truey unquote, válido 30 minutos.POST .../billing/checkoutcon elplanId(y esequote) hace el cambio:upgraded: truecuando se cobró la tarjeta guardada, la página donde pagar (url) para un pago, oscheduled: truepara un cambio a un plan inferior. Un cambio a un plan inferior que supera los límites es un 409over_plan_limitque los lista; una cotización caducada un 409preview_expired; un cobro rechazado un 402payment_declined,payment_needs_actionopayment_method_missing.POST .../billing/keep-plandeshace un cambio a un plan inferior programado, o responde 409no_scheduled_change.POST .../billing/checkout/:sessionId/synclee un pago devuelto desde el proveedor.POST .../billing/portal,.../billing/cancely.../billing/resume, yPATCH .../billing/email, hacen lo que dicen sus nombres.GET .../billing/invoices/:invoiceId/download-linkresponde con un enlace firmado aGET /api/billing/invoices/download?token=..., válido cinco minutos.POST /api/billing/webhooks/striperecibe los eventos de Stripe;GET /api/billing/simulator/:sessionIdconPOST .../completeyPOST .../cancelsirven el pago de prueba.
Vender tus propios planes
Incluido con tu compra. Inicia sesión para leerlo o ábrelo en tu descarga.
Dónde se definen los planes, y todos los lugares que hay que cambiar para vender planes propios.