紹介プログラムとアフィリエイト報酬を設定する
紹介機能がプロダクトに合うか判断し、帰属と報酬を設定し、運用上の不足を補って全体をテストします。
このページを終えると、紹介機能を無効のままにするか、同梱された基盤を実運用できる制度に育てるかを判断できます。安全な既定値は無効です。AffiliateConfig.enabled は false です。有効にすると、コードだけでは解決できない金銭面・サポート面の責任が生じます。
同梱されるもの
| 動作 | 既定値 |
|---|---|
| 有効化 | src/config/affiliate.ts のコードフラグ。環境変数スイッチはない |
| 紹介リンク | /i/{code} とロケール付き /[locale]/i/{code}。生成 URL は現在、接頭辞なしルートを使う |
| 帰属 | 最初に開いた紹介リンクへ帰属、30日間の ref Cookie、自己紹介は禁止 |
| 登録時の取得 | 認証後にクライアントが保存を試みる。失敗時はセッションに完了印を残さないため、後でコンポーネントが再度読み込まれたときに再試行できる |
| 登録報酬 | 0。行は帰属だけを記録し、支払いはない |
| 購入報酬 | 5,000 最小通貨単位と注文額の 20% の大きい方 |
| 報酬状態 | 手動確認・支払い用の pending の現金記録。金銭やクレジットは自動では移動しない |
| ユーザー画面 | 認証必須の /[locale]/my-invites。無効時は 404 |
| 運用画面 | 管理コンソールの読み取り専用 /affiliates テーブル |
データベース制約により、登録時の帰属処理と注文報酬の作成は安全に再実行できます。二つのタブが競合しても、最初の紹介リンクへの帰属が優先されます。支払いイベントを再送しても、同じ注文に報酬が重複することはありません。注文処理では pending の報酬を取り消せます。
プログラムが適するか決める
次の問いに答えるまでは無効を保つことをおすすめします。
- 誰が紹介できるか:全認証ユーザー、承認パートナー、特定グループのどれか。
- 何を成果とするか:登録、初回購入、全注文、返金期間後の確定売上のどれか。
- 固定の最小通貨単位は何の通貨か。複数通貨をどう扱うか。
- 不正、同一人物、返金、税務書類、支払い紛争を誰が確認するか。
pendingをいつ、どのようにapproved、paid、canceled、clawed_backへ変えるか。- 公開するプログラム規約で何を約束するか。
同梱コードは、ユーザーの is_affiliate フィールドを使ってリンク生成を制限しません。有効にすると、ページまたは API を利用できる認証済みユーザーは誰でもコードを作れます。全員向けの制度でない場合は、本番公開前にサーバー側の参加資格確認を追加してください。
コードで方針を設定する
src/config/affiliate.ts の AffiliateConfig をすべて確認します。
export const AffiliateConfig = {
enabled: true,
attributionWindowDays: 30,
allowSelfReferral: false,
attributionModel: AttributionModel.FirstTouch,
payoutType: "cash",
commissionMode: CommissionMode.GreaterOf,
paid: { fixed: 5_000, percent: 20 },
// ...
} as const;FixedOnly、PercentOnly、GreaterOf、Sum は実装済みです。固定値は通貨の最小単位で指定し、同梱 UI は米ドルのセントを想定しています。FirstTouch は維持してください。列挙値には LastTouch もありますが、現行サービスは invited_by が空のときだけ書き込むため、列挙値を変えるだけでは最後に開いたリンクへの帰属にはなりません。
同様に payoutType: "credits" は、決定的な台帳付与を実装する導入者向けに予約された値です。現行の処理は現金相当額を記録するだけで、実際の価値は移動しません。付与処理を実装して再実行テストを行うまでは、表示上の名前だけを変えないでください。
顧客体験と運用を完成させる
言語コード付きのルートはありますが、My Invites ページとコンポーネントの文言は英語で固定され、報酬は米ドル表示です。メインナビゲーションにもリンクがありません。本番公開前に次を行います。
- 翻訳、通貨に応じた表示、空の状態とエラー状態、見つけやすいアカウント内リンクを追加する。
- 共有 URL に言語を残すか決める。現在 API は
/i/{code}を返す。 - サーバー側の紹介資格、プログラム規約、不正対策を追加する。
- 監査可能な承認・支払い処理を作る。管理画面は閲覧のみで、支払いや完了操作はできない。
- 支払いフローの返金、キャンセル、取り戻し方針を定義する。
エンドツーエンドで検証する
まず無効時を確認します。紹介リンクは通常どおりリダイレクトし、My Invites は 404、紹介 API は not found を返す必要があります。
次にテスト環境で有効にし、使い捨てアカウントを使います。
- 紹介者としてリンクを生成する。
- 新しいブラウザで開き、
refCookie が 30 日であることを確認する。 - 紹介された側として登録またはログインし、
invited_byと登録帰属行が一件だけ作られることを確認する。 - 別の紹介リンクを開いても最初の帰属が変わらず、自己紹介が無視されることを確認する。
- 注文を完了し、
max(5,000, floor(注文額 × 20%))のpending行が一件あることを確認する。 - 支払いイベントを再送し、重複がないことを確認する。方針どおりのキャンセル・返金も試す。
- ユーザー集計と管理画面の表が一致し、自動支払いは発生しないことを確認する。
- 一時的な取得失敗を再現し、後の再マウントまたは完全な再読み込みで再試行に成功することを確認する。
本番公開前にサービスとデータベースのテストを実行してください。紹介制度は支払いの正確さと運用上の確認に依存するため、Stripe 課金と管理コンソールの運用も確認します。制度を導入すべきか判断する段階なら、先に紹介プログラムを追加すべきかを読んでください。
まだ完成していないもの
自動支払い、クレジット付与、パートナー承認、不正審査、税務対応、完全に翻訳された UI、複数通貨モデル、ナビゲーションリンク、最後に開いたリンクへの帰属処理はありません。スターターは再実行に強い帰属・会計記録を提供し、制度の方針と運用は導入するチームが完成させます。
ソーススナップショット
スターターのコミット 7580470 で確認済みです。