Digital payment processing on a laptop screen showing transaction dashboard

How to Set Up Payments and Billing for Your SaaS Product (Without the Headaches)

Infinity Sky AIMarch 6, 202612 min read

How to Set Up Payments and Billing for Your SaaS Product (Without the Headaches)#

You've built the product. Users are signing up. Now comes the part that makes most first-time SaaS founders break into a cold sweat: getting people to actually pay you. Setting up payments and billing for a SaaS product sounds straightforward until you're knee-deep in webhook handlers, proration logic, and failed payment retry sequences at 2 AM.

Here's the thing. Billing is not a feature you bolt on at the end. It's infrastructure that touches every part of your product, from user permissions to feature gating to churn management. Get it wrong and you'll spend months patching holes instead of building features your customers actually want.

We've built billing systems for multiple SaaS products, including our own. This guide covers exactly how to set up SaaS payments the right way, which tools to use, which mistakes to avoid, and how to structure everything so it scales without requiring a rewrite six months from now.


Credit card payment being processed on a modern point of sale system
Getting billing right from day one saves you months of painful refactoring later.

Why Billing Is the Most Underestimated Part of Building a SaaS#

Most founders spend 90% of their time on the core product and treat billing like an afterthought. We get it. Billing isn't exciting. Nobody starts a SaaS company because they're passionate about invoice generation. But billing is the system that turns your product into a business.

Here's what billing actually involves in a real SaaS product:

  • Collecting payment information securely (PCI compliance)
  • Creating and managing subscription plans with different tiers
  • Handling upgrades, downgrades, and plan changes mid-cycle
  • Proration calculations when users switch plans
  • Failed payment handling and automatic retry logic
  • Invoice generation and email receipts
  • Usage-based billing if your pricing includes metered components
  • Tax calculation and compliance (VAT, sales tax)
  • Refunds and credits
  • Free trial management and conversion flows
  • Webhook processing for real-time payment events

That's not a weekend project. That's a system. And if you try to build all of it from scratch, you'll burn months that should be spent on your actual product. The good news: you don't have to build most of it. The right payment platform handles 80% of this out of the box.

Choosing Your Payment Platform: Stripe vs. Everything Else#

Let's cut to it. For most SaaS products, the answer is Stripe. Not because it's the only option, but because it's the best balance of power, developer experience, and ecosystem support. Here's how the main options stack up:

Stripe#

Stripe is the default choice for SaaS billing, and for good reason. Their API is exceptionally well-documented, their subscription management (Stripe Billing) handles most of the complex logic for you, and their ecosystem of tools (Stripe Tax, Stripe Checkout, Customer Portal) means you can ship a complete billing experience without stitching together five different services.

Pricing: 2.9% + $0.30 per transaction. Stripe Billing adds 0.5% for recurring payments (or 0.8% with Stripe Tax). For most early-stage SaaS products, these fees are completely reasonable.

Paddle and Lemon Squeezy#

These are "Merchant of Record" platforms. They handle tax compliance, VAT collection, and act as the seller on your behalf. The tradeoff: higher fees (typically 5-8%) but significantly less compliance headache. If you're a solo founder selling globally and don't want to deal with tax registration in multiple jurisdictions, these are worth considering.

When NOT to Use Stripe#

Stripe works for most SaaS products. But if you're in a high-risk industry (adult content, gambling, crypto), you'll need a specialized processor. If you're processing extremely high volume with large transactions, you might negotiate better rates with a direct processor. For 95% of SaaS startups, just use Stripe and move on.

Analytics dashboard showing subscription metrics and revenue data
Your billing system should give you clear visibility into MRR, churn, and subscription health from day one.

The Architecture: How to Structure Your Billing System#

Here's the billing architecture we use and recommend for every SaaS product we build. It's simple, reliable, and scales to thousands of customers without modification.

