LogoShipSaaS
Payment

Stripe

How to set up and use Stripe to handle payments and subscriptions

ShipSaaS uses Stripe for payment management, supporting both one-time payments and subscription payments.

Setup

The ShipSaaS template provides three pricing plans by default: a free plan, a pro subscription plan (monthly/yearly), and a lifetime plan (one-time payment). Follow these steps to configure them:

Create Stripe Account

Create an account at stripe.com.

Get API Keys

Obtain your API keys from the Stripe Dashboard:

  • Navigate to Stripe Dashboard > Developers > API keys
  • Copy the secret key (Note: Test mode starts with sk_test_, while live mode starts with sk_live_)
  • Save it in your environment variable file as STRIPE_SECRET_KEY

Configure Webhook

Set up a Webhook and obtain your Webhook signing secret:

  • Navigate to Stripe Dashboard > Developers > Webhooks
  • Click Add endpoint
  • Enter your Webhook URL: https://YOUR-DOMAIN.com/api/webhooks/stripe
  • Select the events to listen to:
    • invoice.paid
    • checkout.session.completed
    • customer.subscription.created
    • customer.subscription.updated
    • customer.subscription.deleted
  • Click Reveal to view the Webhook signing secret (starts with whsec_)
  • Save it in your environment variable file as STRIPE_WEBHOOK_SECRET

Create Products and Pricing Plans

Create products and configure pricing plans in Stripe:

  • Navigate to Stripe Dashboard > Product Catalog
  • Create a product for the Pro Subscription Plan:
    • Click Add product
    • Name: Pro Plan
    • Description: Premium features with subscription pricing
    • Add Monthly Price:
      • Click Add price
      • Price: 9.90 (Select currency USD)
      • Recurring: Monthly
      • Save and copy the Price ID (starts with price_), which will be used for VITE_STRIPE_PRICE_PRO_MONTHLY
    • Add Yearly Price:
      • Click Add price
      • Price: 99.00 (Select currency USD)
      • Recurring: Yearly
      • Save and copy the Price ID (starts with price_), which will be used for VITE_STRIPE_PRICE_PRO_YEARLY
  • Create a product for the Lifetime Plan:
    • Click Add product
    • Name: Lifetime Plan
    • Description: One-time payment for lifetime access
    • Add Price:
      • Price: 199.00 (Select currency USD)
      • Type: One-time
      • Save and copy the Price ID (starts with price_), which will be used for VITE_STRIPE_PRICE_LIFETIME

Add Environment Variables

Add the following environment variables:

.env

# Payment Provider
VITE_PAYMENT_PROVIDER=stripe

STRIPE_SECRET_KEY=sk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...

# Price plans
VITE_STRIPE_PRICE_PRO_MONTHLY=price_...
VITE_STRIPE_PRICE_PRO_YEARLY=price_...
VITE_STRIPE_PRICE_LIFETIME=price_...

Update Website Configuration

Update the payment section in src/config/website.ts to configure your pricing plans—amount, currency, intervals, and plan metadata. The enable, provider, and priceId fields are automatically resolved based on the environment variables (VITE_PAYMENT_PROVIDER and VITE_STRIPE_PRICE_*), so no hardcoding is needed.

You must configure this section to match the products and prices you created in Stripe:

src/config/website.ts

payment: {
  enable: isPaymentEnabled,              // ← Auto: true when VITE_PAYMENT_PROVIDER is set
  provider: isPaymentEnabled ? paymentProvider : undefined, // ← Auto: 'stripe'
  price: {
    plans: {
      free: {
        id: 'free',
        prices: [],
        isFree: true,
        isLifetime: false,
      },
      pro: {
        id: 'pro',
        prices: [
          {
            type: 'subscription',
            priceId: priceIds.proMonthly,  // ← Auto: from VITE_STRIPE_PRICE_PRO_MONTHLY
            amount: 990,                   // Amount in cents ($9.90)
            currency: 'USD',
            interval: 'month',
          },
          {
            type: 'subscription',
            priceId: priceIds.proYearly,   // ← Auto: from VITE_STRIPE_PRICE_PRO_YEARLY
            amount: 9900,                  // Amount in cents ($99.00)
            currency: 'USD',
            interval: 'year',
          },
        ],
        isFree: false,
        isLifetime: false,
        popular: true,
      },
      lifetime: {
        id: 'lifetime',
        prices: [
          {
            type: 'one_time',
            priceId: priceIds.lifetime,     // ← Auto: from VITE_STRIPE_PRICE_LIFETIME
            amount: 19900,                  // Amount in cents ($199.00)
            currency: 'USD',
            allowPromotionCode: true,
          },
        ],
        isFree: false,
        isLifetime: true,
      },
    },
  },
},

If you are setting up your environment, you can now return to the Environment Configuration document and continue. The remainder of this document can be read later.

Environment configuration set environment variables


Core Features

  • One-time payment for lifetime membership
  • Recurring subscription payments (monthly/yearly)
  • Free trial period support
  • Subscription management with Customer Portal integration
  • Webhook handling for payment events
  • Subscription status tracking and verification
  • Built-in pricing components (tables, cards, buttons)
  • Server-side actions for secure payment operations
  • Support for multiple pricing plans (free, pro, lifetime)

Development Environment

For local development, you can use the Stripe CLI to forward events to your local server.

Install Stripe CLI (macOS):

brew install stripe/stripe-cli/stripe

Or install it globally via npm/bun:

npm install -g stripe-cli

Log in to Stripe:

stripe login

Forward events to your local server:

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

The Webhook secret will be printed in the terminal. Copy it and add it to your environment variable file:

STRIPE_WEBHOOK_SECRET=whsec_...

Finally, you can initiate payments on your website to test whether the event handling workflow behaves as expected.

Customer Portal

The Stripe Customer Portal provides a hosted portal where customers can manage their subscriptions. You can customize the look and feel, as well as the available features.

  • Navigate to Stripe Dashboard > Settings > Billing > Customer Portal
  • Customize what is displayed in the portal (e.g., you can add a custom logo and header)
  • Click Save changes to save the portal configuration

Production Environment

  1. Navigate to Stripe Dashboard > Developers > Webhooks
  2. Click Add endpoint
  3. Enter your Webhook URL: https://YOUR-DOMAIN.com/api/webhooks/stripe
  4. Select the events to listen to:
  • invoice.paid
  • checkout.session.completed
  • customer.subscription.created
  • customer.subscription.updated
  • customer.subscription.deleted
  1. Once created, click Reveal under the Webhook signing secret
  2. Copy the signing secret (starts with whsec_) and add it to your production environment variables

Test Cards

To test your Stripe integration, use Stripe's test mode and test credit cards:

  • 4242 4242 4242 4242 - Successful payment
  • 4000 0000 0000 3220 - Requires 3D Secure authentication
  • 4000 0000 0000 9995 - Fails due to insufficient funds

You can find more information about Stripe Test Cards in the Stripe documentation.

Creating Invoices

ShipSaaS is already configured to automatically create invoices for one-time payments.

src/payment/provider/stripe.ts

// Automatically create invoice for one-time payments
checkoutParams.invoice_creation = {
  enabled: true,
};

If you want to automatically send paid invoices, you can enable it in Customer emails settings. Under Email customers about, select Successful payments. Afterward, you can access invoices under Stripe Dashboard > Invoices.

You can find more information about automatically sending paid invoices in the Stripe documentation.

Payment Flowchart

Here is the complete payment flowchart.

FAQs

How do I activate WeChat Pay and Alipay?

You can activate WeChat Pay and Alipay in the Stripe Dashboard > Settings > Payment methods. Find more information about WeChat Pay and Alipay in the Stripe documentation.

How do I limit customers to only one subscription?

You can enable Limit customers to 1 subscription under Stripe Dashboard > Settings > Checkout and Payment Links > Subscriptions. Find more details about limiting subscriptions in the Stripe documentation.

Best Practices

  1. Secure API Keys: Never expose your Stripe secret keys in client-side code.
  2. Verify Webhook Signatures: Always verify the signature of incoming Webhook events.
  3. Handle Errors Gracefully: Provide user-friendly error messages when a payment fails.
  4. Test Webhooks Thoroughly: Ensure that all Webhook events are processed correctly.

References

On this page