← บทสอนทั้งหมด

บทสอน 4 / 12

สร้างหน้าชำระ ตรวจสอบการจ่าย

สร้างใบแจ้งหนี้จากแบ็กเอนด์และประมวลผลการแจ้งเตือนชำระที่ตรวจสอบแล้ว

สิ่งที่จะได้

ขั้นตอนชำระเงินฝั่งเซิร์ฟเวอร์ที่รองรับลองซ้ำและป้องกันรายการซ้ำ

1. เตรียมรหัสและสิทธิ์เข้าถึง

เริ่มจากร้านที่เปิดและวิธีชำระที่ทดสอบแล้ว ใน การตั้งค่า → การเข้าถึง APIสร้างข้อมูลรับรองอ่าน/เขียนที่จำกัดเฉพาะโปรเจกต์ที่ต้องใช้ เก็บโทเคนบนแบ็กเอนด์ ห้ามใส่ในโค้ดเบราว์เซอร์หรือคลังซอร์สสาธารณะ

คัดลอก รหัส API โปรเจกต์ และ รหัส API ร้าน จากกล่อง พื้นฐาน → รหัส API ของร้าน รหัสเหล่านี้คือ UUID ไม่ใช่ชื่อระบุโปรเจกต์ที่อ่านง่ายหรือเลขคำสั่งซื้อ ใช้ชื่อโฮสต์ API ของคุณเอง

ใน ร้าน → IPNสร้างคีย์ลับลงนามก่อนระบุ ipn_urlตัวรับ HTTPS ของคุณต้องเข้าถึงได้จาก VPS ผู้ค้า

2. สร้างใบแจ้งหนี้

แทนที่ตัวแทนค่าแล้วส่งคำขอนี้จากแบ็กเอนด์ ยอดเป็นสตริงทศนิยม ไม่ใช่ผลคำนวณเลขทศนิยมแบบ floating-point

curl --fail-with-body --request POST \
  'https://api.example.com/v1/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/invoices' \
  --header 'Authorization: Bearer YOUR_MERCHANT_API_TOKEN' \
  --header 'Content-Type: application/json' \
  --header 'Idempotency-Key: order-1042-attempt-1' \
  --data '{
  "amount": "10.00",
  "currency": "EUR",
  "order_id": "order-1042",
  "description": "Example order",
  "ipn_url": "https://shop.example.com/payments/wholly-ipn",
  "metadata": {
    "cart_id": "cart-1042"
  }
}'

บันทึก data.invoice_id ไว้กับคำสั่งซื้อ แล้วเปลี่ยนเส้นทางลูกค้าไป links.checkoutใช้คีย์ idempotency ไม่ซ้ำสำหรับการพยายามชำระครั้งใหม่ หากหมดเวลารอ ให้ลองซ้ำด้วย ข้อมูลรับรอง คีย์ และไบต์เนื้อหาเดิมทุกประการ.

หากไม่ระบุ payment_methods จะใช้วิธีที่ร้านรับ คุณจำกัดรายใบแจ้งหนี้ด้วย slug เชนและชื่อย่อได้ แต่ไม่เปิดสินทรัพย์ที่ร้านไม่ได้รับ ฟิลด์คำขอและตัวอย่างคำตอบทั้งหมด →

3. เลือก IPN, webhook หรือทั้งสอง

IPN ติดตามวงจรใบแจ้งหนี้ ตั้ง URL IPN เริ่มต้นร้านหรือกำหนดทับด้วย ipn_url สำหรับใบแจ้งหนี้นั้น Webhook สมัครปลายทางให้รับเหตุการณ์ที่เลือก เช่น invoice.settled.

ใช้รูปแบบลายเซ็นเดียวกัน แต่ คีย์ลับต่างกัน: IPN ใช้คีย์ลับ IPN ร้าน แต่ละปลายทาง webhook มีคีย์ลับของตน ทั้งสองไม่ใช้โทเคน API bearer ลงนาม

หากทั้งสองส่งเข้าแอป คาดว่าจะมีการแจ้งเตือนทับซ้อน อย่าเพิ่มยอดคำสั่งซื้อสองครั้ง

