DO NOT upgrade any Stripe dependencies unless you’re following their official migration guide and understand the breaking changes. Upgrading without proper migration can break your payment processing, webhooks, and billing functionality. The current Stripe version in the boilerplate is tested and stable.

Setting up payment processing is only necessary when you have a working product that’s ready to accept payments. During the initial learning and MVP development phase, you can keep payments disabled in your Titan config. Only set up a company and payment processing if you’re ready to accept payments.

This guide covers working with payments with Stripe in Titan.

Titan comes with a complete Stripe integration that handles payments, subscriptions, and webhooks. All the necessary code is already implemented to process payments and update your database when payment events occur.

Testing payments locally

Assuming you have the ngrok url running, you can test the authentication flow locally.

  1. Set config.payments.enabled to true in config.ts

  2. Install Stripe CLI

brew install stripe/stripe-cli/stripe
  1. Login to Stripe
stripe login
  1. Listen for webhooks
stripe listen --forward-to <your-ngrok-url>/api/payments/webhook
  1. Copy the webhook secret

When you run the Stripe CLI webhook listener, it will print a webhook signing secret. Copy this value and add it to your .env file:

STRIPE_WEBHOOK_SECRET="whsec_your_webhook_signing_secret"
  1. Run your app
bun run dev
  1. Test the payment flow

Navigate to your pricing page and attempt to make a payment using the Stripe test card details:

  • Card number: 4242 4242 4242 4242
  • Expiry date: Any future date
  • CVC: Any 3 digits
  • Postal code: Any 5 digits

When the payment is successful, you should see the event logged in your Stripe CLI and the subscription created in both Stripe and your database.

Configuring payments in production

  1. Switch to Production Stripe mode

    a. Login to your Stripe Dashboard

    b. In the top-right corner, toggle from ‘Test Mode’ to ‘Live Mode’

    c. Create a new product in production or replicate your test products

    d. Copy your Production Price ID(s) for your subscriptions/products

    e. Copy your Production API Keys:

    • NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY
    • STRIPE_SECRET_KEY
  2. Set up the Production Webhook

    a. In your Stripe Dashboard, go to ‘Developers’ > ‘Webhooks’

    b. Click ’+ Add Destination’

    c. Set the endpoint URL to https://[your-production-domain]/api/payments/webhook

    d. Select the following events:

    • customer.subscription.created
    • customer.subscription.updated
    • customer.subscription.deleted
    • checkout.session.completed
    • invoice.payment_succeeded
    • invoice.payment_failed

    e. Copy the webhook signing secret for your environment variables

  3. Update Environment Variables

    Ensure these environment variables are set in your production environment (e.g., Vercel):

    NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY="Your production publishable key"
    STRIPE_SECRET_KEY="Your production secret key"
    STRIPE_WEBHOOK_SECRET="Your production webhook signing secret"
    NEXT_PUBLIC_STRIPE_PRODUCT_1_PRICE_ID="Your production price ID"

Devising Your Pricing Strategy (In the Future)

Plan Structure - The simpler the better

Remember, choose recurring subscriptions only when you can consistently deliver ongoing value. Forcing subscriptions when value is one-time will lead to high churn rates.

  1. Free Tier

    • Start with a simple free plan to attract users
    • Include basic but valuable features
    • Use as lead generation for premium plans
  2. Pro Plan

    • Position as recommended option with visual cues
    • Price competitively ($29-99/month range)
    • Target growing teams/businesses, for example
    • Include most-requested features
  3. Enterprise Plan (if applicable)

    • Custom solutions and premium support
    • Use “Contact Sales” CTA
    • Focus on scalability features

Add Negotiation Features

Integrate SalesNip if you want to offer AI-powered price negotiations.

Prevent Disputes

ByeDispute / Chargeblast are tools that help you prevent disputes with your customers. They provide a dashboard to monitor your disputes and a set of tools to help you resolve them.

Pricing is simple and transparent. Worth paying for if you’re starting to get disputes. Just setup a few rules and it’ll handle the rest.

Monitor conversion rates and gather user feedback to optimize your pricing strategy. Keep pricing simple at launch to not confuse users. You can always adjust based on market response.

Common Issues & Troubleshooting

Test cards aren’t working locally

Make sure you’re using the correct Stripe test cards for your testing.

Webhooks aren’t being received

  • Verify your ngrok URL is correct and the tunnel is active
  • Ensure the webhook endpoint in Stripe matches exactly your application’s endpoint path
  • Check your STRIPE_WEBHOOK_SECRET is correctly set in your .env file

Payment succeeded but subscription not created

Check the logs in your Stripe CLI output and your application server logs for any error messages.

Never use production Stripe keys in development or test environments. Always use test mode keys for development.