LiaDéveloppeurs

Guides

Un gestionnaire de webhook complet. Vérifiez la signature sur le corps brut, vérifiez avec le API, agissez une seule fois, et répondez rapidement.

Lia envoie charge.paid, charge.refunded et reward.paid à votre adresse de webhook, signée avec votre secret de webhook. Voir Webhooks pour chaque champ.

#Node.js avec Express

Lisez le corps brut : la signature est sur les octets exacts Lia envoyés, vérifiez-la avant toute analyse 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 Workers

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

#Principes généraux

  • Vérifiez la signature, puis vérifiez avec le API. Un webhook dit qu'il s'est passé quelque chose ; GET /charges/:id dit ce'est vrai maintenant.
  • Agir une fois. Les webhooks peuvent arriver deux fois, et votre page peut avoir déjà été livrée. Clé ce que vous faites sur l'identifiant de charge ou la clé de récompense.
  • Réponse 2xx rapidement. Lia tente un webhook deux fois, immédiatement, puis abandonne. Faites le travail lent après avoir répondu.
  • Don'ne se fie pas uniquement aux webhooks. Rattrapez-vous avec Lia.charges() quand un joueur ouvre votre application, donc un webhook manqué ne perd jamais une vente.
  • Faites attention au mode. Les événements de test arrivent au même adresse : vérifiez data.mode.
  • Ignorez les types que vous n''ne pas savoir, et toujours répondre 200.

#Tester votre gestionnaire

Faites un achat test en tant que testeur (voir Tests): il envoie un véritable, signé charge.paid avec mode: "test". Pour l'essayer sur votre ordinateur, placez votre serveur local derrière un tunnel https et demandez à l'équipe Lia de pointer votre adresse webhook vers là-bas.

Traduit automatiquement. L'anglais est la source de vérité. Lire en anglais

Tapez pour rechercher sur toutes les pages, méthodes et points de terminaison.