はじめに
公式サイトから予約を入れるだけなら、話は単純です。難しいのはその後で、OTAから予約が入ったり、運営者が予約管理システム上で日程を1日ずらしたり、キャンセルが発生したりします。これらを公式サイト側にどう反映するか。
この記事では、外部からの変更通知(Webhook)と定期的な照合(突合)を組み合わせて、ずれても必ず戻る同期を作った方法を紹介します。
通知の中身を信用しない
Webhookに署名がないという現実
多くのサービスは、通知が本物かを確認するための電子署名を付けてくれます。しかし今回使った予約管理システムのWebhookには、署名の仕組みがありませんでした。あるのは「好きなヘッダーを1つ付けられる」機能だけです。
そこで合言葉となる文字列をヘッダーに設定し、届いた通知のヘッダーと照合する方式にしました。ただし、これだけでは十分ではありません。合言葉が漏れれば偽の通知を送れてしまいます。
通知は「何かが変わった」だけを伝える合図
そこで根本的に発想を変えました。通知の本文を一切信用せず、データは必ず自分で取りに行くという方針です。
偽の通知で予約内容を書き換えられる。通知の形式が変わると壊れる
「何か変わったらしい」を受けて、正規のAPIから正しいデータを取り直す
この方針なら、仮に偽の通知が送られてきても、起きるのは「無駄な照合処理が1回走る」だけです。データが壊れることはありません。通知の本文は保存もログ出力もせず、内容の指紋(ハッシュ値)だけを重複判定用に記録しています。
同じ通知が2回来ても大丈夫にする
ネットワークの都合で同じ通知が複数回届くことは珍しくありません。そこで通知の指紋をデータベースに記録し、同じものが来たら記録をスキップします。
ただし照合処理そのものはスキップしません。理由は、日程を9月10日→12日→10日と戻したとき、1回目と3回目の通知内容が完全に同じになるからです。「同じ通知だから何もしなくてよい」と判断すると、その変更を取りこぼします。
毎時の突合で取りこぼしを拾う
通知が届かない前提で作る
Webhookは便利ですが、届かないことがあります。実際、外部からの通知が100回以上連続で失敗した事例もありました。通知だけに頼る設計は、いつか必ず破綻します。
そこで1時間ごとに動く定期処理を用意し、現在有効な予約をまとめて取得して自社DBと突き合わせるようにしました。通知が届けば即座に、届かなくても1時間以内には必ず追いつきます。
OTA予約・日程変更・キャンセル
数秒で反応。ただし届かないことがある
最大1時間の遅れ。ただし必ず追いつく
日程・キャンセル・復活を反映
速い経路と確実な経路の両方を用意し、どちらも同じ照合処理を呼ぶ。これで速さと確実さを両立できます。
照合は読むだけにする
この照合処理は、予約管理システムに対して読み取りしか行いません。書き込みをすると、その変更がまた通知を呼び、無限ループになる危険があるからです。
「同期」というと双方向を想像しがちですが、片方向に絞ることで構造がぐっと単純になります。
変更の種類ごとに対応を変える
キャンセルは決済状況で扱いを分ける
予約管理システム側でキャンセルされたとき、公式サイト側がどう振る舞うべきかは、決済がすでに済んでいるかで変わります。
決済済みのキャンセルを自動で処理しないのは、返金額の判断がキャンセルポリシーや個別事情に左右されるからです。システムは「これは人が見るべき案件です」と伝えるところまでを担当します。
日程変更は「動かすもの」と「動かさないもの」を決める
運営者が日程を変更したとき、連動して直すべき項目とそうでない項目があります。
宿泊者専用ページの有効期限はチェックアウト日に連動するので、自動で再計算します。一方、有効開始日は絶対に動かしません。すでにお客様に配ったURLが「まだご利用いただけません」に逆戻りしたら、混乱を招くだけだからです。
金額も自動では変えません。お客様が同意した金額を、後から一方的に書き換えるべきではないからです。日程が変わって料金が変わるなら、それは運営者がお客様と話し合って決めることです。
自動課金日が過ぎているときの扱い
日程が前倒しされて、自動課金の予定日がすでに過去になってしまうことがあります。このとき即座に課金すると、運営者がまだ料金を調整している最中かもしれません。
そこで原則は課金せず、運営者に「確認してください」とメールを送る形にしました。ただしチェックインが当日か翌日なら、待っている余裕がないので即座に課金します。過剰に請求するミスは取り返しがつかないので、判断に迷う場面では人に委ねる設計にしています。
変化がないときはメールを送らない
突合の結果は運営者にメールで報告しますが、差分がゼロの回はメールを送りません。1時間ごとに「変更なし」が届いたら、本当に大事な通知が埋もれてしまうからです。
逆に、1日1回動く自動課金処理は対象がゼロ件でも必ず報告メールを送ります。こちらは「今日も仕組みが動いた」という生存確認を兼ねているからです。目的によって、送る・送らないを使い分けています。
まとめ
崩れない同期を作るために大事にしたのは、次の3点です。
- 通知の中身を信用しない — 合図としてだけ受け取り、データは正規のAPIで取り直す
- 二重の経路を持つ — 速いWebhookと確実な定期突合を組み合わせる
- 判断が要る変更は人に渡す — 返金や料金変更は自動化せず、目印を付けて通知する