SecureStartKit
SecurityFeaturesPricingDocsBlogChangelog
Sign inBuy Now
Billing Model Comparison

One-Time vs Subscription Billing

Two billing models, six mechanical differences in Stripe. A decision framework for solo and indie SaaS founders picking which one to ship.

Reviewed by the SecureStartKit Team·Last updated May 25, 2026
Jump to the decision helperSee the 6 differences

Quick verdict

Pick one-time when the value you deliver is a discrete, one-shot outcome (a template, a calculator, a course, a lifetime tool). Pick subscription when the value is ongoing delivery (hosting, monitoring, content). Supporting both roughly doubles the Stripe surface area, so most indie SaaS founders should commit to one and ship deeper, not wider.

What is a billing model decision?

A billing model decision is the architectural choice between charging customers once for an outcome (one-time billing, Stripe Checkout in mode: 'payment') or charging them on a recurring cycle for ongoing access (subscription billing, Stripe Checkout in mode: 'subscription'). The decision determines which Stripe webhook events your app listens for, how much customer data you retain, whether you need dunning infrastructure, and how refunds map to access revocation.

One-Time Billing

Stripe Checkout in mode: 'payment'. One charge per customer. One checkout.session.completed event per purchase. Guest customers by default. No recurring contract to keep alive.

Best for: discrete value delivery (templates, courses, tools, lifetime deals)

Subscription Billing

Stripe Checkout in mode: 'subscription'. Recurring charges per cycle. Five or more lifecycle events per customer. Customer object required. Smart Retries dunning included.

Best for: ongoing value delivery (hosting, monitoring, content, continuous service)

The 6 mechanical differences in Stripe

The decision is not about pricing strategy; it is about which Stripe surface area your app commits to building and maintaining. These six categories cover the full mechanical diff.

Dimension
One-Time
Subscription
Stripe Webhook Events
Primary purchase event`checkout.session.completed``checkout.session.completed` + lifecycle events
Subscription lifecycle events`customer.subscription.created/updated/deleted`
Invoice events`invoice.paid`, `invoice.payment_failed`
Required handlers (minimum)15+
Customer Object
Customer object requiredNo (guest customers by default)Yes (required for recurring)
Customer data retentionOptional, your choiceRequired for the customer lifetime
PII surface areaEmail at minimum, name optionalEmail, name, address, payment method on file
Stripe Tax
Tax computationOnce at checkoutOn every recurring invoice
Tax-rate change handlingN/A after saleCompounds across customer lifetime
Tax-ID validationOne-time checkOngoing per renewal
Failed Payments & Dunning
Built-in retry layerSmart Retries + custom rules
Failure status surfaceSingle failed `checkout.session``past_due`, `unpaid`, `canceled` states
Customer notification flowYou build itStripe-managed emails available
Recovery responsibilityCustomer re-initiatesStripe + your dunning rules
Refunds & Access Revocation
Refund modelSingle refund per purchasePartial refunds + cancellation logic
Access revocation patternOptional (often skipped)Required (gate every request)
Pro-rata mathN/ARequired on mid-period cancel
Idempotency & Scale
Webhook events per customer112+ per year minimum
Idempotency dedupe pressureBounded by purchasesScales with customer base
Idempotency-Key TTL (Stripe default)24 hours24 hours
Code Surface & Buyer Fit
Webhook handler files (minimum)13-5
Best forTemplates, calculators, courses, lifetime dealsHosting, monitoring, content, ongoing service
Cash flow shapeFront-loadedSmoothed across the customer lifetime
Churn surfaceNone (no recurring contract)Recurring; needs retention metrics

Webhook event names and Smart Retries / dunning behavior verified against Stripe's official documentation (Checkout, Subscriptions, Idempotency).

Where each model wins

Both billing models have a genuine fit. The question is which one fits the value you deliver.

One-time strengths

One webhook handler, one code path

A single `checkout.session.completed` handler is enough to fulfill orders. Per Stripe docs: "Process the checkout.session.completed event to fulfill orders when a customer completes their purchase." No lifecycle state machine, no dunning rules, no pro-rata math.

Smaller data surface to protect

Guest customers are the default. You can ship a one-time SaaS with email-and-payment as the only customer data on file. Less PII to retain means less to encrypt, audit, and rotate when keys leak.

No churn modeling required

There is no recurring contract to keep alive. Customer service load is bounded by the support window you commit to, not by month-over-month retention. Indie SaaS founders can ship and move on instead of running renewal funnels.

