如何用 Stripe 自定义 Checkout 流程把客户与 Dub 关联并自动追踪 sale 事件
2026/9/13 23:43:24 网站建设 项目流程

如何用 Stripe 自定义 Checkout 流程把客户与 Dub 关联并自动追踪 sale 事件

【免费下载链接】dubThe modern link attribution platform. Loved by world-class marketing teams like Framer, Perplexity, Superhuman, Twilio, Buffer and more.项目地址: https://gitcode.com/GitHub_Trending/du/dub

如果你的网站没有直接使用 Stripe 托管的 Checkout 页面,而是在自己服务端调用 Stripe 的checkout.sessions.createAPI 构建自定义结账流程,那么问题来了:用户付款成功后,如何不额外手动上报、就让 Dub 知道这单来自哪次点击?Dub 的集成文档给出的方案是:在创建 checkout session 时,把你数据库中该用户的唯一 ID 以dubCustomerExternalId的形式放进 checkout session 的metadata字段,Dub 就会自动监听 Stripe 的购买事件,并把 sale 关联回用户最初点击 Dub 链接产生的 click event(也就是用户来源的那条链接)。

适用前提:

  • 你的站点使用 Stripe 的checkout.sessions.createAPI 走自定义结账流程(对应 stripe-checkout 集成文档);
  • 用户是通过 Dub 短链接进来的,即 Dub 侧存在该用户的点击记录;
  • 你的数据库中有该客户的唯一用户 ID(下文示例中为user.id)。

Dub 在背后如何完成关联

根据 stripe-checkout 文档 的说明,整个链路是:

  1. Dub 把用户记录为 customer,并与该用户来源的 click event 建立关联;
  2. 当用户完成购买时,Dub 自动把 checkout session 的明细(发票金额、币种等)关联到这个 customer,进而关联回原始 click event;
  3. 这样 Dub 就能自动追踪 sale 事件,无需你在结账成功后手动调用 track 接口。

你需要做的只有一件事:让 Dub 能认出这个 Stripe checkout session 对应的是哪个客户。

创建 checkout session 时传入 dubCustomerExternalId

在你调用stripe.checkout.sessions.create的地方,把你数据库中客户的唯一用户 ID 作为dubCustomerExternalId放进metadata。文档给出的示例如下(其中user对象、priceIdsuccess_url均为文档示例值,替换为你自己系统中的真实值;import { stripe }对应你项目中自己的 Stripe 客户端导入):

import { stripe } from "@/lib/stripe"; const user = { id: "user_123", email: "user@example.com", teamId: "team_xxxxxxxxx", }; const priceId = "price_xxxxxxxxx"; const stripeSession = await stripe.checkout.sessions.create({ customer_email: user.email, success_url: "https://app.domain.com/success", line_items: [{ price: priceId, quantity: 1 }], mode: "subscription", client_reference_id: user.teamId, metadata: { dubCustomerExternalId: user.id, // the unique user ID of the customer in your database }, });

关键点在于metadata里的dubCustomerExternalId:它必须是你在自己数据库中为客户保存的唯一 ID,Dub 会用它来定位已记录的 customer 并完成关联。

完成这一步后,当客户完成 checkout session,Dub 会自动把 checkout session 明细(发票金额、币种等)与该 customer 关联,并进一步关联到原始 click event——sale 事件随之被记录,这就是文档描述的成功结果。

替代分支:不走 checkout.sessions.create 时,在 Stripe customer 上传 metadata

如果你根本不使用 Stripe 的 checkout session 创建流程,stripe-customers 文档 给出了另一条路径:在 Stripe customer 的创建流程中同时传入用户唯一 ID 和 click event ID(dub_id)。

创建 Stripe customer 时(dub_id是 Dub 的 click event ID,文档示例中从请求头读取,请保留你项目中自己的获取方式):

import { stripe } from "@/lib/stripe"; const user = { id: "user_123", email: "user@example.com", teamId: "team_xxxxxxxxx", }; const dub_id = req.headers.get("dub_id"); await stripe.customers.create({ email: user.email, name: user.name, metadata: { dubCustomerExternalId: user.id, dubClickId: dub_id, }, });

如果 customer 已存在,也可以用 Stripe customer 更新流程补传这两个值:

import { stripe } from "@/lib/stripe"; const user = { id: "user_123", email: "user@example.com", teamId: "team_xxxxxxxxx", }; const dub_id = req.headers.get("dub_id"); await stripe.customers.update(user.id, { metadata: { dubCustomerExternalId: user.id, dubClickId: dub_id, }, });

这样当客户发生购买时,Dub 会自动把购买明细(发票金额、币种等)关联到原始 click event。

验证结果与手动补充上报

上述两条路径的成功条件都以文档描述的行为为准:客户完成结账(或发生购买)后,Dub 自动把 checkout session / 购买明细关联到 customer 与原始 click event,sale 事件被自动记录。

如果某次成交无法走自动关联,Dub 文档提供了手动上报 sale 事件的替代方式——服务端 SDK 或 REST API(见 manual-track-sale 文档)。TypeScript SDK 示例:

import { Dub } from "dub"; const dub = new Dub({ // optional, defaults to the DUB_API_KEY environment variable token: process.env.DUB_API_KEY, }); await dub.track.sale({ customerExternalId: "cus_oFUYbZYqHFR0knk0MjsMC6b0", amount: 3000, // sale amount in cents currency: "usd", paymentProcessor: "stripe", eventName: "Invoice paid", invoiceId: "INV_1234567890", });

等价的 REST API 调用(dub_xxxxxx需替换为你的 Dub API key,金额单位为分;请求体字段见 rest-api 文档 的鉴权说明):

const response = await fetch("https://api.dub.co/track/sale", { method: "POST", headers: { Authorization: "Bearer dub_xxxxxx", "Content-Type": "application/json", }, body: JSON.stringify({ customerExternalId: "cus_oFUYbZYqHFR0knk0MjsMC6b0", amount: 3000, // sale amount in cents paymentProcessor: "stripe", eventName: "Invoice paid", invoiceId: "INV_1234567890", currency: "usd", }), }); const data = await response.json();

手动上报时注意customerExternalId要与你在 Dub 侧记录的 customer 标识一致,事件数据(金额、币种、发票 ID)取自本次真实成交。

边界说明

  • 本文主路径对应的是“自建结账流程 +checkout.sessions.create”的场景。如果你用的是 Stripe Payment Links 或 Pricing Tables,Dub 的接入方式不同(通过client_reference_id等参数传递 click ID),参见 stripe-payment-links 文档,不适用于本文的metadata做法;
  • dubCustomerExternalId必须是你数据库中客户的唯一 ID,Dub 依据它把 Stripe 事件归到已记录的 customer 上;
  • 事件明细(金额、币种)来自 checkout session 本身,Dub 自动完成关联,无需你在服务端重复解析 Stripe 事件。

【免费下载链接】dubThe modern link attribution platform. Loved by world-class marketing teams like Framer, Perplexity, Superhuman, Twilio, Buffer and more.项目地址: https://gitcode.com/GitHub_Trending/du/dub

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询