Усі статті
Події вебхука підписки та ліцензії, що проходять через HTTPS-тунель у перевірений локальний обробник розробки.
Lemon Squeezywebhookssubscriptionslocal testing

Тестування вебхуків Lemon Squeezy на localhost

Щоб протестувати вебхуки Lemon Squeezy на локальному хості, запустіть ваш додаток, відкрийте його маршрут вебхука через публічний HTTPS тунель, створіть вебхук у тестовому режимі в Налаштування → Вебхуки та перевірте сирий вміст запиту. X-Signature заголовок. Використовуйте тестове оформлення замовлення для реальних даних замовлень і контроли імітації підписки Lemon Squeezy для подій життєвого циклу, на які складно чекати.

Як виглядає правильне локальне налаштування

Lemon Squeezy відправляє HTTP POST з її інфраструктури, тому вона не може досягти localhost на вашому комп’ютері. Тунель завершують публічний TLS і пересилає незмінений метод, тіло та заголовки на локальний маршрут, такий як http://localhost:3000/api/webhooks/lemonsqueezy.

Повний тест має чотири частини: режим тестування Lemon Squeezy, публічну URL-адресу для зворотного виклику, той самий секрет підпису в панелі керування та локальному середовищі та обробник, який перевіряє перед тим, як змінити стан підписки або ліцензії. Це корисніше, ніж публікувати скопійовані JSON з curl, тому що справжня доставка перевіряє як маршрутизацію, так і підпис, згенерований провайдером.

Створіть вебхук і надішліть тестову подію

  1. Запустіть ваш додаток на порту 3000 і перевірте, чи маршрут приймає POST.
  2. Почніть тунель із npx portpreview 3000.
  3. Переключіть панель управління Lemon Squeezy у тестовий режим.
  4. Відкрийте Налаштування → Вебхуки та додайте https://your-subdomain.portpreview.dev/api/webhooks/lemonsqueezy.
  5. Згенеруйте сильний випадковий секрет підпису, збережіть його як LEMONSQUEEZY_WEBHOOK_SECRET, і обирайте лише ті події, які ваша програма обробляє.
  6. Створіть тестову покупку або використайте доступну дію симуляції підписки в тестовому режимі, потім перевірте журнал доставки та вашу локальну відповідь.

Офіційний Документація вебхуків Lemon Squeezy дає змогу переглядати останні дані та повторно надсилати записані вебхуки зі сторінки налаштувань. Повторна відправка корисна для регресійного тестування, але ваша програма повинна розглядати її як дублікат, а не як другу бізнес-подію.

Перевірити X-Signature перед розбором JSON

Lemon Squeezy обчислює HMAC-SHA256 дайджест для навантаження запиту, використовуючи секрет підпису, і надсилає шістнадцятковий дайджест у X-Signature. Обчисліть дайджест над точними байтами сирого тіла та порівняйте буфери однакової довжини за допомогою функції з постійним часом виконання. Основний документація щодо запитів на підпис включає приклади для Node, PHP, Python і Ruby.

// app/api/webhooks/lemonsqueezy/route.ts
import crypto from 'node:crypto';
import { NextRequest, NextResponse } from 'next/server';

export async function POST(request: NextRequest) {
  const secret = process.env.LEMONSQUEEZY_WEBHOOK_SECRET;
  if (!secret) return new NextResponse('server misconfigured', { status: 500 });

  const rawBody = await request.text();
  const suppliedHex = request.headers.get('x-signature') ?? '';

  if (!/^[0-9a-f]{64}$/i.test(suppliedHex)) {
    return new NextResponse('invalid signature', { status: 401 });
  }

  const expected = crypto
    .createHmac('sha256', secret)
    .update(rawBody)
    .digest();
  const supplied = Buffer.from(suppliedHex, 'hex');

  if (supplied.length !== expected.length ||
      !crypto.timingSafeEqual(supplied, expected)) {
    return new NextResponse('invalid signature', { status: 401 });
  }

  const event = JSON.parse(rawBody);
  await acceptEvent(event);
  return NextResponse.json({ received: true });
}

Не дзвоніть request.json() по-перше. Повторне серіалізування отриманого об'єкта може змінити байти, які здаються незначними, і порушити HMAC. Перевірка довжини також є важливою, оскільки Node's timingSafeEqual викидає помилки, коли довжини буферів відрізняються. Офіційний Lemon Squeezy Покроковий посібник з вебхуків Next.js слідує тій самій послідовності необробленого тіла.

Зрозумійте вміст перед оновленням вашої бази даних

Тіло є об'єктом ресурсу JSON:API. meta.event_name визначає подію, meta.custom_data несе дані, передані через касу, і data містить ресурс замовлення, підписки або ліцензійного ключа. Lemon Squeezy також надсилає X-Event-Name; розглядати підписане тіло як авторитетне введення та використовувати заголовок для діагностики маршрутизації.

Замовлення та ідентичність клієнта

Для order_created, зіставте покупку з внутрішнім користувачем, використовуючи ідентифікатор, згенерований сервером, у користувацьких даних оформлення замовлення. Не довіряйте наданому клієнтом ідентифікатору користувача без перевірки права власності. Збережіть ідентифікатор ресурсу та ідентифікатор варіанту Lemon Squeezy, щоб пізніше можна було узгодити події підписки або повернення коштів.

Підписки є кінцевим автоматом

Ручка subscription_created, subscription_updated, subscription_cancelled, subscription_resumed, і subscription_expired як окремі переходи. Скасування може означати, що доступ залишається дійсним до кінця розрахункового періоду; закінчення терміну дії є більш сильним сигналом того, що підписка закінчилась. Моделюйте дати та статус, а не перемикайте один булевий параметр.

