MR
Marcus Rodriguez
|| Updated December 30, 2025

How to Accept Payments in Your SaaS Application: Complete Integration Guide

Learn how to integrate payment processing, handle subscriptions, and manage billing in your SaaS product. Includes Stripe implementation examples and tax compliance strategies.

The Business of Getting Paid: Payment Processing for SaaS

Payment processing is where your SaaS transforms from a project into a business. According to Stripe's data, companies that optimize their payment experience see up to 11% reduction in failed payments and 3% improvement in conversion rates. Yet payment integration remains one of the most complex technical challenges, involving not just API integrations but also tax compliance, fraud prevention, and subscription management.

The payment provider you choose impacts your revenue, your customers' experience, and your operational burden. This guide will help you navigate the options and implement a robust payment system for your SaaS.

Payment Provider Deep Dive

Stripe: The Industry Standard for SaaS Payments

Stripe processes over $1 trillion in payments annually and has become the default choice for technology companies. Their comprehensive platform handles everything from simple one-time payments to complex subscription billing.

Core Products for SaaS:

Stripe Billing: Subscription management with:

  • Flexible pricing models (per-seat, metered, tiered)
  • Proration for plan changes
  • Smart retries for failed payments (dunning)
  • Customer portal for self-service
  • Invoice generation and hosting

Stripe Checkout: Pre-built payment pages with:

  • Optimized conversion (30+ payment methods)
  • Automatic tax calculation
  • Mobile-optimized UI
  • PCI compliance handled

Stripe Connect: For marketplaces and platforms:

  • Multi-party payments
  • Platform fees and revenue splits
  • Onboarding for sellers

Pricing Structure:

  • Standard: 2.9% + 30¢ per successful transaction
  • Billing: Additional 0.5% for subscription invoicing
  • Tax: 0.5% per transaction for tax calculation
  • No monthly fees, no setup costs

LemonSqueezy: Simplicity for Digital Products

LemonSqueezy operates as a Merchant of Record (MoR), meaning they handle sales tax compliance globally. This dramatically simplifies operations for solo developers and small teams.

Key Differentiators:

Merchant of Record Benefits:

  • LemonSqueezy is the legal seller, not you
  • Global tax compliance handled automatically
  • Reduced liability and audit risk
  • No need for tax registration in multiple jurisdictions

Built-in Affiliate Management:

  • Create affiliate programs without additional tools
  • Automatic commission calculation and payouts
  • Affiliate dashboard and tracking

License Key Generation:

  • Built-in software licensing
  • Automatic key generation and validation
  • License key management API

Pricing Structure:

  • 5% + 50¢ per transaction (higher than Stripe)
  • No additional fees for tax handling (included)
  • No monthly platform fees

Best suited for: Solo developers, digital product sellers, software with license keys, creators who prioritize simplicity over optimization.

Paddle: Enterprise Merchant of Record

Paddle serves larger SaaS companies that want MoR benefits with enterprise features:

Enterprise Capabilities:

  • Invoice billing for B2B
  • Multi-currency pricing
  • Quote-to-cash for sales teams
  • Revenue recognition automation

Pricing Structure:

  • 5% + 50¢ per transaction
  • Volume discounts at scale
  • Additional fees for some enterprise features

Fee Comparison: True Cost Analysis

Understanding total cost requires looking beyond transaction fees:

Scenario Stripe LemonSqueezy Paddle
$29 subscription $1.14 (3.9%) $1.95 (6.7%) $1.95 (6.7%)
$99 subscription $3.17 (3.2%) $5.45 (5.5%) $5.45 (5.5%)
$299 subscription $8.97 (3.0%) $15.45 (5.2%) $15.45 (5.2%)

Hidden costs with Stripe:

  • Tax compliance tools or services (~$50-200/month)
  • Accounting integrations
  • Time spent on tax filings
  • Potential audit liability

For high-volume SaaS: Stripe's lower fees compound significantly. A company processing $100K/month saves approximately $2,000-3,000/month vs MoR options.

For indie developers: LemonSqueezy's all-inclusive approach often provides better value when accounting for time and complexity saved.

Stripe Implementation Guide

Step 1: Product and Pricing Setup

// Create products and prices (typically done once, or via dashboard)
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);

// Create a product
const product = await stripe.products.create({
  name: 'Pro Plan',
  description: 'Full access to all features',
  metadata: {
    plan_type: 'pro'
  }
});

// Create prices (monthly and yearly)
const monthlyPrice = await stripe.prices.create({
  product: product.id,
  unit_amount: 2900, // $29.00
  currency: 'usd',
  recurring: {
    interval: 'month',
  },
  metadata: {
    billing_cycle: 'monthly'
  }
});

const yearlyPrice = await stripe.prices.create({
  product: product.id,
  unit_amount: 29000, // $290.00 (2 months free)
  currency: 'usd',
  recurring: {
    interval: 'year',
  },
  metadata: {
    billing_cycle: 'yearly'
  }
});

Step 2: Checkout Session Creation

