Dodo 支付
Dodo Payments 是一个全球性的商户记录平台,允许 AI、SaaS 和数字业务在 150 多个国家销售产品,而无需处理税务、欺诈或合规问题。一个面向开发者的单一 API 支持结账、计费和支付,让你几分钟内即可全球上线。
此插件由 Dodo Payments 团队维护。如遇到漏洞、问题或功能请求,请访问 Dodo Payments GitHub 仓库。
Get support on Dodo Payments' Discord
有疑问吗?我们的团队随时在 Discord 上为你提供帮助。
特性
【Features】
- 注册时自动创建客户
- 具有产品别名映射的类型安全结账流程
- 自助客户门户
- 计量使用摄取和近期使用报告
- 带签名验证的实时 Webhook 事件处理
Get started with Dodo Payments
你需要一个 Dodo Payments 账户和 API 密钥才能使用此集成。
安装
【Installation】
在你的项目根目录运行以下命令:
npm install @dodopayments/better-auth dodopayments better-auth zod将这些添加到你的 .env 文件中:
DODO_PAYMENTS_API_KEY=your_api_key_here
DODO_PAYMENTS_WEBHOOK_SECRET=your_webhook_secret_here创建或更新 src/lib/auth.ts:
import { betterAuth } from "better-auth";
import {
dodopayments,
checkout,
portal,
webhooks,
usage,
} from "@dodopayments/better-auth";
import DodoPayments from "dodopayments";
export const dodoPayments = new DodoPayments({
bearerToken: process.env.DODO_PAYMENTS_API_KEY!,
environment: "test_mode"
});
export const auth = betterAuth({
plugins: [
dodopayments({
client: dodoPayments,
createCustomerOnSignUp: true,
use: [
checkout({
products: [
{
productId: "pdt_xxxxxxxxxxxxxxxxxxxxx",
slug: "premium-plan",
},
],
successUrl: "/dashboard/success",
authenticatedUsersOnly: true,
}),
portal(),
webhooks({
webhookKey: process.env.DODO_PAYMENTS_WEBHOOK_SECRET!,
onPayload: async (payload) => {
console.log("Received webhook:", payload.event_type);
},
}),
usage(),
],
}),
],
});Set environment to live_mode for production.
创建或更新 src/lib/auth-client.ts:
import { dodopaymentsClient } from "@dodopayments/better-auth";
export const authClient = createAuthClient({
baseURL: process.env.BETTER_AUTH_URL || "http://localhost:3000",
plugins: [dodopaymentsClient()],
});用法
【Usage】
创建结账会话(首选)
【Creating a Checkout Session (preferred)】
对于新的集成,请使用 authClient.dodopayments.checkoutSession。
它与 Dodo Payments 的创建结账会话 API 一一对应,并支持你在服务器上配置的产品别名。
使用已配置的 slug
【Using a configured slug】
const { data: session, error } = await authClient.dodopayments.checkoutSession({
slug: "premium-plan",
referenceId: "order_123",
});
if (session) {
window.location.href = session.url;
}使用产品购物车
【Using a product cart】
const { data: session, error } = await authClient.dodopayments.checkoutSession({
product_cart: [
{
product_id: "pdt_xxxxxxxxxxxxxxxxxxxxx",
quantity: 1,
},
],
referenceId: "order_123",
});
if (session) {
window.location.href = session.url;
}结账会话会自动从客户的 Better Auth 会话中获取客户的电子邮件和名称。必要时,可通过在请求正文中传递 customer 或 billing 来覆盖它们(或提前提供账单信息)。
重定向 URL 来自服务器端结账插件中配置的 successUrl,因此你无需从客户端发送 return_url。
旧版结账(已弃用)
【Legacy Checkout (deprecated)】
authClient.dodopayments.checkout 辅助函数仅保留用于向后兼容。新项目建议使用 checkoutSession。
const { data: checkout, error } = await authClient.dodopayments.checkout({
slug: "premium-plan",
customer: {
email: "customer@example.com",
name: "John Doe",
},
billing: {
city: "San Francisco",
country: "US",
state: "CA",
street: "123 Market St",
zipcode: "94103",
},
referenceId: "order_123",
});
if (checkout) {
window.location.href = checkout.url;
}访问客户门户
【Accessing the Customer Portal】
const { data: customerPortal, error } = await authClient.dodopayments.customer.portal();
if (customerPortal && customerPortal.redirect) {
window.location.href = customerPortal.url;
}列出客户数据
【Listing Customer Data】
// Get subscriptions
const { data: subscriptions, error } =
await authClient.dodopayments.customer.subscriptions.list({
query: {
limit: 10,
page: 1,
active: true,
},
});
// Get payment history
const { data: payments, error } = await authClient.dodopayments.customer.payments.list({
query: {
limit: 10,
page: 1,
status: "succeeded",
},
});追踪计量使用
【Tracking Metered Usage】
启用 usage() 插件(在服务器设置中显示)以获取已登录且邮箱已验证的客户的计量事件,并显示最近的使用记录。
const { error: ingestError } = await authClient.dodopayments.usage.ingest({
event_id: crypto.randomUUID(),
event_name: "api_request",
metadata: {
route: "/reports",
method: "GET",
},
timestamp: new Date(),
});
if (ingestError) {
console.error("Failed to record usage", ingestError);
}
const { data: usage, error: usageError } =
await authClient.dodopayments.usage.meters.list({
query: {
page_size: 20,
meter_id: "mtr_yourMeterId",
},
});
if (usage?.items) {
usage.items.forEach((event) => {
console.log(event.event_name, event.timestamp, event.metadata);
});
}使用时间戳超过一小时前或超过未来五分钟的将被拒绝。
省略meter_id以返回与客户的所有有效订阅相关的所有计量器。
Webhooks
Webhooks 插件通过安全的签名验证处理来自 Dodo Payments 的实时支付事件。默认端点是 /api/auth/dodopayments/webhooks。
在 Dodo Payments 控制面板中为你的端点 URL(例如 https://your-domain.com/api/auth/dodopayments/webhooks)生成一个 webhook 密钥,并将其设置在你的 .env 文件中:
DODO_PAYMENTS_WEBHOOK_SECRET=your_webhook_secret_here示例处理程序:
webhooks({
webhookKey: process.env.DODO_PAYMENTS_WEBHOOK_SECRET!,
onPayload: async (payload) => {
console.log("Received webhook:", payload.event_type);
},
});配置参考
【Configuration Reference】
插件选项
【Plugin Options】
- client(必填):DodoPayments 客户端实例
- createCustomerOnSignUp(可选):在用户注册时自动创建客户
- use(必填):要启用的插件数组(checkout、portal、usage、webhooks)
结账插件选项
【Checkout Plugin Options】
- 产品:产品数组或返回产品的异步函数
- successUrl:支付成功后重定向的 URL
- 仅限经过身份验证的用户:要求用户身份验证(默认值:false)
如果你遇到任何问题,请参阅 Dodo Payments 文档 获取故障排除步骤。
【If you encounter any issues, please refer to the Dodo Payments documentation for troubleshooting steps.】