「お客様から、同じ商品の代金が2回引き落とされているという連絡が入りました」——この一報から始まる調査で、ベンダーから返ってきた説明が「決済APIにべき等性を持たせていませんでした」だった、という経験をお持ちの方は少なくないはずです。返金の手続きも、お詫びの連絡も、社内への報告も、すべて発注側であるあなたの手元に降りてきます。
用語そのものは調べればすぐに出てきます。「同じ処理を何度実行しても結果が変わらない性質」。しかし、そこで本当に知りたいのは定義ではないはずです。知りたいのは、次の発注でこれをどう要件に書けばいいのか、ベンダーの「対応済みです」という回答をどう検証すればいいのか、という点でしょう。
ここに、多くの発注担当者が置かれている難しさがあります。二重課金が起きたときに金銭と信用の損失を負うのは自社なのに、それが防げているかどうかを技術的に確認する手段を持っていない。設計書を見ても判断できず、結局はベンダーの言葉を信じるしかない。この非対称性が、不安の正体です。
一方で、べき等性は決して「エンジニアだけが扱う実装の詳細」ではありません。どの処理を対象にするかを決めるのは事業側の判断ですし、要件定義書に一文を書き加えることも、受入テストで二重送信を試すことも、発注者の側からできます。
本記事では、べき等性の意味とHTTPメソッドとの関係、べき等キー(Idempotency-Key)という代表的な実装パターンを、実装経験のない方にも判断できる粒度で整理します。そのうえで、自社のどの処理を対象にすべきかの絞り込み方、要件定義書に書く文言の例、見積・設計レビューでベンダーに投げる5つの質問、受入テストの4つの検証シナリオまでを解説します。
システム開発 完全チェックリスト――発注前・発注中・完了後の3フェーズで使えるチェック集

この資料でわかること
システム開発の外注・発注を初めて経験する担当者や、過去に失敗を経験した担当者が、発注プロセスの各フェーズで「何をチェックすべきか」を明確に把握できるようにする。
こんな方におすすめです
- 初めてシステム開発を外注する担当者
- 過去の発注で失敗を経験した方
- ベンダー選定の基準が分からない方
入力いただいたメールアドレスにPDFをお送りします。
べき等性とは?同じ処理を何度実行しても結果が1回分になる性質
べき等性(冪等性)の意味を身近な例で理解する
べき等性は「べきとうせい」と読み、英語では idempotency(アイデムポテンシー)と表記します。日本語の記事では「冪等性」と漢字で書かれることも多く、「べき等性」「冪等性」はまったく同じ意味です。ベンダーの設計書に「冪等性」と書かれていても身構える必要はありません。
意味は、一言でいえば「1回実行しても、2回実行しても、10回実行しても、結果は1回分にしかならない」という性質です。
身近な例で考えてみましょう。エレベーターの呼び出しボタンは、焦って何度連打しても、エレベーターが余分に呼ばれることはありません。押した結果は「呼び出し済み」という1つの状態に落ち着きます。これがべき等な操作です。逆に、自動販売機のボタンは1回押すごとに1本ずつ出てきますから、べき等ではありません。
技術的な定義としては、MDN Web Docs が次のように説明しています。「ある HTTP メソッドがべき等であるとは、単一のリクエストを送信した際のサーバーへの意図された効果が、同一のリクエストを複数回送信した場合の効果と同一であること」(Idempotent(べき等)- MDN Web Docs 用語集)。
注意したいのは、「レスポンスの中身が毎回まったく同じになる」という意味ではない点です。2回目のリクエストがエラーを返すこともあります。重要なのは、サーバー側に残る状態が1回分のままであること。決済でいえば「請求が1件しか立たない」ことがゴールです。
べき等性と安全性の違い
べき等性とセットでよく登場するのが「安全性(safe)」です。この2つは似ているようで、指しているものが異なります。
性質 | 意味 | 該当するHTTPメソッド |
|---|---|---|
安全(safe) | サーバー側の状態をまったく変更しない(読み取り専用) | GET / HEAD / OPTIONS / TRACE |
べき等(idempotent) | 状態は変更するが、何度実行しても同じ状態に落ち着く | GET / HEAD / PUT / DELETE / OPTIONS / TRACE |
安全なメソッドはすべてべき等です(何も変えないのですから、何度実行しても状態は同じままです)。一方、べき等なメソッドが必ずしも安全とは限りません。たとえば「この顧客の住所を〇〇に変更する」という PUT の操作は、確かにデータを書き換えますが、同じ内容で何度実行しても住所は〇〇のままです。状態を変える(=安全ではない)けれども、結果は1回分(=べき等)というわけです。
発注の文脈で押さえておくべきなのは、「データを書き換える処理でも、べき等にすることはできる」という点です。「更新系だから重複はやむを得ない」という説明は正しくありません。
なぜ「何度実行しても同じ」が必要になるのか — 通信は成功したか分からない
そもそも、なぜ同じリクエストが2回も送られるのでしょうか。ユーザーがボタンを連打したケースだけを思い浮かべがちですが、より厄介なのはシステム同士の通信です。
インターネット越しの通信には、「リクエストは相手に届いて処理も完了したのに、レスポンスだけが返ってこない」という状態が必ず存在します。回線が切れた、タイムアウトした、レスポンス送信の直前にサーバーが再起動した——原因はさまざまですが、送信した側から見ると、いずれも「返事がない」という同じ見え方になります。
このとき、送信側には決定的な情報が欠けています。返事がないのは、処理が実行されなかったからなのか、実行されたけれど返事が届かなかったからなのか、区別する方法がないのです。
そこで送信側は、2つの選択肢のどちらかを選ばざるを得なくなります。
選択 | 起きること |
|---|---|
リトライしない | 実際には未実行だった場合、決済も注文も取りこぼす。売上の機会損失とユーザーの離脱につながる |
リトライする | 実際には実行済みだった場合、二重課金・重複登録が発生する |
べき等性は、この二者択一を解消するための性質です。「何度送っても結果が1回分」であることが保証されていれば、送信側は迷わずリトライを選べます。取りこぼしも二重実行も起きません。べき等性が「信頼できるシステム連携の前提条件」と言われるのは、このためです。
API連携そのものの進め方や設計の全体像については、API連携とはの記事で基本から整理していますので、あわせてご覧ください。
決済・API連携でべき等性が崩れると何が起きるか