Bounded idempotency surface

Each purchase fires one event with one Stripe Event ID. Idempotency dedupe is straightforward: a unique constraint on `processed_events.event_id` catches duplicates. Subscription apps generate 12+ events per customer per year just from renewals.

Subscription strengths

Recurring revenue is the cash flow shape

Subscription billing smooths cash flow across the customer lifetime. For SaaS that funds ongoing infrastructure (hosting, monitoring, content delivery), recurring revenue matches the recurring cost structure.

Built-in dunning recovers failed payments

Stripe Smart Retries automatically re-attempt failed payments using machine-learned timing. Per Stripe docs: subscriptions can transition to `past_due` and Stripe re-attempts payment "using Smart Retries or based on your custom retry rules." Recovered payments add directly to ARR.

Lifecycle events enable feature gating

The full event surface (`subscription.created`, `subscription.updated`, `subscription.deleted`, `invoice.paid`, `invoice.payment_failed`) lets your app track entitlement state continuously. Tier upgrades, downgrades, and pauses all map to specific events.

Stripe handles recurring tax math

For B2B SaaS billing across jurisdictions, Stripe Tax computes the right rate on every invoice. The cost of managing this manually for a SaaS with even a few hundred customers across regions usually outweighs the operational overhead of running subscriptions.

Which model fits your SaaS?

Decision rules grounded in the value you deliver, not in pricing psychology.

Pick one-time if you...

  • Deliver a discrete outcome the customer adopts once (template, calculator, course, lifetime tool)
  • Want to ship one webhook handler instead of a subscription lifecycle state machine
  • Prefer guest customers over storing payment methods on file
  • Are a solo founder who needs predictable customer-service load
  • Are building a developer tool where the value is in the foundation, not in ongoing access
  • Have no ongoing infrastructure cost tied to per-customer usage
See a one-time pricing example

Pick subscription if you...

  • Deliver ongoing value (hosting, monitoring, content, continuous service)
  • Have recurring infrastructure costs that scale per customer per month
  • Need predictable cash flow smoothed across the customer lifetime
  • Are willing to operate dunning, churn modeling, and renewal funnels
  • Bill across jurisdictions and want Stripe Tax to handle recurring tax math
  • Have a team large enough to handle subscription lifecycle support load
Read Stripe's subscription docs

The verdict

Both models are valid. The decision is not philosophical; it is architectural. Subscription billing adds at least four lifecycle event handlers, a dunning state machine, ongoing customer data retention, pro-rata refund math, and Stripe Tax computation on every invoice. That overhead is justified when the value you deliver is itself recurring. It is not justified when you are selling a one-shot outcome dressed up as recurring access.

For developer-tool SaaS in particular, one-time pricing aligns price with value delivery. A template is adopted once. A calculator is used until the customer outgrows it. A course is completed. Wrapping these in a subscription forces the founder to manufacture ongoing reasons to charge, which usually shows up as feature bloat, artificial limits, or aggressive dunning emails. None of those are good for the brand.

SecureStartKit ships mode: 'payment' exclusively. The template is a one-time architectural decision, not a recurring service. The code path is one Stripe webhook handler, one delivery email, one access grant. We document this choice openly: it is not the right model for every SaaS, but it is the right model for what we deliver. If your SaaS delivers ongoing value, subscription is the right call and the additional surface area is worth it.

One-Time

Discrete value. One handler. SecureStartKit's choice.

Subscription

Ongoing value. Full lifecycle. Worth the overhead when fit.

Frequently asked questions

Compare SecureStartKit with other starters

All five run on the security-first one-time pricing model.

vs ShipFast

Speed-first boilerplate

Read comparison →
vs MakerKit

Feature-complete workhorse

Read comparison →
vs Supastarter

Institutional Supabase kit

Read comparison →
vs Divjoy

Visual code generator

Read comparison →
vs Nextbase

Multi-tenant feature kit

Read comparison →

Related reading

  • How to add Stripe payments to Next.js using Server Actions, one-time implementation walkthrough.
  • Stripe webhook signature verification in Next.js, event-handling depth.
  • Stripe Webhook Verifier, test the signature path before shipping either model.
  • SaaS Pricing Calculator, work out the pricing side of the model choice.
  • Stripe Fee Calculator, understand the cost side of either model.

See one-time pricing in production

SecureStartKit ships mode: 'payment' exclusively. One Stripe webhook handler, one delivery email, one access grant. The pricing page below is the worked example.

See SecureStartKit pricingRead the implementation guide