Skip to content

Add Cashier-equivalent Stripe billing module (subscriptions, invoices, webhooks) #171

@antosubash

Description

@antosubash

Background

There is no first-class billing/subscription module. SaaS apps building on SimpleModule have to integrate Stripe themselves: customer + subscription objects, webhooks, proration, trial flow, invoice PDFs, tax. Laravel Cashier solves all of this.

Motivation

  • Multi-tenant SaaS is an obvious target audience for SimpleModule
  • Billing is high-risk and high-effort to build well; commoditizing it is a big sell
  • Webhook handling, proration, retries, and dunning are common foot-guns

Design sketch

New optional module modules/Billing (Stripe driver only at first; abstraction allows Paddle later):

Capabilities:

  • IBilling service: CreateCustomerAsync, SubscribeAsync(customer, plan), SwapPlanAsync, CancelAsync, ResumeAsync, OnTrial(customer)
  • IsSubscribed(customer) / Subscribed(plan) predicates
  • BillingPortalAsync(returnUrl) — Stripe Customer Portal redirect
  • CheckoutAsync(plan, successUrl, cancelUrl) — Stripe Checkout
  • Webhooks endpoint at /billing/webhook with signature verification; emits IEventBus events (SubscriptionCreated, SubscriptionCanceled, InvoicePaid, InvoiceFailed)
  • Invoices: Invoices(customer) returns paginated list; DownloadInvoicePdf(id)
  • Models stored locally (mirrored from Stripe): Customer, Subscription, SubscriptionItem, Invoice
  • Multi-tenant aware (Customer belongs to a tenant)

Permissions: Billing.View, Billing.Manage.

UI: admin pages — current subscription, plan switcher, payment methods, invoices.

Acceptance criteria

  • Module scaffolded; Stripe driver via Stripe.net
  • Webhook signature verification + idempotency (de-dupe by event_id)
  • Trial + grace-period support
  • Plan swap with proration
  • Invoice PDF download (Stripe-hosted URL)
  • Inertia admin UI
  • xUnit tests with Stripe.NET mock + integration test against Stripe test mode
  • Docs page with end-to-end setup walkthrough

References

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions