Paddle は、EU の多くの SaaS 企業が利用するマーチャント・オブ・レコード型の決済プロバイダーです。Paddle は EU VAT、米国売上税、返金、チャージバック、グローバルコンプライアンスを代行処理し、純額を受け取れます。
Paddle を Zenovay に接続すると、トラフィックデータと並べて Paddle の収益を確認できます。どのキャンペーンが成約につながったか、どのページでコンバートしたか、どのソースの LTV が最も高いかを把握できます。
必要なものは 1 つだけです: Write 権限を持つ Paddle API キーです。Zenovay はあなたに代わって Webhook の送信先を作成し、Paddle の API を通じて署名シークレットを取得してどちらも暗号化して保存します。Sandbox でも Live でも同じフローです。Sandbox/Live トグルでフォーム上の対応する環境を選択するだけです。
セットアップ(2 分)
Paddle で Write 権限の API キーを発行する
New API key をクリック → 名前を "Zenovay analytics" に設定 → 権限: Write → Create。
Paddle はキーを一度だけ表示します。今すぐコピーしてください。Live キーは
pdl_live_apikey_…で始まり、Sandbox キーはpdl_sdbx_apikey_…で始まります。Zenovay に貼り付けて Save Configuration をクリックする
app.zenovay.comで Domains からウェブサイトを開き、Settings に移動して Revenue タブを選択します。- Paddle カードをクリックします。
- API キーを貼り付けて、Sandbox/Live トグルを対応する設定にします(
pdl_sdbx_apikey_…キーは Sandbox;pdl_live_apikey_…キーは Live)。トグルとキーのプレフィックスが一致しない場合、接続は明確なエラーメッセージで拒否されます。 - Save Configuration をクリックします。
以上です。裏側では、Zenovay が次の処理を行います:
- Paddle の
/event-typesエンドポイントに対してキーを検証します。 POST /notification-settingsを呼び出して、https://api.zenovay.com/api/webhooks/paddle/<your-website-id>への Webhook 送信先を作成し、4 つの主要イベント(transaction.completed、subscription.created、subscription.updated、subscription.canceled)を購読します。- Paddle のレスポンスから
endpoint_secret_keyを取得し、暗号化して保存します。 - カードを Connected に切り替えます。
Paddle のダッシュボードを操作する必要はありません。署名シークレットを確認したりコピーしたりする必要もありません。Paddle からのすべての Webhook は、データベースへの書き込みの前に保存されたシークレットを使用して検証されます。
「Paddle で署名シークレットはどこで確認できますか?」— 端的な答え:確認する必要はありません
これは最もよくある誤解です。Paddle は送信先の作成後、ダッシュボードで署名シークレットを意図的に非表示にします。 「表示」ボタンも「確認」リンクも存在せず、Rotate Secret(古いシークレットを無効化して新しいものを発行するボタン)のみがあります。作成時にシークレットを表示するアカウントでも、消える前にコピーできる時間は短いです。
これは Paddle の正常な動作であり、バグではありません。UI 上のシークレットはスクリーンショット、サポートチケット、のぞき見によって漏洩しやすいため、セキュリティ上の理由からこの仕様になっています。
だからこそ、Zenovay の Connect フローでは署名シークレットを探す必要がないのです。 Paddle の API(自分の送信先に対しては署名シークレットをプログラムで公開しています)を使用して自動取得します。あなたが操作する必要はありません。
送信先を手動で作成済みの場合
問題ありません。Zenovay で Paddle カードを保存すると:
- 当社の URL に送信先がすでに存在する場合、Zenovay はそれを再利用し、API 経由でシークレットを取得します。
- 現在無効になっている場合(Paddle の UI で誰かが無効化した場合など)、Zenovay が再度有効化します。
- 重複した送信先の作成や手動でのクリーンアップは必要ありません。
それでも手動でセットアップしたい場合
可能ですが、手間がかかるだけでメリットはありません。どうしても行う場合は:
手動セットアップ手順(非推奨)
- Paddle → Notifications → Destinations → New destination → Webhook。
- URL:
https://api.zenovay.com/api/webhooks/paddle/YOUR_WEBSITE_ID(ウェブサイト ID はapp.zenovay.comで Domains からウェブサイトを開く際のページ URL の UUID です。Revenue 設定タブの上部にも表示されます)。 - All イベントを購読します(Zenovay は処理できないイベントを静かに無視します)。
- 送信先を保存します。
- 多くの方が詰まる箇所:Paddle が次の画面で署名シークレットを表示するかどうかは場合によります。表示されない場合:
- オプション A:シークレットをローテーションします(Paddle → Destinations → 送信先をクリック → Rotate Secret)。新しい値をコピーします。
- オプション B:この送信先を削除して、代わりに Zenovay の Connect フローを使用します(Zenovay が再作成し、API 経由でシークレットを取得します)。
- Zenovay → Paddle カード → API キーを貼り付けた後、Advanced (optional) セクションを開く →
pdl_ntfset_…署名シークレットを Webhook Secret フィールドに貼り付けます。 - 保存します。
ユーザーの 99% には、上記の Connect フローを使用することをお勧めします。
トランザクションに訪問者 ID をタグ付けする(推奨)
決済からトラフィックソースへの帰属を最も正確に機能させるには、サーバーで Paddle トランザクションまたはチェックアウトを作成する際に、訪問者の匿名 Zenovay ID を custom_data として設定してください:
// Node.js example using Paddle's API directly
const visitorId = req.cookies['zv_visitor_id']; // however your client passes it
await fetch('https://api.paddle.com/transactions', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.PADDLE_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
items: [{ price_id: 'pri_01h…', quantity: 1 }],
customer_id: paddleCustomerId,
custom_data: { zenovay_visitor_id: visitorId },
}),
});
トランザクションが完了すると、Zenovay は data.custom_data.zenovay_visitor_id を読み取り、決済を訪問者のセッション(支払い前に訪れたソース、キャンペーン、ページを含む)と紐付けます。
custom_data を設定しない場合でも、(イベントに存在する場合は)顧客のメールアドレスを通じた帰属は機能しますが、精度は低くなります。訪問者が同じメールアドレスで以前に自身を識別している場合のみマッチングされます。
使用される帰属モデル
Zenovay は 2 つの帰属ウィンドウをサポートしています:
- ファーストタッチ — 最初のセッションで訪問者が来たソースにクレジットが付与されます。
- ラストタッチ — 決済を含むセッションで訪問者が来たソースにクレジットが付与されます。
どちらも計算されて、Revenue タブに並べて表示されます。
ステップ 5:Sandbox テスト
Sandbox 統合を確認する正しい方法は、実際のテストチェックアウトを行うことです:
- Paddle の Sandbox ダッシュボードで、テスト商品と価格を作成します。
- Zenovay のトラッキングスクリプトを読み込むテストページで、チェックアウトオーバーレイまたはホスト型チェックアウト URL を使用します。
- Paddle のテストカード番号のいずれかでチェックアウトを完了します。
- 約 10 秒以内に:Paddle が署名済みの
transaction.completedイベントを Zenovay に送信します。Zenovay で Revenue タブを開いて届いたことを確認します。キャプチャが購入者のメールと金額とともに表示されるはずです。
約 30 秒後もキャプチャが表示されない場合:
- Zenovay の設定で Paddle カードの Verification status バッジを確認します。
- 両側で Sandbox と Live モードが一致していることを確認します。Sandbox 環境の Paddle ダッシュボードは
sandbox-api.paddle.comからイベントを発行します。Zenovay が Live モードに設定されている場合、署名の検証が失敗します。 - Paddle で通知送信先がまだ enabled になっていることを確認します(Paddle は 5xx レスポンスが 5 回連続した後、自動的に送信先を無効化します。テスト中に Zenovay がデプロイ中だった場合は、再度有効化してください)。
通貨サポート
Paddle はトランザクション金額を通貨の最小単位で返します(例:49.99 USD の場合は "4999")。Zenovay は ISO 4217 に従って正しく変換します:
- 小数点 2 桁の通貨(USD、EUR、GBP など):100 で割ります →
4999は49.99になります。 - 小数点なし通貨(JPY、KRW、VND など):値をそのまま使用します →
5000JPY は5000のままです。 - 小数点 3 桁の通貨(BHD、KWD、OMR など):1000 で割ります →
1500BHD は1.500になります。
設定は不要です。Zenovay がイベントの currency_code に基づいて自動的に処理します。
Sandbox から Live への切り替え
本番環境の準備ができたら:
- Paddle の Live ダッシュボード(sandbox-vendors ではなく vendors.paddle.com)で、ステップ 1 とステップ 2 を繰り返して、Live 通知送信先と Live API キーを作成します。
- Zenovay で Paddle カードをクリック → Disconnect(履歴の保持は問題ありません)→ 再度クリックして再接続 → Live 認証情報を貼り付け → トグルを Live に切り替え → 保存します。
同じ Zenovay Webhook URL が両方の環境で機能します。Paddle はアクティブな API キーに一致する送信先にイベントを送信します。
切断
Domains からウェブサイトを開く → Settings → Revenue タブ → Paddle カードをクリック → Disconnect。
デフォルトでは、切断すると Paddle の認証情報が削除されるだけです。既存の決済記録、帰属履歴、Revenue ダッシュボードのデータはプランのデータ保持期間に従って維持されます。いつでも再接続して、中断したところから再開できます。
オプション:Paddle の過去データも削除する
切断ダイアログにはチェックボックスが含まれています:「N 件の Paddle レコード(合計 $X)を完全に削除する」。テスト統合を廃止する場合やプライバシーの整理を行う場合など、クリーンな状態にしたい場合のみチェックを入れてください。
チェックを入れると、Zenovay は次の処理を行います:
- このウェブサイトのすべての Paddle 決済イベントを削除します
- このウェブサイトのすべての Paddle 決済レコードを削除します
- すべての識別済みユーザーの Paddle 顧客 ID フィールドをクリアします(ユーザーレコード自体は保持されます。Stripe ID なども維持されます)
削除は単一トランザクションで実行されます。いずれかのステップが失敗した場合、3 つすべてがロールバックされるため、半削除状態になることはありません。この操作は取り消し不能です。
Paddle 側の通知送信先の無効化を忘れずに
Zenovay での切断は、Zenovay がイベントを受け付けることを停止するだけです。Paddle は、あなたが Paddle ダッシュボードで無効化するまで、当社のエンドポイントへのイベント送信を継続します:
- Paddle → Notifications → Destinations を開きます。
https://api.zenovay.com/api/webhooks/paddle/{your-website-id}を指す送信先を見つけます。- それをクリック → Disabled に切り替えます(または Delete)。
無効化するまで、当社のエンドポイントは各配信に対して 400 "Webhook not configured for this website" を返します。Paddle は十分な失敗の後、最終的に送信先を自動無効化しますが、明示的に削除する方がダッシュボードをすっきり保てます。
制限事項(V1)
- 返金イベントはまだ表示されません。 それでも送信先で
adjustment.created/adjustment.updatedを購読してください。Zenovay は現時点でこれらを静かに無視しており、V2 がリリースされ次第レンダリングを開始します。 subscription.past_dueおよびsubscription.pausedイベントは受信・重複排除記録されますが、ダッシュボードにはまだ表示されません。 サブスクリプションのステータスはpast_dueに正しく切り替わりますが、専用のインシデントビューはまだありません。- Zenovay ウェブサイト 1 つにつき Paddle アカウントは 1 つです。 複数の Paddle アカウントで決済を受け付けている場合(地域子会社ごとに 1 つなど)、それぞれを独自の Zenovay ウェブサイトで設定してください。
- OAuth リダイレクト接続はサポートされていません。 認証情報の手動入力のみです。
トラブルシューティング
保存時に「Invalid Paddle API key」と表示される
よくある原因が 3 つあります:
- 環境の不一致。 Live トグルがオンの状態で
pdl_sdbx_apikey_…キーを使用している(または逆の場合)と検証に失敗します。Zenovay は具体的なエラーメッセージを表示します。トグルをプレフィックスと一致させてください。 - キーには Write 権限が必要で、かつ失効していないことが必要です。 読み取り専用キーは検証を通過しますが、Zenovay が送信先を作成しようとすると失敗します(403)。失効したキーは検証自体に失敗します(401)。新しい Write スコープのキーを生成してください。
- 異なるチーム / アカウントのキーが使用された。 Paddle API キーは単一の Paddle アカウントにスコープされています。別のアカウントのキーを貼り付けると即座に失敗します。
「Webhook not configured for this website」と表示される
Zenovay に Paddle の認証情報をまだ保存していないか、誤った Webhook URL をテストしています。URL には接続したウェブサイトの正確な ID(app.zenovay.com で Domains からウェブサイトを開く際のページ URL の UUID)が含まれている必要があります。
「Signature verification failed: replay_window_exceeded」と表示される
Zenovay は現在時刻から 5 分以上ずれたタイムスタンプを持つ Webhook イベントを拒否します。これは通常、自分側または Paddle 側の時刻のずれを意味します。新しいテストでこれが表示された場合:
- サーバーを再起動します(時刻ドリフトはまれですが、長時間稼働後に発生することがあります)。
- Paddle のダッシュボードから Webhook を再送信します(Notifications → Deliveries → Resend)。
検証済みの Webhook が届いているが、トランザクションが Revenue タブに表示されない
Paddle の Webhook は、顧客がスタンドアロンで作成されたかチェックアウトの一部として作成されたかによって、3 つの異なる形式で届きます。Zenovay のパーサーは防御的に設計されていますが、ログに検証済みの配信が確認できるのに Revenue に何も表示されない場合:
- Paddle の配信ログで 2xx が返されたことを確認します。署名またはエンドポイントの不一致は 4xx で表示されます。
- 購入者のメールがイベントに含まれていない場合、Zenovay は Paddle 顧客 ID による照合にフォールバックします。トランザクションは記録されますが、同じ顧客が将来の識別済みユーザーのアップサートを通じてリンクされるまで、識別済みユーザービューには表示されません。
- 表示されない場合は、[email protected] にお問い合わせいただき、Paddle 配信 ID をお知らせください。トレースさせていただきます。