Skip to main content

Overview

The Better Auth adaptor, @dodopayments/better-auth, is a Better Auth plugin that connects your users to Dodo Payments. It provides:
  • Optional customer creation or email-based customer linking on sign-up
  • Checkout sessions, the preferred checkout method, with product slug mapping
  • A self-service Customer Portal
  • Usage ingestion and reporting endpoints for usage-based billing
  • Webhook event processing with signature verification
  • TypeScript types for every endpoint
You need a Dodo Payments account and API keys to use this integration.

Prerequisites

  • Node.js 16 or later
  • Access to your Dodo Payments dashboard
  • An existing project that uses Better Auth 1.4 or a later 1.x release

Installation

1

Install Dependencies

Run this command in your project root:
The adaptor, the Dodo Payments SDK, Better Auth, and Zod are installed.

Setup

1

Configure Environment Variables

Add these variables to your .env file. Create the API key under Developer → API Keys in the dashboard. You get the webhook secret when you add the webhook endpoint, as described under Webhooks on this page. BETTER_AUTH_SECRET is a random string of at least 32 characters.
Never commit API keys or secrets to version control.
2

Set Up Server-Side Integration

Create or update src/lib/auth.ts:
The plugin adds a dodoCustomerId field to the Better Auth user table, where it stores each user’s Dodo Payments customer ID. After you add the plugin, update your database schema with the Better Auth CLI.
Set environment to live_mode for production.
3

Set Up Client-Side Integration

Create or update src/lib/auth-client.ts:

Usage Examples

Use authClient.dodopayments.checkoutSession for new integrations. The legacy checkout method is deprecated and kept only for backward compatibility.

Creating a Checkout Session (Preferred)

Create a checkout session from a configured slug or from a product cart, then redirect the customer to the returned URL:
checkoutSession fills in some fields for you:
  • Billing address: Not required up front, because checkout collects it from the customer. To pre-fill it, pass billing_address.
  • Customer: For a signed-in user, the plugin uses the email and name from their Better Auth session and ignores any customer object you pass. Without a signed-in user, it uses the customer object.
  • Other fields: The argument accepts the same fields as the request body of the Create Checkout Session endpoint, plus slug and referenceId.
If the slug isn’t configured, or you pass neither slug nor product_cart, the request fails with a 400 error.
The return URL comes from the successUrl configured in the server plugin, resolved against your app’s URL. The plugin ignores any return_url in the client payload.

Legacy Checkout (Deprecated)

The authClient.dodopayments.checkout method is deprecated. Use checkoutSession instead for new implementations.
The legacy method requires billing and customer, and creates a payment link through the deprecated dynamic checkout flow. Fields you set in customer override the email and name from the session.

Accessing the Customer Portal

The portal endpoints require a signed-in user with a verified email address. If the user has no Dodo Payments customer yet, the plugin finds one by email or creates one. customer.portal() returns the portal URL:

Listing Customer Data

List the signed-in customer’s subscriptions and payments. page starts at 1, and status filters the results:

Tracking Metered Usage

Enable the usage() plugin on the server to record usage events for usage-based billing and let customers see their usage. Both methods require a signed-in user with a verified email address.
  • authClient.dodopayments.usage.ingest records an event for the signed-in user.
  • authClient.dodopayments.usage.meters.list lists the signed-in customer’s usage events. It accepts page_number, page_size, event_name, meter_id, start, and end query parameters.
Dodo Payments rejects events with timestamps more than one hour in the past or more than five minutes in the future.
If you omit meter_id, the list includes all of the customer’s usage events. With meter_id, it includes only the events that match that meter.

Webhooks

The webhooks plugin verifies the signature of each Dodo Payments event and calls your handlers. The default endpoint is /api/auth/dodopayments/webhooks.
1

Generate and Set Webhook Secret

In the dashboard, go to Developer → Webhooks and add your endpoint URL, for example https://<your-domain>/api/auth/dodopayments/webhooks. Copy the endpoint’s signing secret into your .env file:
2

Handle Webhook Events

Pass a handler for each event you want to process. onPayload runs for every event:
If signature verification fails or a handler throws an error, the endpoint responds with 400. After your handlers finish, it returns { received: true }.

Supported Webhook Event Handlers

Each handler receives the verified payload for its event type:

Configuration Reference

  • client (required): DodoPayments client instance
  • createCustomerOnSignUp (optional): Create a Dodo Payments customer when a user signs up, or link an existing customer with the same email. The plugin also updates the customer when the user’s details change.
  • use (required): Array of plugins to enable (checkout, portal, usage, webhooks)
  • getCustomerParams (optional): Function that receives the Better Auth User and returns extra fields to attach to the Dodo Payments customer on creation and update (e.g. metadata, phone_number). It can be async.
  • products: Array of { productId, slug } objects, or an async function that returns one
  • successUrl: URL to redirect to after successful payment
  • authenticatedUsersOnly: Require user authentication (default: false)

Troubleshooting & Tips

  • Invalid API key: Check DODO_PAYMENTS_API_KEY in .env, and check that the key’s mode matches environment.
  • Webhook signature mismatch: Check that the webhook secret matches the one set in the Dodo Payments dashboard.
  • Customer not created: Check that createCustomerOnSignUp is set to true.
  • Portal or usage requests return 401: The user’s email address isn’t verified.
  • Use environment variables for all secrets and keys.
  • Test in test_mode before you switch to live_mode.
  • Log webhook events for debugging and auditing.

Prompt for LLMs

Copy this prompt into your AI coding assistant to have it add the adaptor to your project. To give your agent the Dodo Payments docs and skills as well, install the Agent Plugin.
Last modified on September 25, 2026