Dub conversion tracking:lead・sale APIとStripeの顧客対応
このトピックを深掘りする
SaaSの導入・連携
AIに仕事の続きを渡すために、会議の原文、未完了の宿題、確認できない項目をどう残すか。導入判断と連携実装を掘り下げる。
全5本中 2 本目。
次に読む記事
Slackのhuddleを録り、毎晩22時にAIへ渡す:Circlebackの設定6か所
AIに仕事の続きを渡すためのCircleback運用記録。Slack huddle、22時の同期、元の発言と未完了ToDo、採用する条件を具体化。運用経験・公式仕様・ローカル試験の根拠も示す。
Circlebackの会議アクションをタスクへ渡す:Webhookの署名・担当者・重複処理を検証
CirclebackのWebhookからToDoを保存するコードを検証。署名・担当者なしに加え、SQLiteの重複防止、古い再送で完了状態が戻る条件、保存先の状態を別に保存してDONEを保つ方法を合成データで確かめた。
Dubの紹介リンクを日英で計測する:UTM生成で紹介IDを壊さない実装と検証
紹介リンクへUTMを足すと、既存の値が同じでもURL表記が変わる。空白とチルダの再現コード、署名付きURLへ適用する限界、クリックと確定報酬の区別をまとめた。
シリーズ全体の流れを見ながら、次に読む記事へ進めます。 初めての方はホームへ →
紹介リンクのクリックが増えても、その先の登録や購入まで分かるとは限らない。Dub conversion trackingでは、クリックIDと自社の顧客IDをleadで結び、購入時のsaleへ同じ顧客IDを渡す。既存の日英UTMの生成と検証から、登録・売上の計測へ進むための実装ガイドだ。
2026年10月21日に公式ガイド・API・Stripe連携資料を確認した。手元で実行したのは合成入力から送信前のJSONを作る例だけで、Dub APIへの送信、実売上の帰属、Stripe接続、紹介料の確定は未検証。Dubは公式サイトへリンクし、未参加の紹介リンクは使っていない。
利用条件と、先に確認する設定
サーバー側の公式ガイドはBusiness以上を条件にしている。まず対象リンクのConversion Trackingを有効にする。workspaceのTracking設定は将来作るリンクに適用され、既存の特定リンクはLink Builderから切り替える。APIで作成・更新するなら trackConversion: true を指定する。Dub Partnersのリンクは既定で有効だ。
次にDub Analytics scriptを導入する。公式の構成では到着URLの dub_id をfirst-party cookieへ保存し、サーバーで登録時に読む。UTMは流入の分類、dub_id はクリックとの対応に使う値なので、UTMや記事slugから架空のクリックIDを作らない。自社の登録処理と決済処理を変更できる人向けの手順であり、他社の紹介リンクを掲載するだけで購入イベントを送れるという意味ではない。
登録時にleadで顧客IDを対応させる
lead APIの必須項目は clickId、eventName、customerExternalId。登録が完了した時点で、cookieのクリックIDと自社データベースの顧客IDを渡す。Node SDKなら dub.track.lead(body)、RESTなら POST https://api.dub.co/track/lead に相当する。次は送信するJSONの例で、実行用APIクライアントは後述のサンプルに含めない。
{
"clickId": "synthetic_click_001",
"eventName": "Sign up",
"customerExternalId": "demo_user_001",
"mode": "wait"
}mode: "wait" はleadの記録完了まで待つ設定だ。後続のsaleをすぐ送る構成では、順序と応答を確認してから進める。公式資料では同じ customerExternalId と eventName のleadを再送しても、最初のイベントだけを記録し、重複は null を返す。成功した通信回数と新規lead件数を同一視しない。
クリックIDが見つからない場合、この例は missing-click-id として送信計画を空にする。公式にはdeferred leadやdirect saleの別経路もあるが、この例は既にクリックIDがある登録から購入までに絞る。欠落を別のIDや0で埋めず、cookie、登録処理への受け渡し、対象リンクを確認する。
購入時にsaleを送る:USDとJPYの単位
sale APIでは customerExternalId と amount が必須。通常のlead後の構成では同じ自社顧客IDで購入を対応させる。leadEventName を指定すれば特定のleadへ結び、大文字小文字も区別される。ここでは Sign up にそろえた。
{
"customerExternalId": "demo_user_001",
"amount": 1999,
"currency": "usd",
"eventName": "Invoice paid",
"invoiceId": "demo_invoice_001",
"leadEventName": "Sign up",
"paymentProcessor": "custom"
}USDの19.99ドルは 1999、JPYの1580円は 1580 を渡す。公式仕様は小数2桁の通貨をcents、小数0桁の通貨を整数の金額として扱う。すべての通貨を100倍する変換は避ける。金額は決済側の確定した値から取り、ブラウザの任意入力を売上として採用しない。
invoiceId は同じ請求の重複防止に使える。再試行のたびに新しいIDを作ると同じ請求を示せないため、決済側の安定したIDを使う。これは公式の契約であり、今回のローカル例がDubの重複排除を確認したわけではない。例は送信も保存もせず、同じ入力から同じJSONができることだけを確かめる。
Stripeを使う場合は公式連携の顧客対応を確認する
DubのStripe連携ガイドはBusiness以上で、Stripe AppのインストールとDub workspaceへの接続を前提にしている。Checkoutの例ではleadに使った自社顧客IDをSessionの metadata.dubCustomerExternalId へ渡す。client_reference_id へ同じ値を入れると読み替えない。公式例はそこに teamId を置いている。
// 既存のCheckout Session作成処理へ渡すmetadataの例
const metadata = { dubCustomerExternalId: user.id }公式連携は invoice.paid などのイベントを受け取る。guest checkoutで customer が null になる場合はsaleを記録できず、customer_creation: "always" を指定するよう案内されている。連携を採用する場合は、同じ決済を手動saleでも二重送信しない設計にする。この記事はStripeの支払い処理やWebhook受信を実装しない。実接続の確認は公式が案内するStripe sandboxとDub staging workspaceなど、承認済みの検証環境で別途行う。
資格情報なしで送信前のJSONを再現する
実行例 dub-conversion-demo.mjsを保存し、BunまたはNode.js 22以降で実行する。依存パッケージやAPIキーは不要で、ネットワーク通信もファイル保存もしない。
bun dub-conversion-demo.mjs
# または
node dub-conversion-demo.mjs出力の usd.requests はlead、saleの順のJSON、jpy.requests は金額1580のJPY例になる。missingClick は status: "skipped"、空の requests、networkRequests: 0 を返す。USDとJPYだけを許可し、負数・小数・安全整数の上限を超えた金額、空の顧客ID・請求IDを拒否する。0は受け付ける。これらはサンプル固有の入力検査で、Dubの全機能や全通貨の対応範囲を表さない。
本番用の送信処理では既存の承認済み認証をサーバーで扱い、APIの応答とエラーを確認する。サンプルの networkRequests: 0 は送信成功数ではない。以前の共通デモはCirclebackとUTMの検証用で、本稿の実行には不要だ。
公開後に見る値を分ける
記事閲覧、紹介クリック、lead、sale、確定報酬は別々に記録する。JSONができたことを計測成功や売上実績と扱わない。対象リンクから登録・購入までの承認済み試験ができたら、顧客ID、請求ID、金額単位、再送時の結果を照合する。
URL生成で既存の紹介IDを保つ検証はDubのUTM記事、会議からタスクへ渡す実装はCircleback Webhook記事にまとめている。
よくある質問
Dub conversion trackingに必要なプランは?
2026年10月21日に確認した公式ガイドではBusiness以上です。リンクのconversion trackingを有効にし、Dub Analyticsでdub_idを保存して、サーバーからlead・saleを送る構成です。申込みや実接続は今回検証していません。
clickIdとcustomerExternalIdには何を入れますか?
clickIdはDubが発行したクリックIDで、通常はdub_id cookieから読みます。customerExternalIdは自社データベースの顧客IDです。UTMや記事slugをクリックIDの代わりに作らず、登録と購入で同じ顧客IDを使います。
saleのamountは円でも100倍しますか?
公式APIではUSDなど小数2桁の通貨はcents、JPYなど小数0桁の通貨は整数の金額です。19.99 USDは1999、1580 JPYは1580を渡します。サンプルはusdとjpyだけを受け付けます。
同じleadやsaleを再送するとどうなりますか?
公式資料ではleadはcustomerExternalIdとeventNameの組合せで重複を排除し、重複した要求はnullを返します。saleには同じ請求を示すinvoiceIdを渡し、請求ごとに安定した値を使います。今回Dubのサーバー上の重複排除は未検証です。
Stripe Checkoutではどの値で顧客を対応させますか?
Dubの公式Stripe連携ではCheckout Sessionのmetadata.dubCustomerExternalIdへleadと同じ自社顧客IDを渡します。連携のインストールと接続が前提です。guest checkoutでcustomerがnullになる場合はcustomer_creation: alwaysを設定するよう案内されています。今回Stripe接続は検証していません。
よくある質問
- Q. Dub conversion trackingに必要なプランは?
- 2026年10月21日に確認した公式ガイドではBusiness以上です。リンクのconversion trackingを有効にし、Dub Analyticsでdub_idを保存して、サーバーからlead・saleを送る構成です。申込みや実接続は今回検証していません。
- Q. clickIdとcustomerExternalIdには何を入れますか?
- clickIdはDubが発行したクリックIDで、通常はdub_id cookieから読みます。customerExternalIdは自社データベースの顧客IDです。UTMや記事slugをクリックIDの代わりに作らず、登録と購入で同じ顧客IDを使います。
- Q. saleのamountは円でも100倍しますか?
- 公式APIではUSDなど小数2桁の通貨はcents、JPYなど小数0桁の通貨は整数の金額です。19.99 USDは1999、1580 JPYは1580を渡します。サンプルはusdとjpyだけを受け付けます。
- Q. 同じleadやsaleを再送するとどうなりますか?
- 公式資料ではleadはcustomerExternalIdとeventNameの組合せで重複を排除し、重複した要求はnullを返します。saleには同じ請求を示すinvoiceIdを渡し、請求ごとに安定した値を使います。今回Dubのサーバー上の重複排除は未検証です。
- Q. Stripe Checkoutではどの値で顧客を対応させますか?
- Dubの公式Stripe連携ではCheckout Sessionのmetadata.dubCustomerExternalIdへleadと同じ自社顧客IDを渡します。連携のインストールと接続が前提です。guest checkoutでcustomerがnullになる場合はcustomer_creation: alwaysを設定するよう案内されています。今回Stripe接続は検証していません。