Webhookの処理について

初めまして、お世話になります。

私は現在、Shopifyの注文ステータスが「発送済み」になった際にWebhookを受信し、とある処理を行おうと思っております。

Shopifyの仕様上、「5秒以内にステータスコード200で返答する必要がある。返答がない場合はそのあと19回再試行される」とのことですが、私が現在行っている処理(小計の100分の1を計算しポイントアプリのAPIを使用しポイントを付与する)を行うまでに2~3回のWebhookが送られてきてしまい、ポイント付与が重複してしまう状況です。

直接的なShopifyの技術的質問でなくて恐縮ですが、この場合は

・Webhookをうけとったらとりあえず返答し、署名のチェックやWebhookで行いたい処理はその後に行うことで返答を早くして多重起動を防ぐ

・何かしら別の仕組み(イベントID等の識別子を管理してプログラムの重複実行を防ぐためにDB等で管理)

・その他ShopifyのWebhookを扱う上でのベストプラクティス(もしございましたらご紹介いただきたいです)

どの手法をとることが望ましいでしょうか。

見当違いなご質問でしたら申し訳ございません。

ご教授いただければ幸いです。

@Anonymous_3c09b082a09fec75f310cdc6c7b9f99f

ShopifyのWebhookに詳しいわけではないので、

一個人の所感とお考えいただきたいのですが、

・ Webhookをうけとったらとりあえず返答し、署名のチェックやWebhookで行いたい処理はその後に行うことで返答を早くして多重起動を防ぐ

・何かしら別の仕組み(イベントID等の識別子を管理してプログラムの重複実行を防ぐためにDB等で管理)

この2つを組み合わせるのが良さそうに思いました。

例えば、

イベント管理は、お考えの通りDBでも良いですし、

Shopifyの注文のメタフィールドに「処理ID」を用意する方式でも良さそうです。

ポイント計算処理の最初にメタフィールド「処理ID」にイベントIDを登録し、

処理を完了しポイントを更新する段でもう一度「処理ID」を確認し、

処理中のイベントであることを確認してから最終的にポイントの更新を行う、といったイメージです。

この場合、「処理ステータス」というメタフィールドも用意して、

「ロック」や「処理済み」などの値で実行状態を管理されると、

より固い実装になりそうですね。

・その他ShopifyのWebhookを扱う上でのベストプラクティス(もしございましたらご紹介いただきたいです)

処理に先行してエンドポイントが200を返す仕様にする場合、

処理が失敗しても、Webhookがリトライしてくれません。

この場合に備えて、例えば、5分間間隔や10分間隔のバッチを用意して、

条件に当てはまる注文のうち「処理済み」になっていないものを後追いで処理する仕組みもあると良いかもしれません。

ご参考まで。

(キュー田辺)

株式会社Q

田辺様

丁寧にご回答頂きましてありがとうございます。

また、メタフィールドを使用したステータス管理や先行して200のレスポンスを返す場合の注意事項などもご教授いただきましてありがとうございます。

今回ご教授いただいた内容にて設計を検討させていただきます。

ありがとうございます。