26
26

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Shopify の Webhook を試してみる

Posted at

Shopify では、外部サービスと連携する仕組みの一環として、多くの Webhook イベントを用意している。カートに商品追加したとか、注文完了とか、支払い完了したとか。これを使って、Shopfiy だけではできない様々なことが行えるようになる。

ここでは、以下2点を紹介する。

  • Shopify の Webhook の仕様
  • Webhook リクエストをローカルのサービスで動作確認する方法

Shopify の Webhook について

Shopify がサポートしている Webhook タイミング

Shopify が提供している Wehook の一覧は、以下のページに書いてある。
https://help.shopify.com/api/reference/webhook

Shopify の Webhook の仕様

リクエストメソッド: POST
リクエストボディの形式: JSON か XML
タイムアウト: 5 秒
失敗時の繰り返しルール: 最初の失敗から、48時間で、19回繰り返す。(間隔についての記載はないので、不明)
レスポンス: Webhook を受けたら、200 を返す。

詳しくは、ドキュメントのここを参照。

ヘッダー

Shopify の Webhook へのリクエストヘッダーには以下の情報が含まれる。これは、サービス側でのリクエストの検証に使える。

  • X-Shopify-Topic : どの Webhook イベントか。例: orders/create
  • X-Shopify-Hmac-Sha256 : Body を Hmac 化したもの。検証に使う。例: XWmrwMey6OsLMeiZKwP4FppHH3cmAiiJJAweH5Jo4bM=
  • X-Shopify-Shop-Domain : どの Shopify ストアからのものか。例: johns-apparel.myshopify.com

ボディ

ボディの内容は、Webhook の topic によって異なるので、各 Webhook の仕様を確認ください。

設定方法

Shopify の Webhook を利用する手順は以下の通り。

事前条件: Shopify ストアにログインできること。

  1. Shopify の管理画面にログインし、画面左下の Settings をクリックする。
  2. Notifications メニュークリックする。
  3. 一番下までスクロールすると、Webhooks というセクションがある。
  4. Create webhook ボタンを押し、以下の情報を入力する。
    • Event : Webhook 送信タイミング。
    • Format : JSON or XML
    • URL : 送信先の URL
  5. Save webhook をクリックする。

以上。これで、設定したタイミングになったときに、設定した宛先に POST リクエストが飛んで行く。

注: みての通り、Shopify の Webhook では設定で、API キーや認証情報は指定できない作りになっている。そのため、送られてきたリクエストが、本当に Shopify からのものか、途中で改竄されていないかは、サービス側で検証する必要がある。

次に、その検証方法を説明する。

Webhook リクエストの検証方法

Shopify ドキュメントにあるまんまを書く。ここでは、Ruby (というか Sinatra) を使った場合の例を示す。ドキュメントには、PHP の場合の例も載っている。

検証ロジック

検証は、リクエストヘッダーにある Shopify からの HAMC (X-Shopify-Hmac-SHA256) とリクエストボディとシークレットキーを使って、算出した HMAC が同じ値になるかを比較する。

検証に使うデータ

  • リクエストヘッダーにある X-Shopify-Hmac-SHA256
  • シークレットキー: シークレットキーは、Shopify 管理画面の Webhook の設定の一番下に以下のメッセージがあるので、そこにある文字列。
All your webhooks will be signed with dfdfdfadsfadf2332ad3da09un3krjfdjflsafadfoj32lfadfcfdauf2a1ca4 so you can verify their integrity.

コード

require 'rubygems'
require 'base64'
require 'openssl'
require 'sinatra'

# The Shopify app's shared secret, viewable from the Partner dashboard

SHARED_SECRET = 'my_shared_secret'

helpers do
  # Compare the computed HMAC digest based on the shared secret and the request contents

  # to the reported HMAC in the headers

  def verify_webhook(data, hmac_header)
    digest  = OpenSSL::Digest::Digest.new('sha256')
    calculated_hmac = Base64.encode64(OpenSSL::HMAC.digest(digest, SHARED_SECRET, data)).strip
    ActiveSupport::SecurityUtils.secure_compare(calculated_hmac, hmac_header)
  end
