Lia开发者

指南

在你的应用中用 $LIA 卖东西,端到端。在你的页面上生成支付表单,然后在你的服务器上确认并交付,即使页面重新加载也不会丢失任何东西。

你'会出售 "3次额外生命" 对于 5 LIA。 该人将在 Lia 支付'的表单,你的服务器会与Lia 核对费用,添加生命值,并标记费用已送达。

#1. 添加产品

请Lia团队在您的应用中添加一个产品:ID extra-lives,名称 "3次额外生命",价格5.你的服务器可以检查它'是:

curl https://api.lialabs.org/api/apps/v1/products -H "Authorization: Bearer $LIA_KEY"

#2. 在您的页面中:支付,然后告诉您的服务器

shop.js
async function buyExtraLives() {
  let charge;
  try {
    charge = await Lia.pay("extra-lives");
  } catch (error) {
    if (error.code === "cancelled") return; // they changed their mind
    Lia.toast("Couldn't open the payment", { tone: "error" });
    return;
  }
  await deliver(charge.chargeId);
}

// Your server checks the charge and gives the lives. Safe to call twice for one charge.
async function deliver(chargeId) {
  const { session } = await Lia.session();
  const res = await fetch("/api/deliver", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ session, chargeId }),
  });
  if (!res.ok) return Lia.toast("We'll add it as soon as we can", { tone: "error" });
  const { lives } = await res.json();
  showLives(lives);
  Lia.haptic("success");
}

#3. 在您的服务器上:检查,交付,标记它

server.js
import { lia } from "./lia.js"; // the helper from the Server API page

app.post("/api/deliver", async (req, res) => {
  // Who is asking: from Lia, not from the page.
  const { valid, playerId } = await lia("POST", "/session/verify", { session: req.body.session });
  if (!valid) return res.status(401).json({ error: "session" });

  // Is this charge real, paid, and theirs?
  let charge;
  try {
    ({ charge } = await lia("GET", `/charges/${encodeURIComponent(req.body.chargeId)}`));
  } catch (error) {
    return res.status(404).json({ error: "no_charge" });
  }
  if (charge.playerId !== playerId) return res.status(403).json({ error: "not_yours" });
  if (charge.status === "refunded") return res.status(409).json({ error: "refunded" });

  // Give it once, keyed on the charge id (a second call finds it already given).
  const lives = await db.grantOnce(charge.id, playerId, () => db.addLives(playerId, 3));

  // Then tell Lia it's delivered (safe to repeat).
  await lia("POST", `/charges/${charge.id}/deliver`);
  res.json({ lives });
});

重要部分:

  • 玩家来自 /session/verify,从不来自页面。
  • 费用来自 GET /charges/:id: 它的播放器、产品和状态是 Lia's.
  • 每个充值ID只能获得一次奖励,在你自己的数据库中,因此重试、webhook和页面可以'不要重复两次。在一次交易中完成并记录费用ID。
  • 在授权后交付。 如果你的服务器在两者之间崩溃,费用仍然有效 paid 和你'你会再次看到它(如下所示),你每次充电的检查可以防止双重授予。

#4. 永远不要丢失一个

页面在支付和你的服务器之间可能重新加载或失去连接。当你的应用打开时,或者当一笔费用没有伴随信息到达时,进行追赶。 pay() 等待:

Lia.init().then(async function () {
  Lia.ready();
  for (const charge of await Lia.charges()) await deliver(charge.chargeId);
});
Lia.onCharge(function (charge) { deliver(charge.chargeId); });

#5. 或通过 Webhook 交付

如果你的服务器在没有页面的情况下提供物品(例如向账户添加硬币),请使用 charge.paid 网络钩子 也。检查费用与 GET /charges/:id,每个充值ID只能授予一次,然后交付。通过页面和webhook,先到达的会进行交付,另一个会发现已经完成了。

#当你可以的时候't 交付

如果你出售的某样东西可以't 会被给予(它售罄,账户已消失),把$LIA还回去:

await lia("POST", `/charges/${charge.id}/refund`);

这个人会得到全额退款,并且可以't 会被送达。告诉他们在你的页面上。

#测试它

使用您的测试密钥和您的测试应用,作为测试者购买它:表格显示“测试”,没有 $LIA 移动,但其他一切都会真实发生。参见 测试.

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

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