Rehberler
Webhookları işle
Sayfayı kopyala
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.
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
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/:idne 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
2xxhı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