LogoShipTanStarter Docs

Stripe

How to set up and use Stripe for payments and subscriptions

ShipTanStarter uses Stripe for payment processing, supporting both one-time payments and subscriptions.

Setup

ShipTanStarter 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 set up:

Create Stripe Account

Create a Stripe account at stripe.com.

Get API Keys

  • Go to Stripe Dashboard > Developers > API keys
  • Copy the secret key (Note: test mode starts with sk_test_, production mode starts with sk_live_)
  • Save it to your environment file as STRIPE_SECRET_KEY

Set Up Webhook

  • Go to Stripe Dashboard > Developers > Webhooks
  • Click Add endpoint
  • Enter Webhook URL: https://YOUR-DOMAIN.com/api/webhooks/stripe
  • Select events to listen for:
    • 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 to your environment file as STRIPE_WEBHOOK_SECRET

Create Products and Pricing Plans

Create products in Stripe and set up pricing plans:

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

Add 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 pricing plans — amounts, currencies, intervals, and plan metadata. The enable, provider, and priceId fields are automatically resolved from your environment variables (VITE_PAYMENT_PROVIDER and VITE_STRIPE_PRICE_*), so you don't need to hardcode them.

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 go back to the Environment Configuration and continue. The rest of this document can be read later.

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 (table, card, button)
  • Server-side actions for secure payment operations
  • Multiple pricing plan support (free, pro, lifetime)

Development

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

pnpm install -g stripe/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 is printed in the terminal, copy it and add it to your environment file:

STRIPE_WEBHOOK_SECRET=whsec_...

Finally, you can make payment operations on the website to test whether the event processing flow works as expected.

Customer Portal

The Stripe Customer Portal provides a hosted portal for customers to manage their subscriptions. You can customize the appearance and available features.

  • Go to Stripe Dashboard > Settings > Billing > Customer Portal
  • Customize the content displayed in the customer portal, for example, you can add a custom logo and title
  • Click Save changes to save the portal configuration

Production

When deploying to production, you need to set up the webhook endpoint:

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

Test Cards

To test 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 - Insufficient funds failure

You can find more about Stripe test cards in the Stripe documentation.

Creating Invoices

ShipTanStarter has invoice creation configured 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. After that, you can access invoices in Stripe Dashboard > Invoices.

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

Payment Flow Diagram

This is the complete payment flow diagram.

Payment Diagram

FAQ

How to activate WeChat Pay and Alipay?

Activate in Stripe Dashboard > Settings > Payment methods. For more details, see the WeChat Pay and Alipay documentation.

How to limit users to only one subscription?

Enable Limit customers to 1 subscription in Stripe Dashboard > Settings > Checkout and Payment Links > Subscriptions. For more details, see Limit subscriptions.

Best Practices

  1. Protect API keys - Never expose your secret key in client-side code. Only use it in server-side actions.
  2. Validate webhook signatures - Always verify the webhook signing secret to ensure events are from Stripe.
  3. Handle errors gracefully - Provide user-friendly error messages when payments fail.
  4. Test webhooks thoroughly - Use the Stripe CLI to test webhook event handling before going to production.

References

On this page