Помилки платежів та їх відновлення

Перевірка відновлення процесів поновлення, які підтримуються в режимі тестування, завершилася невдало. Невдала оплата не обов’язково повинна одразу скасовувати доступ; застосуйте пільговий період, визначений вашою продуктовою політикою, і дозвольте наступним платежам або подіям підписки привести обліковий запис у відповідність до останнього стану постачальника.

Повторні спроби вимагають ідемпотентної обробки

Згідно з Lemon Squeezy посилання на запит вебхука, а 200 Позначки відповіді фіксують як успішне. Інші статуси повторюються ще до трьох разів із експоненційними затримками, які приблизно становлять 5, 25 і 125 секунд. При повторному надсиланні інформаційної панелі створюється ще одна причина, через яку одна й та сама логічна подія може надійти більше одного разу.

Побудуйте ключ ідемпотентності з постійних підписаних полів даних. Практичний підхід — це унікальний рядок бази даних для ID ресурсу вебхука, назви події та часу події, або хеш сирого підписаного тіла, коли спеціального ID події немає. Вставте цей запис і оновіть стан застосунку в одній транзакції. Поверніть 200 для раніше виконаного дубліката.

BEGIN;
INSERT INTO webhook_receipts (fingerprint, received_at)
VALUES ($1, now())
ON CONFLICT DO NOTHING;
-- Continue only if one row was inserted.
UPDATE subscriptions SET provider_status = $2 WHERE provider_id = $3;
COMMIT;

Не робіть доставку електронної пошти або повільний виклик стороннього API частиною шляху підтвердження. Збережіть завдання в тій самій транзакції, відповідайте та дозвольте робітнику обробляти побічні ефекти. Ширше посібник з повторних спроб вебхука та ідемпотентності покриває цей шаблон.

Виправлення неполадок тестів вебхука Lemon Squeezy на локальному хості

Жоден запит не доходить до додатка

Перевірте, що тунель все ще працює, що зворотний виклик містить суфікс маршруту, і що у вашому фреймворку є обробник POST за цим точним шляхом. Викличте публічну кінцеву точку самостійно. Тунель 502 вказує на локальний порт; фреймворк 404 вказує на розташування маршруту.

Кожний підпис недійсний

Підтвердьте, що тестовий режим і режим живого використання не використовують різні записи або секрети вебхука. Прочитайте тіло один раз як текст або байти, не обрізайте ні тіло, ні секрет, і переконайтеся, що глобальний JSON-посередник не запускається першим. Перевірте, чи X-Signature прибув, але ніколи не друкуйте секрет підпису.

Доставка постійно намагається повторити

Лемон Сквізі очікує 200, не перенаправляючи на сторінку входу. Виключіть шлях вебхука з CSRF та проміжного програмного забезпечення користувацької сесії, зберігаючи перевірку підпису. Ловіть помилки бази даних, тримайте роботу короткою та переконайтеся, що відповідь про успіх дійсно повертається на кожній обробленій гілці події.

Моделювання підписки недоступне

Керування симуляцією вимагає відповідних даних про підписку в тестовому режимі. Деякі симуляції платежів потребують історії поновлення. Спершу створіть необхідну тестову підписку або тестову покупку, а потім використовуйте меню дій підписки, описане в Lemon Squeezy. керівництво для розробника вебхуків.

Перевірочний список з безпеки та запуску

  • Згенеруйте випадковий секрет підпису, збережіть його в конфігурації середовища та змінюйте, якщо він буде скомпрометований.
  • Перевірте HMAC над необробленим тілом перед розбором JSON, записами в базу даних, генерацією ліцензії або змінами доступу.
  • Використовуйте порівняння, безпечне за часом, та відхиляйте відсутні або пошкоджені підписи.
  • Тримайте секрети та записи тестового режиму та живого вебхука окремо.
  • Дозволяйте тільки POST, встановлюйте розумний ліміт розміру тіла, обмежуйте частоту некоректних запитів та видаляйте дані клієнтів з журналів.
  • Перевірте дублікати, події життєвого циклу поза порядком, простої бази даних та відновлення після тайм-ауту перед заміною тунелю на ваш продукційний URL.

Успішне проходження «щасливого сценарію» оплати лише доводить, що одна подія надійшла. Інтеграція, готова до виробництва, доводить відхилення підпису, безпечність проти дублювання, збіг життєвого циклу та відновлення після відповіді, що не є 200. Щодо основних криптографічних підводних каменів дивіться посібник з перевірки підпису.

Поширені запитання

Як мені протестувати вебхуки Lemon Squeezy на локальному сервері?
Пропишіть свій локальний маршрут вебхука через HTTPS-тунель, створіть вебхук, поки панель керування знаходиться в режимі тестування, використовуйте той самий секрет підпису локально та запустіть тестовий чек-аут або симуляцію підтримуваної підписки.
Як перевіряється підпис вебхука Lemon Squeezy?
Обчисліть HMAC-SHA256 дигест над точним необробленим тілом запиту за допомогою вашого секретного ключа підпису, декодуйте шістнадцяткове значення X-Signature і порівняйте буфери однакової довжини за допомогою функції, безпечної щодо часу.
Чи Lemon Squeezy повторно намагається обробити невдалі вебхуки?
Так. У його документації сказано, що відповіді, відмінні від 200, повторюються до трьох додаткових разів із експоненційною затримкою, приблизно через 5, 25 і 125 секунд.
Чи можу я симулювати поновлення підписки Lemon Squeezy в тестовому режимі?
Тестовий режим забезпечує симуляцію дій для підтримуваних подій підписки. Деякі симуляції, пов'язані з оплатою, потребують наявної тестової підписки та даних для поновлення, тому спочатку створіть необхідний тестовий стан.