こんにちは😊
株式会社プロドウガの@YushiYamamotoです!
らくらくサイトの開発・運営を担当しながら、React.js・Next.js専門のフリーランスエンジニアとしても活動しています❗️
この記事は 決済を実装した体験談や決済関連(クレカ、QRコード、何でもOK!)の情報を投稿しよう! by PAY Advent Calendar 2025 の参加記事です🎄
SaaSやサブスクリプションサービスを運営していると、避けて通れないのが 「決済失敗(Payment Failed)」 です。
「カードの有効期限切れ」や「限度額オーバー」で決済が落ちることは日常茶飯事。
しかし、「決済失敗 = 即解約」にしてしまうのは、ビジネスとしてあまりにも勿体ない ですよね。
ユーザーはサービスを辞めたいわけではなく、単にカード情報の更新を忘れているだけかもしれません。
今回は、開発者フレンドリーな決済サービス PAY.JP のWebhook機能を使い、「決済失敗をリアルタイムで検知し、n8n経由でユーザーにカード更新依頼を自動送信する」 仕組みを構築します。
🏗️ 全体アーキテクチャ
PAY.JPは決済に関するイベント(成功・失敗・定期課金作成など)が発生すると、即座にWebhookを飛ばしてくれます。これを利用します。
🛠️ PAY.JP側の設定:Webhookを受け取る
まず、PAY.JPの管理画面でWebhookのエンドポイントを設定します。
- PAY.JP管理画面 > API > Webhook を開く。
- n8nのWebhook URL(例:
https://n8n.example.com/webhook/payjp-events)を入力。 - 通知するイベントタイプを選択。
- 今回は
charge.failed(支払い失敗)とsubscription.failed(定期課金失敗)にチェックを入れます。
- 今回は
PAY.JPのここが推せる!
PAY.JPはテスト環境でも本番と同じようにWebhookを飛ばしてくれます。開発中に「わざと失敗させるテスト」が非常にやりやすく、DX(開発者体験)が最高です。
⚙️ n8n側の実装:失敗イベントをハンドリング
n8nでWebhookを受け取り、イベントの種類によって処理を分岐させます。
1. Webhookノード
PAY.JPから送られてくるJSONペイロードを受け取ります。
charge.failed の場合、以下のようなデータが届きます。
PAY.JP Webhook Payload (例)
{
"type": "charge.failed",
"id": "ev_0000000000000000000000000",
"data": {
"id": "ch_0000000000000000000000000",
"amount": 1000,
"card": {
"last4": "4242",
"brand": "Visa",
"customer": "cus_1234567890abcdef"
},
"error": {
"message": "The card was declined.",
"code": "card_declined"
}
}
}
2. Switchノード(条件分岐)
イベントタイプ (body.type) を見て処理を分けます。
-
charge.succeeded→ 成功(今回は無視、またはサンクスメール送信) -
charge.failed→ リカバリーフローへ
3. リカバリーメッセージの作成
ここが腕の見せ所です。事務的な「失敗しました」メールは読まれません。
「サービスが止まってしまうのを防ぐために、カード情報を更新してくださいね」 というニュアンスで、AI(ChatGPT)に文面を作らせるのも手です。
// メッセージ生成のイメージ
const customerId = $input.item.json.body.data.card.customer;
const amount = $input.item.json.body.data.amount;
return {
message: `⚠️ 【重要】決済処理に失敗しました\n\nいつもご利用ありがとうございます。\n本日予定されておりました ${amount}円 の決済が完了できませんでした。\n\nサービスのご利用が一時停止される可能性があります。以下のリンクよりカード情報の更新をお願いいたします。\n\n👉 https://myapp.com/settings/billing`
};
4. 通知送信(LINE / SendGrid)
ユーザーの連絡先にメッセージを送信します。
LINE公式アカウントと連携していれば、プッシュ通知で届くため開封率が段違いです。
🛡️ セキュリティ対策:Webhook署名の検証
Webhookは外部から誰でも叩けるURLになってしまうため、「本当にPAY.JPから送られてきたものか?」 を検証する必要があります。
PAY.JPはヘッダーに X-Payjp-Signature を付与してくれるので、n8nの Cryptoノード を使って検証しましょう。
署名検証のロジック
公開鍵認証方式ではない場合でも、PAY.JPのWebhook設定画面にある「シークレットキー」を使ってHMAC-SHA256ハッシュを生成し、ヘッダーの署名と比較することで改ざんを検知できます。本番運用では必須の実装です!
📊 導入後の効果
この「自動リカバリーフロー」を導入することで、以下の効果が期待できます。
- 機会損失の防止: カード有効期限切れによる意図しない解約を阻止。
- 運用コスト削減: 「決済落ちてますよ」と手動でメールを送るオペレーションがゼロに。
- ユーザー体験向上: サービスが突然止まる前に通知が来るため、ユーザーも安心。
まとめ
決済機能の実装というと「カード情報のトークン化」や「決済画面のUI」に目が行きがちですが、「決済した後(特に失敗した後)」の運用設計 こそが、SaaSの収益を支える要です。
PAY.JPの使いやすいWebhookとn8nを組み合わせれば、この「守りの要」をノーコード・ローコードで爆速構築できます。
ぜひ、あなたのサービスにも「鉄壁のリカバリーフロー」を導入してみてください!
最後に:業務委託のご相談を承ります
私は業務委託エンジニアとしてWEB制作やシステム開発を請け負っています。最新技術を活用したレスポンシブなWebサイト制作、インタラクティブなアプリケーション開発、API連携など幅広いご要望に対応可能です。
「課題解決に向けた即戦力が欲しい」「高品質なWeb制作を依頼したい」という方は、お気軽にご相談ください。一緒にビジネスの成長を目指しましょう!
👉 ポートフォリオ
🌳 らくらくサイト