Як надійно отримувати вебхуки 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-IdRailhook відповідає збереженою копією і вдруге її не пересилає. - Будь-який збережений вебхук можна відтворити, доки зберігаються події, навіть коли чотири години Shopify давно минули.
Підключення Shopify
Section titled “Підключення Shopify”Знадобляться проєкт Railhook і API-ключ. Ті самі кроки є в панелі керування, у розділі «Вхідні».
export RAILHOOK_URL=https://railhook.io # or your own instanceexport RAILHOOK_API_KEY=...export PROJECT_ID=...-
Створіть джерело із секретом клієнта (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із відповіді. -
Додайте призначення, 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}' -
Оформіть підписку в
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). -
Надішліть тестовий вебхук:
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 уже зберіг.
Що отримує ваш сервіс
Section titled “Що отримує ваш сервіс”Тіло точно таке, яким його надіслав 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 за обліковими даними призначення, тож секрет клієнта йому не потрібен. Див. Призначення.
Локальна розробка з CLI
Section titled “Локальна розробка з CLI”-
Встановіть CLI й увійдіть, як описано в CLI, а потім відкрийте тунель до порту вашого застосунку:
Terminal window railhook listen 3000 -
Додайте джерелу друге призначення: публічну адресу, яку вивела команда, з вашим маршрутом у кінці, наприклад
https://<host>/tunnel/<slug>/webhooks/shopify. Запит потрапить наhttp://localhost:3000/webhooks/shopify. -
Надішліть тестовий вебхук або створіть замовлення в магазині для розробки, і він надійде у ваш локальний застосунок із заголовком
X-Shopify-Topic. Коли закриєте тунель, вимкніть це призначення.
Відтворення після збою
Section titled “Відтворення після збою”Кожен відтворений вебхук піде на кожне призначення джерела як нове пересилання:
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, бо відтворення може надіслати вебхуки, які ваш сервіс уже обробив. Див. Відтворення.