Skip to main content

การตรวจสอบลายเซ็น Webhook

การแจ้งเตือนการชำระเงินมาถึงที่อยู่ซึ่งมีเพียงร้านค้าของคุณและบริการของเราที่รู้ แต่ที่อยู่อาจรั่วไหลได้ — จากล็อก จากการตั้งค่า จากประวัติการพัฒนา เพื่อแยกการแจ้งเตือนของจริงออกจากของปลอม คำขอทุกคำขอจึงถูกเซ็นด้วยคีย์ลับของ Webhook

ตรวจสอบลายเซ็นก่อนส่งมอบคำสั่งซื้อหรือเปลี่ยนสถานะของคำสั่งซื้อ

Header ของลายเซ็น

Headerค่า
X-Timestampเวลาส่ง เป็น unix time หน่วยวินาที
X-Signatureคำนำหน้า sha256= ตามด้วย HMAC-SHA256 แบบ hex

สตริงที่ถูกเซ็นคือเวลาส่ง ตามด้วยจุด และเนื้อหาคำขอ:

1756901234.{"wallet":{...},"project":{...},"invoice":{...},"payment":{...}}

คีย์ที่ใช้เซ็นคือฟิลด์คีย์ลับของ Webhook (Webhook secret) ในการตั้งค่าโปรเจกต์ คุณออกคีย์ใหม่ได้ที่นั่นหากค่ารั่วไหล

ขั้นตอนการตรวจสอบ

  1. นำเนื้อหาคำขอแบบ raw ก่อนแยกวิเคราะห์ JSON
  2. ต่อสตริงจากค่า X-Timestamp จุด และเนื้อหาคำขอ
  3. คำนวณ HMAC-SHA256 ด้วยคีย์ลับของ Webhook
  4. เทียบผลลัพธ์กับ X-Signature ด้วยการเปรียบเทียบแบบเวลาคงที่
  5. ปฏิเสธคำขอหาก X-Timestamp ห่างจากเวลาปัจจุบันมากเกินไป

ตัวอย่างการนำไปใช้

<?php
$secret = 'webhook secret from your project settings';

$body = file_get_contents('php://input');
$timestamp = $_SERVER['HTTP_X_TIMESTAMP'] ?? '';
$signature = $_SERVER['HTTP_X_SIGNATURE'] ?? '';

// Guards against a replayed request
if (abs(time() - (int)$timestamp) > 300) {
http_response_code(400);
exit;
}

$expected = 'sha256='.hash_hmac('sha256', $timestamp.'.'.$body, $secret);

// hash_equals compares in constant time
if (!hash_equals($expected, $signature)) {
http_response_code(403);
exit;
}

$data = json_decode($body, true);

// Handle the order

http_response_code(200);

สิ่งที่พึงระลึก

สิ่งที่ถูกเซ็นคือเนื้อหาแบบ raw หากคุณแยกวิเคราะห์ JSON แล้วประกอบขึ้นใหม่ ลำดับคีย์และช่องว่างจะเปลี่ยน — ลายเซ็นจะไม่ตรง ให้คำนวณ HMAC ก่อนแยกวิเคราะห์

การลองส่งใหม่แต่ละครั้งมีลายเซ็นของตัวเอง เวลาส่งใหม่ทุกครั้งที่ลองใหม่ ลายเซ็นจึงต่างกันด้วย อย่าเก็บลายเซ็นไว้เทียบกับคำขอในอนาคต

คีย์ลับออกใหม่ได้ คีย์เก่าหยุดทำงานทันทีหลังออกใหม่ ดังนั้นให้อัปเดตค่าในร้านค้าของคุณพร้อมกัน

การตรวจสอบลายเซ็นไม่ได้แทนที่ความเป็น idempotent ลายเซ็นพิสูจน์ว่าคำขอเป็นของแท้ ไม่ได้พิสูจน์ว่าคุณเห็นเป็นครั้งแรก การลองส่งใหม่มาถึงพร้อมลายเซ็นที่ถูกต้อง — ให้ตรวจกับ invoice.id