Перейти до вмісту
На сайт

Як надійно отримувати вебхуки Shopify

Shopify надсилає вебхуки на джерело Railhook. Джерело перевіряє HMAC, зберігає кожен вебхук таким, яким він надійшов, і пересилає його у ваш сервіс із повторними спробами. Railhook відповідає Shopify одразу, тож повільний чи збійний застосунок більше не ставить підписку під загрозу.

Чому вебхукам Shopify потрібен буфер

Section titled “Чому вебхукам Shopify потрібен буфер”

Shopify чекає на відповідь застосунку п’ять секунд. Невдалий вебхук він повторює до восьми разів протягом чотирьох годин, а якщо невдачі тривають, видаляє підписку. (Shopify: Troubleshooting webhooks) Доставки слід дедуплікувати за X-Shopify-Webhook-Id. (Shopify: Deliver webhooks through HTTPS)

Коли попереду стоїть Railhook:

  • Railhook відповідає Shopify, щойно збереже вебхук, задовго до спливу п’яти секунд.
  • Ваш сервіс отримує до 5 спроб на кожне пересилання з інтервалами від 1 хвилини до 1 години, а те, що так і не вдалося доставити, потрапляє в «Недоставлені пересилання».
  • На другу доставку з тим самим X-Shopify-Webhook-Id Railhook відповідає збереженою копією і вдруге її не пересилає.
  • Будь-який збережений вебхук можна відтворити, доки зберігаються події, навіть коли чотири години Shopify давно минули.

Знадобляться проєкт Railhook і API-ключ. Ті самі кроки є в панелі керування, у розділі «Вхідні».

Terminal window
export RAILHOOK_URL=https://railhook.io # or your own instance
export RAILHOOK_API_KEY=...
export PROJECT_ID=...
  1. Створіть джерело із секретом клієнта (client secret) вашого застосунку. Shopify обчислює X-Shopify-Hmac-SHA256 саме з ним, тож за ним Railhook і перевіряє підпис:

    Terminal window
    curl -X POST "$RAILHOOK_URL/api/v1/projects/$PROJECT_ID/incoming-sources" \
    -H "X-API-Key: $RAILHOOK_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"name":"Shopify","providerType":"SHOPIFY","verificationMode":"PROVIDER","hmacSecret":"'"$SHOPIFY_CLIENT_SECRET"'"}'

    Збережіть id і ingressUrl із відповіді.

  2. Додайте призначення, URL вашого сервісу:

    Terminal window
    curl -X POST "$RAILHOOK_URL/api/v1/projects/$PROJECT_ID/incoming-sources/$SOURCE_ID/destinations" \
    -H "X-API-Key: $RAILHOOK_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"url":"https://api.example.com/webhooks/shopify","authType":"BEARER","authConfig":"{\"token\":\"...\"}","enabled":true}'
  3. Оформіть підписку в shopify.app.toml, указавши ingressUrl як uri:

    shopify.app.toml
    [webhooks]
    api_version = "2026-07"
    [[webhooks.subscriptions]]
    topics = ["orders/create"]
    uri = "https://railhook.io/ingress/<token>"

    Розгорніть зміни командою shopify app deploy. Поки працює shopify app dev, кожна збережена зміна одразу застосовується до вашого магазину для розробки (development store).

  4. Надішліть тестовий вебхук:

    Terminal window
    shopify app webhook trigger --api-version=2026-07 --topic=orders/create --address="$INGRESS_URL"

    Він з’явиться в розділі «Вхідні» → «Отримані» з одним пересиланням на кожне призначення.

Як перевіряється підпис

Section titled “Як перевіряється підпис”

Railhook обчислює HMAC-SHA256 необробленого тіла із секретом клієнта, кодує результат у Base64 і порівнює з X-Shopify-Hmac-SHA256. На запит, що не збігається, Railhook відповідає 401 і не зберігає його. Підпис, який уже траплявся в межах вікна захисту від повторного використання (типово 5 хвилин), теж відхиляється, якщо тільки запит не є повторним надсиланням вебхука, який Railhook уже зберіг.

Тіло точно таке, яким його надіслав Shopify, байт у байт. Railhook передає далі заголовки подій Shopify: X-Shopify-Topic, X-Shopify-Webhook-Id, X-Shopify-Shop-Domain, X-Shopify-API-Version, X-Shopify-Event-Id і X-Shopify-Triggered-At. X-Shopify-Hmac-SHA256 не пересилається: ваш сервіс автентифікує Railhook за обліковими даними призначення, тож секрет клієнта йому не потрібен. Див. Призначення.

  1. Встановіть CLI й увійдіть, як описано в CLI, а потім відкрийте тунель до порту вашого застосунку:

    Terminal window
    railhook listen 3000
  2. Додайте джерелу друге призначення: публічну адресу, яку вивела команда, з вашим маршрутом у кінці, наприклад https://<host>/tunnel/<slug>/webhooks/shopify. Запит потрапить на http://localhost:3000/webhooks/shopify.

  3. Надішліть тестовий вебхук або створіть замовлення в магазині для розробки, і він надійде у ваш локальний застосунок із заголовком X-Shopify-Topic. Коли закриєте тунель, вимкніть це призначення.

Відтворення після збою

Section titled “Відтворення після збою”

Кожен відтворений вебхук піде на кожне призначення джерела як нове пересилання:

Terminal window
curl -X POST "$RAILHOOK_URL/api/v1/projects/$PROJECT_ID/incoming-events/bulk-replay" \
-H "X-API-Key: $RAILHOOK_API_KEY" \
-H "Content-Type: application/json" \
-d '{"sourceId":"'"$SOURCE_ID"'","from":"2026-09-18T10:00:00Z","to":"2026-09-18T14:00:00Z","verified":true}'

Відтворити можна все, що ще зберігається: 7 днів у Railhook Cloud і скільки налаштуєте на власному сервері. Обробник має залишатися ідемпотентним за X-Shopify-Webhook-Id, бо відтворення може надіслати вебхуки, які ваш сервіс уже обробив. Див. Відтворення.