決済の二重課金 — 返金対応と顧客信用にかかるコスト
もっとも分かりやすく、もっとも被害が大きいのが決済の二重課金です。発生経路は主に3つあります。
- ユーザーの二重クリック: 処理中の表示が遅く、購入ボタンをもう一度押してしまう
- クライアント側の自動リトライ: アプリやフロントエンドが、レスポンスのないリクエストを自動で再送する
- サーバー間の再送: 自社サーバーから決済代行サービスへのリクエストがタイムアウトし、リトライ処理が走る
金銭の損失は返金すれば戻る、と考えると被害を過小評価してしまいます。実際にかかるコストを分解すると次のようになります。
コストの種類 | 内容 |
|---|---|
直接コスト | 返金手数料、決済手数料の取り戻し不能分 |
対応工数 | カスタマーサポートの一次対応、経理の返金処理、原因調査に投じるエンジニア工数 |
信用の損失 | レビューサイト・SNSへの投稿、リピート購入の停止、法人取引であれば取引継続の見直し |
二次リスク | カード会社への異議申し立て(チャージバック)の増加、決済代行サービスからの審査・警告 |
とくに信用の損失は数字に表れにくいぶん、後から取り返しがつきません。「1件返金すれば終わり」という認識でリスクを見積もると、対策への投資判断を誤ります。
Webhookの重複配信による重複登録・重複通知
決済処理そのものよりも見落とされやすいのが、Webhook の重複配信です。Webhook は、決済代行サービスや外部SaaSが「支払いが完了しました」といったイベントを自社サーバーに通知してくる仕組みです(Webhookとはで仕組みを詳しく解説しています)。
多くのサービスの Webhook は「at-least-once(少なくとも1回は届ける)」という配信保証を採用しています。裏を返せば、同じイベントが2回以上届く可能性があるということです。
たとえば Stripe の公式ドキュメントは、「Webhook エンドポイントは、同じイベントを複数回受信する可能性があります」と明記したうえで、「処理したイベントIDをログに記録し、すでにログに記録したイベントを処理しないようにすることで、重複するイベントの受信に対処することができます」と案内しています。さらに、配信に失敗した場合は「指数バックオフを使用して最長3日間、送信先へのイベントの配信を試行します」ともあります(Webhook エンドポイントで Stripe イベントを受信する - Stripe Docs)。
ここで起きやすいのが、次のような事故です。自社サーバーは通知を受け取り、注文レコードの作成もポイント付与も正常に完了した。ところが、その処理に時間がかかりすぎてレスポンスを返す前にタイムアウトしてしまった。送信元は「配信に失敗した」と判断して再送し、自社サーバーは同じイベントをもう一度処理する。結果として、注文が2件、ポイントが2倍になります。
処理そのものは1回も失敗していないのに重複が起きる、という点がこの事故の厄介なところです。
リトライ・バッチ再実行による在庫やポイントの二重反映
3つ目の経路がバッチ処理です。夜間の一括処理が途中でエラー終了し、翌朝に運用担当者が「最初からもう一度実行」した——このとき、処理済みのレコードまで再度処理されると、次のような二重反映が発生します。
- 会員へのポイント付与が2倍になる
- 在庫の引当が二重に走り、実在庫と帳簿在庫がずれる
- 案内メールが同じ顧客に2通届く
- 請求データが二重に計上される
バッチの再実行は、障害復旧の場面では避けられない運用です。だからこそ「途中まで実行された状態から再実行しても結果が変わらない」という設計、つまりべき等性が必要になります。
決済のリトライ対策だけを要件に入れて、Webhook 受信処理とバッチ処理を対象から外してしまうケースは実際によくあります。棚卸しの段階で3つの経路を並べて確認しておくことが、抜け漏れを防ぐ第一歩です。
HTTPメソッドのべき等性とPOSTが抱える問題
GET・PUT・DELETEはべき等、POST・PATCHはべき等でない
Web APIでは、処理の種類ごとに HTTP メソッドを使い分けます。そして、このメソッドごとにべき等かどうかが仕様で定められています。
メソッド | 主な用途 | 安全 | べき等 |
|---|---|---|---|
GET | データの取得 | ○ | ○ |
HEAD | ヘッダ情報のみ取得 | ○ | ○ |
PUT | リソースの内容を指定した状態に置き換える | × | ○ |
DELETE | リソースの削除 | × | ○ |
OPTIONS | 対応メソッドの確認 | ○ | ○ |
POST | 新しいリソースの作成・処理の実行 | × | × |
PATCH | リソースの部分更新 | × | × |
MDN Web Docs は「べき等なメソッドは GET, HEAD, PUT, DELETE, OPTIONS, TRACE です」「POST および PATCH メソッドは、べき等であることが保証されません」と整理しています(Idempotent(べき等)- MDN Web Docs 用語集)。
DELETE がべき等である理由は少し分かりにくいかもしれません。1回目の削除は成功し、2回目は「そのリソースは存在しません」というエラーになります。レスポンスは違いますが、サーバー側の状態は「そのリソースが存在しない」という同じ状態に落ち着いています。だからべき等、という整理です。
ここで発注者として押さえておきたい注意点が1つあります。仕様上べき等とされているメソッドでも、実装がべき等になっているとは限らないということです。PUT で送っているのに内部で毎回新しいレコードを追加している、という実装は現実に存在します。「PUT だから大丈夫です」という説明は、それだけでは根拠になりません。
決済や注文がPOSTになる理由と、リトライ耐性を後付けする必要性
ではなぜ、決済実行や注文登録という「もっとも二重実行されたくない処理」が、よりによってべき等でない POST になるのでしょうか。
理由は、これらが「新しいものを作る」処理だからです。PUT は「このURLのリソースを、この内容にしてください」という指定ができます。しかし注文登録の時点では、注文番号がまだ決まっていません。「新しい注文を1件作ってください」としか言えないため、POST を使うことになります。決済実行も同様に「新しい支払いを1件発生させる」処理です。
つまり、構造としてこうなります。
- 二重実行の被害がもっとも大きい処理ほど、性質上 POST になる
- POST は仕様上べき等ではない
- したがって、べき等性は自動では手に入らず、設計で後付けする必要がある
見積書に「べき等性対応」という項目が独立して現れ、追加の工数が計上されるのは、この3番目の事情によるものです。決して不当な上乗せではなく、POST に対してリトライ耐性を後付けするための実装・テスト・運用設計の費用と考えるのが妥当です。
逆にいえば、決済や注文の機能を含む案件で、べき等性に関する記述も工数もまったく見当たらない見積は、対策が計画に入っていない可能性を疑うべきサインになります。
べき等キー(Idempotency-Key)でPOSTを安全にリトライする仕組み

