RORK LABEN
MAX — Rork MaxはiPhone・iPad・Apple Watch・Apple TV・Vision Pro向けにネイティブSwiftを生成し、2クリックでApp Store公開でき、Xcodeを必要としませんSTACK — 通常のRorkはReact Native(Expo)でクロスプラットフォームのモバイルアプリを作る位置づけ。用途に応じた使い分けが鍵ですFOCUS — BoltやLovableのようなWeb中心ツールと違い、RorkはiOS/Androidのネイティブアプリ生成に特化していますBUGS — 実利用レビューでは遭遇したバグの約70%を手動介入なしで解決、残り3割はエクスポート済みコードでの手修正が必要と報告されていますFUNDING — Rorkはa16z(Andreessen Horowitz)から$2.8Mを調達しましたPRICING — 無料で開始でき、有料プランは$25/月からです。まず触ってから判断できますMAX — Rork MaxはiPhone・iPad・Apple Watch・Apple TV・Vision Pro向けにネイティブSwiftを生成し、2クリックでApp Store公開でき、Xcodeを必要としませんSTACK — 通常のRorkはReact Native(Expo)でクロスプラットフォームのモバイルアプリを作る位置づけ。用途に応じた使い分けが鍵ですFOCUS — BoltやLovableのようなWeb中心ツールと違い、RorkはiOS/Androidのネイティブアプリ生成に特化していますBUGS — 実利用レビューでは遭遇したバグの約70%を手動介入なしで解決、残り3割はエクスポート済みコードでの手修正が必要と報告されていますFUNDING — Rorkはa16z(Andreessen Horowitz)から$2.8Mを調達しましたPRICING — 無料で開始でき、有料プランは$25/月からです。まず触ってから判断できます
記事一覧/開発ツール
開発ツール/2026-06-16上級

Rork アプリの Stripe Webhook が本番でだけ取りこぼす — 冪等化・再送・順序ずれに耐える受信設計の実装メモ

ローカルでは通るのに本番でだけ権限付与がずれる Stripe Webhook を、署名検証・冪等化・順序ずれ補正・再送ストーム対策の4層で安定させた実装メモです。Cloudflare Workers と KV を前提にした受信設計を、運用で踏んだ落とし穴ごとに整理します。

Stripe17webhookCloudflare Workers18冪等性決済6

プレミアム記事

決済は成功しているのに、ユーザーの権限が変わらない。Stripe の管理画面では Payment succeeded、Recent deliveries も 200 OK。なのにアプリ側は無料プランのまま——。個人開発で課金まわりを触っていると、この「全部正しく見えるのに合わない」状態に何度かぶつかります。

厄介なのは、ローカルでは stripe trigger で一発で通るのに、本番でだけ静かに取りこぼすことです。署名検証のような分かりやすいエラーは早めに気づけます。本当に時間を溶かすのは、検証は通っているのに「同じイベントを二回処理した」「イベントが順番どおりに来なかった」「処理が遅くて Stripe に再送された」といった、ログを見ても一見正常に見える種類の失敗でした。

ここでは Rork で作ったアプリのバックエンド(Cloudflare Workers + KV)を題材に、Webhook 受信を安定させるために実際に入れた4つの層を、踏んだ落とし穴とセットで残しておきます。署名検証の話は最小限にして、その先の「受け取った後どう壊れるか」に重心を置きます。

なぜ「200 が返っているのに合わない」が起きるのか

最初に押さえておきたいのは、Stripe の Webhook が at-least-once(少なくとも一回)配信だという前提です。これは「同じイベントが二回以上届くことがある」という意味です。ネットワークの揺らぎ、こちらのレスポンスが遅い、Stripe 側のリトライ——理由は色々ありますが、結果として checkout.session.completed が二回飛んでくる状況は、低頻度ながら確実に起きます。

