Справочник сервера
Вебхуки
Копировать страницу
Lia информирует ваш сервер, когда оплата или возврат произошли и когда награда была выплачена, подписанная вашим вебхуком. Что отправляется, как проверить подпись и как работают повторные попытки.
#Настройка одного
Сообщите команде Lia адрес https на вашем сервере и сохраните секрет подписи вебхука (whsec_…) которые поступили с вашими ключами. Lia затем отправляет POST они будут там, когда что-то произойдёт в вашем приложении.
Вебхук — это напоминание, не правда: проверьте API перед тем, как действовать на нем (для платежа, GET /charges/:id. И не'не полагаться только на вебхуки; ваша страница также может сообщить вашему серверу (см. Продать предмет).
#Что'ваше отправлено
POST /lia/webhook
Content-Type: application/json
Lia-Signature: t=1761998400,v1=5f2c8a…
{
"type": "charge.paid",
"app": "your-app",
"at": 1761998400123,
"data": {
"id": "ch_9b1f4c2e7a0d5b8f3e6a1c4d",
"playerId": "p_3f9c0a6d1b2e4f5a6b7c",
"productId": "extra-lives",
"amount": 5,
"status": "paid",
"mode": "live",
"createdAt": 1761998400000,
"deliveredAt": null,
"refundedAt": null
}
}| Поле | Тип | |
|---|---|---|
type | строка | Что произошло (ниже). |
app | строка | Идентификатор вашего приложения. |
at | число | Когда это было отправлено, в миллисекундах с 1970. |
data | объект | Что оно's о. |
#Типы
| Тип | Когда | data |
|---|---|---|
charge.paid | Человек заплатил на Lia'платежная ведомость, в тестовом или живом режиме. | The оплата, с status: "paid" |
charge.refunded | Вы вернули платеж. | Сбор средств, с status: "refunded" |
reward.paid | Вы оплатили вознаграждение из своего пула, в тестовом или живом режиме. | { key, playerId, amount, reason, mode } |
Проверить data.mode (или плата's mode) поэтому тестовые события никогда не дают ничего реального. Могут быть добавлены другие типы: игнорируйте типы, которые вы не знаете'не знать и отвечать 200.
#Проверка подписи
Каждый вебхук имеет Lia-Signature заголовок, t=<seconds>,v1=<signature>. Подпись — это HMAC SHA-256, в шестнадцатеричном виде, секунд, точки и необработанного тела, с ключом вашего полного вебхука (включая whsec_):
v1 = hex(HMAC_SHA256(key = "whsec_…", message = t + "." + rawBody))Проверьте его на исходном теле, как оно прибыло, до его разбора, и откажите вебхуках, старше нескольких минут.
import { createHmac, timingSafeEqual } from "node:crypto";
export function liaWebhook(rawBody, header, secret, toleranceSeconds = 300) {
const parts = Object.fromEntries((header ?? "").split(",").map((part) => part.split("=")));
const t = Number(parts.t);
if (!t || !parts.v1) return null;
if (Math.abs(Date.now() / 1000 - t) > toleranceSeconds) return null;
const expected = Buffer.from(createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex"));
const given = Buffer.from(parts.v1);
if (expected.length !== given.length || !timingSafeEqual(expected, given)) return null;
return JSON.parse(rawBody);
}export async function liaWebhook(request, secret, toleranceSeconds = 300) {
const rawBody = await request.text();
const parts = Object.fromEntries((request.headers.get("Lia-Signature") ?? "").split(",").map((part) => part.split("=")));
const t = Number(parts.t);
if (!t || !parts.v1 || Math.abs(Date.now() / 1000 - t) > toleranceSeconds) return null;
const key = await crypto.subtle.importKey("raw", new TextEncoder().encode(secret), { name: "HMAC", hash: "SHA-256" }, false, ["verify"]);
const signature = new Uint8Array(parts.v1.match(/../g).map((byte) => parseInt(byte, 16)));
const ok = await crypto.subtle.verify("HMAC", key, signature, new TextEncoder().encode(`${t}.${rawBody}`));
return ok ? JSON.parse(rawBody) : null;
}Обработка вебхуков имеет полный обработчик.
#Ответы и повторы
- Ответьте любым
2xxсостояние, быстро. Выполняйте медленную работу после ответа. - Если ваш сервер не't ответ
2xx(или может't быть достигнуто), Lia пытается снова сразу. После этого вебхук не'не отправлять снова. - Поскольку вебхуки могут быть пропущены и приходить дважды, сделайте ваш обработчик безопасным для двойного запуска (используйте идентификатор платежа или ключ вознаграждения), и имейте другой способ догнать, например
Lia.charges()когда игрок открывает ваше приложение.
#Ваш секрет
Ваш секрет вебхука меняется каждый раз, когда ваши ключи создаются заново. Храните его на вашем сервере рядом с вашим ключом.
Автоматически переведено. Английский — источник истины. Читать на английском