べき等キーの発行・保存・レスポンス再利用の流れ
POST にべき等性を後付けする代表的な方法が、べき等キー(Idempotency-Key)を使う方式です。Stripe をはじめとする多くの決済APIが採用しており、事実上の標準的なパターンといえます。
仕組みは3ステップで説明できます。
ステップ1: リクエスト側がキーを発行する
「この1つの業務操作」を識別するための一意な文字列(UUIDなどのランダムな値)を生成し、Idempotency-Key というヘッダに載せてリクエストを送ります。重要なのは、リトライのときは新しいキーを作らず、1回目とまったく同じキーを送るという点です。
ステップ2: 受信側がキーと結果を保存する サーバーは、受け取ったキーが未処理のものであれば通常どおり処理を実行し、そのキーと処理結果(レスポンス内容)をセットで保存します。
ステップ3: 同じキーが再送されたらレスポンスを再利用する すでに保存済みのキーが届いた場合、サーバーは処理を実行しません。保存しておいた1回目のレスポンスをそのまま返します。呼び出し側から見れば「成功した」という同じ返事が返るので、処理は正常に完了したと判断できます。実際の課金は1件のままです。
この方式で、発注者が意識しておくべきポイントが「キーを何の単位で発行するか」です。ユーザーが「購入する」を押した1回のアクションに対して1つのキーを発行するのが基本です。ここを「リクエストごとに毎回新しいキーを生成する」実装にしてしまうと、リトライのたびに別のキーになるため、べき等キーを導入していても二重課金は防げません。
キーの保持期間をどう決めるか(Stripeの24時間・30日を例に)
べき等キーは永久に保存されるわけではありません。保存には容量とコストがかかるため、一定期間で消去されます。この保持期間の設定が、防御できる範囲を決めます。
Stripe の公式ドキュメントは、APIのバージョンによって異なる保持期間を明記しています。API v1 では「同じべき等キーを使用し、互いに24時間以内に発生した場合」に同一リクエストとみなされ、API v2 では「同じべき等キーを使用し、同じAPIに対して作成され、同じアカウントまたはサンドボックス内で発生し、さらにそれぞれのリクエストが30日以内の間隔で発生している場合」とされています(API v2 の概要 - Stripe Docs)。
24時間と30日という差は、そのままトレードオフの幅を表しています。
保持期間 | メリット | デメリット |
|---|---|---|
短い(数時間〜24時間) | 保存コストが小さい。運用がシンプル | 期間を過ぎてからの再送は防げない |
長い(数日〜30日) | 遅延したリトライや手動再実行まで防げる | 保存容量と管理コストが増える |
自社の保持期間を決めるときは、「リトライがいつまで発生しうるか」から逆算するのが実務的です。たとえば Webhook の自動再試行が最長3日間続くサービスを使っているなら、Webhook 受信処理の重複防止には最低でも3日、余裕をみて7日程度は保持しておく必要があります。ここを24時間で設計してしまうと、4日目に届いた再送を素通りさせてしまいます。
発注時には「保持期間を何日に設定しますか。その根拠は何ですか」と聞いてください。数字そのものよりも、根拠を説明できるかどうかが判断材料になります。
同時に同じキーが届いたときの挙動と、DBのUNIQUE制約という代替手段
べき等キーの実装で見落とされやすいのが、同じキーのリクエストがほぼ同時に届くケースです。
先ほどの3ステップは「1回目の処理と保存が完了してから2回目が届く」ことを前提にしていました。しかし、ユーザーがボタンを2回続けて押した場合、2つのリクエストがミリ秒差でサーバーに到達します。このとき両方が「このキーはまだ未処理だ」と判定してしまうと、結局どちらも処理を実行し、二重課金が発生します。べき等キーを実装したのに防げなかった、という事故の典型パターンです。
対策としては、キーの登録時点で排他制御をかけ、後から来たリクエストには「処理中です」という応答(HTTPステータス 409 や 429 など)を返して、しばらく待ってから再試行させる設計が一般的です。設計レビューでは「同一キーの同時到達をどう扱いますか」と具体的に確認してください。
なお、すべての処理にべき等キーの仕組みを組み込む必要はありません。より軽量な代替手段として、データベースのUNIQUE制約を使う方法があります。「同じ注文番号のレコードは1件しか作れない」という制約をデータベース側に設定しておけば、2件目の登録は必ず失敗します。仕組みが単純で、実装コストも低く抑えられます。
ただしこの方法にも設計上の判断は必要です。2件目が失敗したときにエラーを返すのか、それとも「すでに登録済みです」として成功扱いにするのか。前者だとユーザーには失敗に見えてしまうため、リトライの文脈では後者が適切なことが多くなります。「UNIQUE制約で対応します」という説明を受けたら、「2回目のリクエストには何を返しますか」まで確認しておくとよいでしょう。
決済代行サービスを使う場合の責任分界点
「Stripe や決済代行サービスを使っているのだから、二重課金は向こうが防いでくれるのでは」という理解は、発注者のあいだで非常によく見られます。半分は正しく、半分は誤りです。
決済プロバイダが守ってくれるのは、あくまで「同じべき等キーで、期間内に、同じAPIへ送られた再送」に対する重複課金です。それ以外の範囲は自社アプリケーション側の責任になります。
守る範囲 | 担当 | 具体例 |
|---|---|---|
同一キー・期間内の同一API再送に対する課金の重複防止 | 決済プロバイダ側 | 同じ |
べき等キーの発行と、再送時に同じキーを使うこと | 自社アプリケーション側 | 「購入」1回につき1キー。リトライ時に同じキーを再利用する |
自社DBの注文レコードが重複しないこと | 自社アプリケーション側 | 注文テーブルへの重複INSERTの防止 |
ポイント付与・在庫引当・会員ステータス更新の重複防止 | 自社アプリケーション側 | 決済成功をトリガーに動く後続処理すべて |
Webhook 受信処理の重複実行防止 | 自社アプリケーション側 | 受信済みイベントIDの記録とスキップ |
通知メール・チャットの重複送信防止 | 自社アプリケーション側 | 送信済みフラグの管理 |
つまり、決済プロバイダ側で課金が1件に抑えられていても、自社側で注文レコードが2件作られ、ポイントが2倍付与され、確認メールが2通届くという事態は十分に起こり得ます。顧客から見れば、これも立派な「二重処理」です。
「決済代行を使っているので大丈夫です」という説明を受けたら、「決済の重複は防げるとして、注文レコードとポイント付与はどこで防いでいますか」と一段掘り下げて確認してください。
システム開発 完全チェックリスト――発注前・発注中・完了後の3フェーズで使えるチェック集

