本文へスキップ

注文が二重登録されるのはなぜ?Webhook連携で再送しても重複させない方法

まず押さえたいこと

Webhookでは同じ通知が再送されたり、処理結果の応答だけが失われたりします。通知IDの記録に加え、注文や出荷単位で同じ仕事を重ねない仕組みが必要です。結果不明を失敗と決めつけず、照会や確認待ちを含めて再開します。

  • 通知が二回来ること自体は、連携の異常とは限らない。
  • 通知のIDと、実行する業務の識別子を分ける。
  • 登録後の通信切断を試し、結果不明の処理を追えるようにする。
発注前のチェックリストを見る
このガイドの背景

お客様の注文は一件なのに、倉庫には同じ出荷指示が二件ある。担当者は再送ボタンを押しただけで、二度送るつもりはなかった。連携が不安定なときに起こり得る困りごとです。

原因には、同じ通知の再送や、登録済みなのに応答だけ届かない通信切断があります。Webhookは届いた回数と仕事をする回数を分ける設計が必要です。二重登録を防ぎながら、未処理も取りこぼさない方法を説明します。

相手は受け付けた。でも、こちらには返事が届かなかった

説明用の例として、決済完了の通知を受け、倉庫へ出荷指示を送る連携を考えます。倉庫は指示を登録したものの、その応答が通信途中で失われたとします。送信側にはタイムアウトが表示されますが、倉庫には既に指示があります。新しい番号で送り直せば、相手は別の指示として受け付けるかもしれません。

このとき「失敗だから再送」は成り立ちません。まず結果が分からない状態として記録し、倉庫の指示番号や外部注文番号から調べます。すぐ検索して出てこないことも、未登録の証拠になるとは限りません。相手側の反映に時間がかかるなら、確認まで待つ必要があります。業務担当者がこの状態を見分けられることが、安全な復旧の入口です。

検討の流れ説明用の例:二重出荷につながる分かれ道
  1. 倉庫で登録済み

    出荷指示は受け付けられている

  2. 応答だけ届かない

    送信側は結果を確定できない

  3. 同じ指示を照会

    既存の結果を確認してから再開を決める

通信の失敗と、出荷指示が未登録であることは同じではありません。

Webhookは、一回だけ届く前提にしない

Webhookは、注文や決済などの変化を相手へ知らせる通知です。送信元が受領の応答を確かめられない場合などに、同じ通知が再び届くことがあります。Stripeの公式資料も重複配送と到着順の不確実さを説明しています。通知が再送されたら仕事まで繰り返す設計では、一時的な通信の揺らぎが二重登録につながります。

受信側では、まず署名を検証します。Stripeでは未加工のリクエスト本文を使い、検証に失敗した通知は重複判定用の記録へ入れません。正当な通知だけを対象に、通知IDの重複判定と後から処理できる内容の永続保存を行い、その後に受領応答を返します。「署名検証→重複判定と永続保存→受領応答」の順です。保存前に成功を返すと、直後の停止で通知を失うおそれがあります。重い業務処理は保存後の別工程で進め、未処理を追えるようにします。

参考:Stripe:Receive Stripe events in your webhook endpoint

通知が違っても、同じ注文を動かしていることがある

注文確定と決済完了という別々の通知から、同じ出荷を指示してしまう場合があります。通知IDが違うため、通知の重複だけを見ていても防げません。店舗、注文、出荷する単位などを組み合わせて、何を同じ仕事とみなすかを決めます。分納を扱うなら、注文番号だけで「一度済んだら禁止」とすると、必要な二回目の出荷まで止めてしまいます。

また、二つの処理が同時に未実行と判断する競合にも備えます。データベースの一意制約や条件付き更新などで、同じ仕事を実行する権利を重ねて取れないようにします。完了だけでなく処理中も記録し、途中停止したものをどう調べるかを決めます。「実行前に検索しています」という説明に加えて、同時に届いたときの結果を確かめるのが要点です。

冪等性は、送り直しても仕事を増やさないための仕組み

冪等性は、同じ操作を繰り返しても結果を重ねない性質です。外部APIが冪等キーを受け付けるなら、同じ仕事の再試行には同じキーを使います。毎回別のキーを作ると、相手には別の操作に見えます。StripeのAPIではキーに対応する結果を保存しますが、保持や適用には条件があり、期限を超えた再実行まで無条件に守られるわけではありません。