The Core Components#

  • Stripe as the source of truth for billing state. Never store subscription status in your own database as the primary source. Always check Stripe or sync from Stripe via webhooks.
  • Webhooks for real-time sync. Stripe sends events (payment succeeded, subscription cancelled, invoice paid) to your server. Process these to update your app's state.
  • Your database for access control. Store the user's current plan and feature access in your database, but always derive it from Stripe events. Think of your DB as a cache of Stripe's state.
  • Stripe Customer Portal for self-service. Let users manage their own billing, update cards, cancel subscriptions, and view invoices through Stripe's hosted portal. Don't build this yourself.
  • Stripe Checkout for payment collection. Use Stripe's hosted checkout page for initial subscription creation. It handles card validation, 3D Secure, and PCI compliance. Again, don't build this yourself.

The Webhook Events You Actually Need to Handle#

Stripe sends dozens of webhook event types. You don't need to handle all of them. Here are the ones that matter for a typical SaaS:

  • checkout.session.completed - User just subscribed. Create their account or upgrade their plan.
  • customer.subscription.updated - Plan changed (upgrade/downgrade). Update feature access.
  • customer.subscription.deleted - Subscription cancelled. Revoke premium access.
  • invoice.payment_succeeded - Recurring payment went through. Keep things running.
  • invoice.payment_failed - Payment failed. Trigger your dunning flow (email the user, retry).
  • customer.subscription.trial_will_end - Trial ending soon. Send a conversion email.

Start with these six. You can add more granular handling later as your needs grow. The key is getting the basics rock-solid before adding complexity.

Setting Up Your Pricing Plans in Stripe#

Before you write a single line of billing code, set up your plans in Stripe's dashboard. If you haven't decided on how to price your SaaS product, do that first. Your billing implementation depends entirely on your pricing model.

Here's the Stripe hierarchy you need to understand:

  • Products represent your different plan tiers (e.g., Starter, Pro, Enterprise).
  • Prices are attached to Products and define the actual billing (e.g., $29/month, $290/year for the same Product).
  • Subscriptions are created when a customer subscribes to a Price.
  • Customers are your users in Stripe's system, linked to your app's user records.

Pro tip: Create both monthly and annual Prices for each Product from the start, even if you only plan to offer monthly initially. Adding annual pricing later when your Prices are already structured correctly is trivial. Restructuring your entire pricing setup six months in is not.

Business metrics and financial data displayed on a computer monitor
Structure your Stripe products and prices correctly from the start to avoid painful migrations.

The Implementation: Step by Step#

Here's the exact implementation sequence we follow when building billing into a new SaaS product. This works whether you're using Next.js, Django, Rails, or any other framework.

Step 1: Create Your Stripe Account and Products#

Sign up for Stripe, complete verification, and create your Products and Prices in test mode. Use Stripe's dashboard for this. Don't create products via API during setup, it's slower and you'll make mistakes.

Step 2: Implement Stripe Checkout#

When a user clicks "Subscribe" or "Upgrade" in your app, create a Stripe Checkout Session on your server and redirect them to Stripe's hosted checkout page. This handles card collection, validation, and 3D Secure authentication. After successful payment, Stripe redirects back to your app with a success URL.

javascript
// Example: Creating a Checkout Session (Node.js)
const session = await stripe.checkout.sessions.create({
  customer: stripeCustomerId,
  mode: 'subscription',
  line_items: [{
    price: 'price_xxxxx', // Your Stripe Price ID
    quantity: 1,
  }],
  success_url: 'https://yourapp.com/billing?success=true',
  cancel_url: 'https://yourapp.com/billing?cancelled=true',
});

// Redirect user to session.url

Step 3: Set Up Webhook Handling#

Create an API endpoint that receives Stripe webhook events. Verify the webhook signature (critical for security), parse the event, and update your database accordingly. This is where subscription state flows from Stripe into your application.

Important: Make your webhook handler idempotent. Stripe may send the same event multiple times. If you process "subscription created" twice, you shouldn't create two subscriptions in your database. Check if the event has already been processed before acting on it.