この資料でわかること
システム開発の外注・発注を初めて経験する担当者や、過去に失敗を経験した担当者が、発注プロセスの各フェーズで「何をチェックすべきか」を明確に把握できるようにする。
こんな方におすすめです
- 初めてシステム開発を外注する担当者
- 過去の発注で失敗を経験した方
- ベンダー選定の基準が分からない方
入力いただいたメールアドレスにPDFをお送りします。
自社のどの処理にべき等性が必要かを絞り込む

二重実行の損失で優先度を決める3つの判断軸
べき等性の対策には設計・実装・テストの工数がかかります。すべての機能に一律で適用しようとすればコストは跳ね上がり、かえって重要な処理への手当てが薄くなりかねません。優先度をつけて絞り込むことが現実的です。
判断軸は次の3つです。
軸1: 二重に実行されたら、金銭・在庫・信用の損失が出るか 決済・請求・ポイント付与・在庫引当・外部への発注は「出る」に該当します。一方、閲覧履歴の記録や検索ログのように、重複しても実害がない処理もあります。
軸2: 損失が自動で回復できるか、人手の対応が必要か システム側で自動的に打ち消せる処理と、返金処理・お詫び連絡・帳簿の修正といった人手が必要な処理では、優先度がまったく違います。人手が必要な処理は、件数が少なくても優先度を上げてください。
軸3: 外部から再送される経路があるか ユーザーの二重クリック、クライアントの自動リトライ、Webhook の重複配信、バッチの再実行、管理画面からの手動再実行。これらの経路があるほど、重複が起きる確率は上がります。
この3軸を組み合わせると、次のように優先度を整理できます。
優先度 | 条件 | 対応方針 |
|---|---|---|
高 | 金銭の損失があり、回復に人手が必要で、再送経路もある | べき等キー方式で厳密に対策する |
中 | 損失はあるが自動回復できる、または再送経路が限定的 | UNIQUE制約など軽量な手段で防ぐ |
低 | 重複しても実害がない | 対策不要。工数を割かない |
対象処理の棚卸し表のつくり方(記入例つき)
3つの軸を、そのまま社内会議やベンダーとの打ち合わせに持ち込める形にしたのが次の棚卸し表です。発注前に事業側で下書きし、ベンダーとのキックオフで内容をすり合わせる使い方を想定しています。
処理名 | 再送が起きる経路 | 二重実行時の影響 | 回復方法 | 優先度 |
|---|---|---|---|---|
決済実行 | ユーザーの二重クリック、通信断からのリトライ | 二重課金・返金・信用低下 | 人手(返金処理と顧客連絡) | 高 |
注文登録 | 決済と同経路、Webhook 再配信 | 出荷が2件・在庫の過剰引当 | 人手(出荷停止・在庫修正) | 高 |
ポイント付与 | Webhook 再配信、バッチ再実行 | ポイント原価の増加・不公平 | 人手(個別調整) | 高 |
在庫引当 | バッチ再実行 | 実在庫と帳簿在庫の乖離 | 人手(棚卸し照合) | 高 |
注文確認メール送信 | Webhook 再配信 | 顧客の混乱・問い合わせ増 | 回復不能(送信済み) | 中 |
会員ステータス更新 | 管理画面からの再実行 | 上書きのみで実害は限定的 | 自動(再計算で戻る) | 中 |
閲覧履歴の記録 | クライアントのリトライ | 集計値がわずかにずれる | 自動(集計時に排除) | 低 |
「回復方法」の列に「人手」が並ぶ行が、優先的に守るべき処理です。逆に「自動」が並ぶ行まで厳密な対策を求めると、費用対効果は下がります。この表を埋めておくと、ベンダーに対して「この4つを対象範囲としてください」と発注側から範囲を提示できるようになります。
発注時にべき等性を要件へ落とし込む確認点
要件定義書・RFPに書く文言の例
べき等性は非機能要件のひとつです。「よしなにお願いします」では認識がずれますし、後から「その範囲は聞いていません」という水掛け論にもなります。検証できる形で書くことが重要です。
要件定義書やRFPに記載する文言の例を挙げます。そのまま使えるよう、対象・条件・期待結果を明示した形にしています。
決済・注文の重複防止 決済実行APIおよび注文登録APIは、同一のべき等キーによる再送に対して、二重に決済・登録が行われないこと。再送時には初回と同じ処理結果を返却すること。べき等キーは1回の購入操作につき1つ発行し、リトライ時は同一のキーを使用すること。
Webhook 受信処理の重複防止 外部サービスからのWebhook受信処理は、同一イベントIDのイベントを複数回受信した場合においても、後続処理(注文登録・ポイント付与・通知送信)が二重に実行されないこと。処理済みイベントIDの保持期間は、送信元サービスの再試行期間を上回る日数とすること。
バッチ処理の再実行耐性 日次バッチは、処理が中断した状態から再実行された場合においても、処理済みレコードに対して重複した更新・付与を行わないこと。
検証可能性 上記各要件について、受入テストで検証可能なテストシナリオと期待結果を、テスト仕様書に記載すること。
最後の「検証可能性」の一文が効きます。要件に書いてあってもテスト項目に落ちていなければ、実際に確認されないまま納品されてしまうためです。
なお、べき等性は API 連携の発注時に確認すべき非機能要件の1つにすぎません。要件・仕様・見積・契約まで含めた確認手順は、API連携を発注する際のチェックポイントで全体像を整理しています。
見積・設計レビューでベンダーに確認する5つの質問
要件を書いたら、次は見積と設計レビューの場での確認です。技術的な実装内容を評価する必要はありません。以下の5つを聞き、回答の方向性を照らし合わせるだけで、対策の実質を判断できます。
質問1: べき等性の対象範囲はどこまでですか
- 望ましい回答: 「決済実行、注文登録、ポイント付与、Webhook受信処理の4つです」と処理名で具体的に返ってくる
- 危うい回答: 「API全体で対応しています」という範囲の曖昧な説明
質問2: べき等キーは誰が生成し、何を単位に発行しますか
- 望ましい回答: 「フロントエンドで購入操作1回につき1つUUIDを生成し、リトライ時も同じ値を送ります」
- 危うい回答: 「リクエストごとに生成します」(リトライで別キーになり、防げません)
質問3: キーの保持期間は何日ですか。その根拠は何ですか
- 望ましい回答: 「Webhookの再試行が最長3日なので、余裕をみて7日保持します」と根拠つきで返ってくる
- 危うい回答: 「デフォルト設定のままです」と根拠を説明できない
質問4: 同一キーのリクエストが同時に届いた場合、どう応答しますか
- 望ましい回答: 「排他制御をかけ、後着には409を返して再試行させます」
- 危うい回答: 「同時に来ることは想定していません」(実際には起こります)
質問5: 保持期間を過ぎてから同じキーで再送された場合、どうなりますか
- 望ましい回答: 「新規リクエストとして処理されます。そのため保持期間を〇日に設定しています」とリスクを認識した説明
- 危うい回答: 「永久に防げます」(保持期間がある以上、あり得ません)
5つとも、専門知識がなくても回答の具体性で判断できる質問です。「対応済みです」という一言に対して、これらを順に投げていくことで、対策の中身が可視化されます。
追加費用の妥当性を判断する3つの分解軸
「べき等性対応」として提示された追加見積が妥当かどうかは、金額の相場を調べても判断できません。案件によって作業量がまったく違うためです。判断するには、見積を次の3軸に分解してもらうのが有効です。
分解軸 | 確認すること | 費用が増える条件 |
|---|---|---|
対象処理の数 | 何本のAPI・処理に適用するか | 対象が多いほど実装・テストの本数が増える |
保持要件 | キーの保存先(DB/キャッシュ)、保持期間、期限切れの管理、監視の有無 | 保持期間が長い、専用の保存基盤が必要、監視を組む場合 |
並行制御の要否 | 同時到達への排他制御が必要か、既存DB制約で足りるか | 排他ロックや分散ロックの実装が必要な場合 |
この3軸で内訳を求めたとき、「対象は4処理、保存はキャッシュで7日保持、うち決済のみ排他制御あり」というように説明できるベンダーであれば、実際に設計を検討したうえで見積を出していると判断できます。逆に、一式で計上されていて内訳の説明を求めても分解できない場合は、「対応します」という前提だけ置いて具体的な設計が未着手の可能性があります。
なお、対象処理を減らせば費用は下がりますが、その分だけ守られない処理が残ります。棚卸し表の「優先度:高」の行が対象範囲から外れていないかは、必ず確認してください。
受入テストと運用で「本当に防げているか」を検証する

