Skip to content

Stripe

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

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 an account at stripe.com.

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

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 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 the following environment variables:

.env

Terminal window
# 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 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


  • 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)

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

Install Stripe CLI (macOS):

Terminal window
brew install stripe/stripe-cli/stripe

Or install it globally via npm/bun:

Terminal window
npm install -g stripe-cli

Log in to Stripe:

Terminal window
stripe login

Forward events to your local server:

Terminal window
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:

Terminal window
STRIPE_WEBHOOK_SECRET=whsec_...

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

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
  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

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.

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.

Here is the complete payment flowchart.

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?

Section titled “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.

  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.