Step 4: Implement Feature Gating#

Once your webhook handler syncs subscription state to your database, you need to gate features based on the user's plan. Keep this simple. Store the user's current plan identifier in your database and check it wherever you need to restrict access.

javascript
// Simple feature gating
function canAccessFeature(user, feature) {
  const planFeatures = {
    starter: ['basic_reports', 'api_access'],
    pro: ['basic_reports', 'api_access', 'advanced_analytics', 'priority_support'],
    enterprise: ['basic_reports', 'api_access', 'advanced_analytics', 'priority_support', 'custom_integrations', 'sla'],
  };
  return planFeatures[user.plan]?.includes(feature) ?? false;
}

Step 5: Add the Customer Portal#

Stripe's Customer Portal lets users manage their own billing without you building any UI. They can update payment methods, switch plans, cancel subscriptions, and download invoices. Set it up in your Stripe dashboard and create a portal session to redirect users there.

This single integration eliminates an enormous amount of billing UI work. We've seen founders spend weeks building custom billing dashboards when Stripe's portal does it better out of the box.

Financial planning documents and calculator on a desk representing billing setup
Stripe's Customer Portal handles billing management UI so you can focus on your core product.

Handling the Tricky Parts#

The basic setup is straightforward. Here's where things get interesting.

Free Trials#

Stripe supports trials natively. You can set a trial period on the subscription so the user isn't charged for the first 7/14/30 days. The question is whether to require a credit card upfront. Card-required trials convert at higher rates (typically 40-60%) but generate fewer signups. No-card trials get more signups but convert at 2-5%. For most early-stage SaaS products, we recommend requiring a card. You need revenue, not vanity metrics.

Failed Payments and Dunning#

Credit cards expire. Payments fail. This is called involuntary churn, and it's responsible for 20-40% of all SaaS churn. Stripe has built-in Smart Retries that automatically retry failed payments at optimal times. Enable this. Beyond that, set up a dunning email sequence: notify users when a payment fails, remind them to update their card, and give them a grace period before downgrading their account.

Proration#

When a user upgrades mid-billing-cycle, do they pay the full new price immediately or the prorated difference? Stripe handles proration automatically by default, which is usually what you want. The user gets credited for the unused portion of their current plan and charged the prorated amount for the new plan. Don't try to calculate this yourself. Let Stripe do it.

Tax Compliance#

If you're selling to customers in the EU, UK, Canada, Australia, or many US states, you need to collect and remit sales tax or VAT. Stripe Tax automates this for an additional 0.5% per transaction. For most founders, this is absolutely worth it compared to hiring a tax accountant or registering for VAT manually in 27 EU countries.

Common Billing Mistakes (And How to Avoid Them)#

We've seen these mistakes repeatedly across the SaaS products we've built and audited. Save yourself the pain.

  • Building custom checkout instead of using Stripe Checkout. You'll spend weeks building something worse than what Stripe offers for free. Their checkout handles card validation, 3D Secure, Apple Pay, Google Pay, and 40+ payment methods. Don't reinvent this.
  • Storing billing state in your database as the primary source. Your database should mirror Stripe's state via webhooks, not the other way around. If your DB says a user is subscribed but Stripe says they're not, Stripe is right.
  • Not handling webhook failures. Your webhook endpoint will go down. Stripe retries failed webhooks, but you need to handle duplicate events gracefully. Log every event and check for duplicates before processing.
  • Launching without a dunning flow. Failed payments are inevitable. Without automated retry and email notifications, you'll silently lose customers who would have stayed if you'd just reminded them to update their card.
  • Overcomplicating pricing tiers at launch. Start with 2-3 simple plans. You can always add complexity later. Starting with a usage-based model, per-seat pricing, and add-ons from day one is a recipe for billing bugs and customer confusion.
  • Not testing with Stripe's test mode. Stripe has excellent test cards, test clocks (for simulating subscription lifecycle), and a complete test environment. Use it extensively before going live. Simulate failed payments, trial expirations, and plan changes.