受入テストで実施する4つの検証シナリオと期待結果
要件に書き、見積で確認したうえで、最後に残るのが「実際に防げているか」の検証です。ここは発注者が主体的に実施できる領域です。以下の4シナリオを受入テストの項目として提示してください。
# | シナリオ | 実施手順 | 期待される結果 |
|---|---|---|---|
1 | 同一リクエストの2連打 | テスト環境で購入ボタンを短い間隔で2回押す | 決済1件・注文1件のみ。ユーザー画面には正常完了が表示される |
2 | レスポンス受信前の通信断からの再送 | 購入処理の実行中に通信を遮断し、復旧後に同じ操作を再実行する | 決済1件・注文1件のみ。1回目の結果が反映されている |
3 | Webhook の重複配信 | 同一イベントIDの通知を2回送信する(ベンダーに再送を依頼) | 注文登録・ポイント付与・メール送信がいずれも1回のみ |
4 | 保持期間経過後の再送 | 設定した保持期間を過ぎてから同じキーで再送する | 事前に合意した挙動どおりであること(新規処理になる場合、その旨が仕様書に明記されている) |
シナリオ4は「防げること」ではなく「仕様どおりであること」を確認する項目です。保持期間がある以上、それを過ぎれば新規リクエストとして扱われます。この挙動を発注側が把握しないまま運用に入ると、後から「防げると聞いていた」という認識の齟齬になります。
もう1つ、余裕があれば加えたいのが「同じキーで、異なる内容のリクエストを送る」ケースです。たとえば同じべき等キーで金額だけを変えて送信したとき、エラーになるのが望ましい挙動です。素通りしてしまう場合、キーの扱いに設計上の欠陥がある可能性があります。
テストの実施をベンダーに任せる場合でも、テスト結果のエビデンス(実行ログ、DBの登録件数、決済管理画面のスクリーンショット)の提出を求めてください。「テスト済みです」という報告ではなく、件数が1件であることを示す証拠が判断材料になります。
運用開始後のモニタリングと、重複が起きた場合のリカバリ手順の合意
受入テストで潰せるのは、想定したシナリオの範囲だけです。想定外の経路や、リリース後の機能追加によって、重複のリスクは再び生まれます。運用に入ってからの備えを、契約・保守の範囲に含めておくことが重要です。
モニタリング項目
- 同一べき等キーによる再送の検知件数(急増していれば、どこかでリトライが多発しているサイン)
- 重複と判定してスキップした処理の件数
- 決済管理画面の決済件数と、自社DBの注文件数の日次照合(差分が出ていれば重複または欠落が起きている)
- Webhook の受信件数と処理件数の差分
これらは「重複が起きたことを検知する」ための仕組みです。何も検知していない状態は、防げているのか、気づいていないだけなのか区別がつきません。
リカバリ手順の合意
実際に重複が発生したとき、慌てずに動けるかどうかは事前の取り決めで決まります。次の項目を、リリース前にベンダーと文書で合意しておいてください。
決めておくこと | 内容 |
|---|---|
検知の担当 | アラートを誰が受け取り、どのチャネルに通知されるか |
一次対応 | 影響範囲(対象顧客・件数・金額)を誰がどの手順で特定するか |
実行の担当 | 返金・取消の操作を自社が行うのか、ベンダーが行うのか |
顧客連絡 | 通知の文面と送信タイミングを誰が判断するか |
保守範囲 | 原因調査と恒久対策が保守契約に含まれるか、別途見積か |
とくに最後の「保守範囲」は、事故が起きてから交渉すると必ず揉めます。契約段階で確認しておく価値のある項目です。
まとめ|べき等性は発注者が確認できる非機能要件
べき等性とは、同じ処理を何度実行しても結果が1回分にしかならない性質です。ネットワーク越しの通信では「実行されたかどうか分からない」状態が必ず発生するため、安全にリトライできることが、決済やAPI連携における信頼性の前提になります。
そして、決済・注文といったもっとも重要な処理は性質上 POST になり、POST は仕様上べき等ではありません。だからこそ、べき等キーやDB制約による後付けの設計が必要になり、それが見積上の「べき等性対応」として現れます。
ここまで見てきたとおり、この非機能要件は実装の詳細に閉じたものではありません。発注者の側から、次の5つのステップで関与できます。
- 対象処理を絞り込む — 損失の大きさ・回復に人手が必要か・再送経路の有無の3軸で棚卸し表を作り、優先度「高」の処理を特定する
- 要件定義書に書く — 「同一のべき等キーによる再送に対して二重に実行されないこと」「受入テストで検証可能なシナリオを提示すること」を明記する
- 見積時に5つの質問を投げる — 対象範囲・キーの生成単位・保持期間と根拠・同時到達時の挙動・期限切れ後の扱い
- 受入テストで検証する — 2連打・通信断からの再送・Webhook重複配信・保持期間経過後の4シナリオを実施し、エビデンスを受け取る
- 運用のリカバリ手順を合意する — 検知の仕組みと、重複発生時の一次対応・返金実行・顧客連絡・保守範囲を文書で残す
「対応済みです」という回答を信じるしかない状態から、「どこまでを対象にして、キーは何単位で、保持期間は何日で、同時到達はどう扱いますか」と具体的に問える状態へ。この5ステップを手元に置いておけば、次の打ち合わせから実践できます。
まずは、自社の処理を棚卸し表に書き出すところから始めてみてください。優先度「高」の行が何本あるかが分かった時点で、ベンダーに提示すべき対象範囲は決まります。
関連情報
システム開発の見積の見方や、費用の内訳をどう確認すればよいかを整理したい方は、お役立ち資料のシステム開発の費用を正しく理解するガイドブックもあわせてご覧ください。非機能要件を含む見積の読み解き方をまとめています。
決済連携やAPI連携の要件定義でお困りの場合は、お問い合わせフォームからご相談ください。要件を整理する段階からのご相談も承っています。
システム開発 完全チェックリスト――発注前・発注中・完了後の3フェーズで使えるチェック集

