Все статьи
События заказов и продуктов электронной коммерции покидают магазин WordPress и пересекают подписанный туннель к обработчику веб-перехватчика локального хоста.
WooCommerceWordPresse-commerce webhookslocalhost

Тестирование веб-хуков WooCommerce на локальном хосте

Чтобы протестировать веб-перехватчики WooCommerce на локальном хосте, откройте локальный обработчик с помощью туннеля HTTPS, создайте веб-перехватчик в разделе WooCommerce → Настройки → Дополнительно → Веб-перехватчики и проверьте. X-WC-Webhook-Signature в качестве дайджеста Base64 HMAC-SHA256 необработанного тела. Запустите заказ или изменение продукта в безопасном тестовом магазине, проверьте доставку и выполните итерацию без развертывания получателя.

Что и когда отправляет WooCommerce

WooCommerce может уведомлять URL-адрес доставки, когда заказы, продукты, купоны или клиенты создаются, обновляются или удаляются. Расширения могут добавлять темы, а разработчики могут определять собственные темы. У каждого настроенного веб-перехватчика есть имя, статус, тема, URL-адрес доставки, секрет и версия API. официальная документация по вебхуку WooCommerce описывает создание, темы, журналы доставки и поведение при сбоях.

Вебхук прикрепляется к теме, а не к каждой мутации магазина автоматически. Выберите самую узкую тему, необходимую для вашей интеграции. Потребитель, создающий заказ, не должен также обрабатывать каждое обновление продукта. Это снижает риск раскрытия персональных данных, трафика и случайных побочных эффектов во время локального тестирования.

Создание конечной точки Express с необработанным телом

Подпись WooCommerce рассчитывается по отправляемому телу. Сохраните эти байты до завершения проверки. Заголовок подписи содержит двоичный дайджест HMAC-SHA256 в кодировке Base64, а не шестнадцатеричную строку.

import express from 'express';
import crypto from 'node:crypto';

const app = express();

