Subscription Billing for SaaS: What Stripe Taught Us
Mario Fernandez
CEO · Apr 1, 2026 · 3 min read
Billing is deceptively simple on the surface. A customer picks a plan, enters a credit card, and gets charged every month. In practice, billing is one of the most complex subsystems in any SaaS product. Mid-cycle upgrades, prorated credits, failed payment retries, tax calculations across jurisdictions, and customer self-service portals all need to work correctly, every time, without human intervention. We chose Stripe because it handles the hard parts so we can focus on building crew management features instead of payment infrastructure.
Plan Tiers and Pricing Architecture
JamCrew offers four plan tiers: Free, Pro, Business, and Enterprise. The Free tier lets small crews try the platform with limited features. Pro unlocks scheduling, client management, and integrations. Business adds payroll, advanced reporting, and custom branding. Enterprise includes dedicated support, SSO, and custom contract terms.
Each tier is represented as a Stripe Product with a corresponding Price object. Monthly and annual billing intervals are separate Price objects on the same Product. Annual plans offer a discount, which Stripe handles natively through the price amount rather than through coupons or custom logic. This keeps the billing model clean and auditable.
The pricing page on the marketing site pulls plan details from a shared configuration, ensuring that what customers see matches what Stripe charges. There is no drift between the displayed price and the actual charge because both reference the same source of truth.
Handling Upgrades, Downgrades, and Prorations
A customer on the Pro plan who upgrades to Business mid-cycle should not pay the full Business price for a partial month. They should pay the prorated difference for the remaining days. Stripe calculates this automatically when you update a subscription with proration enabled.
Downgrades are trickier. If a Business customer moves to Pro, they have already paid for features they will lose. Stripe can issue a prorated credit that applies to the next billing cycle, so the customer is not overcharged. The key decision is when the downgrade takes effect: immediately or at the end of the current billing period. We chose end-of-period for downgrades so customers retain access to the features they paid for until their billing cycle completes. Upgrades take effect immediately because the customer wants access to new features right away.
Failed Payments and Dunning
Credit cards expire. Bank accounts run low. Payment failures are inevitable, and how you handle them determines whether you lose a customer or recover gracefully. Stripe's Smart Retries system uses machine learning to determine the optimal time to retry a failed payment. Instead of retrying on a fixed schedule, it considers factors like the card network, the failure reason, and historical success patterns for similar transactions.
JamCrew layers its own communication on top of Stripe's retry logic. When a payment fails, the workspace admin receives an in-app notification and an email. The notification is direct and helpful: "Your payment for the Business plan failed. Update your payment method to avoid service interruption." No panic-inducing language, no threats. Just a clear description of the problem and a link to fix it.
If all retry attempts fail after the configured dunning period, the subscription moves to a past-due state. Features are gradually restricted rather than cut off entirely. The workspace remains accessible, but premium features lock behind a payment update prompt. This gives customers time to resolve the issue without losing their data or disrupting active gigs.
Webhooks and State Management
Stripe communicates billing events through webhooks: subscription created, payment succeeded, payment failed, subscription cancelled. JamCrew's webhook handler processes these events and updates the workspace's billing state in the database. The webhook endpoint is idempotent, meaning it can safely process the same event multiple times without creating duplicate records or inconsistent state.
This webhook-driven architecture means the application never polls Stripe for billing status. The database always reflects the current state because Stripe pushes updates in real time. When a payment succeeds, the workspace's plan tier updates immediately. When a subscription is cancelled, feature access adjusts on the next page load.
Tax Compliance and the Customer Portal
Tax calculation is the part of billing that nobody wants to build from scratch. Sales tax rules vary by state, and some states tax SaaS products while others do not. Stripe Tax handles jurisdiction detection, rate calculation, and reporting. We provide the customer's billing address, and Stripe determines the correct tax amount. This covers US state sales tax and positions us for international expansion without rebuilding the tax system.
For self-service billing management, Stripe's Customer Portal lets workspace admins update their payment method, view invoices, switch plans, and cancel their subscription without contacting support. The portal is hosted by Stripe but styled to match JamCrew's branding, so the experience feels seamless.
Ready to streamline your crew management?
JamCrew helps production companies manage crews, gigs, and schedules in one place.
Get Started