// API route to create checkout session
export async function POST(request) {
  const { priceId, userId, customerEmail } = await request.json();

  // Find or create customer
  let customer;
  const existingCustomers = await stripe.customers.list({
    email: customerEmail,
    limit: 1,
  });

  if (existingCustomers.data.length > 0) {
    customer = existingCustomers.data[0];
  } else {
    customer = await stripe.customers.create({
      email: customerEmail,
      metadata: { userId },
    });
  }

  // Create checkout session
  const session = await stripe.checkout.sessions.create({
    customer: customer.id,
    mode: 'subscription',
    payment_method_types: ['card'],
    line_items: [{
      price: priceId,
      quantity: 1,
    }],
    success_url: `${process.env.NEXT_PUBLIC_URL}/success?session_id={CHECKOUT_SESSION_ID}`,
    cancel_url: `${process.env.NEXT_PUBLIC_URL}/pricing`,
    subscription_data: {
      metadata: { userId },
    },
    allow_promotion_codes: true, // Enable discount codes
    billing_address_collection: 'required', // Needed for tax
    automatic_tax: { enabled: true }, // Stripe Tax
  });

  return Response.json({ sessionUrl: session.url });
}

Step 3: Webhook Handler for Subscription Events

// Webhook endpoint
export async function POST(request) {
  const body = await request.text();
  const signature = request.headers.get('stripe-signature');

  let event;
  try {
    event = stripe.webhooks.constructEvent(
      body,
      signature,
      process.env.STRIPE_WEBHOOK_SECRET
    );
  } catch (err) {
    console.error('Webhook signature verification failed:', err.message);
    return new Response('Webhook signature verification failed', { status: 400 });
  }

  switch (event.type) {
    case 'checkout.session.completed': {
      const session = event.data.object;
      const userId = session.metadata.userId;
      const subscriptionId = session.subscription;

      // Fetch full subscription details
      const subscription = await stripe.subscriptions.retrieve(subscriptionId);

      // Update user in your database
      await db.user.update({
        where: { id: userId },
        data: {
          stripeCustomerId: session.customer,
          stripeSubscriptionId: subscriptionId,
          stripePriceId: subscription.items.data[0].price.id,
          subscriptionStatus: 'active',
          currentPeriodEnd: new Date(subscription.current_period_end * 1000),
        },
      });
      break;
    }

    case 'customer.subscription.updated': {
      const subscription = event.data.object;
      const userId = subscription.metadata.userId;

      await db.user.update({
        where: { id: userId },
        data: {
          stripePriceId: subscription.items.data[0].price.id,
          subscriptionStatus: subscription.status,
          currentPeriodEnd: new Date(subscription.current_period_end * 1000),
        },
      });
      break;
    }

    case 'customer.subscription.deleted': {
      const subscription = event.data.object;
      const userId = subscription.metadata.userId;

      await db.user.update({
        where: { id: userId },
        data: {
          subscriptionStatus: 'cancelled',
        },
      });
      break;
    }

    case 'invoice.payment_failed': {
      const invoice = event.data.object;
      // Notify user, attempt recovery
      await sendPaymentFailedEmail(invoice.customer_email);
      break;
    }
  }

  return new Response('OK', { status: 200 });
}

Tax Compliance Strategies

Option 1: Stripe Tax (Recommended for Growing SaaS)

Stripe Tax automates sales tax, VAT, and GST calculation and collection:

Setup:

const session = await stripe.checkout.sessions.create({
  // ... other options
  automatic_tax: { enabled: true },
  billing_address_collection: 'required',
});

Cost: 0.5% per transaction on top of payment fees

You're still responsible for: Filing and remitting taxes to jurisdictions

Option 2: Merchant of Record (LemonSqueezy/Paddle)

The MoR handles everything:

  • Tax calculation and collection
  • Tax remittance and filing
  • Compliance monitoring
  • Audit responsibility

Cost: Higher transaction fees (typically 5%)

Trade-off: Less control, higher fees, but zero tax compliance burden

Option 3: Third-Party Tax Services

Services like TaxJar or Avalara handle filing while you use Stripe for payments:

  • Automated filing in all jurisdictions
  • Economic nexus monitoring
  • Integration with Stripe

Cost: $50-500+/month depending on volume

Revenue Recovery: Reducing Churn from Failed Payments

Failed payments account for 20-40% of SaaS churn. Implement these recovery strategies:

  1. Smart Retries: Stripe automatically retries failed payments with intelligent timing
  2. Card Updater: Automatically updates expired cards through card network partnerships
  3. Dunning Emails: Automated sequences to prompt payment method updates
  4. Payment Method Backup: Encourage users to add backup payment methods
  5. Grace Periods: Don't immediately cancel—provide time to resolve

The right payment implementation combines the best provider for your situation with robust automation to maximize revenue capture.

MR

Written by

Marcus Rodriguez

Technical Writer & Developer Advocate

Full-stack developer focused on developer tools, APIs, and cloud infrastructure.

Developer ToolsAPIsCloud Infrastructure
Updated December 30, 2025

Tools Mentioned in This Guide

Browse all tools

Related Comparisons

View all comparisons

Related Guides

View all guides

Need Help Building Your Stack?

Use our Stack Builder to get personalized recommendations

Build Your Stack