ออก license อัตโนมัติหลังรับชำระเงิน ด้วย Management API

อ่าน 7 นาที

เชื่อม webhook ของร้านค้าเข้ากับ KeyThai Management API เพื่อออก license key อัตโนมัติทันทีที่ลูกค้าจ่ายเงินสำเร็จ พร้อมส่งคีย์ทางอีเมล

เป้าหมายในฝันของการขายซอฟต์แวร์คือ: ลูกค้าจ่ายเงิน → ได้ license key อัตโนมัติทางอีเมลภายในไม่กี่วินาที โดยคุณไม่ต้องทำอะไรด้วยมือ บทความนี้จะต่อ webhook ของร้านค้า (หรือ payment gateway) เข้ากับ KeyThai Management API เพื่อออก license key อัตโนมัติ

ภาพรวมการทำงาน

ขั้นตอนคือ: (1) ร้านค้ายิง webhook payment.succeeded มาที่เซิร์ฟเวอร์ของคุณ → (2) คุณเรียก POST /v1/licenses ออก license → (3) ส่ง key ให้ลูกค้าทางอีเมล ทั้งหมดใช้ API key ของคุณที่มี scope license:write

หา product / policy id ก่อน

การสร้าง license ต้องระบุ product และ policyId เรียกครั้งเดียว เพื่อหา id แล้วเก็บไว้ (เช่นใส่ใน env):

JavaScript
// หา product/policy id ครั้งเดียว (เก็บใส่ env ก็ได้)
const products = await keythai.listProducts();
const policies = await keythai.listPolicies(products[0].id);
console.log(policies.map((p) => ({ id: p.id, name: p.name, type: p.type })));

เชื่อม Webhook → ออก License

ตัวอย่าง endpoint ด้วย Express + SDK keythai — สังเกตว่าเราตรวจลายเซ็น webhook ของร้านค้าก่อนเสมอ เพื่อกันคนยิง request ปลอมมาขอ license ฟรี:

Node.js (Express + keythai)
import { KeyThaiClient } from "keythai";
import crypto from "node:crypto";

const keythai = new KeyThaiClient({ apiKey: process.env.KEYTHAI_API_KEY! });

// webhook endpoint ของร้านค้า (เช่น Express) — ยิงเมื่อชำระเงินสำเร็จ
app.post("/webhooks/shop", express.raw({ type: "*/*" }), async (req, res) => {
  // 1) ตรวจลายเซ็น webhook ของร้านค้าก่อน (กันคนปลอม request)
  if (!verifyShopSignature(req.body, req.headers["x-shop-signature"])) {
    return res.status(401).end();
  }

  const event = JSON.parse(req.body.toString());
  if (event.type !== "payment.succeeded") return res.status(200).end();

  // 2) ออก license ผ่าน Management API
  const { licenses } = await keythai.createLicense({
    product: "my-app",
    policyId: "01J...",                       // ดูได้จาก listPolicies()
    holderName: event.customer.name,
    holderEmail: event.customer.email,
    metadata: { order: event.order_id },
    quantity: 1,
  });

  // 3) ส่ง key ให้ลูกค้า (plaintext key มีให้ "ครั้งเดียว" ตรงนี้)
  await sendLicenseEmail(event.customer.email, licenses[0].key);

  res.status(200).end();
});

สำคัญ: plaintext license key ใน licenses[0].key จะมีให้ “ครั้งเดียว” ตอนสร้างเท่านั้น (ระบบเก็บแค่ hash) ต้องส่งให้ลูกค้า/บันทึกทันที

ฝั่ง Python ก็ทำได้เหมือนกัน

Python (keythai)
from keythai import KeyThaiClient

keythai = KeyThaiClient(api_key=os.environ["KEYTHAI_API_KEY"])

created = keythai.create_license(
    product="my-app",
    policy_id="01J...",
    holder_name=customer["name"],
    holder_email=customer["email"],
    metadata={"order": order_id},
    quantity=1,
)
send_license_email(customer["email"], created["licenses"][0]["key"])

กันออก license ซ้ำ (idempotency)

webhook มักถูกส่งซ้ำได้ (retry) ถ้าไม่ป้องกัน ลูกค้าอาจได้หลายคีย์จากการจ่ายครั้งเดียว แก้ด้วยการผูกกับ order_id: เช็คก่อนว่าเคยออก license ให้ออเดอร์นี้แล้วหรือยัง

idempotency guard
// กันออก license ซ้ำเมื่อ webhook ถูกส่งซ้ำ (retry):
// เก็บ order_id ที่เคยออก license แล้วลงฐานข้อมูล แล้วเช็คก่อนเรียก createLicense
const already = await db.licenseByOrder(event.order_id);
if (already) return res.status(200).end();   // ออกไปแล้ว ข้าม

เท่านี้คุณก็มีระบบขายซอฟต์แวร์อัตโนมัติเต็มรูปแบบ ดูรายละเอียด Management API ทั้งหมด (list/update/revoke) ได้ที่ เอกสารสำหรับนักพัฒนา

พร้อมปกป้องซอฟต์แวร์ของคุณแล้วหรือยัง?

เริ่มต้นฟรี ไม่ต้องใช้บัตรเครดิต ออก license key แรกของคุณได้ในไม่กี่นาที