Stripe の入金アラート:お金が危ないときだけ電話を鳴らす

Stripe の Webhook をイベントごとに適した緊急度でスマートフォンへ。決済成功は静かな通知、期限付きの異議申し立ては着信で。

更新日

目次

Stripe は何についてもメールを送ってきますが、それは結局「何も知らせていない」のとほとんど同じです。決済の成功、サブスクリプション更新の失敗、チャージバック。どれも同じ受信箱に同じ顔で届き、読むころにはその違いは失われています。

必要なのは通知を増やすことではありません。Stripe の各イベントに、それが本当に持つべき緊急度を与えることです。誰かが支払ったときは静かなプッシュ、更新が失敗したときは時間指定通知、そして回答期限つきの異議申し立てが来たときは電話です。

本当にあなたを必要とする Stripe イベント

すべてのイベントが通知に値するわけではありませんし、値するものどうしも緊急度は同じではありません。

Stripe イベントなぜ重要か緊急度
payment_intent.succeeded誰かが支払った。知っておきたいが、急ぎではない。通常
invoice.payment_failed更新に失敗。サブスクリプションが失効する前に再試行の猶予がある。時間指定
charge.dispute.createdチャージバック。Stripe はカードネットワークが定めた回答期限を示し、それを逃すと自動的に敗れる。着信
payment_intent.payment_failed単発の決済が失敗。件数としては有用だが、1 件ずつだとうるさい。通常、または通知しない

電話に値するのは異議申し立てだけです。それ以外は、あなたが自分で端末を手に取るまで待てます。1 週間後に気づいたチャージバックは、そもそも守れなかったお金です。

ステップ 1 —— 緊急度ごとにチャンネルを作る

Echobell でチャンネルを 3 つ作ります。緊急度はチャンネル単位の設定だからです。

  • Stripe · 売上 —— 通常通知。決済成功用
  • Stripe · 決済失敗 —— 時間指定
  • Stripe · 異議申し立て —— 着信

各チャンネルの設定から webhook URL をコピーしてください。Stripe からはこの 3 つすべてに向けます。

ついでに、それぞれで POST のみ を有効にしておきましょう。Stripe は必ず POST で送信するので、リンクプレビューやアドレスバーの補完によってチャンネルが誤って発火するのを防げます。

ステップ 2 —— Stripe 側にエンドポイントを追加する

Stripe ダッシュボードで Developers → Webhooks → Add endpoint を開き、チャンネル URL を貼り付けて、そのチャンネルが扱うべきイベントだけを選びます。

すべてを 1 つのエンドポイントにまとめるのではなく、チャンネルごとに 1 つ作るのがおすすめです。Stripe はエンドポイントごとにイベントを選べるので、振り分けが Stripe 側で完結し、チャンネル側はシンプルなままにできます。

どうしてもエンドポイントを 1 つにしたい場合は、1 つのチャンネルに向けて条件で絞り込みます。

type == "charge.dispute.created"

条件はテンプレートで使う {{ }} の囲みなしで書きます。

ステップ 3 —— payload を読める形に整える

Stripe が送ってくる JSON はおおよそこの形です。

{
  "type": "charge.dispute.created",
  "data": {
    "object": {
      "amount": 4900,
      "currency": "usd",
      "reason": "fraudulent",
      "status": "warning_needs_response"
    }
  }
}

そこでチャンネルのテンプレートは data.object の中を参照します。

タイトル

異議申し立て:{{data.object.reason}}

本文

{{data.object.amount}} {{data.object.currency}} が異議申し立ての対象
ステータス:{{data.object.status}}

ほぼ全員がはまる落とし穴: Stripe の金額はその通貨の最小単位です。4900 は 49.00 ドルであって、4,900 ドルではありません。Echobell のテンプレートは値をそのまま差し込むので、送信前に割るか、通貨を後ろに書いて「セント」として読むかのどちらかにしてください。数字がひと目で正しくある必要があるなら、割り算は Stripe と Echobell のあいだにあるもの(Worker、自動化ツール、自前のエンドポイント)に置きます。

売上チャンネルは、同じ考え方をもっと短く。

タイトル

+{{data.object.amount}} {{data.object.currency}}

本文

{{data.object.description}}

ステップ 4 —— 実際の入金を待たずにテストする

Stripe CLI から、本物と同じ形のイベントをエンドポイントに撃ち込めます。

stripe trigger payment_intent.succeeded
stripe trigger charge.dispute.created

本番で頼る前にこれをやっておきましょう。「あるはずだと思っていたフィールドが null だったときにテンプレートがどう描画されるか」を確認する一番早い方法でもあります。

この構成でできないこと

売上の前に置く前に、知っておくべき制約が 2 つあります。

Echobell は Stripe の署名を検証しません。 Stripe はすべての webhook に Stripe-Signature ヘッダーで署名し、その検証にはエンドポイントシークレットが必要です。Echobell の webhook はこの検証を行わないため、チャンネルを守っているのは URL だけです。これは秘密情報として扱い、POST のみ を有効なままにし、公開リポジトリやスクリーンショットに貼らないでください。

条件で弱いチェックを足すことはできます。

header["stripe-signature"] != ""

これは「Stripe の形をしたリクエストを何かが送っている」ことは確認できますが、「それが Stripe である」ことは確認できません。偽の通知が(一瞬の混乱ではなく)実害につながるなら、前段に自前のエンドポイントを置いてそこで署名を検証し、そこから Echobell を呼んでください。

これは通知経路であって台帳ではありません。 Stripe は失敗した webhook 配信を再試行しますが、通知は「何が起きたか」の記録ではありません。突合は通知履歴ではなく Stripe に対して行ってください。

よくある質問

Stripe から直接電話をかけてもらえますか?

できません。Stripe が送るのはメールと webhook です。電話にするには、電話を発信できるサービスへ webhook を回す必要があります。

異議申し立ての通知で本当に目が覚めますか?

チャンネルを着信モードにしていれば、はい。着信として届き、集中モードやおやすみモードを貫通して鳴ります。詳しくは重要な通知で iOS の集中モードを貫通させる方法をご覧ください。

共同創業者も同じ通知を受け取れますか?

受け取れます。チャンネルを共有すれば、購読者ごとに通知タイプを選べます。同じイベントについて、あなたは電話で受け、相手は静かなプッシュで受ける、といった使い分けができます。

テストモードはどうなりますか?

Stripe のテストモードのイベントは、テストモードで登録されたエンドポイントにのみ届きます。テストのトラフィックも見たいなら両方に登録し、構成を信頼できるまではテストモードだけに登録しておくのもよいでしょう。

まとめ

チャンネル 3 つ、エンドポイント 3 つ、それぞれにテンプレートが 1 つ。要点は「Stripe から通知が来るようになる」ことではありません——それは元から来ていました。要点は、チャージバックが領収書とまったく同じ顔をするのをやめる、ということです。

iPhone 版 Echobell をダウンロード、または Google Play で入手して、stripe trigger charge.dispute.created を一度実行し、わざと電話を鳴らしてみてください。


関連記事