Ошибки токенов
Token already used (401)
Причина: Один и тот же preimage был отправлен дважды — атака повторного воспроизведения или случайная повторная попытка.
Решение: Каждый платёж по инвойсу создаёт одноразовый токен. Сгенерируйте новый инвойс и оплатите его снова. На стороне клиента убедитесь, что L402Client кэширует токены по URL конечной точки (по умолчанию это так).
Token expired (401 / valid: false)
Причина: Инвойсы истекают через 1 час. Поле exp токена задаётся в миллисекундах.
Решение: Запросите новый инвойс. Если срок действия истекает слишком быстро, проверьте точность системных часов сервера (Date.now() на сервере и time.time() на клиенте должны отличаться не более чем на несколько секунд).
Invalid preimage format (вместо 200 возвращается 402)
Причина: Preimage содержит не ровно 64 шестнадцатеричных символа (32 байта).
Решение: Убедитесь, что ваш кошелёк возвращает сырой preimage в виде hex-строки из 64 символов. Некоторые кошельки возвращают его в формате base64 — в этом случае сначала декодируйте его.
Webhook signature mismatch (401)
Причина: Заголовок l402-signature не совпадает с секретом, или тело запроса было изменено при передаче.
Решение:
- Убедитесь, что
L402_WEBHOOK_SECRETсовпадает на стороне отправителя и получателя. - Используйте
express.raw({ type: 'application/json' })(а неexpress.json()) для чтения сырого тела запроса перед верификацией — JSON-парсинг переформатирует строку и аннулирует подпись. - Проверьте, что ваш обратный прокси (nginx, Cloudflare) не изменяет тело запроса.
Ошибки провайдера
ManagedProvider: invoice creation failed / HTTP 503
Причина: l402kit.com временно недоступен или API Blink не работает.
Решение: Повторите запрос с экспоненциальной задержкой. Проверьте статус на status.blink.sv. Для производственных нагрузок, требующих нулевого времени простоя, используйте собственный провайдер (BlinkProvider, AlbyProvider и т. д.) с вашими учётными данными.
Blink: INSUFFICIENT_CHANNEL_BALANCE
Причина: Ваш кошелёк Blink имеет недостаточную исходящую ликвидность для разделённого платежа.
Решение: Пополните кошелёк shinydapps@blink.sv. Платформе требуется небольшой баланс для маршрутизации разделённых платежей. Это влияет только на разделение через ManagedProvider — создание инвойсов не затрагивается.
LNURL fetch failed при разделении платежа
Причина: Lightning Address разработчика не разрешается. Конечная точка /.well-known/lnurlp/ вернула статус, отличный от 200.
Решение: Убедитесь, что Lightning Address действителен, а LNURL-pay конечная точка домена доступна. Проверьте с помощью:
AlbyProvider: HTTP 401
Причина: Токен доступа Alby истёк или был отозван.
Решение: Перегенерируйте токен в Alby Hub → Настройки → Токены доступа. Убедитесь, что область видимости включает invoices:create.
BTCPayProvider: HTTP 403
Причина: У API-ключа отсутствует необходимое разрешение.
Решение: В BTCPay Server → Аккаунт → API-ключи убедитесь, что ключ имеет область видимости btcpay.store.cancreatelightninginvoice для нужного магазина.
Защита от повторных атак
Несколько экземпляров / повторные атаки не блокируются
Причина: По умолчаниюMemoryReplayAdapter работает только в рамках текущего процесса. При перезапуске или при наличии нескольких экземпляров он сбрасывается.
Решение: Используйте RedisReplayAdapter для развёртываний с несколькими экземплярами:
payment_hash в Supabase выступает в роли надёжного второго уровня защиты вне зависимости от адаптера в памяти, поэтому повторные атаки всегда блокируются даже без Redis.
Ограничения скорости
Too many requests. Max 20 invoices/minute per IP. (429)
Причина: Более 20 запросов на создание инвойса в минуту с одного IP-адреса, достигших конечной точки ManagedProvider.
Решение: Реализуйте кэширование на стороне клиента — не создавайте новый инвойс при каждой загрузке страницы. L402Client автоматически кэширует токены по URL конечной точки. Для потоков между серверами, генерирующих много инвойсов, используйте собственный провайдер.
Специфика фреймворков
Express: middleware не срабатывает
Причина: Обработчик маршрута Express зарегистрирован до middlewarel402(), или порядок middleware неверен.
Решение:
FastAPI: 422 Unprocessable Entity при ответе 402
Причина: FastAPI валидирует тела ответов в соответствии с объявленной моделью ответа. Тело ответа 402 не совпадает с ней.
Решение: Исключите статус 402 из валидации ответа или не объявляйте модель ответа для декорированных конечных точек:
Go: panic: l402: no Lightning provider set
Причина: Options.Lightning равен nil.
Решение: Всегда задавайте провайдер:
Всё ещё не решили проблему?
Откройте issue на github.com/ShinyDapps/l402-kit/issues, указав:- Язык и версию SDK
- Минимальный воспроизводящий пример
- Сообщение об ошибке и трассировку стека