ออก license อัตโนมัติหลังรับชำระเงิน ด้วย Management API
เชื่อม 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):
// หา 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 ฟรี:
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 ก็ทำได้เหมือนกัน
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 ให้ออเดอร์นี้แล้วหรือยัง
// กันออก 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) ได้ที่ เอกสารสำหรับนักพัฒนา