function validWooSignature(rawBody, supplied, secret) {
  if (!supplied || !secret) return false;
  const expected = crypto
    .createHmac('sha256', secret)
    .update(rawBody)
    .digest('base64');
  const a = Buffer.from(supplied);
  const b = Buffer.from(expected);
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

app.post(
  '/webhooks/woocommerce',
  express.raw({ type: 'application/json', limit: '2mb' }),
  async (req, res) => {
    const supplied = req.get('x-wc-webhook-signature');
    if (!validWooSignature(req.body, supplied, process.env.WC_WEBHOOK_SECRET)) {
      return res.sendStatus(401);
    }

    const payload = JSON.parse(req.body.toString('utf8'));
    await webhookInbox.insertOnce({
      deliveryId: req.get('x-wc-webhook-delivery-id'),
      topic: req.get('x-wc-webhook-topic'),
      payload,
    });
    return res.sendStatus(202);
  },
);

app.use(express.json());
app.listen(3000);

Необработанный анализатор для конкретного маршрута должен запускаться перед глобальным анализатором JSON. Если промежуточное программное обеспечение сначала анализирует тело, повторное преобразование объекта в строку может привести к изменению пробелов или экранированию и аннулированию дайджеста. Это то же самое правило сырого тела, которое описано в руководство по подписи вебхука, но WooCommerce специально использует вывод Base64.

Запустите HTTPS-туннель

  1. Запустите приемник и убедитесь, что он слушает http://localhost:3000.
  2. Бегать npx portpreview 3000 во втором терминале.
  3. Скопируйте общедоступный URL-адрес HTTPS и добавьте /webhooks/woocommerce.
  4. Продолжайте процесс, пока WordPress отправляет первоначальный пинг и доставку тем.

Хост WordPress, а не браузер, в котором вы открыли wp-admin, должен иметь доступ к общедоступному URL-адресу. Туннель соединяет этот публичный запрос с вашим частным процессом разработки. Он также обеспечивает доверенный TLS, поэтому вам не нужно раскрывать порт маршрутизатора или устанавливать собственный общедоступный сертификат.

Настройте вебхук в WooCommerce

  1. Открыть WooCommerce → Настройки → Дополнительно → Вебхуки..
  2. Выбирать Добавить вебхук и дайте ему узнаваемое имя местной разработки.
  3. Выбирать Активный статус и конкретную тему, например «Заказ создан».
  4. Вставьте полный URL-адрес доставки туннеля.
  5. Создайте длинный случайный секрет и поместите идентичное значение в WC_WEBHOOK_SECRET.
  6. Сохраните вебхук, а затем активируйте тему в тестовом хранилище.

Когда активный вебхук сохраняется впервые, WooCommerce отправляет пинг на URL-адрес доставки. Пинг подтверждает подключение, но не заменяет полезную нагрузку реального заказа. Сделайте так, чтобы ваша конечная точка допускала первоначальный запрос, а затем создайте или обновите тестовые данные для проверки выбранной темы.

export WC_WEBHOOK_SECRET="$(openssl rand -base64 48)"

Если вы вставляете секрет Base64 в файл среды, заключите его в кавычки, чтобы сохранить пунктуацию. Секрет заключается в ключе HMAC; Потребительские ключи WooCommerce REST API и пароли WordPress не являются связанными учетными данными.

Используйте заголовки для маршрутизации и отслеживания доставок

WooCommerce включает полезные заголовки метаданных. В зависимости от версии и среды к ним относятся тема, ресурс, событие, источник, идентификатор веб-перехватчика и идентификатор доставки. Обрабатывайте имена без учета регистра, как того требует HTTP. Используйте тему для отправки и идентификатор доставки для отслеживания, но всегда сначала проверяйте подлинность тела.

const handlers = {
  'order.created': handleOrderCreated,
  'order.updated': handleOrderUpdated,
  'product.updated': handleProductUpdated,
};

const handler = handlers[topic];
if (handler) await handler(payload);
else await recordUnsupportedTopic(topic);

Не делайте вывод о теме только по форме JSON. Созданный заказ и обновленная полезная нагрузка заказа могут выглядеть одинаково, но правильное последующее действие может отличаться. И наоборот, отклоните комбинацию заголовка и темы, на которую ваша конечная точка никогда не была настроена.

Обработка полезных данных заказа в целях защиты

Используйте неизменяемые идентификаторы

Сопоставляйте записи по идентификатору магазина и идентификатору объекта WooCommerce, а не по форматированию номера заказа, электронной почте клиента или отображаемым именам. Оба магазина могут иметь идентификатор заказа 42, поэтому для интеграции нескольких магазинов необходим составной ключ.

Ожидайте, что расширения изменят поля

Расширения оплаты, подписки, налогов, оформления заказа и выполнения могут добавлять поля метаданных и позиций. Проверьте поля, которые требуются вашей бизнес-логике, игнорируйте неизвестные поля и сохраните версию схемы или минимально отредактированное приспособление для регрессионных тестов.

Отделить получение события от выполнения

Веб-перехватчик, сообщающий об изменении заказа, должен попасть в надежную очередь или в почтовый ящик. Синхронизация запасов, отгрузочные этикетки, звонки ERP и электронная почта клиентов должны выполняться после подтверждения. Это не позволяет медленной зависимости интерпретировать WooCommerce успешное получение как неудачную доставку.

Обновления модели при смене состояний

Заказ может проходить через состояния ожидания, обработки, ожидания, завершения, отмены, возврата средств или сбоя. Обновления могут происходить быстро, и порядок доставки не является безопасной заменой сравнения временных меток и текущего состояния источника. Сделайте повторяющиеся переходы безвредными.

Идемпотентность обязательна для коммерческих событий.

Тайм-аут может произойти после того, как ваш получатель зафиксирует запрос, но до того, как WooCommerce увидит ответ. Повторная доставка затем приводит к тому же бизнес-действию, если только обработчик не является идемпотентным. Сохраните идентификатор доставки, если он присутствует. Также обеспечьте уникальность на уровне домена, например один запрос на выполнение для каждого магазина и переход заказа.

await db.transaction(async (tx) => {
  if (!(await tx.deliveries.claim(deliveryId))) return;
  await tx.orders.applyWooCommerceEvent(storeId, topic, payload);
  await tx.outbox.enqueueRequiredActions(storeId, topic, payload.id);
});

Транзакция «Входящие плюс исходящие» предотвращает как дублирование обработки, так и потерю последующей работы. Видеть повтор вебхука и идемпотентность для полной схемы.

Используйте журналы WooCommerce для отладки на стороне отправителя.

WooCommerce записывает поставки через вебхук. Открыть WooCommerce → Статус → Журналы и фильтр для источника доставки веб-перехватчика, описанного в официальной документации. Сравните URL-адрес доставки, время запроса, статус ответа и текст ответа с трассировкой локального туннеля. Журналы отправителей отвечают, пытался ли WordPress выполнить запрос; журналы приемника отвечают, что с ним сделало ваше приложение.

Не копируйте неотредактированные полезные данные заказа в общедоступную задачу. Он может содержать имена, адреса для выставления счетов и доставки, адрес электронной почты, телефон, выбранные продукты и метаданные оплаты. Сократите фикстуру до полей, необходимых для воспроизведения ошибки.

Устранение распространенных ошибок веб-перехватчика WooCommerce

Вебхук становится отключенным

WooCommerce автоматически отключает вебхук после более чем пяти последовательных неудачных попыток доставки. Согласно официальному руководству, ответы за пределами 2xx, 301 или 302 считаются неудачными. Исправьте конечную точку, повторно активируйте веб-перехватчик и отправьте контролируемый тест. В любом случае избегайте перенаправлений: они усложняют отладку подписей и могут случайно отправить подписанные данные клиента на непредусмотренный хост.

Подпись всегда отличается

Хешируйте точное необработанное тело с настроенным секретом веб-перехватчика, запросите двоичный вывод HMAC, а затем закодируйте его в Base64. В узле это .digest('base64'). Распространенными ошибками являются использование шестнадцатеричного значения, использование секрета REST API, сначала анализ JSON или включение дополнительных байтов новой строки.

Первоначальный пинг работает, но события заказа — нет.

Убедитесь, что выбранная тема соответствует инициированному вами действию. Создание заказа и изменение существующего заказа — это разные темы. Убедитесь, что статус активен, проверьте журналы WooCommerce и убедитесь, что плагин или промежуточный кеш не препятствуют базовому перехватчику.

Локальные запросы возвращают 404

Проверьте полный путь, метод маршрутизации и целевой порт туннеля. WordPress должен POST для /webhooks/woocommerce, а не просто происхождение туннеля. Промежуточное программное обеспечение Framework не должно перенаправлять веб-перехватчик на локализованную или аутентифицированную страницу.

Время доставки истекло

Сохраните событие аутентификации и незамедлительно верните 200 или 202. Перенесите удаленные вызовы API и тяжелые преобразования на рабочий процесс. Проверьте, приостанавливают ли локальные точки останова запрос на достаточно долгое время, чтобы его можно было классифицировать как сбой.

Воспроизведение полезной нагрузки вызывает ошибку 401.

Перехваченный запрос должен сохранять точные необработанные байты и заголовок подписи. Редактирование JSON делает исходную подпись недействительной. Для тестов бизнес-логики используйте очищенное приспособление после границы проверки; для сквозных тестов создайте новый HMAC со специальным секретным ключом теста. Следуйте безопасный рабочий процесс воспроизведения.

Контрольный список безопасности для данных местного магазина

  • По возможности тестируйте в промежуточном магазине с синтетическими покупателями и продуктами.
  • Используйте уникальный секрет веб-перехватчика для локальной разработки и меняйте его после раскрытия.
  • Проверьте подпись перед синтаксическим анализом, протоколированием или постановкой тела в очередь.
  • Ожидаемый источник и тема сохранения белого списка после криптографической проверки.
  • Удаление адресов, контактных данных, примечаний к заказам и метаданных платежей из записей.
  • Никогда не отключайте проверку TLS и не предоставляйте получателю учетные данные wp-admin.

Локальная архитектура должна соответствовать производственной: транспорт HTTPS, необработанная аутентификация, устойчивое принятие, идемпотентная обработка, быстрый ответ и проверяемые сбои. Для другого коммерческого поставщика с другим заголовком HMAC сравните Shopify Руководство по локальному веб-перехватчику.

Часто задаваемые вопросы

Как протестировать веб-перехватчики WooCommerce на локальном хосте?
Откройте свой локальный маршрут POST с помощью туннеля HTTPS, введите его общедоступный URL-адрес в настройках веб-перехватчика WooCommerce, настройте один и тот же секретный ключ с обеих сторон и активируйте выбранную тему.
Как проверить подпись X-WC-Webhook?
Вычислите HMAC-SHA256 по точному необработанному телу запроса с настроенным секретом веб-перехватчика, закодируйте двоичный дайджест в Base64 и сравните его по времени с заголовком.
Почему WooCommerce отключил мой вебхук?
WooCommerce отключает вебхук после более чем пяти неудачных попыток доставки подряд. Исправьте ошибки соединения, тайм-аута или ответа, затем повторно активируйте его и повторите тестирование.
Где я могу увидеть неудачные доставки вебхука WooCommerce?
Откройте WooCommerce → Статус → Журналы и отфильтруйте журналы доставки веб-перехватчиков. Сравните записанный ответ с журналами туннеля и локального приложения.