DashCommerce for SaaS subscriptions
DashCommerce fits the SaaS shape where your marketing site, docs, and checkout all want to live in the same repo — with Stripe doing the recurring billing and your CMS doing everything around it.
Why a CMS plugin for SaaS billing?
Every content-led SaaS company ends up maintaining two projects. There’s the marketing site — the homepage, the pricing page, the docs, the blog, the customer-facing changelog, the integrations page, the security page. And there’s the product, which handles auth and billing and the actual thing the customer is paying for. Somewhere between those two, there’s a pricing page that has to know about Stripe price IDs, a checkout flow that has to hand off cleanly from marketing to app, and a “Start free trial” button that has to end up as a Stripe Subscription with the right metadata.
The seam between those two projects is where most SaaS companies spend a surprising amount of engineering time. The marketing site hard-codes price IDs. The product hard-codes plan names. Somebody adds a new tier and forgets to update the pricing page. The trial CTA on the homepage goes to a different route than the trial CTA on the docs site. None of it is hard, all of it is annoying, and most of it exists because the CMS and the billing stack were always two separate systems stitched together with environment variables.
DashCommerce on EmDash makes that seam go away. The products collection in your EmDash project is a typed schema — including recurring SKUs for subscription products — that the marketing site reads and the checkout reads. One source of truth. When you add a tier, the pricing page picks it up; when you change a trial length, it changes in both places. Your docs, your blog, your pricing page, and your Stripe-backed checkout all live in one repo, typed end-to-end, deployed to the edge.
The Stripe Subscriptions primitive
DashCommerce does not try to be a billing engine. Stripe Subscriptions is the billing engine. It holds the subscription object, runs the clock, handles the card, retries on failure, applies proration, and emits webhooks. That’s Stripe’s job and it does it well.
What DashCommerce adds is the plumbing. A typed schema for subscription products (monthly, annual, trials, sign-up fees as first-invoice line items). A set of webhook-idempotent handlers that translate invoice.paid, customer.subscription.updated, customer.subscription.deleted, and friends into rows in your own database. A React admin with a subscriptions page you can use to inspect state, force-cancel, refund a cycle, or change a quantity. Transactional email templates wired to the lifecycle events. A customer portal link generator.
If you already know Stripe Subscriptions, DashCommerce will feel like a thin layer that saves you a few days of boilerplate. If you don’t know Stripe Subscriptions, DashCommerce doesn’t hide it — you’ll still want to read their docs and understand the lifecycle. The value isn’t abstraction; the value is not having to write the webhook-idempotency code yourself.
What you get for free
The pieces that most SaaS teams end up building in-house at some point:
- Trials — N-day free trials with automatic conversion on day N+1, or cancel-on-trial-end with no charge.
- Sign-up fees — one-time charges billed as a line item on the first invoice, not as a separate transaction.
- Proration on upgrades and downgrades — Stripe’s proration math applied correctly, with the expected credit-and-charge behavior.
- Dunning emails — failed-payment retry with customizable cadence (usually 3, 5, 7 days), template-driven from your own transactional email setup.
- Pause and resume — for billing-pause scenarios like a customer on sabbatical who wants to come back.
- Self-serve customer portal — either Stripe-hosted or built on DashCommerce’s API surfaces under your own navigation.
- Webhook-idempotent lifecycle events — safe to replay, safe to miss-and-recover.
All of it is Stripe doing the work, with DashCommerce as the wiring.
Three SaaS shapes that fit
Content-led SaaS. A developer-tool SaaS, a design-tool SaaS, any product where the documentation is load-bearing for conversion. You want the docs, the marketing site, the pricing page, and the checkout in one repo because maintaining a separate docs site on a separate stack ages badly. DashCommerce on EmDash gives you one Astro project that handles all of it. The pricing page reads from the same products collection the checkout uses. The docs are Markdown. The changelog is content.
Tiered subscription SaaS. Three plans, four plans, a pricing page with a monthly/annual toggle and maybe a “contact us” for enterprise. Every tier is a row in your products collection with a recurring SKU. The toggle swaps price IDs. Upgrades and downgrades run through Stripe’s proration engine. Nothing exotic — just a clean shape that would be painful to build from scratch.
License-key SaaS. Sell activation keys, seat licenses, API keys, or any credential tied to an active subscription. DashCommerce’s digital-download system hands out signed tokens — the same primitive it uses for selling ebooks and Figma files — and you wire it into your subscription renewal flow. The subscription goes into past_due, the token stops validating in your app. Clean lifecycle, no custom key server to build.
The Merchant-of-Record honesty section
This is the section most comparison pages skip, so here it is.
DashCommerce is not a Merchant of Record. You are the seller on every invoice. Practically, this means:
- VAT in the EU is your responsibility. You register for VAT (via OSS or directly), you collect at the right rate, you file quarterly. DashCommerce can use Stripe Tax to calculate the right amount at checkout, but it does not file returns on your behalf.
- US sales tax is your responsibility once you cross economic nexus thresholds. Same story — Stripe Tax can calculate; you file.
- UK VAT, Canadian GST, Australian GST — same pattern. Your registrations, your filings.
If you sell globally to consumers and you don’t want to deal with any of this, DashCommerce is the wrong tool. Lemon Squeezy and Paddle are Merchant of Record platforms — they become the seller on the invoice, handle the tax complexity worldwide, and remit to you after taking their cut. That cut is higher than Stripe’s processing fee, and in exchange you never have to think about international tax. For a solo founder selling a $20/month indie SaaS to a global customer base, MoR is often the right call.
DashCommerce is the right call when you already have tax figured out, or you’re B2B-only (where the buyer handles VAT via reverse charge), or your revenue scale makes professional tax handling worthwhile and the MoR premium stops making sense. Those are real situations. They’re not the universal situation.
Usage-based and metered billing
Stripe supports metered billing via usage records. DashCommerce doesn’t block it — the subscription schema accepts metered price types, and the webhook handlers process invoice.created with metered line items correctly. What’s missing is the reporting UI. There’s no built-in admin page that shows “customer X used Y API calls this cycle” with a graph. You’ll build that yourself, from Stripe’s data or from your own usage ledger.
If usage-based pricing is your entire billing model and you want sophisticated metering UI out of the box, DashCommerce is not the sharpest tool. Products like Orb, Metronome, and Lago are purpose-built for metered billing at scale. DashCommerce handles metered as a variant of subscription billing — it works, it’s honest about not being the specialist.
Implementation sketch
A subscription product in the EmDash seed, illustratively:
// src/content/products/pro-plan.ts
export default {
slug: "pro-plan",
name: "Pro",
type: "subscription",
prices: [
{
id: "pro-monthly",
stripePriceId: "price_1Oabc...",
interval: "month",
amount: 2900,
currency: "usd",
trialDays: 14,
},
{
id: "pro-annual",
stripePriceId: "price_1Oxyz...",
interval: "year",
amount: 29000,
currency: "usd",
trialDays: 14,
},
],
signupFee: { amount: 0, currency: "usd" },
features: ["unlimited projects", "team seats", "priority support"],
};
The marketing pricing page and the checkout route both read the same file. Stripe price IDs live next to feature lists. When Marketing wants to add a tier, they add a file; Engineering doesn’t rediscover that the pricing page has hard-coded IDs in six places.
When NOT to use DashCommerce for SaaS
Being honest about fit:
- Pure-billing SaaS with no content. If your entire company is a product and a login page and a few legal pages, Stripe Checkout plus the Customer Portal is less setup and less ongoing maintenance than a full EmDash project. You’ll graduate into needing a CMS eventually — when you do, migrate.
- MoR-mandatory businesses. If you’re a solo founder selling to a global B2C audience and don’t want to touch VAT, use Lemon Squeezy or Paddle. DashCommerce cannot make you not-the-seller; nothing open-source can.
- Heavy metering UI needs. If you’re building Stripe-competitor-grade billing analytics — per-customer consumption dashboards, meter-level reporting, invoice previews — DashCommerce won’t ship that out of the box. Look at Orb, Metronome, or a custom build on top of Stripe directly.
- You want a hosted admin. DashCommerce’s admin runs in your Astro app. If you want a dashboard you can log into from any machine without deploying anything, you want a SaaS product — DashCommerce isn’t one.
For the remaining shape — content-heavy SaaS, B2B or B2C, with a real marketing site and real docs and real pricing pages — DashCommerce fits. It’s v0.1.3 as of April 2026 and pre-1.0, so pin your versions carefully and treat minor releases as potentially breaking. With that caveat: everything above works today.
Store types inside SaaS subscriptions
Content-led SaaS
A dev-tool SaaS where the marketing site, blog, documentation, and checkout all live in one EmDash/Astro project. Monthly and annual plans with docs one click from pricing — not on a separate subdomain, not behind a Storefront API shim, just routes in the same repo.
Tiered subscription SaaS
Starter, Pro, and Team tiers with annual-discount toggle, prorated upgrades and downgrades via Stripe's proration math, and a single `products` collection that drives both the pricing page and the checkout. One schema, two surfaces.
License-key SaaS
Sell per-seat licenses or activation keys. DashCommerce's digital-download primitive hands out signed tokens on subscription renewal; your app validates the token at activation time. Revocation flows through the webhook-idempotent subscription lifecycle.
DashCommerce for SaaS subscriptions — FAQ
- Is DashCommerce a real Stripe Subscriptions replacement?
- No — and it shouldn't be. DashCommerce uses Stripe Subscriptions. Stripe is the billing engine: it holds the subscription object, runs the renewal clock, applies proration, retries failed charges, and emits webhooks. DashCommerce wraps that primitive with a typed schema, a React admin for subscription management, and webhook-idempotent handlers that mirror state into your database. If Stripe Subscriptions ever disappeared, DashCommerce would too. We are not trying to rebuild Stripe's billing stack.
- Should I use DashCommerce or just Stripe Checkout for my SaaS?
- Honest answer: if your SaaS is pure billing — no marketing site to speak of, no docs, no blog, no knowledge base — Stripe Checkout + the Customer Portal is probably simpler than DashCommerce. You get a hosted checkout URL and a hosted portal URL and you're done. DashCommerce earns its keep when your SaaS has content around it: a marketing site you actually update, a documentation hierarchy, changelogs, a customer-facing changelog or roadmap. That's when having commerce inside your CMS starts mattering.
- Does DashCommerce handle usage-based billing?
- Partially. Stripe Subscriptions supports metered billing via usage records — DashCommerce doesn't block that, and you can wire your app to `POST /v1/subscription_items/:id/usage_records` on whatever event counts as usage. What DashCommerce does not ship is a usage-reporting UI inside the admin: there's no built-in dashboard showing per-customer consumption graphs or meter-level breakdowns. You'll build that in your own app, or rely on Stripe's dashboard. DashCommerce is good at billing state, not usage analytics.
- What about tax compliance and Merchant of Record?
- DashCommerce is not a Merchant of Record. You are the seller of record for every sale. That means VAT registration in each jurisdiction, sales tax nexus in each US state where you cross thresholds, and invoice-level tax calculation are your problem. Stripe Tax can handle the calculation side — DashCommerce plays nicely with it — but filings and registrations still fall on you. If you sell globally and want MoR so you never touch VAT, look at Lemon Squeezy or Paddle; they are a different product category, and for some SaaS businesses they're the right call.
- Can I sell seat-based licensing?
- Yes, with the caveat that seat counting is your app's job. DashCommerce treats a subscription as a subscription — it can hold quantity, multiple line items, and metadata about seat counts, but it does not automatically count active users in your product and adjust the quantity. Typical pattern: your app tracks active seats, calls Stripe's subscription-update API (or DashCommerce's admin API) to bump quantity when someone invites a teammate, and the next invoice prorates the difference. The billing math is handled; the seat accounting is on you.
- How does the self-serve customer portal work?
- Two options, pick either or both. Stripe's Customer Portal is a hosted URL your logged-in user is redirected to; they can update payment methods, cancel, see invoices, and pause — all handled by Stripe's UI. Or you can build portal surfaces inside your own app using DashCommerce's subscription APIs — useful when the portal needs to live under your own navigation and branding. Most teams start with Stripe's hosted portal and graduate to a custom one when the design gap gets annoying.
- Can I have annual and monthly pricing with prorated switching?
- Yes. Define both prices as separate Stripe products (or a single product with two prices), expose a toggle on your pricing page, and pass the chosen price ID into the subscription-creation flow. Upgrades, downgrades, and monthly-to-annual switches flow through Stripe's proration engine — the customer sees a prorated credit for unused time on the old plan and a prorated charge for the new plan. DashCommerce doesn't invent proration logic; it just surfaces Stripe's.
- What happens on failed payment?
- Stripe retries the payment on a schedule (configurable in Stripe dashboard or per-subscription). Between retries, DashCommerce sends dunning emails from your transactional templates — first failure, second failure, final notice — with a link back to the customer portal to update their card. If all retries fail, the subscription transitions to `past_due` or `canceled` depending on your configured behavior; DashCommerce's webhook handlers mirror that state into your database and your app can read it to gate access. All of it is idempotent: replay a webhook safely and the outcome is the same.
Build a saas subscriptions store in an afternoon.
Every feature category in core. One command to scaffold. Stripe-ready checkout.