4. ตรวจและบันทึกการแจ้งเตือน

  1. อ่านเนื้อหาคำขอดิบให้ตรงทุกไบต์ก่อนแยก JSON ตรวจ Wholly-Signature ด้วยคีย์ลับที่ตรง พร้อมตรวจเวลาและป้องกัน replay SDK ทางการมีตัวตรวจให้
  2. ตรวจตัวตนโปรเจกต์ ร้าน ใบแจ้งหนี้ และเหตุการณ์ในเนื้อหาที่ลงนาม ส่วนหัวส่งที่ไม่ลงนามไม่ใช่แหล่งยืนยันตัวตน
  3. เก็บเหตุการณ์อย่างถาวรพร้อมค่าที่ไม่ซ้ำของ event_idแล้วคืน HTTP 2xx โดยเร็ว ประมวลผลคำสั่งซื้อในตัวทำงานเบื้องหลัง
  4. เรียกใบแจ้งหนี้ปัจจุบันจากโฮสต์ API ที่ตั้งไว้ ไม่ใช่โฮสต์ใด ๆ ที่ส่งมาในคำขอ เทียบโปรเจกต์ ร้าน ยอด สกุลเงิน และข้อมูลอ้างอิงคำสั่งซื้อที่บันทึก

PHP · Python · JavaScript / TypeScript · ข้อกำหนดลายเซ็นและตัวอย่างตัวรับ

5. ดำเนินการตามคำสั่งซื้อครั้งเดียวเมื่อชำระเสร็จ

สำหรับตัวรับ ที่อิงเหตุการณ์ ให้จัดการ event_type = invoice.settledแล้วตรวจค่าปัจจุบันของ status = settled และนโยบายข้อยกเว้น ดำเนินการตามคำสั่งซื้อครั้งเดียวภายใต้ธุรกรรมฐานข้อมูล/ข้อจำกัดรหัสคำสั่งซื้อไม่ซ้ำ

ชนิดเหตุการณ์และสถานะเป็นคนละอย่าง

เชนที่สรุปผลเร็วอาจส่งทั้ง payment.received และ invoice.settled ร่วมกับ status = settledบนเชนอื่น payment.received อาจยังระบุ processing ทั้งสองกรณีไม่ใช่ข้อผิดพลาด

ตัดเหตุการณ์ซ้ำด้วย event_idไม่ใช่ sequence อย่างเดียว: เหตุการณ์ต่างชนิดอาจใช้ sequence เดียวกัน ตัวจัดการ SDK แบบอิงสถานะจะรวมรุ่นแก้ไขใบแจ้งหนี้และตรวจสถานะโดยไม่สนชนิดเหตุการณ์แทน อย่าผสมการรวมรุ่นนั้นกับตัวกรองชนิดเหตุการณ์ ทั้งสองวิธียังต้องป้องกันซ้ำระดับคำสั่งซื้อ

ตรวจ requires_review และผลการแก้ด้วยตนเองก่อนดำเนินการตามคำสั่งซื้อ amount_status = paid อย่างเดียวไม่พิสูจน์การยืนยัน ฟิลด์สินทรัพย์ที่ชำระระดับบนสรุปการชำระเสร็จ ส่วน payment_info เก็บรายละเอียดเงินที่รับและข้อมูลราคาเสนอ สถานะ เหตุการณ์ และกฎข้อยกเว้นทั้งหมด →

6. ทดสอบการลองซ้ำและกู้คืน

ทดสอบชำระยอดเล็ก การส่งซ้ำ ใบแจ้งหนี้หมดอายุ และตัวรับที่ใช้ไม่ได้ชั่วคราว การเล่นเหตุการณ์ซ้ำต้องไม่เพิ่มยอดคำสั่งซื้อครั้งที่สอง จัดการเหตุการณ์มาผิดลำดับโดยไม่เขียนทับสถานะใหม่กว่า

ตรวจ ร้าน → IPN / Webhook → ประวัติ → รายละเอียดหรือส่วนการส่งในรายละเอียดใบแจ้งหนี้ การส่งซ้ำใช้เหตุการณ์ที่บันทึกไว้ ไม่ใช่การชำระเสร็จใหม่

เครดิตประมวลผลต่ำพัก IPN/webhook แต่การรับชำระยังทำงาน กระทบยอดคำสั่งซื้อค้างผ่าน API และจัดการการส่งที่เก็บไว้หลังฟื้นการทำงาน ห้ามดำเนินการตามคำสั่งซื้อจากการเปลี่ยนเส้นทางเบราว์เซอร์หรือภาพหน้าจอลูกค้า