
Tenant Data Isolation: Patterns and Anti-Patterns
Explore effective patterns and pitfalls of tenant data isolation in multi-tenant systems to enhance security and compliance.
Jul 30, 2025
Read More

Billing is where SaaS revenue lives. Get it wrong and you're leaking money through failed payments, missed upgrades, and manual intervention on what should be automatic.
const session = await stripe.checkout.sessions.create({
customer: stripeCustomerId,
mode: 'subscription',
line_items: [{ price: process.env.STRIPE_STARTER_PRICE_ID, quantity: 1 }],
success_url: `${BASE_URL}/dashboard`,
cancel_url: `${BASE_URL}/pricing`,
subscription_data: { trial_period_days: 14 },
});
Never trust the Checkout success_url redirect to confirm payment. Webhooks are the authoritative source of truth. Always verify webhook signatures with stripe.webhooks.constructEvent.
| Event | Action |
|---|---|
| checkout.session.completed | Activate subscription, provision workspace |
| customer.subscription.updated | Sync plan, update feature access |
| customer.subscription.deleted | Downgrade or lock account |
| invoice.payment_succeeded | Record payment, update billing period |
| invoice.payment_failed | Start dunning sequence, email customer |
| invoice.payment_action_required | Prompt for 3D Secure (critical for EU) |
Set trial_period_days on subscription creation. Stripe won't charge during trial. Schedule trial-end reminder emails at T-7 and T-1 days yourself via your email provider.
Don't build your own billing management UI. Stripe's Customer Portal handles plan changes, cancellation, invoice history, and payment method updates out of the box.
const portal = await stripe.billingPortal.sessions.create({
customer: stripeCustomerId,
return_url: `${BASE_URL}/dashboard/billing`,
});
return redirect(portal.url);
Stripe Smart Retries automatically retries failed payments using ML-optimized timing. Complement with a 3-email dunning sequence triggered by invoice.payment_failed: immediate, day 3, and day 7 notifications.
For pricing strategy, see SaaS Pricing Models. For scaling architecture, see Scaling SaaS from MVP to Enterprise.
Create a Stripe Customer on signup, collect payment via Checkout or Elements, create the Subscription with the correct Price ID, then handle all billing events via signed webhooks. Sync subscription status to your database on every webhook event.
At minimum: checkout.session.completed, customer.subscription.updated, customer.subscription.deleted, invoice.payment_succeeded, and invoice.payment_failed. Add invoice.payment_action_required for European SCA compliance.
Set trial_period_days on subscription creation. Stripe won't charge during trial. At trial end it fires an invoice and sends a subscription update webhook. You must schedule your own trial-end reminder emails.
Dunning is automatic retry logic for failed payments. Stripe Smart Retries retries at ML-optimized intervals. Complement with your own dunning email sequence triggered by the invoice.payment_failed webhook.
Need an expert team to provide digital solutions for your business?
Book A Free CallDive into a wealth of knowledge with our unique articles and resources. Stay informed about the latest trends and best practices in the tech industry.
View All articlesTell us about your vision. We'll respond within 24 hours with a free AI-powered estimate.
© 2026 Propelius Technologies. All rights reserved.