Payments

Set up Stripe, Polar, or Dodo Payments via Better Auth plugins to handle one-time and subscription payments.

Setup

Stripe

  1. Sign up at Stripe and create an account.
  2. Create a Product in the Stripe Dashboard.
    • Add pricing plans (e.g. Monthly $10, Yearly $60).
    • Copy the Price IDs (they look like price_xxx).
  3. Copy your Secret Key and Webhook Secret from the Stripe Dashboard (Developers > API Keys and Webhooks).
  4. Set the following environment variables:
    .env
    STRIPE_SECRET_KEY="your-stripe-secret-key"
    STRIPE_WEBHOOK_SECRET="your-stripe-webhook-secret"
    
  5. Update pricing plans in your config:
    shared/config.ts
    pricing: {
        paymentProvider: enums.paymentProvider.stripe, // Set paymentProvider Stripe
        successUrlPath: '/payment-success', // Redirect after successful payment
        failedUrlPath: '/payment-failed', // Redirect after failed payment
        plans: {
            pro: {
                enable: true,  // Is show Pro Plan
                key: 'pro',
                monthly: {
                    key: 'pro-monthly',
                    priceId: 'price_monthly', // Set Stripe Price ID for monthly subscription
                    mode: 'subscription', // Payment is subscription
                },
                yearly: {
                    key: 'pro-yearly',
                    priceId: 'price_yearly', // Set Stripe Price ID for yearly subscription
                    mode: 'subscription', // Payment is subscription
                },
            },
            lifetime: {
                enable: true,  // Is show Lifetime Plan
                key: 'lifetime',
                priceId: 'price_lifetime', // Set Stripe Price ID for one-time payment
                promoCodeId: '', // Optional - Set Stripe Promo ID for any promo/coupon to discount
                mode: 'payment', // Payment is one-time
            },
        },
    },
    
  6. Set up a webhook:
    • Local: Use Stripe CLI
      Terminal
      stripe listen --forward-to localhost:3000/api/auth/stripe/webhook
      
      Copy the Webhook Secret into .env.
    • Production: Add a webhook endpoint in Stripe Dashboard pointing to:
      https://your-site.com/api/auth/stripe/webhook
      
      Select events like checkout.session.completed, customer.subscription.created, customer.subscription.updated, and customer.subscription.deleted.

Polar

  1. Sign up at Polar and create an account.
  2. Create a Product in the Polar Dashboard.
    • Add pricing plans (e.g. Monthly $10, Yearly $60).
    • Copy the Product IDs (found in the product details/API settings).
  3. Generate a Personal Access Token (or Organization Token) and configure a Webhook in the Polar Dashboard (Settings > Developers).
  4. Set the following environment variables:
    .env
    POLAR_ACCESS_TOKEN="your-polar-access-token"
    POLAR_WEBHOOK_SECRET="your-polar-webhook-secret"
    
  5. Update pricing plans in your config:
    shared/config.ts
    pricing: {
        paymentProvider: enums.paymentProvider.polar, // Set paymentProvider Polar
        successUrlPath: '/payment-success', // Redirect after successful payment
        failedUrlPath: '/payment-failed', // Redirect after failed payment
        plans: {
            pro: {
                enable: true, // Is show Pro Plan
                key: 'pro',
                monthly: {
                    key: 'pro-monthly',
                    priceId: 'price_monthly', // Set Polar Product ID for monthly subscription
                    mode: 'subscription', // Payment is subscription
                },
                yearly: {
                    key: 'pro-yearly',
                    priceId: 'price_yearly', // Set Polar Product ID for yearly subscription
                    mode: 'subscription', // Payment is subscription
                },
            },
            lifetime: {
                enable: true, // Is show Lifetime Plan
                key: 'lifetime',
                priceId: 'price_lifetime', // Set Polar Product ID for one-time payment
                mode: 'payment', // Payment is one-time
            },
        },
    },
    
  6. Set up a webhook:
    • Local: Use a tunneling service (like ngrok) or Polar's CLI if available to forward events to your local environment. Copy the Webhook Secret into .env.
    • Production: Add a webhook endpoint in Polar Dashboard pointing to:
      https://your-site.com/api/auth/polar/webhooks
      
      Select at least the following events like order.created, subscription.created, subscription.updated, subscription.canceled.

Dodo Payments

  1. Sign up at Dodo Payments and create an account.
  2. Create a Product and its associated pricing plans in the Dodo Payments Dashboard.
    • Copy the Product IDs (they typically start with pdt_) for each unique plan/interval.
  3. Copy your API Key and Webhook Secret from the Dodo Payments Dashboard (Developer > API Keys and Webhooks).
  4. Set the following environment variables:
    .env
    DODO_PAYMENTS_API_KEY="your-dodo-api-key"
    DODO_PAYMENTS_WEBHOOK_SECRET="your-dodo-webhook-secret"
    
  5. Update pricing plans in your config:
    shared/config.ts
    pricing: {
        paymentProvider: enums.paymentProvider.dodo, // Set paymentProvider Dodo
        successUrlPath: '/payment-success', // Redirect after successful payment
        failedUrlPath: '/payment-failed', // Redirect after failed payment
        plans: {
            pro: {
                enable: true, // Is show Pro Plan
                key: 'pro',
                monthly: {
                    key: 'pro-monthly',
                    priceId: 'price_monthly', // Set Dodo Product ID for monthly subscription
                    mode: 'subscription', // Payment is subscription
                },
                yearly: {
                    key: 'pro-yearly',
                    priceId: 'price_yearly', // Set Dodo Product ID for yearly subscription
                    mode: 'subscription', // Payment is subscription
                },
            },
            lifetime: {
                enable: true, // Is show Lifetime Plan
                key: 'lifetime',
                priceId: 'price_lifetime', // Set Dodo Product ID for one-time payment
                mode: 'payment', // Payment is one-time
            },
        },
    },
    
  6. Set up a webhook:
    • Local: Use a tunneling service (like ngrok) to expose your local development server.
      terminal
      # Example using ngrok to tunnel to your app's port
      ngrok http 3000
      
      Copy the resulting URL and add /api/payment/dodo/webhook to it for the Dodo Webhook configuration.
    • Production: Add a webhook endpoint in Dodo Payments Dashboard pointing to:
      https://your-site.com/api/payment/dodo/webhook
      
      Select at lease the following events like payment.succeeded, payment.failed, subscription.active, subscription.updated, subscription.renewed, subscription.cancelled, subscription.on_hold, and subscription.failed.

Usage

  • Handle Webhooks: Plugin automatically updates subscription status on payment events.
  • Verify Payments: Check transactions and subscriptions in the plugin dashboard.
  • Initiate Checkout: Use the paymentCheckout function to start a payment.
    const { payment } = useAuth(); payment.paymentCheckout(appConfig.pricing.plans.lifetime.key, locale.value);
    
    Users are redirected to payment's checkout page, then back to successUrlPath or failedUrlPath
  • Customer Portal: Let users manage subscriptions, invoices, and payment methods:
    const { payment } = useAuth(); payment.toCustomerPortal();