Чтобы использовать симулятор веб-хуков Paddle с локальным хостом, разоблачите своего локального обработчика через туннель HTTPS, создайте пункт назначения уведомлений песочницы, который указывает на общедоступный URL-адрес, а затем запустите симуляцию одного события или жизненного цикла против этого пункта назначения. Paddle отправляет реалистичный запрос Paddle-Signature заголовок, поэтому один и тот же путь проверки необработанного тела может работать локально и в производстве.
Почему симулятор Paddle больше, чем просто образец полезной нагрузки
Скопированный крепеж JSON проверяет ваше заявление о переключателе. Симулятор Paddle тестирует сетевое назначение, заголовки провайдеров, секрет подписи, статус ответа и схему событий вместе. Официальный webhook симулятор обзор Поддерживает многоразовые отдельные события и сценарии. Одиночные события нацелены на один тип события и могут быть настроены после запуска. Сценарии отправляют заранее определенную последовательность для жизненного цикла, такую как создание подписки или обновление.
Конфигурация сценария может заполнять полезные нагрузки существующими объектами Paddle и изменять поток. Каждый запуск создает симуляционные записи событий, где вы можете проверить полезную нагрузку, исходящий запрос и ответ конечной точки. Это делает симулятор полезным для отладки переходов состояний, а не только для доказательства того, что маршрут находится в сети.
Подключите локальную конечную точку к песочнице Paddle
- Запустите приложение, например, на
http://localhost:3000. - Добавить маршрут POST, такой как:
/api/webhooks/paddle. - Беги.
npx portpreview 3000и скопировать адрес HTTPS. - В песочнице Paddle создайте пункт назначения уведомления
https://your-subdomain.portpreview.dev/api/webhooks/paddle. - Раскрыть и скопировать секрет конечной точки назначения в
PADDLE_WEBHOOK_SECRETЭто не ваш ключ API. - Откройте инструменты разработчика → Моделирование, выберите одно событие или сценарий, выберите пункт назначения, настройте его и запустите.
- Сравните симуляционный ответ Paddle с локальными журналами и постоянным получением веб-хук.
Используйте ресурсы песочницы и учетные данные повсюду. Смешивание секрета реального назначения с запросом симулятора песочницы гарантирует отказ подписи, даже если обе строки выглядят правдоподобно.
проверить Paddle-Signature заголовок
Paddle подписывает каждый веб-хук с секретом, принадлежащим пункту назначения уведомления. Заголовок содержит компоненты, включая метку времени Unix, идентифицированную ts и одной или более подписей, идентифицированных h1Paddle может добавлять подписные версии, поэтому разберите заголовок, а не предположите, что он содержит один голый хеш.
Подписанная полезная нагрузка - это метка времени, толстая кишка и нетронутый корпус запроса. Paddle применяет HMAC-SHA256 с секретом конечной точки. Его подтверждающая подпись документация Рекомендуется официальный SDK, где доступен и документируется ручной алгоритм. Всегда применяйте стойкость SDK к временным меткам или явную терпимость в вашем проверяющем устройстве для ограничения повторных атак.
Предпочитаете официальный SDK в Node
import express from 'express';
import { Environment, Paddle } from '@paddle/paddle-node-sdk';
const app = express();
const paddle = new Paddle(process.env.PADDLE_API_KEY, {
environment: Environment.sandbox,
});
app.post(
'/api/webhooks/paddle',
express.raw({ type: 'application/json' }),
async (req, res) => {
const signature = req.header('paddle-signature') ?? '';
const rawBody = req.body.toString('utf8');
try {
const event = await paddle.webhooks.unmarshal(
rawBody,
process.env.PADDLE_WEBHOOK_SECRET,
signature,
);
await acceptOnce(event.eventId, event);
return res.status(200).send('accepted');
} catch (error) {
return res.status(400).send('invalid webhook');
}
},
);
app.listen(3000);
гора express.raw() Перед любым глобальным express.json() Промежуточное ПО для этого маршрута. В фреймворке в стиле Fetch, таком как Next.js App Router, используйте await request.text() Один раз и передайте эту точную строку SDK. Официальный web-cook быстро запускается Это свидетельствует об этой необработанной потребности организма.
Что должна делать ручная проверка
- Прочитайте сырое тело без нормализации JSON.
- Парсировать каждый полуколонный компонент заголовка и собирать поддерживаемые
h1ценностей. - Отвергнуть недостающее, деформированное или необоснованно старое
ts. - вычислять
HMAC_SHA256(secret, ts + ':' + rawBody). - Сравните ожидаемый дайджест с подписями кандидатов, используя безопасное по времени сравнение.
- Только после матча разберите JSON и отправьте на
event_type.
Принятие любых действительных поддержанных вопросов подписи во время секретной ротации, когда может присутствовать более одной подписи. Не раскалывайте заголовок и слепо возьмите второй пункт. Не регистрируйте секрет конечной точки или полную полезную нагрузку клиента при диагностике несоответствия.
Моделирование дизайна вокруг выставления счетов инвариантами
Создание подписки
Запустите сценарий создания подписки и проверьте, что ваша база данных может получать связанные транзакции и события подписки, не предполагая один заказ на вход в сеть. Храните идентификаторы сущности Paddle и обновляйте записи. Заявка должна предоставить ровно одно право, даже если запрос неприятен.
Возобновление и невыплата
Упражняйтесь в успешном обновлении, просроченных и восстановленных путях, доступных в конфигурации сценария. Отдельный статус выставления счетов от политики доступа к продукту: ваш льготный период может намеренно поддерживать активный доступ, в то время как Paddle сообщает о проблеме сбора.
Отмена и запланированные изменения
Отличить подписку, которую планируется отменить, от подписки, которая достигла своей фактической отмены. сохранять next_billed_atданные о запланированных изменениях и статус поставщика, а не разрушение жизненного цикла is_active.
Обновления Entity
Моделируйте обновления продукта, цены, клиентов и подписки, которые потребляет ваш кэш. Обработчик должен безопасно игнорировать неизвестные типы событий и признавать их, если подпись действительна; будущие дополнения Paddle не должны превращаться в бесконечный цикл отказа.
Импотенция и порядок на каждом ходу
Используйте стабильный идентификатор события webhook в качестве уникального ключа в таблице квитанций. В одну транзакцию вставьте квитанцию, примените изменение состояния и очертите побочные эффекты. Если вставка конфликтует, возвращайте успех, не повторяя работу. Не дублируйте только идентификатор организации, потому что многие законные обновления могут быть нацелены на одну подписку.
События могут выйти из строя. Сравните время возникновения события или извлеките последний объект Paddle перед применением разрушительного перехода. Храните состояние и временную метку провайдера и отклоните более старое обновление, которое перезапишет новое. Сценарии моделирования идеально подходят для проверки этих предположений, потому что они создают связанные последовательности, а не изолированные приспособления.
Неисправности симулятора к локальному хосту
Направление возвращается 404 или 405
Убедитесь, что общедоступный URL включает полный маршрут и что маршрут экспортирует POST. Браузер GET не является действительным тестом веб-хука POST. Использовать curl -X POST Отличить туннельную маршрутизацию от конфигурации Paddle.
Направление возвращается 400
Проверить, есть ли Paddle-Signature Прибывший и подтвердивший, что секрет конечной точки принадлежит выбранному пункту уведомления. Убедитесь, что ни один парсер тела, регистратор запросов или промежуточное программное обеспечение не потребляли и не переформатировали тело. Симулятор отправляет проверяемые подписи, как это задокументировано. Руководство по симуляции Paddle.
Направление возвращается 500 или больше раз
Настаивайте быстро и перемещайте электронную почту, резервирование и исходящие вызовы API в очередь. Возврат 2xx после длительного приема. Бросок на незнакомый тип события является распространенной причиной ненужных сбоев; используйте ветвь по умолчанию, которая записывает и признает это.
Сценарий использует неожиданные данные
Проверьте, использует ли моделирование автоматически генерируемые значения или заполнено реальными объектами песочницы. Осмотрите настроенные параметры сценария и полезную нагрузку события запуска, а не предполагая, что она отражает предыдущий запуск.
Контрольный список безопасности перед производством
- Храните ключи API и секреты назначения уведомлений отдельно и только на сервере.
- Проверьте необработанное тело, подпись заголовка и временную метку перед обработкой.
- Используйте безопасное по времени сравнение или официальный верификатор SDK.
- Дублировать идентификаторы событий и обрабатывать внезапные обновления.
- Применяйте ограничения по корпусу, маршрутизацию только POST, отредактированную регистрацию и контроль скорости.
- Используйте отличную песочницу и живые места назначения, а затем повторите моделирование и реальные потоки песочницы, прежде чем переключать производственный URL.
Симулятор доказывает вашу интеграцию в контролируемых последовательностях жизненного цикла; настоящая касса в песочнице также доказывает отношения между кассами. Используйте оба варианта, затем просмотрите общий Руководство по подписи webcook и Руководство по импотенции перед запуском.
