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 withsk_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.paidcheckout.session.completedcustomer.subscription.createdcustomer.subscription.updatedcustomer.subscription.deleted
- Click
Revealto view the Webhook signing secret (starts withwhsec_) - 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 currencyUSD) - Recurring:
Monthly - Save and copy the Price ID (starts with
price_), which will be used forVITE_STRIPE_PRICE_PRO_MONTHLY
- Click
- Add Yearly Price:
- Click
Add price - Price:
99.00(Select currencyUSD) - Recurring:
Yearly - Save and copy the Price ID (starts with
price_), which will be used forVITE_STRIPE_PRICE_PRO_YEARLY
- Click
- Click
- 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 currencyUSD) - Type:
One-time - Save and copy the Price ID (starts with
price_), which will be used forVITE_STRIPE_PRICE_LIFETIME
- Price:
- Click
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/stripeOr install it globally via npm/bun:
npm install -g stripe-cliLog in to Stripe:
stripe loginForward events to your local server:
stripe listen --forward-to localhost:3000/api/webhooks/stripeThe 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 changesto save the portal configuration
Production Environment
- 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.paidcheckout.session.completedcustomer.subscription.createdcustomer.subscription.updatedcustomer.subscription.deleted
- Once created, click
Revealunder the Webhook signing secret - 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 payment4000 0000 0000 3220- Requires 3D Secure authentication4000 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
- Secure API Keys: Never expose your Stripe secret keys in client-side code.
- Verify Webhook Signatures: Always verify the signature of incoming Webhook events.
- Handle Errors Gracefully: Provide user-friendly error messages when a payment fails.
- Test Webhooks Thoroughly: Ensure that all Webhook events are processed correctly.