Back to Blog

Stripe integration done right: subscription management in Next.js

Payments
Subscriptions
Integration
Next.js
TypeScript
Webhooks

Implementing Stripe subscription management from scratch is complex and error-prone. From handling checkout sessions and webhooks to managing subscription lifecycles and customer portals, building a production-ready payment system requires weeks of careful development. Fastack comes with a complete, battle-tested Stripe integration that handles all subscription management, webhook processing, and billing operations—saving you weeks of development time.

Why proper Stripe integration matters

Payment processing is critical for SaaS applications. A poorly implemented payment system can lead to:

  • Lost revenue from failed payments
  • Security vulnerabilities from improper webhook handling
  • Poor user experience from manual subscription management
  • Data inconsistencies between Stripe and your database

What you get with Fastack

Fastack includes a complete @saas/payment package that provides:

Stripe checkout integration

Fastack provides a complete checkout flow with Stripe Checkout:

  • Subscription checkout - One-click subscription creation with Stripe Checkout
  • One-time payments - Support for one-time product purchases
  • Guest checkout - Allow purchases without account creation
  • Upgrade/downgrade validation - Prevents invalid subscription changes
  • Coupon support - Built-in discount code handling
import { useCreateCheckoutSession } from '@saas/payment/hooks';

function PricingPage() {
  const createCheckout = useCreateCheckoutSession();
  
  const handleSubscribe = (priceId: string) => {
    createCheckout.mutate({
      priceId,
      paymentMode: 'subscription',
      planId: 'pro',
      billingInterval: 'month',
      successUrl: '/dashboard?success=true',
      cancelUrl: '/pricing?canceled=true',
    });
  };
  
  return (
    <button onClick={() => handleSubscribe('price_123')}>
      Subscribe to Pro
    </button>
  );
}

Comprehensive webhook handling

Fastack handles all critical Stripe webhook events automatically:

  • checkout.session.completed - Processes successful checkouts
  • customer.subscription.created - Creates subscription in database
  • customer.subscription.updated - Updates subscription status and plan
  • customer.subscription.deleted - Handles subscription cancellations
  • invoice.paid - Processes successful payments and sends notifications
  • invoice.payment_failed - Handles failed payments and updates subscription status
  • customer.subscription.trial_will_end - Sends trial expiration reminders
packages/payment/api/webhook/index.ts
import { webhookHandler } from '@saas/payment/api/webhook';

export async function POST(request: Request) {
  return webhookHandler(request, async (userId, subscription) => {
    // Optional: Custom logic after purchase completion
    // e.g., grant access, send welcome email, etc.
    console.log('Purchase completed', { userId, subscription });
  });
}

All webhooks are automatically verified using Stripe's signature verification, ensuring security and preventing unauthorized requests.

Subscription lifecycle management

Fastack provides complete subscription management operations:

  • Create subscriptions - Start new subscriptions via checkout
  • Upgrade/downgrade - Change subscription plans seamlessly
  • Cancel subscriptions - Cancel at period end or immediately
  • Resume subscriptions - Reactivate canceled subscriptions
  • Status tracking - Monitor active, past_due, canceled, and trialing states
import { 
  useSubscription, 
  useCancelSubscription,
  useResumeSubscription,
  useChangeSubscription 
} from '@saas/payment/hooks';

function SubscriptionManagement() {
  const { data: subscription } = useSubscription();
  const cancel = useCancelSubscription();
  const resume = useResumeSubscription();
  const change = useChangeSubscription();
  
  return (
    <div>
      <p>Current plan: {subscription?.plan}</p>
      <button onClick={() => cancel.mutate()}>
        Cancel subscription
      </button>
      <button onClick={() => resume.mutate()}>
        Resume subscription
      </button>
      <button onClick={() => change.mutate({ priceId: 'price_new' })}>
        Change plan
      </button>
    </div>
  );
}

Stripe customer portal integration

Fastack includes seamless integration with Stripe's Customer Portal, allowing customers to manage their billing without leaving your app:

  • Payment method management - Update credit cards and payment methods
  • Invoice history - View and download past invoices
  • Subscription changes - Modify or cancel subscriptions
  • Billing address updates - Manage billing information
import { useCreatePortalSession } from '@saas/payment/hooks';

