LogoTanStarter Docs
LogoTanStarter Docs
HomepageIntroductionCodebaseGetting StartedEnvironments
Configuration
Deployment

Integrations

CloudflareDatabaseAuthenticationEmailNewsletterStoragePaymentNotificationsAnalyticsChatboxAffiliates

Customization

MetadataPagesLanding PageBlogComponentsUser ManagementAPI Key Management

Codebase

Project StructureFormatting & LintingEditor SetupUpdating the Codebase
X (Twitter)

Payment

How to set up and use Stripe for payments and subscriptions

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

Setup

TanStarter 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

Get your API keys from the Stripe Dashboard:

  • 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

Set up Webhook and get your Webhook secret:

  • 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

Add the following environment variables:

.env
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_...

Set Up Customer Portal

Set up Stripe Customer Portal:

  • 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

Update Website Configuration

Update the website.ts file to use Stripe as the payment provider, and configure the pricing plans:

src/config/website.ts
import { clientEnv } from '@/env/client';

export const websiteConfig: WebsiteConfig = {
  // ...other config
  payment: {
    enable: true,
    provider: 'stripe',
    price: {
      plans: {
        free: {
          id: 'free',
          prices: [],
          isFree: true,
          isLifetime: false,
        },
        pro: {
          id: 'pro',
          prices: [
            {
              type: 'subscription',
              priceId: clientEnv.VITE_STRIPE_PRICE_PRO_MONTHLY!,
              amount: 990,
              currency: 'USD',
              interval: 'month',
              trialPeriodDays: 7,
            },
            {
              type: 'subscription',
              priceId: clientEnv.VITE_STRIPE_PRICE_PRO_YEARLY!,
              amount: 9900,
              currency: 'USD',
              interval: 'year',
              trialPeriodDays: 7,
            },
          ],
          isFree: false,
          isLifetime: false,
          popular: true,
        },
        lifetime: {
          id: 'lifetime',
          prices: [
            {
              type: 'one_time',
              priceId: clientEnv.VITE_STRIPE_PRICE_LIFETIME!,
              amount: 19900,
              currency: 'USD',
              allowPromotionCode: true,
            },
          ],
          isFree: false,
          isLifetime: true,
        },
      },
    },
  },
  // ...other config
}

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.

Environment Configuration

Set up 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 (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.

Production

  1. Go to Stripe Dashboard > Developers > Webhooks
  2. Click Add endpoint
  3. Enter Webhook URL: https://YOUR-DOMAIN.com/api/webhooks/stripe
  4. Select 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

Custom Payment Provider

TanStarter supports extending with new payment providers:

  1. Create a new file in the src/payment/provider directory
  2. Implement the PaymentProvider interface from types.ts
  3. Register the new provider in the providerRegistry in index.ts

Example implementation for a new payment provider:

src/payment/provider/my-provider.ts
import type {
  PaymentProvider,
  CreateCheckoutParams,
  CheckoutResult,
  CreatePortalParams,
  PortalResult,
} from '../types';

export class MyProvider implements PaymentProvider {
  getProviderName(): string {
    return 'my-provider';
  }

  public async createCheckout(params: CreateCheckoutParams): Promise<CheckoutResult> {
    // Create checkout session implementation
  }

  public async createCustomerPortal(params: CreatePortalParams): Promise<PortalResult> {
    // Create customer portal implementation
  }

  public async handleWebhookEvent(payload: string, signature: string): Promise<void> {
    // Handle webhook events implementation
  }
}

Then register the new provider in the providerRegistry in index.ts:

src/payment/index.ts
import { MyProvider } from './provider/my-provider';

const providerRegistry: Record<PaymentProviderName, ProviderFactory> = {
  stripe: () => new StripeProvider(),
  'my-provider': () => new MyProvider(),
};

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

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

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

How to limit users to only one subscription?

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

Best Practices

  1. Protect API keys: Never expose your Stripe secret key in client-side code
  2. Validate webhook signatures: Always verify the signature of webhook events
  3. Handle errors gracefully: Provide user-friendly error messages when payments fail
  4. Test webhooks thoroughly: Ensure all webhook events are handled correctly

References

  • Stripe Documentation
  • Stripe Payment Objects Overview
  • Stripe Best Practices

Next Steps

Now that you understand how to use payments in TanStarter, you might want to explore these related features:

Price Configuration

Configure subscription plans and pricing

Authentication

Configure user authentication

Analytics

Configure analytics services

Email

Configure email services

Table of Contents

Setup
Create Stripe Account
Get API Keys
Set Up Webhook
Create Products and Pricing Plans
Add Environment Variables
Set Up Customer Portal
Update Website Configuration
Core Features
Development
Production
Custom Payment Provider
Test Cards
Creating Invoices
Payment Flow Diagram
FAQ
How to activate WeChat Pay and Alipay?
How to limit users to only one subscription?
Best Practices
References
Next Steps