LiaGeliştiriciler

Rehberler

Bir tam webhook işleyicisi. Ham gövdedeki imzayı kontrol edin, API ile kontrol edin, bir kez harekete geçin ve hızlı yanıt verin.

Lia gönderir charge.paid, charge.refunded ve reward.paid webhook adresinize, webhook sırrınızla imzalı. Bkz. Webhook'lar her alan için.

#Node.js ile Express

Vücutta ham oku: imza, Lia tarafından gönderilen tam baytların üzerine, herhangi bir JSON ayrıştırmasından önce kontrol edin.

webhook.js
import express from "express";
import { createHmac, timingSafeEqual } from "node:crypto";
import { lia } from "./lia.js";

const app = express();

function verified(rawBody, header, secret) {
  const parts = Object.fromEntries((header ?? "").split(",").map((part) => part.split("=")));
  const t = Number(parts.t);
  if (!t || !parts.v1 || Math.abs(Date.now() / 1000 - t) > 300) 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);
}

app.post("/lia/webhook", express.raw({ type: "application/json" }), async (req, res) => {
  const event = verified(req.body.toString("utf8"), req.get("Lia-Signature"), process.env.LIA_WEBHOOK_SECRET);
  if (!event) return res.status(400).end();

  // Answer first; do the work after.
  res.status(200).end();

  if (event.type === "charge.paid") {
    // A nudge: check with Lia, then grant once per charge.
    const { charge } = await lia("GET", `/charges/${event.data.id}`);
    if (charge.status !== "paid") return;
    await db.grantOnce(charge.id, charge.playerId, () => grant(charge.playerId, charge.productId));
    await lia("POST", `/charges/${charge.id}/deliver`);
  }

  if (event.type === "charge.refunded") {
    await db.takeBack(event.data.id); // if you'd already given it
  }

  if (event.type === "reward.paid") {
    await db.noteReward(event.data.key, event.data.playerId, event.data.amount);
  }
});

#Cloudflare İşçileri

worker.js
async function verified(request, secret) {
  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) > 300) 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;
}

export default {
  async fetch(request, env, ctx) {
    const url = new URL(request.url);
    if (request.method === "POST" && url.pathname === "/lia/webhook") {
      const event = await verified(request, env.LIA_WEBHOOK_SECRET);
      if (!event) return new Response(null, { status: 400 });
      ctx.waitUntil(handle(event, env)); // the work, after answering
      return new Response(null, { status: 200 });
    }
    return new Response("Not found", { status: 404 });
  },
};

#Kurallar

  • İmzayı kontrol edin, ardından API ile kontrol edin. Bir webhook bir şeyin olduğunu söyler; GET /charges/:id ne söylediğini'şimdi doğru.
  • Bir kerede harekete geç. Webhook'lar iki kez gelebilir ve sayfanız zaten teslim edilmiş olabilir. Charge id veya ödül anahtarına göre ne yapacağınızı belirleyin.
  • Cevap 2xx hızla. Lia bir webhook'u iki kez, hemen hemen aynı anda deneyip sonra vazgeçer. Cevap verden sonra yavaş işler yapın.
  • Don'sadece webhooklara güvenmeyin. Geri kalmayı yakala Lia.charges() oyuncu uygulamanızı açtığında, böylece bir webhook kaçırıldığında bir satış kaybedilmez.
  • Moda dikkat edin. Test olayları aynı adresle gelir: kontrol edin data.mode.
  • Sahip olduğunuz türleri görmezden gelin'bilmek, ve hâlâ cevapla 200.

#Elde edilen işleyicinizi test edin

Tester olarak bir test satın alımı yapın (bakınız Test): gerçek, imzalı charge.paid ile mode: "test". Bilgisayarında denemek için, yerel sunucunu bir https tünelinin arkasına koy ve Lia ekibine webhook adresini oraya yönlendirmesini iste.

Otomatik çeviri. İngilizce, doğru kaynaktır. İngilizce olarak oku

Her sayfa, yöntem ve uç noktayı aramak için yazın.