Claude CodeでStripe APIバージョン更新の影響を洗い出す — webhookの新旧比較
Stripeの変更ログから互換性に関わる変更だけを抜き出し、自社コードの参照箇所と突き合わせる手順。webhookは新旧エンドポイントを並走させて差分を確かめます。
StripeのAPIバージョンを上げる作業で時間がかかるのは、バージョンを書き換える部分ではありません。変更ログの数十行から「自分のコードが触れている項目」を探す部分です。この絞り込みを、Claude Codeに変更ログとコードを突き合わせさせて進めます。
最後にwebhookのペイロードを新旧で見比べる段取りまで含めて、手順にまとめます。
影響を受ける面は3つに分かれる
Stripeの変更ログは、バージョンごとに表で並び、各行に「Breaking change?」の列があります。2026-09-30.endiveの節だけで、Breakingが28行、Non-breakingが39行ありました。全部を読む必要はありません。Non-breakingの行は後回しで構いませんが、受け側が未知のフィールドを厳密に検証している実装なら、そちらも目を通します。
自社コードへの影響は、次の3つの面に分けて見ると整理できます。
変更ログの1行がコードに効く経路
リクエスト
パラメーター名や型の変更です。たとえばbilling_cycle_anchorは文字列のnowから{type: 'now'}のオブジェクトに変わります。古い書き方は、バージョンを上げた瞬間にエラーになります。
レスポンス
APIの戻り値に含まれるフィールドの追加・削除・名前変更です。読み取り側のコードが、消えたフィールドを参照していると落ちます。
webhookのペイロード
スナップショットイベントの中身は、イベント送信先に設定したAPIバージョンで決まります。SDKの設定とは別物です。
3つ目が見落とされやすい点です。Stripeのアップグレード手順には、送信先のsnapshot_api_versionがペイロードの生成に使うバージョンを決め、サーバーサイドSDKのバージョンとは独立している、と書かれています。SDKだけを上げても、webhookの中身は変わりません。逆に、送信先だけ上げるとハンドラーが新しい形のペイロードを受けます。
シンイベントにはAPIバージョンが適用されません。受けているのがスナップショットイベントかシンイベントかを、最初に確認します。
変更ログから互換性に関わる変更だけを抜き出す
Stripeは変更ログをMarkdownでも配信しています。URLの末尾に.mdを付けた形で、Claude Codeに読ませる前に絞り込めます。次のコマンドは、移行先バージョンの節にあるBreaking行だけを取り出す例です。
curl -s https://docs.stripe.com/changelog.md \
| awk '/^## 2026-09-30.endive/{f=1;next} /^## /{f=0} f' \
| grep '| Breaking |' > breaking.md行の中にある個別ページのURLも.mdで取れます。各ページには「変更点」の表があり、Added・Removed・Changedの別と、対象のフィールド名がSDK言語ごとに載っています。フィールド名が分かれば、コードベースへの検索がほぼ機械的にできます。
grep -o 'https://docs.stripe.com/changelog/[^)]*\.md' breaking.md \
| while read u; do curl -s "$u" > "entries/$(basename "$u")"; doneentriesディレクトリは先に作っておきます。ここまでは決定論的な作業です。Claude Codeに任せるのは、次の「自社コードのどこがこのフィールドを参照しているか」の突き合わせです。
参照箇所の洗い出しをClaude Codeに任せる
公式のcommon workflowsには、リファクタリングの入口としてfind deprecated API usage in our codebaseというプロンプトが載っています。今回の作業はこの型の応用です。まず編集を伴わない調査として始めるため、プランモードで起動します。
claude --permission-mode planプランモードでは、ファイルを読んで計画を出すだけで、承認するまで編集しません。調査の段階で誤って書き換わる心配がなくなります。プロンプトは、対象と出力の形を指定して渡します。
breaking.md と entries/ にあるStripeの互換性に関わる変更について、
src/ と test/ がそのフィールド・パラメーターを参照している箇所を洗い出して。
出力は次の表にして、該当なしの項目は別の一覧にまとめて。
| 変更ログの項目 | 面(リクエスト/レスポンス/webhook) | ファイル:行 | 必要な修正 |
サブエージェントに分担させ、メインの会話には表だけ返して。最後の一行は、公式の「Delegate research to subagents」に沿った指示です。サブエージェントは自分のコンテキストでファイルを読み、要約だけを返します。変更ログの項目が多い移行では、メインの会話がファイルの読み込みで埋まるのを避けられます。
返ってきた表は、そのまま信じず検算します。ここで効くのが「該当なしの項目」の別一覧です。該当なしと判定された項目のうち、自社が使っているリソースのものがあれば、検索の取りこぼしを疑えます。
CLAUDE.mdに固定しておく規約
何度も使う前提は、CLAUDE.mdに書いておくと毎回の説明が要りません。例えば次のような形になります。
## Stripe
- APIバージョンはコードで固定する(Dashboardのデフォルトに頼らない)
- 固定値は src/lib/stripe.ts の apiVersion に1か所だけ置く
- webhookは snapshot イベントのみ受ける。ハンドラーは req.query.version で世代を分ける
- バージョン更新の調査は、変更ログのBreaking行から始める1行目は、Stripeのアップグレード手順が推奨している運用そのものです。アカウントのデフォルトバージョンに依存すると、コードを触っていないのに挙動が変わる余地が残ります。
webhookは新旧のエンドポイントを並走させて差分を見る
リクエストとレスポンスの影響は、コードの検索とテストで確認できます。webhookは、受け側のペイロードが変わるため、実際にイベントを受けて比べるのが確実です。Stripeが示している手順は、新しいバージョンの送信先を別に作って並走させる方式です。
新旧エンドポイントの並走手順
- 1
新しい送信先を無効状態で作る
URLは元と同じにして、区別用のクエリパラメーターを付けます(例:
?version=2024-04-10)。enabled_eventsは元と揃え、api_versionに移行先を指定し、作成したらすぐ無効にします。 - 2
ハンドラーを「旧だけ処理」に更新する
クエリが旧バージョンなら通常どおり処理します。新バージョンのクエリなら、イベントは無視して200を返し、再送を防ぎます。比較用にペイロードの保存も加えます。この状態で新しい送信先を有効にします。
- 3
同じイベントを新旧で受け、ペイロードを比べる
有効にすると、同じイベントが2回届きます。旧はそのまま処理し、新は保存したペイロードを比較に回します。
- 4
ハンドラーを「新だけ処理」に切り替える
旧バージョンのクエリには400を返して無視します。400を返すと再送されるため、元に戻すときに旧エンドポイントへ再配信されます。
- 5
旧エンドポイントを無効にする
400を返し続けないよう、移行が済んだら旧側を無効にします。無効にした後は、400を返したイベントは再配信されません。
snapshot_api_versionはイベント送信先の作成時にしか設定できません。既存の送信先のバージョンは後から書き換えられず、新しい送信先を作る必要があります。
保存したペイロードの差分をClaude Codeで読む
3つ目の手順で保存したJSONが、比較の材料になります。同じ種類のイベントを新旧のペアで集め、キーをそろえて差分を出します。
jq -S . payloads/old/invoice.paid.json > /tmp/old.json
jq -S . payloads/new/invoice.paid.json > /tmp/new.json
diff /tmp/old.json /tmp/new.json差分の出力は、そのままClaude Codeに渡して構いません。
/tmp の diff は invoice.paid の新旧ペイロードの差分。
src/webhooks/ のハンドラーが、追加・削除・名前が変わったキーを
参照している箇所を挙げて。参照がなければ「影響なし」と書いて。ペイロードの実物がある状態なので、変更ログの文章から推測するより確度が高い比較になります。テストイベントはStripe CLIで発生させられます。CLIの--stripe-versionオプションは、リクエストごとにバージョンを指定します。ローカルでの受信の組み方はStripe CLIのwebhook開発にまとめています。
並走中は新旧どちらのエンドポイントにもイベントが届くため、ハンドラーが冪等であることが前提です。重複配信への備えはwebhookの冪等受信で扱っています。
つまずきやすい点
落とし穴
SDKを固定しただけでは、webhookの世代は固定されない
SDKのapiVersionと、イベント送信先のsnapshot_api_versionは別の設定です。SDKだけ新しい値にしても、受信するペイロードは送信先の設定のままです。調査のたびに、両方の値を表にして確認します。
もう一つ。Java、Go、.NETのような強い型付けの言語では、SDKが別のAPIバージョンを指定できません。SDKの更新とAPIバージョンの更新は、同じ計画の中で進めます。
アップグレード手順には、サンドボックスでの実装テストが含まれます。サブスクの挙動を確かめるなら、Billingのテストクロックでサブスクをシミュレートできます。課金周期をまたぐ変更は、テストクロックを進めて確認します。アップグレード差分のレビューという進め方は、Railsのアップグレードやsemverの破壊的変更の判定と同じ形です。
まとめ
作業の順序は、変更ログのBreaking行の抽出、Claude Codeによる参照箇所の表づくり、webhookの新旧並走、ペイロード差分の読み取りです。決定論的な部分はコマンドで済ませ、Claude Codeには表を作らせて検算する、という分担にします。
webhookだけは、変更ログの文章を読むより、実物のペイロードを2世代分並べたほうが早く確かな答えが出ます。並走の準備が重いと感じるなら、受けているイベントの種類が少ないかどうかを先に数えてみてください。種類が少なければ、検証するペイロードも少なくて済みます。
参照した一次ソース
この記事の記述は、次の一次ソースと照合しています。更新時に参照先が変わった場合は一覧も更新します。