Complete guide to setting up Stripe for payments, subscriptions, and billing in ShipSafe.
Overview
ShipSafe integrates Stripe to handle all payment processing, including one-time payments, recurring subscriptions, customer billing portal, and webhook events. This guide will walk you through the complete Stripe setup from account creation to production configuration.
What you'll set up:
- Stripe account and business information
- API keys (test and live)
- Products and pricing plans
- Webhook endpoints (local and production)
- Customer portal configuration
- Environment variables
Prerequisites
- Email address for Stripe account
- Business information (for production)
- Node.js project set up
- Basic understanding of Stripe concepts
Step 1: Create Stripe Account
1.1 Sign Up
- Visit stripe.com
- Click Sign in or Start now
- Enter your email address
- Create a password
- Click Create account
1.2 Complete Business Information
For Development:
- You can use test mode without full business details
- Test mode allows you to simulate payments
For Production:
-
Complete business information:
- Business type (Individual, Company, Non-profit)
- Business name and address
- Tax information
- Banking details for payouts
-
Verify your email address
-
Activate your account (may require additional verification)
Note: Production account activation can take a few days. Start with test mode for development.
Step 2: Get API Keys
2.1 Access API Keys
- Log into Stripe Dashboard
- Click Developers in the left sidebar
- Click API keys
2.2 Copy Test Keys
You'll see two keys:
-
Publishable key (starts with
pk_test_)- Safe to expose in client-side code
- Used for Stripe.ts and checkout
-
Secret key (starts with
sk_test_)- Never expose to client-side code
- Used for server-side operations
- Click Reveal test key to see it
2.3 Save Keys Securely
Development:
- Copy both keys to your
.env.localfile (see Step 6)
Production:
- Copy Live keys (switch toggle in Dashboard)
- Store in hosting platform environment variables
- Never commit to Git
Important:
- Test keys start with
pk_test_/sk_test_ - Live keys start with
pk_live_/sk_live_ - Never mix test and live keys
Step 3: Create Products & Prices
3.1 Create Your First Product
-
In Stripe Dashboard, click Products in the left sidebar
-
Click Add product
-
Product Information:
- Name: Your plan name (e.g., "Starter Plan")
- Description: Brief description (optional)
- Image: Upload product image (optional)
-
Pricing:
- Price: Enter amount (e.g.,
99for $99.00) - Billing period:
- Recurring → Monthly/Yearly subscription
- One time → One-time payment
- Currency: Select currency (USD, EUR, etc.)
- Price: Enter amount (e.g.,
-
Click Save product
-
Copy Price ID:
- After saving, you'll see a Price ID (starts with
price_) - Copy this ID - you'll need it for
config.ts
- After saving, you'll see a Price ID (starts with
3.2 Create Additional Plans
Repeat Step 3.1 for each pricing plan:
- Starter plan (e.g., $99/month)
- Pro plan (e.g., $199/month)
- Enterprise plan (optional)
Tip: Use descriptive names that match your config.ts plan names.
3.3 Note Price IDs
Keep track of your Price IDs:
Starter Plan: price_1234567890abcdef
Pro Plan: price_abcdef1234567890
Enterprise Plan: price_xyz789...
You'll add these to environment variables.
Step 4: Configure Stripe Checkout
4.1 Branding (Optional but Recommended)
- Go to Settings → Branding
- Upload your logo
- Set brand colors
- Customize checkout appearance
This makes checkout match your brand.
4.2 Customer Portal
- Go to Settings → Customer Portal
- Click Activate test link or Activate live link
- Configure portal settings:
- Allow customers to update payment methods
- Allow customers to cancel subscriptions
- Set cancellation behavior
Customer Portal:
- Customers can manage subscriptions
- Update payment methods
- View invoices
- Cancel subscriptions (if enabled)
Step 5: Set Up Webhooks
Webhooks allow Stripe to notify your app about payment events.
5.1 Local Development Setup
For local development, use Stripe CLI to forward webhooks:
Install Stripe CLI:
macOS:
brew install stripe/stripe-cli/stripe
Windows: Download from Stripe CLI releases
Linux:
# Download and install
wget https://github.com/stripe/stripe-cli/releases/latest/download/stripe_*_linux_x86_64.tar.gz
tar -xvf stripe_*_linux_x86_64.tar.gz
sudo mv stripe /usr/local/bin
Login:
stripe login
This opens a browser to authorize the CLI.
Forward Webhooks:
stripe listen --forward-to localhost:3000/api/webhooks/stripe
The CLI will:
- Display a webhook signing secret (starts with
whsec_) - Forward all Stripe events to your local server
- Show event logs in real-time
Copy Webhook Secret:
- Copy the webhook signing secret displayed
- Add to
.env.localasSTRIPE_WEBHOOK_SECRET=whsec_...
5.2 Production Webhook Setup
Create Webhook Endpoint:
- In Stripe Dashboard, go to Developers → Webhooks
- Click Add endpoint
- Endpoint URL:
https://www.yourdomain.com/api/webhooks/stripe - Description: "ShipSafe Production Webhooks"
Select Events:
Required for Subscriptions:
checkout.session.completed- Customer completed checkout (handles both subscription and one-time)customer.subscription.created- New subscription createdcustomer.subscription.updated- Subscription plan changed, status updatedcustomer.subscription.deleted- Subscription canceledinvoice.payment_succeeded- Subscription payment succeededinvoice.payment_failed- Subscription payment failed
Optional for One-Time Payments:
payment_intent.succeeded- One-time payment succeeded (if you need separate handling)payment_intent.payment_failed- One-time payment failed (if you need separate handling)
Note: ShipSafe handles both subscription and one-time payments. The checkout.session.completed event works for both - the handler checks session.mode to determine payment type. For subscriptions, you need all the subscription events listed above.
Get Signing Secret:
- After creating endpoint, click on it
- Find Signing secret section
- Click Reveal to see the secret (starts with
whsec_) - Copy this secret
- Add to production environment variables
Test Webhook:
- Click Send test webhook
- Select an event type
- Verify your endpoint receives the event
Step 6: Configure Environment Variables
6.1 Add Stripe Keys
Add to your .env.local file:
# Stripe API Keys (Test Mode for Development)
STRIPE_SECRET_KEY=sk_test_51... # From Step 2.2
STRIPE_PUBLIC_KEY=pk_test_51... # From Step 2.2
# Stripe Webhook Secret (Local Development)
STRIPE_WEBHOOK_SECRET=whsec_... # From Step 5.1
# Stripe Price IDs
STRIPE_PRICE_STARTER=price_1234567890abcdef # From Step 3.3
STRIPE_PRICE_PRO=price_abcdef1234567890 # From Step 3.3
6.2 Production Variables
For production (in Vercel or your hosting platform):
# Stripe API Keys (Live Mode)
STRIPE_SECRET_KEY=sk_live_51... # Live secret key
STRIPE_PUBLIC_KEY=pk_live_51... # Live publishable key
# Stripe Webhook Secret (Production)
STRIPE_WEBHOOK_SECRET=whsec_... # From Step 5.2
# Stripe Price IDs (Same as test or create new live prices)
STRIPE_PRICE_STARTER=price_...
STRIPE_PRICE_PRO=price_...
Important:
- Never mix test and live keys
- Use test keys for development
- Use live keys only in production
- Keep webhook secrets separate for local and production
Step 7: Configure Plans in config.ts
7.1 Update Pricing Plans
Open config.ts and update the stripe.plans array:
stripe: {
plans: [
{
priceId: process.env.STRIPE_PRICE_STARTER || "",
name: "Starter",
description: "Perfect for getting started",
price: 99,
priceAnchor: 199, // Optional: original price to show crossed out
isFeatured: false,
features: [
"Feature 1",
"Feature 2",
"Feature 3",
],
},
{
priceId: process.env.STRIPE_PRICE_PRO || "",
name: "Pro",
description: "For power users",
price: 199,
isFeatured: true, // Highlights this plan
features: [
"Everything in Starter",
"Advanced Feature 1",
"Advanced Feature 2",
],
},
],
}
7.2 Match Price IDs
Ensure priceId values match your Stripe Price IDs from Step 3.3.
Step 8: Test Stripe Integration
8.1 Test Checkout Flow
- Start your development server:
npm run dev - Start Stripe webhook forwarding:
stripe listen --forward-to localhost:3000/api/webhooks/stripe - Visit your pricing page:
http://localhost:3000/pricing - Click a checkout button
- Use test card:
4242 4242 4242 4242- Expiry: Any future date (e.g.,
12/34) - CVC: Any 3 digits (e.g.,
123) - ZIP: Any 5 digits (e.g.,
12345)
- Expiry: Any future date (e.g.,
8.2 Verify Webhook Events
Check your Stripe CLI terminal to see webhook events being received.
8.3 Test Different Scenarios
Test Cards:
- Success:
4242 4242 4242 4242 - Decline:
4000 0000 0000 0002 - Requires Authentication:
4000 0025 0000 3155 - Insufficient Funds:
4000 0000 0000 9995
Test Payment Methods:
- See Stripe Test Cards for more
8.4 Check Stripe Dashboard
- Go to Payments in Stripe Dashboard
- Verify test payments appear
- Check customer information
Troubleshooting
Checkout Not Redirecting
Issue: Clicking checkout button doesn't work
Solutions:
- Check API keys - Verify keys are correct in
.env.local - Restart server - Environment variables only load on startup
- Check console - Look for errors in browser console
- Verify price ID - Ensure price ID exists in Stripe
Webhooks Not Receiving Events
Issue: Webhook events not arriving
Solutions:
- Check CLI is running -
stripe listenmust be active - Verify endpoint URL - Must match your API route
- Check webhook secret - Must match the one from CLI
- Test endpoint - Manually trigger a test webhook
Payment Fails
Issue: Payments are declined
Solutions:
- Use test cards - Only test cards work in test mode
- Check card details - Verify expiry date is in future
- Check Stripe logs - View payment details in Dashboard
- Verify API keys - Ensure using test keys in development
Webhook Signature Verification Fails
Issue: Webhook events rejected
Solutions:
- Check webhook secret - Must match Stripe Dashboard or CLI
- Verify raw body - API route must use raw body for verification
- Check headers - Stripe signature header must be present
- Test signature - Use Stripe CLI test events
Production Checklist
Before going live:
- Stripe account activated and verified
- Live API keys obtained and configured
- Production webhook endpoint created
- Webhook signing secret added to production env vars
- Products and prices created in live mode
-
config.tsupdated with live price IDs - Customer portal activated
- Branding configured (logo, colors)
- Test payments processed successfully
- Webhook events verified in production
- Error handling tested
Best Practices
- Separate Accounts - Use different Stripe accounts for test and production
- Test Thoroughly - Test all payment scenarios before production
- Monitor Webhooks - Set up alerts for failed webhook deliveries
- Handle Failures - Implement retry logic for failed payments
- Secure Keys - Never expose secret keys in client-side code
- Log Events - Log all Stripe events for debugging
Testing Checklist
Before production:
- Test successful payment
- Test declined payment
- Test subscription creation
- Test subscription cancellation
- Test payment method update
- Test webhook event handling
- Test customer portal access
- Test invoice generation
Next Steps
Now that Stripe is set up:
- Billing Features - Learn billing functionality
- Stripe Subscriptions Tutorial - Build subscription flow
- Webhooks - Handle webhook events
- ButtonCheckout Component - Use checkout button