受信ハンドラが「届いたイベントを毎回そのまま処理する」前提で書かれていると、二回目の配信でもう一度権限を付与したり、サブスク開始処理を重ねて走らせたりします。冪等化していなければ、これは正常系のログ(200 OK が二行)として記録されるだけで、エラーには見えません。「全部正しく見えるのに合わない」の正体の多くがこれです。

もうひとつ、サブスクリプションのライフサイクルイベントは 順序が保証されませんcustomer.subscription.created より先に customer.subscription.updated が届くことがあります。payload の中身を時系列の真実として信じて状態機械を回すと、古い情報で上書きしてしまいます。

つまり安定化の本質は、署名検証そのものよりも「重複に強い」「順序ずれに強い」「遅延に強い」受信設計をどう作るかにあります。

第1層: Workers 上での署名検証を非同期版で通す

土台として署名検証は必要です。ここだけは Cloudflare Workers 固有のはまりどころがあるので最小限に触れておきます。Node 向けでよく使う同期版 constructEvent() は Workers の Web Crypto 環境では動きません。非同期版に切り替え、ボディは必ず生テキストで受け取ります。

// src/app/api/webhook/route.ts
import Stripe from 'stripe';
import { NextRequest, NextResponse } from 'next/server';
 
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);
 
export async function POST(req: NextRequest) {
  // json() ではなく text()。パースするとバイト列が変わり署名検証が必ず落ちる
  const body = await req.text();
  const signature = req.headers.get('stripe-signature') ?? '';
 
  let event: Stripe.Event;
  try {
    const cryptoProvider = Stripe.createSubtleCryptoProvider();
    event = await stripe.webhooks.constructEventAsync(
      body,
      signature,
      process.env.STRIPE_WEBHOOK_SECRET!,
      undefined,
      cryptoProvider,
    );
  } catch (err) {
    // 署名が合わない=こちらの設定ミス。400 を返すと Stripe は再送しない
    console.error('signature verification failed:', err);
    return NextResponse.json({ error: 'invalid signature' }, { status: 400 });
  }
 
  return handleEvent(event);
}

ここで覚えておきたいのは、署名検証で落としたときに 400 を返す ことです。署名不一致は通信障害ではなく設定の問題なので、再送させても直りません。逆に、後述する一時的な処理失敗では 500 を返して再送させます。この「いつ再送させ、いつ諦めさせるか」の区別が、再送ストーム対策の出発点になります。

ここまでお読みいただきありがとうございます。

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
イベントIDを使った KV 冪等化で、Stripe の at-least-once 再送による二重付与を止める具体的な実装
署名検証の通過後に「速く 2xx を返してから処理する」設計へ切り替え、再送ストームを未然に防ぐ手順
順序ずれするサブスクリプションイベントを payload で信じず、retrieve で現在状態に寄せて補正する運用パターン
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

お読みいただきありがとうございます

Rork Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

関連記事

開発ツール2026-04-26
Rork × Stripe Meter で AI アプリの使用量課金を実装する — トークン数・API 呼び出し回数で正確に課金する設計ガイド
Stripe Meter Billing を使い Rork アプリに使用量ベース課金を実装する完全ガイド。Cloudflare Workers でのメーター報告・サブスクリプション設計・エラーハンドリングまで動作確認済みコード付きで解説します。
開発ツール2026-04-12
Rork × Stripe Connect でマーケットプレイスアプリの決済を構築する
Rork と Stripe Connect を組み合わせ、出品者・購入者間の決済が動くマーケットプレイスアプリを構築する方法を体系的に解説。アカウント登録から収益分配・手数料設定まで完全網羅。
開発ツール2026-04-07
Rork Max × Stripe で Apple Pay / Google Pay を実装する — ワンタップ決済で購入転換率を劇的に改善する実践手法
Rork Max と Stripe Payment Sheet を使って Apple Pay・Google Pay を実装する方法を完全解説。Merchant ID 設定からバックエンド構築、本番リリースまでの全工程を網羅したプロ向け実践ガイドです。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →