Pricing a consumo per SaaS: i pattern di metering e billing che funzionano
Come implementare billing a consumo in un SaaS senza rompere la fiducia: meter, idempotenza, piani ibridi e scelta della piattaforma.
Alla fine di questa guida avrai una pipeline di billing a consumo funzionante in un SaaS Next.js + Stripe: un meter che ingerisce eventi al ritmo dell'API, un piano ibrido che combina abbonamento base e overage a consumo, registrazione idempotente degli eventi, una vista d'uso dentro il prodotto e i presidi che impediscono a un bug di billing di trasformarsi in una raffica di rimborsi.
Il pricing a consumo non è più una scelta di nicchia. Nei benchmark 2025 di OpenView e Metronome, l'85% dei SaaS interpellati aveva adottato o stava testando il pricing a consumo, contro il 28% del 2023. Le aziende su modelli a consumo registrano circa 10% in più di net retention e 22% in meno di churn rispetto ai pari su modello seat-based. La ragione è semplice: quando il revenue cresce con il successo del cliente, il cliente vede la spesa come proporzionale, non come una voce fissa da tagliare.
Il rovescio è che ora vendi qualcosa di più difficile da consegnare. Un errore dell'1% sul metering in un piano seat è invisibile. Un errore dell'1% in un piano a consumo è un ticket di finance e un cliente perso.
Cosa serve prima di iniziare
- Un SaaS già su Stripe (Subscriptions o Customer in piedi) o un PSP comparabile. I pattern qui sotto sono scritti su Stripe Billing perché è il punto di partenza più comune e mette a disposizione Meters e Meter Events come primitive di prima classe.
- Un'unità fatturabile chiaramente nominata. Chiamata API, token, seat-hour, riga processata, immagine generata. Se non riesci a nominarla in tre parole, non sei pronto a metterla a prezzo.
- Una sorgente di eventi che già esiste. Log, code, scritture DB che registrano l'unità. Non costruire un nuovo event bus solo per fatturare: strumenta ciò che già gira.
- Un referente finance che firmi su regole di arrotondamento, proration, policy di rimborso e tasse. Non è opzionale in un piano B2B.
Step 1. Scegli una forma di pricing, non solo un prezzo
La forma che converte e rinnova meglio nel 2026 è il piano ibrido: un abbonamento base che copre una quota inclusa generosa, più un costo a unità sopra quella soglia. La maggior parte dei clienti la preferisce perché ottiene una base prevedibile e paga di più solo quando scala davvero. Il pay-as-you-go puro funziona per dev tools e infrastruttura, dove i compratori se lo aspettano; per tutti gli altri tende a deprimere il passaggio da trial a paid.
Decidi tre numeri e scrivili prima di toccare codice:
- Prezzo base per ogni tier (Starter, Team, Business).
- Quota inclusa per periodo di fatturazione a ogni tier.
- Prezzo unitario di overage, idealmente con uno scaglione di volume sopra una soglia (così un cliente che fa 10x la quota inclusa non paga 10x l'overage).
Tieni il modello noioso il primo giorno. Tariffazione a tier con un solo asse di overage è già abbastanza. Aggiungi meter per feature solo dopo che il primo modello è live da due cicli.
Step 2. Definisci il meter
In Stripe, un meter è lo schema di un segnale d'uso aggregato. Configuri il meter una volta: nome evento (per esempio api_request), metodo di aggregazione (count o sum) e il campo del payload che porta il valore numerico.
// One-off, da uno script server
await stripe.billing.meters.create({
display_name: 'API requests',
event_name: 'api_request',
default_aggregation: { formula: 'count' },
customer_mapping: { event_payload_key: 'stripe_customer_id', type: 'by_id' },
value_settings: { event_payload_key: 'value' },
});Tre regole. Primo, un meter per dimensione fatturabile; non multiplexare due significati nello stesso event name. Secondo, il customer mapping è il contratto che lega un evento a una riga di fattura: se è sbagliato, nessun consumo emergerà. Terzo, prima o poi rinominerai l'evento; tieni stabile l'id del meter.
Step 3. Registra gli eventi in modo idempotente
Questo è lo step che decide se il modello è affidabile. Ogni meter event deve portare una idempotency key derivata da una proprietà stabile dell'azione sottostante (request id, job id, message id), non da un timestamp. L'endpoint Meter Events di Stripe accetta un campo identifier a questo scopo, e il singolo endpoint sostiene fino a 1.000 chiamate al secondo in live mode.
// Nel tuo handler, dopo che il lavoro è andato a buon fine
await stripe.billing.meterEvents.create({
event_name: 'api_request',
payload: {
stripe_customer_id: customer.stripeId,
value: '1',
},
identifier: requestId, // già unico a monte
timestamp: Math.floor(Date.now() / 1000),
});Manda l'evento dopo che il lavoro è riuscito, non prima. Una chiamata fallita per cui hai già fatturato è il bug peggiore, perché produce fatture che il support non può difendere. Deduplica al confine di ingestione e tratta le code a valle come best-effort.
Step 4. Collega il meter a un Price e a una Subscription
Crea un Price Stripe con recurring.usage_type = 'metered' che referenzia il tuo meter. Aggancia quel price alla subscription accanto al price flat-fee di base. Il cliente ora ha una subscription con due item: un item flat-fee che fattura prevedibile, e un item metered che fattura il consumo aggregato a chiusura periodo.
L'overage a tier è una proprietà del Price metered: configura i tier con una quota inclusa free e un prezzo unitario di overage. Stripe gestisce il calcolo a invoice time.
Step 5. Mostra il consumo dentro il prodotto
Questa è la leva che la maggior parte dei team ignora e quella che genera il maggior guadagno di retention. Renderizza un widget di consumo nella dashboard con tre cose: consumo del periodo corrente, quota inclusa e percentuale usata, overage proiettato a fine periodo basato sul run-rate corrente. Tira i dati dal tuo event store, non da Stripe; Stripe è il sistema di record per il billing, non per la UX live.
Manda una notifica al 75%, al 90% e al 100% della quota inclusa. I clienti che non vedono mai un numero vengono colti di sorpresa dalla prima fattura; i clienti che guardano il numero salire fanno upgrade volontariamente. Lo stesso widget è anche il punto in cui mettere un CTA di upgrade quando un cliente comincia a sforare per due cicli di fila.
Step 6. Verifica che funzioni
- Round trip event-fattura. Manda un set controllato di eventi di test su un cliente test in un Stripe test clock. Avanza l'orologio fino alla chiusura periodo. Verifica che la riga di fattura combaci al centesimo con la matematica attesa.
- Replay duplicato. Manda lo stesso evento due volte con lo stesso identifier. Il secondo non deve incrementare il meter.
- Eventi in ritardo. Manda un evento con timestamp 24 ore nel passato. Verifica che cada nel periodo corretto e che la chiusura notturna non abbia già lockato il periodo.
- Customer mapping. Manda un evento con uno
stripe_customer_idsconosciuto. Verifica che venga rifiutato in modo rumoroso e finisca nel tuo alerting, non scartato in silenzio.
Failure mode più comuni
Il meter mostra zero in produzione. Quasi sempre un bug di customer mapping: il campo nel payload non corrisponde al customer_mapping.event_payload_key del meter. Stripe accetta gli eventi ma non li lega a nessun cliente. Aggiungi un'asserzione server-side che ogni evento in uscita porti un customer id noto.
La matematica della fattura sbaglia dell'1-5%. Race condition tra emit dell'evento e successo del lavoro. Sposta l'emit sul percorso di successo, e se non puoi, passa a un outbox transazionale: scrivi il meter event in una tabella locale dentro la stessa transazione DB della scrittura business, poi un worker drena la tabella verso Stripe con retry.
Rate limit Stripe nei picchi di traffico. Il cap di 1.000 eventi al secondo è per account, non per cliente. Il blog di engineering Stripe descrive il pattern di batching: aggrega gli eventi client-side in una finestra di 1-5 secondi, emetti un evento Stripe per (customer, meter, finestra) invece di uno per richiesta. Non perdi nulla in fattura, guadagni 100x di headroom.
Cliente che contesta una voce non riconciliabile. Costruisci il percorso di disputa nel prodotto, non nei ticket support. Esponi un export CSV di ogni evento registrato per il cliente nel periodo contestato. Il carico di support cala della metà appena il cliente può fare l'audit del proprio consumo.
Quando lasciare Stripe Billing per una piattaforma dedicata
Stripe Billing porta agevolmente un SaaS a singolo meter fino a un ARR di metà otto cifre. I punti di rottura in cui i team passano a Metronome, Orb o all'open source Lago sono: più di tre meter indipendenti, pricing contract-aware (rate custom per cliente enterprise firmate in DocuSign), entitlement in tempo reale (paywall che devono sapere entro 50 ms se al cliente resta quota), o requisiti multi-PSP per cui il lock-in Stripe diventa rischio strategico. Sotto questi punti, cambiare piattaforma è lavoro di engineering che non produce ricavi.
Due cicli di dati live valgono più di due mesi di platform shopping. Spedisci il piano ibrido noioso su Stripe Billing, guarda le fatture, poi decidi.
Approfondimenti
- Multi-tenant dal giorno uno per l'architettura dati sotto qualsiasi piano a consumo.
- L'agency tax per il contesto di pricing più ampio in cui questo si inserisce.
Studio
Inizia un progetto.
Un partner unico per aziende, PA, startup e SaaS. Produzione più veloce, tecnologie moderne, costi ridotti. Un team, una fattura.