Referência do servidor
Webhooks
Copiar página
Lia informa seu servidor quando uma cobrança é paga ou reembolsada e quando uma recompensa é paga, assinada com sua chave de webhook. O que é enviado, como verificar a assinatura e como os retries funcionam.
#Configurar um
Dê ao time Lia um endereço https no seu servidor e mantenha o segredo de assinatura do webhook (whsec_…) que vieram com suas chaves. Lia então envia uma POST lá quando algo acontece no seu app.
Um webhook é um empurrão, não a verdade: verifique com o API antes de agir sobre um (para uma carga, GET /charges/:id). E não'para depender apenas de webhooks; sua página também pode informar ao seu servidor (veja Vender um item).
#O que'enviado
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
}
}| Campo | Tipo | |
|---|---|---|
type | string | O que aconteceu (abaixo). |
app | string | Seu app id. |
at | número | Quando foi enviado, em milissegundos desde 1970. |
data | objeto | O que ele's sobre. |
#Tipos
| Tipo | Quando | data |
|---|---|---|
charge.paid | Uma pessoa pagou em Lia'sua folha de pagamento, em teste ou em produção. | O cobrar, com status: "paid" |
charge.refunded | Você reembolsou uma cobrança. | A cobrança, com status: "refunded" |
reward.paid | Você pagou uma recompensa da sua pool, em teste ou ao vivo. | { key, playerId, amount, reason, mode } |
Verifique data.mode (ou a cobrança's mode) então os eventos de teste nunca concedem nada real. Mais tipos podem ser adicionados: ignore os tipos que você não'saber e responder 200.
#Verificação da assinatura
Todo webhook tem um Lia-Signature cabeçalho, t=<seconds>,v1=<signature>. A assinatura é HMAC SHA-256, em hex, dos segundos, um ponto, e o corpo bruto, com chave com sua senha de webhook inteira (incluindo whsec_):
v1 = hex(HMAC_SHA256(key = "whsec_…", message = t + "." + rawBody))Verifique-o contra o corpo bruto exatamente como chegou, antes de analisá-lo, e recuse webhooks com mais de alguns minutos de idade.
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;
}Tratar webhooks tem um manipulador completo.
#Respostas e tentativas
- Responda com qualquer
2xxstatus, rapidamente. Faça trabalho lento após responder. - Se o seu servidor não't resposta
2xx(ou pode'não seja alcançado), Lia tenta novamente imediatamente. Depois disso, o webhook não'para enviar novamente. - Assim, webhooks podem ser perdidos e podem chegar duas vezes. Faça seu manipulador seguro para ser executado duas vezes (chave-o pelo id da cobrança ou pela chave da recompensa), e tenha outra forma de se recuperar, como
Lia.charges()quando o jogador abre seu app.
#Sua senha
Sua senha de webhook muda sempre que suas chaves são geradas novamente. Mantenha-a no seu servidor, ao lado da sua chave.
Traduzido automaticamente. O inglês é a fonte de verdade. Leia em inglês