Payments

Accept payments with Stripe integration including subscriptions and one-time payments.

shipsaas includes production-ready Stripe integration with checkout flows, customer portal, and webhook handling via lib/stripe.ts.

Setup

1. Create Stripe Account

Sign up for a Stripe account if you don't have one already.

2. Get API Keys

Find your API keys at dashboard.stripe.com/apikeys:

.env.local
STRIPE_SECRET_KEY=sk_test_your-stripe-secret-key
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_your-stripe-publishable-key

# Webhook secret (for local: stripe listen --forward-to localhost:3000/api/stripe/webhook)
STRIPE_WEBHOOK_SECRET=whsec_your-webhook-secret

3. Configure Pricing Plans

Define your plans in lib/config.ts. Replace the price IDs with your actual Stripe price IDs from the Products page:

lib/config.ts
// lib/config.ts → stripe section
stripe: {
  plans: [
    {
      priceId: process.env.NODE_ENV === "development"
        ? "price_dev_starter"
        : "price_prod_starter",
      name: "Starter",
      description: "Perfect for individuals getting started",
      price: 29,
      priceAnchor: 49,
      isFeatured: false,
      features: [
        { name: "Feature 1" },
        { name: "Feature 2" },
        { name: "Feature 3" },
        { name: "Email support" },
      ],
    },
    {
      priceId: process.env.NODE_ENV === "development"
        ? "price_dev_pro"
        : "price_prod_pro",
      name: "Pro",
      description: "Best for growing businesses",
      price: 79,
      priceAnchor: 129,
      isFeatured: true,   // Gets "Most Popular" badge
      features: [
        { name: "Everything in Starter" },
        { name: "Advanced Feature 1" },
        { name: "Advanced Feature 2" },
        { name: "Priority support" },
        { name: "API access" },
      ],
    },
  ],
},

Stripe Helpers

All Stripe logic lives in lib/stripe.ts with three ready-to-use functions:

lib/stripe.ts

Stripe helpers for checkout sessions, customer portal, and session retrieval.

View Source

createCheckout

Creates a Stripe Checkout session for one-time payments or subscriptions:

import { createCheckout } from "@/lib/stripe";

const url = await createCheckout({
  priceId: "price_xxx",
  mode: "payment", // or "subscription"
  successUrl: "https://yourapp.com/success",
  cancelUrl: "https://yourapp.com/pricing",
  user: {
    email: session.user.email,
    customerId: dbUser.stripeCustomerId, // optional
  },
});

// Redirect user to Stripe checkout
redirect(url);

createCustomerPortal

Creates a Stripe Customer Portal session for subscription management:

import { createCustomerPortal } from "@/lib/stripe";

const portalUrl = await createCustomerPortal({
  customerId: user.stripeCustomerId,
  returnUrl: "https://yourapp.com/dashboard/billing",
});

findCheckoutSession

Retrieves a checkout session by ID — useful in webhooks:

import { findCheckoutSession } from "@/lib/stripe";

const session = await findCheckoutSession(sessionId);
// session.line_items contains the purchased plan

Webhooks

Events to listen for:

  • checkout.session.completed
  • customer.subscription.created
  • customer.subscription.updated
  • customer.subscription.deleted
  • invoice.payment_succeeded
  • invoice.payment_failed

Testing webhooks locally: Use the Stripe CLI:

stripe listen --forward-to localhost:3000/api/stripe/webhook

Ready to accept payments! Remember to switch to live mode keys before going to production.