Lia开发者

服务器参考

Lia会在支付或退款时以及奖励支付时通知你的服务器,并用你的webhook密钥进行签名。发送的内容、如何检查签名以及重试的工作方式。

#设置一个

给Lia团队一个你服务器的https地址,并保留webhook签名密钥(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字符串您的应用程序 ID。
at数字当它被发送时,以 1970. 以来的毫秒数表示
data对象它's 关于。

#类型

类型何时data
charge.paid有人在Lia上付款'的付款表格,在测试或正式环境中。的 收费,带有 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))

将其与原始身体内容精确对比,就像它到达时一样,在解析之前,拒绝几分钟以上的网络钩子。

Node.js
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);
}
Cloudflare Workers, Deno, Bun
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会立即再试一次。之后,webhook不会'再次发送。
  • 因此webhooks可能会被错过,也可能重复到达。请确保您的处理程序可以安全地运行两次(根据charge id或reward key进行键控),并有另一种方式来追上进度,例如 Lia.charges() 当玩家打开你的应用时。

#您的密钥

您的网络钩子密钥在您的密钥重新生成时会更改。将其保留在您的服务器上,与您的密钥放在一起。

自动翻译。英语是真实来源。 阅读英文

输入以搜索每一页、方法和端点。