Better Auth Integration

The Better Auth Stripe plugin provides a simple, zero-configuration payment system using external Stripe checkout pages only. This is separate from the Custom Boilerplate's advanced checkout system.
External checkout only: Better Auth uses Stripe-hosted external checkout pages. For embedded forms, guest checkout, or installments, use the Custom Boilerplate System.
Perfect for: Simple SaaS subscriptions where users create accounts before purchasing and you prefer zero configuration over advanced features.

Better Auth Stripe Plugin

The Stripe plugin is configured in src/lib/better-auth/auth.ts and provides automatic integration:
// From src/lib/better-auth/auth.ts
import { stripe } from '@better-auth/stripe'
import { stripeClient } from '@/lib/stripe/stripe-client'
import { onStripeEvent } from '@/lib/stripe/stripe-events'

plugins: [
  // ... other plugins
  stripe({
    stripeClient,
    stripeWebhookSecret: env.STRIPE_WEBHOOK_SECRET,
    createCustomerOnSignUp: true,
    subscription: {
      enabled: true,
      plans: () => getActivePlansForBetterAuthService(),
      authorizeReference: createAuthorizeReference(),
      // Subscription lifecycle hooks...
    },
    onEvent: onStripeEvent,
  }),
]
Better Auth Stripe Checkout Interface: Better Auth Stripe integration checkout

Core Plugin Features

Automatic Customer Creation
// From src/lib/better-auth/auth.ts
stripe({
  createCustomerOnSignUp: true, // Automatically create Stripe customer
  stripeClient,
  stripeWebhookSecret: env.STRIPE_WEBHOOK_SECRET,
})
What happens automatically:
  • User registers → Stripe customer created
  • Customer ID stored in user profile
  • Email synchronization between systems
  • Customer metadata management
Seamless integration: Users don't need to know about Stripe customers - it's all handled automatically during registration.

Subscription Lifecycle Hooks

The plugin provides hooks for all subscription events with automatic notification integration:

Subscription Creation

// From src/lib/better-auth/auth.ts
onSubscriptionComplete: async ({ subscription }) => {
  if (!subscription.stripeCustomerId) {
    return
  }

  const user = await getUserByStripeCustomerIdDao(
    subscription.stripeCustomerId as string
  )

  if (user) {
    await createTypedNotificationService({
      userId: user.id,
      type: NotificationTypeConst.subscription_created,
      metadata: { subscription },
    })
  }
}
What happens:
  1. User completes payment
  2. Stripe webhook triggers completion
  3. User receives confirmation email
  4. Database updated with subscription details

Subscription Updates

// From src/lib/better-auth/auth.ts
onSubscriptionUpdate: async ({ subscription }) => {
  if (!subscription.stripeCustomerId) {
    return
  }

  const user = await getUserByStripeCustomerIdDao(
    subscription.stripeCustomerId as string
  )

  if (user) {
    await createTypedNotificationService({
      userId: user.id,
      type: NotificationTypeConst.subscription_updated,
      metadata: { subscription },
    })
  }
}
Triggers on:
  • Plan upgrades/downgrades
  • Billing cycle changes
  • Seat count modifications
  • Price adjustments

Subscription Cancellation

// From src/lib/better-auth/auth.ts
onSubscriptionCancel: async ({ subscription }) => {
  if (!subscription.stripeCustomerId) {
    return
  }

  const user = await getUserByStripeCustomerIdDao(
    subscription.stripeCustomerId as string
  )

  if (user) {
    await createTypedNotificationService({
      userId: user.id,
      type: NotificationTypeConst.subscription_canceled,
      metadata: { subscription },
    })
  }
}
Cancellation handling:
  • Immediate cancellation support
  • End-of-period cancellation
  • Reactivation options
  • Access period management

Subscription Deletion

// From src/lib/better-auth/auth.ts
onSubscriptionDeleted: async ({ subscription }) => {
  if (!subscription.stripeCustomerId) {
    return
  }

  const user = await getUserByStripeCustomerIdDao(
    subscription.stripeCustomerId as string
  )

  if (user) {
    await createTypedNotificationService({
      userId: user.id,
      type: NotificationTypeConst.subscription_deleted,
      metadata: { subscription },
    })
  }
}

Database Integration

The plugin automatically manages subscription data with your database:

User-Customer Relationship

// From src/db/repositories/user-repository.ts
getUserByStripeCustomerIdDao(stripeCustomerId: string)
Maintains:
  • User ↔ Stripe Customer ID mapping
  • Subscription status synchronization
  • Payment method information
  • Billing address details

Plan Management

// From src/services/facades/subscription-service-facade.ts
getActivePlansForBetterAuthService()
Provides:
  • Active subscription plans
  • Pricing information
  • Feature limitations
  • Plan availability rules

Custom Event Processing

The plugin delegates custom events to your handler:
// From src/lib/stripe/stripe-events.ts
export const onStripeEvent = async (event: Stripe.Event) => {
  // Custom business logic for Stripe events
  // Handle events not covered by the plugin
  console.log(`Processing Stripe event: ${event.type}`)

  // Add your custom event handling here
  switch (event.type) {
    case 'invoice.payment_failed':
      // Handle failed payments
      break
    case 'customer.subscription.trial_will_end':
      // Send trial ending notifications
      break
    // Add more custom events...
  }
}

Security Features

Automatic Verification
// Plugin automatically verifies webhook signatures
stripe({
  stripeWebhookSecret: env.STRIPE_WEBHOOK_SECRET,
})
Security measures:
  • Webhook signature verification
  • Request timestamp validation
  • Duplicate event prevention
  • Secure endpoint protection

Plugin Benefits

Zero Configuration

Automatic customer creation, webhook processing, and database synchronization

Real-time Updates

Webhooks automatically update subscription status and user access

Email Integration

Automatic email notifications for all subscription lifecycle events

Security Built-in

Webhook verification, authorization checks, and secure data handling

Testing the Integration

1

Verify Plugin Loading

Check your application logs for successful plugin initialization:
[Better Auth] Stripe plugin loaded successfully
[Better Auth] Webhook endpoint: /api/auth/stripe/webhook
2

Test Customer Creation

  1. Register a new user account
  2. Check your Stripe dashboard for the new customer
  3. Verify the customer ID is stored in your database
3

Test Subscription Flow

  1. Complete a test subscription purchase
  2. Check webhook logs for event processing
  3. Verify subscription data in your database
  4. Confirm user received email notification
Better Auth Stripe integration complete! Your authentication system now seamlessly manages Stripe customers and subscriptions with zero additional configuration.
    Better Auth Integration | ShipSaaS Documentation | ShipSaaS - Launch your SaaS with AI in days