Stack of coins representing financial growth and recurring revenue
Avoiding common billing mistakes early means more revenue retained and fewer support headaches.

Usage-Based Billing: When and How#

If your SaaS involves AI features, API calls, or resource consumption, you'll likely need some form of usage-based billing. This is especially relevant for AI SaaS products where API costs (OpenAI, Anthropic, etc.) scale with usage.

Stripe Billing supports metered usage. You report usage to Stripe via their API, and Stripe calculates the charge at the end of the billing period. The implementation looks like this:

  • Create a metered Price in Stripe (e.g., $0.01 per API call).
  • Track usage in your application as users consume resources.
  • Report usage to Stripe periodically (we recommend daily or at the end of each billing period).
  • Stripe adds the usage charges to the customer's next invoice.

A common hybrid approach that works well: charge a flat monthly subscription fee that includes a usage allowance, then bill overage at a per-unit rate. This gives customers cost predictability while protecting your margins on heavy users. If you're building an AI SaaS, our AI SaaS tech stack guide covers how to manage API costs alongside your billing model.

Your Billing Launch Checklist#

Before you go live with billing, run through this checklist. We use this for every SaaS product we launch.

  • All Stripe Products and Prices created in live mode (not just test mode)
  • Webhook endpoint deployed and verified with Stripe CLI
  • All six core webhook events handled and tested
  • Feature gating works correctly for every plan
  • Stripe Checkout flow tested end-to-end (subscribe, upgrade, downgrade)
  • Customer Portal configured and accessible from your app
  • Dunning emails set up for failed payments
  • Test mode simulations complete: failed payment, trial expiration, plan change, cancellation
  • Stripe Tax enabled if selling internationally
  • Terms of Service and Privacy Policy linked from checkout
  • Refund policy documented and team trained on processing refunds
  • Revenue reporting dashboard set up (Stripe Dashboard or a tool like Baremetrics/ProfitWell)

If you're building a SaaS product and want to make sure your billing infrastructure is solid from day one, that's exactly the kind of thing we help with. We've built complete billing systems for multiple products, including MVP features that actually matter. Book a free strategy call and let's talk about your product.


How long does it take to set up billing for a SaaS product?
With Stripe Checkout and the Customer Portal, a basic billing integration takes 2-5 days for an experienced developer. A more complex setup with usage-based billing, multiple plan tiers, and custom dunning flows can take 1-3 weeks. The key is using Stripe's pre-built components instead of building everything custom.
Should I use Stripe or a Merchant of Record like Paddle?
For most SaaS startups, Stripe is the better choice due to lower fees and more flexibility. However, if you're a solo founder selling globally and don't want to deal with tax registration and compliance in multiple countries, a Merchant of Record like Paddle or Lemon Squeezy handles all of that for you at a higher fee (typically 5-8% vs Stripe's ~3.4%).
Do I need to be PCI compliant to accept payments?
If you use Stripe Checkout or Stripe Elements, Stripe handles PCI compliance for you. Card data never touches your servers. You just need to fill out a simple Self-Assessment Questionnaire (SAQ-A) annually. Never build your own card input form or store card numbers on your servers.
How do I handle pricing changes for existing customers?
You have two options: grandfather existing customers on their current price (create a new Price in Stripe and only use it for new subscribers), or migrate everyone to the new pricing with advance notice. Most SaaS companies grandfather existing customers for 6-12 months, then migrate them. Stripe makes both approaches straightforward.
What's the best way to handle refunds in a SaaS product?
Process refunds directly through Stripe's dashboard or API. For monthly subscriptions, most SaaS companies offer prorated refunds for the unused portion of the current billing period. Have a clear refund policy documented on your website and make the process as frictionless as possible. A generous refund policy actually reduces churn because it lowers the barrier to signing up.

Related Posts