Entita Sottoscrizione (Subscription)
Gestione piani ricorrenti, addon seat-based e transizioni lifecycle senza rompere i flussi legacy.
Entita Sottoscrizione
L'oggetto Subscription rappresenta un accordo ricorrente collegato a un Customer. Combina piano, addon, cadenza di rinnovo e stato lifecycle.
Utilizzo
Usa la Subscription per:
- Associare un piano al cliente.
- Gestire pricing a seat tramite quantita addon.
- Applicare sconti globali e per addon.
- Tracciare usage metered quando presente.
- Eseguire transizioni lifecycle (
pause,resume,change,cancel-at-period-end). - Conservare storico amendments per audit.
Modello Seat-Based
Nel modello attuale Donutwork i seat sono gestiti tramite addons.
- Il costo per seat e il prezzo unitario addon.
- Il numero seat e
addons[].quantity. - Il rinnovo include automaticamente la componente seat.
Esempio:
- Addon
workspace_seat:12.00 - Quantita:
25 - Totale seat:
300.00(prima di tasse/sconti)
Flusso Atteso
Associazione Piano
Associa il piano con POST /customers/{id}/subscriptions.json.
Configurazione Runtime
Aggiorna quantita addon (inclusi seat), sconti e usage.
Transizioni Lifecycle
Applica opzionalmente operazioni lifecycle (pause, resume, change-plan, change-addons, cancel-at-period-end).
Boundary di Rinnovo
Alla data next_renew, eventuali modifiche schedulate vengono applicate e parte l'addebito ricorrente.
Stati Lifecycle e Transizioni
| Stato Lifecycle | Significato | Ingresso Tipico |
|---|---|---|
active | Subscription rinnovabile e addebitabile | Attach, resume, change riuscita |
paused | Billing sospeso temporaneamente | Azione pause |
cancel_pending | Cancellazione programmata a fine periodo | Cancel-at-period-end |
cancelled | Contratto non piu attivo | Stop a boundary / cancellazione legacy |
trialing / past_due | Stati avanzati opzionali | Orchestrazioni esterne |
Definizione Stati con Esempi Pratici
active: il cliente viene addebitato regolarmente al rinnovo. Esempio: piano mensile con rinnovo al 1 maggio 2026.paused: fatturazione temporaneamente sospesa. Esempio: sospensione richiesta dal cliente per 30 giorni.cancel_pending: abbonamento impostato per la chiusura a fine periodo. Esempio: cancellazione richiesta il 15 aprile 2026, servizio attivo fino al boundary.cancel_pendingpuo essere annullato prima del boundary. Esempio: il cliente annulla e poi cambia idea dopo 3 giorni; con undo-cancel-at-period-end ritorna inactive.cancelled: abbonamento chiuso definitivamente. Esempio: boundary raggiunto e chiusura completata.trialing: periodo prova prima del primo addebito. Esempio: trial gratuito di 14 giorni all'associazione del piano.past_due: problema di pagamento in corso. Esempio: rinnovo fallito in attesa di aggiornamento metodo pagamento.
Semantica Pausa e Ripresa Fatturazione
Quando una subscription viene messa in pausa, Donutwork interrompe i rinnovi e azzera next_renew, salvando la data precedente in pause_state.previous_next_renew.
Alla ripresa:
- Se
resume_ate presente e futura, quella data diventa il nuovonext_renew. - Se
resume_atnon e presente, Donutwork prova a riusareprevious_next_renew. - Se la data salvata e gia nel passato,
next_renewviene impostata al giorno di ripresa (oggi), senza recupero retroattivo automatico.
Esempio timeline:
- Pausa il 1 maggio 2026.
- Riattiva il 1 luglio 2026 (dopo 2 mesi).
- Risultato: nessun addebito automatico arretrato per maggio/giugno;
next_renewviene riallineata al 1 luglio 2026 (o aresume_atse impostata nel futuro).
Grafico Lifecycle
Regole Proration
- Delta positivo (upgrade): addebito immediato.
- Delta negativo (downgrade): credito in
carryover_credit. - Il credito viene consumato ai rinnovi successivi prima di nuovi addebiti.
Scheduled Changes
Per change-plan e change-addons puoi usare when: period_end.
La modifica viene salvata in scheduled_change e applicata al prossimo boundary.
Amendment History
Ogni modifica lifecycle genera un amendment immutabile con before/after e metadati proration.
Schema Dati
| Campo | Tipo | Descrizione |
|---|---|---|
id | eid | Identificativo customer-subscription. |
subscription_id | string | Piano attualmente applicato. |
status | string | Stato legacy (active, dismiss, dismissed, ...). |
next_renew | date | null | Prossimo boundary di billing. |
addons | array | Addon con prezzo e quantity (inclusi seat). |
global_discount | object | Sconto a livello piano. |
lifecycle | object | Metadati stato lifecycle avanzato. |
pricing_snapshot | object | Snapshot pricing usato nelle transizioni. |
scheduled_change | object | null | Mutazione differita a fine periodo. |
pause_state | object | null | Metadati pausa/ripresa. |
carryover_credit | number | Credito accumulato da proration negativo. |
cancel_at_period_end | boolean | Intenzione esplicita di stop a fine periodo. |
Backward Compatibility
Nessuna route o shape legacy viene rimossa.
Legacy vs New lifecycle behavior
| Area | Comportamento Legacy | Nuovo Comportamento Lifecycle |
|---|---|---|
| Attach/Detach | Route esistenti valide | Invariato, con metadati lifecycle additivi |
| Update addons | Mutazione addon legacy invariata | Opzionale change-addons con proration/scheduling |
| Status endpoint | status legacy mantenuto | Visibilita lifecycle aggiuntiva senza rimuovere chiavi |
| Seat pricing | Addon con quantity | Stesso modello, ora documentato esplicitamente |
| Cancellazione | Flow basato su dismiss | cancel_at_period_end mappato in compatibilita legacy |