Liaالمطورون

الدروس

معالجة ويب هوك كاملة. تحقق من التوقيع في الجسم الأصلي، وتحقق مع API، واتخذ إجراء واحد، ورد بسرعة.

يُرسل Lia charge.paid, charge.refunded و reward.paid إلى عنوان ويب هوك الخاص بك، موقعة بسر ويب هوك الخاص بك. انظر الويب هوكس لكل مجال.

#Node.js مع إكسبريس

اقرأ الجسم بحالة خام: التوقيع على البايتات الدقيقة Lia المرسلة، لذلك تحقق قبل أي تحليل JSON.

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 العمال

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 });
  },
};

#قواعد عامة

  • تحقق من التوقيع، ثم تحقق مع API. يقول الويب هوك شيئًا حدث؛ GET /charges/:id تقول ما'الواقع الآن.
  • اعمل مرة واحدة. يمكن أن تصل الويب هوكس مرتين، وقد تم تسليم صفحتك بالفعل. قم بتحديد ما تفعله على معرف الدفع أو مفتاح المكافأة.
  • إجابة 2xx بسرعة. يحاول Lia مُعدَّل الويب مرتين، مباشرة، ثم يستسلم. قم بعمل بطيء بعد الإجابة.
  • لا'لا تعتمد فقط على الـ webhooks. اللحاق بالركب Lia.charges() عندما يفتح اللاعب تطبيقك، لذلك لا يفقد بيعًا أبدًا بسبب ويب هوك مفقود.
  • انتبه للوضع. تصل الأحداث التجريبية إلى نفس العنوان: تحقق من data.mode.
  • تجاهل الأنواع التي لا'لأنك تعرف والإجابة, ويرد على 200.

#اختبار معالجك

قم بشراء تجريبية كمُختبر (انظر الاختبار): يرسل رمزًا حقيقيًا مُوقَّعًا charge.paid مع mode: "test". لتجربته على جهازك، ضع خادمك المحلي خلف جسر HTTPS واطلب من فريق Lia توجيه عنوان ويب هوك الخاص بك إليه.

تم الترجمة تلقائيًا. الإنجليزية هي مصدر الحقيقة. اقرأ باللغة الإنجليزية

اكتب للبحث في كل صفحة، وطريقة ونقطة نهاية.