function BillingSettings() {
  const createPortal = useCreatePortalSession();
  
  const handleManageBilling = () => {
    createPortal.mutate({
      returnUrl: window.location.href,
    });
  };
  
  return (
    <button onClick={handleManageBilling}>
      Manage billing
    </button>
  );
}

The customer portal is fully hosted by Stripe, reducing your maintenance burden while providing a professional billing experience.

Webhook security and reliability

Fastack implements best practices for webhook handling:

  • Signature verification - All webhooks are verified using Stripe's signature
  • Idempotency handling - Prevents duplicate processing of events
  • Error logging - Comprehensive logging for debugging
  • Database transactions - Ensures data consistency
  • Notification integration - Sends user notifications for payment events

Pre-built React hooks

Fastack provides type-safe React hooks for all payment operations:

import {
  useSubscription,          // Get current subscription
  useCreateCheckoutSession, // Create checkout
  useCreatePortalSession,   // Open customer portal
  useCancelSubscription,    // Cancel subscription
  useResumeSubscription,    // Resume subscription
  useChangeSubscription,    // Change plan
  useProducts,              // Get available products
  usePurchases,             // Get purchase history
  useUpcomingInvoice,       // Get next invoice
} from '@saas/payment/hooks';

All hooks are built on TanStack Query, providing loading states, error handling, and automatic refetching out of the box.

Pre-built UI components

Fastack includes production-ready UI components for payment flows:

  • Subscription plans - Display pricing plans with features
  • Current subscription card - Show active subscription details
  • Upgrade/downgrade modals - Handle plan changes
  • One-time products - Display and purchase one-time items
  • Cancel subscription modal - Handle cancellations with confirmation
import {
  SubscriptionPlans,
  CurrentSubscriptionPlanCard,
  OneTimeProducts,
} from '@saas/payment/ui';

function PricingPage() {
  return (
    <div>
      <SubscriptionPlans />
      <OneTimeProducts />
    </div>
  );
}

function Dashboard() {
  return (
    <CurrentSubscriptionPlanCard />
  );
}

Database integration

Fastack automatically syncs all subscription data with your database:

  • Subscription records - Tracks all subscription details and status
  • Purchase history - Records all one-time purchases
  • Stripe customer IDs - Links users to Stripe customers
  • Billing period tracking - Monitors current and next billing dates

Time saved: 40+ hours

Building Stripe integration from scratch typically requires:

  • Setting up Stripe configuration (2-3 hours)
  • Implementing checkout session creation (4-6 hours)
  • Building webhook handlers for all events (8-12 hours)
  • Creating subscription management APIs (6-8 hours)
  • Implementing customer portal integration (2-3 hours)
  • Building React hooks for payment operations (4-6 hours)
  • Creating UI components for pricing and subscriptions (6-8 hours)
  • Database schema design and migrations (2-3 hours)
  • Testing payment flows and edge cases (4-6 hours)
  • Handling errors and edge cases (2-3 hours)

Total: 40-58 hours of development time that you save with Fastack.

Security features

Fastack implements security best practices for payment processing:

  • Webhook signature verification - All webhooks are cryptographically verified
  • Server-side only operations - Sensitive operations never exposed to client
  • User authentication checks - All payment operations require authentication
  • Input validation - Zod schemas validate all payment inputs
  • Error logging - Comprehensive logging without exposing sensitive data

Conclusion

Stripe integration is essential for SaaS applications, but building it correctly requires deep knowledge of payment processing, webhook handling, and subscription management. Fastack provides a complete, production-ready Stripe integration that saves you weeks of development time while ensuring security, reliability, and a great user experience.

With Fastack, you get:

  • Complete Stripe checkout integration for subscriptions and one-time payments
  • Comprehensive webhook handling for all subscription events
  • Full subscription lifecycle management (create, upgrade, downgrade, cancel, resume)
  • Stripe Customer Portal integration for self-service billing
  • Type-safe React hooks for all payment operations
  • Pre-built UI components for pricing pages and subscription management
  • Automatic database synchronization with Stripe data
  • Security best practices with webhook verification and input validation

Ready to build your SaaS faster?

Get our scalable, production-ready boilerplate to save endless hours of development and setup

Stripe integration done right: subscription management in Next.js - Fastack