この資料でわかること
システム開発の外注・発注を初めて経験する担当者や、過去に失敗を経験した担当者が、発注プロセスの各フェーズで「何をチェックすべきか」を明確に把握できるようにする。
こんな方におすすめです
- 初めてシステム開発を外注する担当者
- 過去の発注で失敗を経験した方
- ベンダー選定の基準が分からない方
入力いただいたメールアドレスにPDFをお送りします。
よくある質問
- べき等性の対応漏れがないか、見積・設計レビューの場で一番早く確認できる方法は何ですか?
見積・設計レビューの場で「べき等性の対象範囲はどこまでか」を処理名で具体的に答えられるか確認する方法が最も早く判断できます。「API全体で対応済みです」という範囲の曖昧な回答は、対策が計画に入っていない可能性を疑うサインです。
- 決済代行サービス(Stripeなど)を使っていれば、べき等性対応は不要ですか?
いいえ、決済代行が防ぐのは同一べき等キー・期間内の課金重複のみです。自社DBの注文レコードやポイント付与、Webhookの重複処理、通知メールの重複送信の防止は自社アプリケーション側の責任であり、別途の対応が必要になります。
- べき等性対応として提示された追加見積は、どう妥当性を判断すればよいですか?
金額の相場だけでは判断できません。対象処理の数・キーの保持要件・並行制御の要否という3つの軸に見積を分解してもらい、内訳を具体的に説明できるベンダーかどうかで妥当性を判断してください。一式で計上され内訳を説明できない場合は、設計が未着手の可能性を疑いましょう。
- すべての処理にべき等キーを導入する必要がありますか?
不要です。金銭的損失があり人手対応が必要な処理には厳密なべき等キー方式を、実害の少ない処理にはデータベースのUNIQUE制約などの軽量な手段を使い分けるのが現実的な対応です。優先度は損失の大きさ・回復の容易さ・再送経路の有無という3つの軸で判断してください。
- べき等性対応が「本当に効いているか」を非エンジニアでも検証する方法はありますか?
受入テストで「2連打」「通信断からの再送」「Webhookの重複配信」「保持期間経過後の再送」の4シナリオを実施してもらい、決済・注文件数が1件であることを示すエビデンス(実行ログやスクリーンショット)の提出を求める方法があります。