金額や対象を変えた訂正は、同じ操作のやり直しとは区別します。古いキーを流用すればよいとは限りません。自社側でも、どの業務操作をいつ試し、結果がどうなったかを保持します。連携先に重複防止や結果照会の手段がなければ、人が確認する範囲を残す設計も必要です。相手の仕様を超えた無人復旧を約束しないことが、依頼範囲を決めるうえで重要になります。

参考:Stripe:Idempotent requests

待てば直る問題と、止めて確認する問題を分ける

アクセスが集中した一時的な制限と、住所の必須項目が空欄という入力不備は、同じ再試行では解決しません。前者は待機、後者は入力修正が必要です。AWS SDKの資料には、再試行の上限や待ち時間をばらつかせる考え方が示されています。一斉に送り直して相手へ負荷をかけないように、使うSDKと自社処理の双方の挙動を確認します。

業務上の締め切りも上限になります。いつまでも自動で待つと当日の出荷に間に合わないなら、途中で担当者へ知らせます。下表は判断の例で、実際には連携先の応答と処理の意味を合わせて決めます。HTTPの番号だけで、更新が実行されたかまで断定しないことが大切です。

表が収まらない場合は横にスクロールできます。

外部への書き込みをやり直す前の判断
起きたこと先にすること再開の条件
呼び出し制限指定された待機条件を確認許可される頻度で再試行
入力不足元データと必要項目を確認修正と履歴の記録が済む
権限切れ接続管理者へ連絡認証回復と対象状態の確認
登録後の通信切断外部の処理結果を照会重複を防ぐ根拠が得られる

参考:Amazon Web Services:Retry behavior - AWS SDKs and Tools

依頼先には、わざと途中で止める試験を頼む

正常な一件だけでは重複対策を評価できません。同じ通知の同時到着、古い通知の遅着、保存直後の停止、外部登録後の切断を試します。取消済みの注文を古い確定通知で戻さないこと、処理が増えず未処理だけ残ることを確認します。最新状態を取得して判断する案もありますが、途中の出来事を一件ずつ扱う業務は、それを省いてよいか別に検討します。

復旧の実演には、担当者が手入力で補った場面も入れます。自動処理を再開したときにその結果を認識できなければ、同じ重複が起こるためです。見積もりでは受信処理に加え、結果照会、保留一覧、手動復旧、漏れを探す照合の範囲を確かめます。二重登録を防ぐ仕組みと同じくらい、「今どの注文がどうなっているか」を人が説明できることが大切です。

検討・発注前のチェックリスト

担当者と確認状況を添えて、社内の検討メモや打ち合わせの議題にご活用ください。

チェックリストをテキストで保存

確認日:________________ / 担当者:________________

  • 通知IDと業務の識別子を分ける。確認状況・メモ:
  • 分納や訂正を同じ仕事と誤認しない単位を決める。確認状況・メモ:
  • 通知の同時到着を試験に含める。確認状況・メモ:
  • 登録直後の通信切断で結果を照会できるか試す。確認状況・メモ:
  • 再試行の上限と担当者へ戻す期限を決める。確認状況・メモ:
  • 手入力で補った結果を自動処理へ反映する。確認状況・メモ:
  • 古い通知と取りこぼしを照合できるようにする。確認状況・メモ:

よくある質問

再送をやめれば、二重登録はなくなりますか?

再送をやめるだけでは、届かなかった通知や途中で止まった処理が残ります。同じ仕事を重ねない記録を持ち、状態を確認したうえで未処理を再開する設計が必要です。

イベントIDを保存するだけでは足りませんか?

同じ通知の重複は見つけられますが、別の通知から同じ出荷を作る場合や同時実行は別に扱います。業務単位の識別、処理権の確保、外部の結果確認を合わせて設計します。

参考資料

製品の仕様・提供条件は変更されることがあります。採用時には公式資料と契約内容をご確認ください。

記事の内容を、自社の検討へ

二重登録を防ぐ連携の開発について相談する

どの注文が、どの連携先へ、どんな操作の後に重複したかをお知らせください。認証情報を除いた実行状況から、再送・結果照会・復旧を含む開発範囲を考えます。

相談で整理すること

対象業務・開発する範囲・運用の分担。まだ決まっていないことも含めて、一緒に整理します。

API連携・自動化を相談する

この記事について

編集・発行:株式会社ダンドリ

AI・業務システム・Webサービスの設計、開発、運用を支援する会社です。開発を検討する方が判断に使えるよう、公式資料と公開情報をもとに解説しています。

説明用の例と公開事例を区別し、参照した資料は本文と記事末尾に掲載しています。

会社情報を見る