Panduan
Menangani webhooks
Salin halaman
Handler webhook lengkap. Periksa tanda tangan pada tubuh mentah, periksa dengan API, lakukan sekali, dan jawab dengan cepat.
Lia mengirim charge.paid, charge.refunded dan reward.paid ke alamat webhook kamu, yang ditandatangani dengan rahasia webhook kamu. Lihat Webhook untuk setiap bidang.
#Node.js dengan Express
Baca tubuh mentah: tanda tangan berada di atas byte eksak Lia yang dikirim, jadi periksa sebelum pemrosesan JSON apa pun.
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 Pekerja
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 });
},
};#Aturan umum
- Periksa tanda tangan, lalu periksa dengan API. Sebuah webhook menyatakan sesuatu terjadi;
GET /charges/:idkatakan apa'benar sekarang. - Lakukan sekali. Webhook bisa datang dua kali, dan halaman Anda mungkin sudah mengirimkan. Pastikan apa yang Anda lakukan pada charge id atau reward key.
- Jawaban
2xxcepat. Lia mencoba webhook dua kali, langsung, lalu menyerah. Lakukan pekerjaan lambat setelah menjawab. - Tidak'tidak mengandalkan webhooks saja. Menyusul
Lia.charges()ketika pemain membuka aplikasi kamu, jadi webhook yang terlewat tidak pernah kehilangan penjualan. - Perhatikan mode. Uji acara tiba di alamat yang sama: periksa
data.mode. - Abaikan tipe yang tidak'tidak tahu, dan tetap menjawab
200.
#Menguji handler Anda
Lakukan pembelian uji sebagai penguji (lihat Pengujian): mengirimkan sebuah charge.paid dengan mode: "test". Untuk mencobanya di komputer Anda, tempatkan server lokal Anda di balik tunnel https dan mintalah tim Lia untuk mengarahkan alamat webhook Anda ke sana.
Diterjemahkan otomatis. Bahasa Inggris adalah sumber kebenaran. Baca dalam Bahasa Inggris