アフィリエイトを追跡し、コミッションを計算し、支払いを承認・実行し、不正を防止するWebアプリを作るステップバイステップ案。MVP範囲とローンチのコツ付き。

fx_rate、tax_withheld_amount、tax_region のようなフィールドを検討してください。これにより支払い自動化やレポートの拡張が容易になります。\n\n最後に監査ログテーブルを追加します:actor_type(admin/affiliate/system)、actor_id、entity_type、entity_id、action、before、after、created_at。コミッションが approved から reversed に変わったとき、誰が何をいつ変更したかが分かるようにします。\n\n## 主要画面とワークフローを設計する\n\nコードを書く前に画面と各役割の「ハッピーパス」をスケッチしてください。アフィリエイトプログラムは機能不足で失敗するよりも、混乱したワークフローで失敗することが多いです。各ページは「次に何ができるか」と「現在のステータスは何か」を明確に答える設計を目指します。\n\n### アフィリエイトポータル(パートナー体験)\n\nパートナーポータルは、数分でプロモートを開始できることが目標です。\n\n主要画面:\n\n- サインアップ/ログイン: メール確認と基本プロフィール(税/支払い情報は後から追加可)。\n- トラッキングリンク取得: オファーを選び、リンクを生成してコピー、クリエイティブをダウンロード可能に。\n- パフォーマンスダッシュボード: クリック、コンバージョン、保留/承認済みコミッション、最近のアクティビティ。\n- 支払い履歴: 支払いバッチ、金額、支払い方法、支払いステータス(scheduled/paid/failed)\n\nデザインチップ:コミッションが“保留”である理由(例:「返金ウィンドウ待ち」)と予想承認日を常に表示してください。\n\n### 管理コンソール(プログラム運用)\n\n管理者はスピードとコントロールを必要とします。\n\nコアワークフロー:\n\n- アフィリエイト管理: 承認/却下、ステータス設定、条件調整、内部メモの記入。\n- オファー定義: 支払いルール、許可トラフィック、上限、クリエイティブ。\n- コンバージョンレビュー: コンバージョンを承認、却下、調査フラグできるキュー。\n\n大量処理(例:50件の承認、一括で複数アフィリエイトを一時停止)を用意すると運用が楽になります。\n\n### 財務ワークフロー(資金の安全な出金)\n\n財務画面は繰り返し可能な支払いサイクルをサポートする必要があります:\n\n- 支払いバッチ作成: 日付範囲と「承認済み・未払い」コミッションでフィルタ。\n- 支払いエクスポート: CSV出力か、支払いプロバイダへ送信。\n- 支払済みマーキング: 参照IDを付与、部分支払いの対応、失敗時のリトライ。\n- 返金/チャージバック: コミッションを差し戻し、既に支払われていれば次回サイクルで負の調整を作成。\n\n### サポートワークフロー(信頼と紛争処理)\n\n軽量なケースビューを構築します:アフィリエイト+コンバージョン+クリックトレイル(可能な範囲で)を表示し、メモ、添付、紛争ステータスを付けられるように。目的はツール間を探し回らずに迅速に解決することです。\n\n## トラッキング実装:リンク、ピクセル、サーバーイベント\n\nトラッキングはアフィリエイトプログラムの基盤です。クリックを購入に確実に結びつけられなければ、下流のコミッションや支払い、レポートがノイズだらけになり、紛争が増えます。\n\n### トラッキング手法を選ぶ\n\n多くのプログラムは次を組み合わせます:\n\n- パラメータ付きリファーラルリンク(例:?aff_id=123\u0026campaign=spring)。導入が簡単でコンテンツ系に向く。\n- プロモコード(例:ALICE10)。インフルエンサーやオフラインでの共有に有用で、リンクパラメータが失われたときのバックアップになる。\n- ポストバック/Webhook(サーバー間コールバック)。精度が高く、特に有料流入やパートナー側で独自のレポートが必要な場合に最適。\n\n### トラッキングがどこで動くかを決める\n\n通常、次から選択します:\n\n- クライアント側ピクセル: サンクスページ上のスクリプトでコンバージョンを報告。実装は早いがブロックされる可能性がある。\n- サーバー間イベント: バックエンドで直接コンバージョンを記録し、Webhookでパートナーに通知。より信頼性が高い。\n- 両方: マーケティングツール用にピクセルを置き、サーバーイベントを真実のソースにする組み合わせが理想。\n\n### 実運用のエッジケースを扱う\n\n「見えないコンバージョン」チケットを減らすために準備しておくべきこと:\n\n- 広告ブロッカー/ブラウザのプライバシー: ファーストパーティクッキーとサーバーイベントを優先する。\n- 複数デバイス: ユーザーログイン時にアカウントベースのアトリビューションを使う(クッキーだけに頼らない)。\n- パラメータ欠落: プロモコードでの帰属や、サーバー側に保存した最後のリファラーにフォールバック。\n- 二重計上: コミッション作成前に order_id(および必要なら event_id)で重複除外する。\n\n### エンドツーエンドのイベントフローを文書化する\n\nプロダクト、エンジニアリング、パートナー間で共有する契約(フロー)を書いてください:\n\ntext\nClick (affiliate link) -\u003e Store attribution (cookie + user/profile) -\u003e\nConversion (order created) -\u003e Validate/dedupe -\u003e Create commission -\u003e\nNotify partner (optional webhook) -\u003e Appear in partner portal\n\n\nこのドキュメントがデバッグ、パートナーサポート、将来の統合の参照になります。\n\n## コミッション計算エンジンを構築する\n\nコミッションエンジンはトラッキングデータを「お金」に変える“真実のソース”です。会計のように扱い、決定的なルール、明確なステータス、完全な監査トレイルを備えてください。\n\n### 明確な計算パイプラインを使う\n\n「起きたこと」と「支払うべきこと」を分離します。実用的なパイプライン例:\n\n- Raw events(生イベント): クリック、リード、購入、返金など。\n- Eligible(適格): ルールにマッチしたイベント(正しいプログラム、クッキールックバック内、除外商品でない等)。\n- Approved(承認): レビュー/保留期間を通過したイベント。\n- Payable(支払い対象): 承認済みで未払い、支払い可能なアフィリエイトに属する項目。\n\n各ステップを明示的に保存しておくと、サポートチームは「なぜ支払われなかったのか?」に推測なしで答えられます。\n\n### 調整を第一級市民として扱う\n\n実運用では訂正が必要になります。次をサポートしてください:\n\n- 手動ボーナス(例:「四半期プロモで+ $50」)\n- ペナルティ(ポリシー違反や返却等)\n- 巻き戻し(Reversals)(以前承認されたコミッションの取り消し)\n\n可能ならこれらを元のコンバージョンにリンクされた別の台帳エントリとして扱い、履歴を直接編集しないことが一貫性と監査性を保ちます。\n\n### 二重計上を防ぐための冪等性\n\nトラッキングは同じコンバージョンを再送することがあります。要求されるもの:\n\n- 一意のコンバージョンID(通常はマーチャントの注文ID+行アイテムID)\n- 受信イベントごとの冪等キー、再送されても重複作成されないようにする\n\nデータベースレベルで一意性を強制し、拒否された重複はトラブルシューティング用にログに残します。\n\n### 丸めと返金の挙動を定義する\n\n次を決めて文書化します:\n\n- 丸めルール: 行ごと、注文ごと、支払いバッチごとなどどの単位で丸めるか(四捨五入ルールも含む)。\n- 部分返金: 例えば注文の30%が返金された場合、コミッションの30%を差し戻すか(推奨)/次回支払いで負の調整を作るか。\n\nこれらのルールをコードとパートナーポータルのUIに組み込み、エクスポートや請求書と一貫した数値を表示してください。\n\n## 支払い:スケジュール、バッチ、支払い方法\n\n支払いはパートナーにとって“現実”になる瞬間です。予測可能で監査可能、サポートしやすい体験にしてください。v1はシンプルに始め、後で支払い方法や制御を追加できるよう設計します。\n\n### 支払いサイクルとリリースルールを定義する\n\n支払い頻度(週次か月次)を決め、次の2つのガードレールを設けます:\n\n- 最低支払額(例:$50)\n- ホールド期間(例:14〜30日)— 返金やチャージバック、遅延アトリビューションに備える\n\nこれらのルールはパートナーポータルで見えるようにして、なぜコンバージョンが「承認済みだが支払い対象でないのか」を説明できるようにします。\n\n### v1で使う支払いレールを選ぶ\n\n初期リリースでは運用が簡単な手段を選びます:\n\n- 手動銀行振込: システムが金額と支払いリストを生成し、財務が別途支払う方式。\n- PayPal: 小口のアフィリエイトに一般的。本人確認や手数料対応が必要。\n\nどちらを選んでも、手数料と通貨制約を明確にモデル化してください。v1は単一通貨でも、支払いレベルで通貨を保存しておくと移行が楽になります。\n\n### 支払いバッチをワークフローとしてモデル化する\n\n支払いは次のステータスでバッチとして扱います:\n\ndraft → approved → processing → completed\n\n「draft」はシステムが支払い対象を集計する段階。「approved」は人間のチェックポイント。「processing」は支払いを開始した段階(または財務へ指示を出した段階)。「completed」は合計が固定されタイムスタンプ付きでロックされます。\n\n### 信頼できるエクスポートと受領書\n\n次を提供してください:\n\n- 内部会計や照合用のCSVエクスポート\n- パートナーポータル内の支払い受領書:バッチID、対象期間、行アイテム、調整、支払い参照これによりサポートチケットが減り、アフィリエイトはコミッション管理が一貫していると信頼できます。\n\n## セキュリティ、権限、機密データの扱い\n\nアフィリエイトプラットフォームはお金、身元、パフォーマンスデータを扱います。セキュリティは単なる付加機能ではなく、明確なルールと妥当なデフォルト、厳格なアクセス制御を持つ製品機能として扱ってください。\n\n### 必要なものだけを収集する\n\n最初は運用に必要な最低限のデータから始めます:\n\n- 法人情報(正式名称、税ステータス)\n- 支払い情報(銀行/PayPalの詳細)\n- アカウント回復や支払い通知用の連絡メール\n\nドキュメント、住所、電話番号などはコンプライアンス上で本当に必要な場合以外は収集を避けてください。データが少なければリスクもサポートコストも減ります。\n\n### 機密データを安全に保管する\n\n支払いに関連するものは高機密扱いにしてください:\n\n- 機密フィールドは保存時に暗号化する(ディスク暗号だけでなくフィールド暗号)\n- APIキーやWebhookシークレットは専用のシークレットマネージャーを使う\n- 可能ならトークン化を優先(生の銀行情報の代わりに支払いプロバイダのトークンを保存)\n- 機密レコードへのアクセスはログに残し、変更履歴(誰が何をいつ変更したか)を保存する\n\nまた、分析エクスポートに支払い詳細が混入しないよう、「パフォーマンスレポート」と「財務オペレーション」を分離してください。\n\n### 権限:誰が何を見られるか・できるか\n\nロールベースのアクセス制御で、チームが生産的かつ情報過剰にならないようにします。実用的な分離:\n\n- プログラム設定、ユーザー管理、統合設定\n- 支払い方法、支払い承認、エクスポート、支払い実行\n- アフィリエイトプロファイルとステータスの閲覧(支払い詳細は不可)\n\nすべての機密アクションに対して(UIだけでなく)権限チェックを入れ、デフォルトは最小権限にします。\n\n### 将来的な強化オプション\n\nコアが安定したら強化を追加:\n\n- 管理者および財務ロール向けの\n- 内部スタッフ向けの\n- 財務ツールや承認画面向けの\n\nこれらはアカウント乗っ取りリスクを下げ、監査を容易にします。\n\n## 不正防止と品質管理\n\n不正対策は最初から組み込むべきです。目的はパートナーを非難することではなく、支払いを守り、パフォーマンスデータの信頼性を保ち、承認を予測可能にすることです。\n\n### シンプルで高シグナルなチェックから始める\n\nいくつかの基本シグナルで多くの不正を検知できます:\n\n- 共有銀行情報、税ID、支払いメール、署名デバイスフィンガープリント、同一IPレンジなど。\n- 一人のパートナーからの突然の大量発生、高すぎるコンバージョン率、同一タイムスタンプの繰り返し。\n- アフィリエイトのクリックが同一メール/ドメイン/IP/デバイス/支払い手段でコンバージョンしている場合。\n\n閾値はプログラムごとに設定可能にしてください(新規パートナーは履歴がないため厳しくするなど)。\n\n### 「フラグ→レビュー」アプローチを採る\n\nイベントを即時に却下する代わりに、に入れてフラグを立てます。ルール発動時にレビューが必要なイベントは「なぜフラグされたか」「証拠(タイムスタンプ、IP、注文ID)」と現在のステータス(Pending/Approved/Rejected)が見えるようにしてください。これにより誤検知を減らし、判断に根拠を持たせられます。\n\n### トラッキングエンドポイントをレート制限&強化する\n\nトラッキングは偽トラフィックの標的になります。次を追加してください:\n\n- IP/パートナー/ユーザーエージェントごとの\n- (基本的なヒューリスティクス+許可/拒否リスト)\n- や短寿命トークン(センシティブなキャンペーン向け)\n- ルールで前のクリックとマッチすることが要件なら、それを検証する\n\n### 判断を説明可能に保つ\n\n紛争は起こります。保留や拒否の「理由(why)」を保存してください(ルール名、閾値、関連データ)。パートナーポータルに短い理由を表示することで、サポートの議論を減らし、誠実なパートナーが問題を早く修正できるようにします。\n\n## 意味のあるレポーティングと分析\n\nレポーティングはアフィリエイトプログラムの信頼を生む場所です。アフィリエイトは「何が起きたか」を知りたがり、管理者は「次に何をすべきか」を知りたがります。双方に答える小さな指標セットから始めてください。\n\n### 必須の指標\n\n最低限表示すべきもの:\n\n- とユニーククリック数\n- (ステータス別:pending/approved/rejected)\n- :アフィリエイトがキャンペーンを比較するための指標\n- (approved ÷ total conversions)\n- :承認済みだが未払いのコミッション\n\n定義はツールチップで表示し、数値の解釈を統一してください。\n\n### 管理者向けとアフィリエイト向けの2つのダッシュボード\n\n管理者はコントロールパネルを必要とします:時間推移、上位パートナー、上位キャンペーン、クリック急増や承認率の急落、EPCの異常検出などのアラート。\n\nアフィリエイトにはシンプルなサマリを提供:自分のクリック、コンバージョン、収益、保留と承認済みの内訳。ステータスの意味を明確にしてサポートを減らしてください。\n\n### レポートのフィルタで「混乱」を防ぐ\n\nすべてのレポートで次のフィルタを用意します:\n\n- (過去7日/30日などのプリセット)\n- (オファー)\n- (管理者用)\n- (pending/approved/rejected/paid)\n\nフィルタ変更時には合計とチャートが一緒に更新されることを保証してください。数値が一致しないと信頼が失われます。\n\n### エクスポートと定期レポート(後段)\n\nCSVエクスポートは有用ですが、MVPを遅らせないでください。コアのトラッキングとコミッション管理が安定したら、エクスポートや定期メールレポートをフェーズ2で追加します。\n\n## アーキテクチャと技術選定\n\nアーキテクチャはトラッキングと支払いの信頼性に直結します。目標は「完璧なスタック」ではなく、チームが運用・デバッグ・拡張できることです。\n\n### 地味でメンテナブルな部品を選ぶ\n\nチームがすでに慣れているメジャーなWebフレームワーク(Rails、Django、Laravel、Express/Nest、ASP.NET)を選んでください。コミッション管理や監査性が重要なため、トランザクションと一貫性が強いリレーショナルDB(PostgreSQL/MySQL)が無難です。\n\nホスティングは主要クラウド(AWS/GCP/Azure)かマネージドプラットフォーム(Render/Fly/Heroku系)で問題ありません。観測性(ログ、メトリクス、トレーシング)を優先してください。運用中に「なぜこのコンバージョンがカウントされなかったか?」と聞かれることが多いです。\n\nプロトタイピング段階でコアフロー(パートナーポータル+管理コンソール+基本ワークフロー)を素早く検証したいなら、のようなvibe-codingプラットフォームでチャットベースにプロトタイプを作り、要件が流動的な初期段階を早く反復するのも有効です。準備が整ったらソースコードをエクスポートしてハードニングできます。\n\n### 責務を明確に分割する\n\n最低限、次のコンポーネントを分けます:\n\n- パートナーポータル、管理UI、プログラムルール、レポーティング\n- クリック/ピクセル/サーバーイベントを素早く受け付ける軽量サービス\n- アトリビューション、コミッション計算、支払い自動化、通知等の非同期処理\n- アトリビューション決定、ステータス、支払いの真実のソース\n\nトラッキングエンドポイントを軽く保つことで、プロモーションやメール配信時のスパイクがパートナーポータル全体をダウンさせるのを防げます。\n\n### 重い作業はキュー化する\n\nトラッキングでは補完や重複排除が必要なことが多いです。高コスト処理はキュー(SQS/RabbitMQ/Redis)に入れます:\n\n- コミッション計算の実行\n- 支払いバッチ作成と照合\n- メール通知(承認、巻き戻し、支払い確認)\n- ルール変更後のバックフィルや再アトリビューション\n\n### 統合を早めに計画する\n\n多くのチームは少なくとも次を統合します:\n\n- (Shopify/Woo/WHS): コンバージョントラッキングと注文ステータス更新\n- (Stripe/PayPal/Wise): アフィリエイト支払い\n- : オンボーディングや支払いメッセージ\n\n各統合の失敗モード(レート制限、リトライ、冪等性)を文書化しておくと、システムが不安定になってもアフィリエイト分析の信頼性を保てます。\n\n## テスト、ローンチ、継続運用\n\nテストと運用がアフィリエイトプラットフォームの信頼を築くか、サポート地獄を生むかを決めます。お金が関わるため、動くだけでなく実際の負荷・エッジケースでも動き続けることに自信が必要です。\n\n### マネー経路を優先的にテストする\n\n残高に影響するロジックを優先してテストしてください:\n\n- アトリビューションルール(first/last click、ルックバックウィンドウ、クーポンの優先、セルフリファーラル)\n- コミッション計算(ティア、上限、最低注文額、通貨丸め)\n- 巻き戻しと調整(返金、チャージバック、部分返金)\n\nこれらはタイムスタンプを固定し、既知の為替レートを使う(またはFXをスタブする)ことで決定論的なテストにしてください。\n\n### 実際の紛争に似たステージングデータを用意する\n\nステージングに「ハッピーパス」だけ入れても不十分です。想定される実運用シナリオを用意してください:\n\n- 異なるアフィリエイトからの複数クリックの後に1件のコンバージョンが発生\n- Webhookの遅延再送によってコンバージョンが遅れて到着\n- 支払いがキューされた後の返金\n- サポートによる手動オーバーライド\n\nこのデータセットでサポートワークフローをリハーサルします:なぜコミッションが発生したか説明でき、監査可能な形で修正できるかを確認してください。\n\n### 決済製品のようにシステムをモニタリングする\n\nローンチ前に監視を用意します。最低でも:\n\n- バックエンドとフロントエンドのエラートラッキング(リリースタグ付き)\n- Webhookの健全性:失敗、リトライ、プロバイダ応答時間\n- 遅延ジョブ/キュー:遅延時間、デッドレター数、リトライの嵐\n- 支払いバッチの健康状態:保留中支払い数、停止したバッチ、異常に大きい合計\n\n主要イベント(conversion created、commission approved、payout sent)をID付きでログに残し、サポートが検索できるようにしてください。\n\n### ローンチチェックリスト + v2ロードマップ\n\n実用的なローンチチェックリスト:プログラムルールの最終化、エンドツーエンドのテスト支払い、メールテンプレート確認、パートナー向けオンボーディング文面、ロールバック計画。\n\nv2は学びに基づくシンプルなロードマップにしてください:より良い不正シグナル、豊富なレポーティング、手動介入を減らす管理ツールなど。ドキュメントがある場合はパートナーポータルからリンクしてバージョン管理してください(例:/docs/affiliate-guidelines)。
各役割(管理者/パートナーマネージャー、財務/オペレーション、アフィリエイト)について、1日の業務を3〜5件箇条書きで書き出すことから始めてください。その後、それらをv1のループに落とし込みます:
そのループを支えないものは「後回し」にしてください。たとえ人気があっても、まずはこの流れを優先します。
ワンページのスコープを作成してください:
ビルド中に機能要望が来たら、このスコープを判断基準として使います。
v1では1つのモデルを選び、明確に説明できるようにします:
基準(総額か純額か、税・送料を含めるか、返金/チャージバックの扱い)を文書化してください。迷う場合は**支払われた純額(net paid amount)**を基準にし、後で返金を差し引く方法が安全です。
まずは1つのアトリビューションルールを選び、明確にしてください:
最低限モデル化すべきテーブル/エンティティ:
共通のステータスを早めに定義してください(例:、および と )。特にクリックやコンバージョンのIDは不変にしておくと、再計算してもレポートが壊れません。
複数の手法を組み合わせつつ、ソース・オブ・トゥルースを決めてください:
?aff_id=123&campaign=spring):ローリングアウトが簡単でコンテンツ系に適する。\n- サーバー間(postback/webhook)イベント:特に有料流入や正確性が求められる場合に最良。\n- ピクセル:マーケツールや冗長化用。ブロッカーで動作しないことがあるため単独のソースにしない。重複排除は order_id で行い、パラメータ欠落時はプロモコードやサーバー側に保存した参照情報にフォールバックする方針を用意してください。
コミッションは台帳のように扱い、決定的で監査可能なパイプラインを作ります:
補正(ボーナス、ペナルティ、巻き戻し)は別エントリとして扱い、履歴を書き換えないようにしてください。Webhooksの再送などで重複が起きないよう、データベースレベルでの冪等性を必須にします。
シンプルかつ監査可能な設計から始めます:
支払いはバッチとして扱い、ステータスを持たせます:draft → approved → processing → completed。アフィリエイト向けには、バッチID、対象期間、明細、調整、支払い参照IDを含む領収書を表示してください。
必要最小限のデータ収集と厳格な扱いを。\n
権限は最小権限で、Admin/Finance/Supportといったロール分離を導入してください。
高シグナルの簡易チェックをまず導入します:
自動拒否ではなく「フラグ→レビュー」のフローにして、判定理由(ルール名・データポイント)を保存して説明可能にします。トラッキングエンドポイントはレート制限やボットフィルタリングも忘れずに。