end

# Respond to HTTP POST requests sent to this web service

post '/' do
  request.body.rewind
  data = request.body.read
  verified = verify_webhook(data, env["HTTP_X_SHOPIFY_HMAC_SHA256"])

  # Output 'true' or 'false'

  puts "Webhook verified: #{verified}"
end

※: my_shared_secret は上記に書いたシークレットキーで置き換える

Webhook リクエストの内容の確認

上記までで、リクエストを検証できる段階になったかと思います。ただ、実際にどんなデータが飛んで来るのか、事前に確認したいかと思います。ここではそれを確認します。

確認するためのツールとして、RequestBinという外部サービスを利用します。これは一時的に有効は URL を発行していくれて、そこで受けたリクエストを Web 画面上に表示してくれるサービスです。このような外部リクエストの内容確認用のサービスなのです。

  1. RequestBinにアクセスします。
  2. private にチェックし、Create a RequestBin を押します。
  3. URL が発行されるので、この URL をコピーします。この画面はこのまま閉じずに置いておきます。リクエストが飛んできたらこの画面に内容が表示されるからです。
  4. Shopify の管理画面の Webhook の設定 (Settings > Notifications) に行き、URL にこの URL を設定します。
  5. 設定後、その設定の右の(ゴミ箱アイコンの左) send test notification をクリックします。これで、テストデータで RequestBin 宛にリクエストが送信されました。
  6. RequestBin の画面に戻り、画面をリフレッシュします。これでリクエストの内容を確認できたと思います。リクエストヘッダーやボディを確認してください。
  7. ストアの準備ができている場合は、Webhook のイベントに設定したタイミングで、実際にどんなデータが飛んで来るのか、確認してください。(例えば、購入完了のタイミングに設定しているのであれば、実際に購入完了をしてみてください。)

RequestBin は同じ URL で何回もリクエストを受けることができるので、送信したら画面をリフレッシュし、内容を確認してください。

ローカルで動作確認

上記までで、Shopify の Webhook を受けるエンドポイントを作成できる状態になったと思います。ここでは、必要な内容を実装し終わり、それが正常に動くのか、実際の Shopfiy の Webhook からのリクエストを受けて確認する方法を説明します。

そのサービスをインターネットに公開できていれば、ここで説明する内容は必要ありませんが、普通は先にローカルで確認したいかと思います。

実際に Shopify からの Webhook を受けるためには、サービスがインターネットに公開されていなくてはいけません。ここでは、ngrok というトンネルサービスを利用して、ローカルで立ち上げたサーバーを一時的に、インターネットからアクセスできるようにします。

ngrok の準備

  1. ngrok をダウンロード
  2. ダウンロードしたディレクトリに移動。
  3. OSX または、Linux の場合は、./ngrok http 4567 で起動。Windows の場合は、ngrok http 4567
  4. 起動すると、ngrok が立ち上がり、Forwarding ってとこに、外部からアクセス可能な URL が表示される。これが、Shopify 側に今回設定する URL となる。例: http://ac2a51a0.ngrok.io
  5. ブラウザで一旦、このアドレスにアクセスし、localhost の場合と同じ結果か確認する。

4567 というのは Sinatra のデフォルトポートなので、各自起動しているサーバーのポート番号に置き換えること

動作確認

ngrok が準備できたら、後は RequestBin のときと同じで、Shopify の管理画面の Webhook の設定の URL に ngrok で発行されている URL (https の方)を設定する。

後は、テスト送信で内容を動作を検証したり、実際にストアを動かして、正常にリクエストを処理できるか確認する。

備考

Shopify との連携という意味でいうと、Shopify アプリを作るという手段もある。それについては、Shopify 用のプライベートアプリを作ってみたで説明している。

26
26
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
26
26

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?