Webhooks สำหรับการชำระเงิน (เดิมเรียกว่า "การอัพเดตแบบเรียลไทม์") เป็นวิธีการสำคัญที่จะแจ้งให้คุณทราบถึงการเปลี่ยนแปลงในคำสั่งซื้อที่ดำเนินการผ่านการชำระเงินบน Facebook ภายในแอพของคุณ |
Webhooks เป็นระบบที่อิงตามการสมัครรับข้อมูลระหว่าง Facebook กับเซิร์ฟเวอร์ของคุณ ซึ่งแอพของคุณจะสมัครรับข้อมูลอัพเดตต่างๆ จาก Facebook ผ่านตำแหน่งข้อมูล HTTPS ที่ระบุ เมื่อคำสั่งซื้อในแอพมีการอัพเดต เราจะออกคำขอ HTTPS POST ให้กับตำแหน่งข้อมูลดังกล่าว โดยแจ้งให้เซิร์ฟเวอร์ของคุณทราบถึงการเปลี่ยนแปลง
ระบบจะส่งการอัพเดตไปยังเซิร์ฟเวอร์ของผู้พัฒนาใน 3 สถานการณ์หลักต่อไปนี้
หากต้องการสมัครรับข้อมูล Webhooks สำหรับการชำระเงิน อันดับแรกให้สร้าง URL ตำแหน่งข้อมูลเป็นแบบสาธารณะที่รับทั้ง HTTPS GET สำหรับการตรวจสอบยืนยันการสมัครรับข้อมูล และ POST สำหรับคำขอข้อมูลการเปลี่ยนแปลง ซึ่งโครงสร้างของคำขอทั้ง 2 ประเภทนี้มีคำอธิบายที่ด้านล่าง จากนั้น ตั้งค่าการสมัครรับข้อมูลให้กับอ็อบเจ็กต์ payment ในแอพของคุณ โดยสามารถทำได้ 2 วิธี ดังนี้
ซึ่งไม่ว่าจะเป็นกรณีใด ตำแหน่งข้อมูลของคุณก็จะได้รับข้อมูลเดียวกันนี้ในรูปแบบเดียวกัน โปรดดูข้อมูลเพิ่มเติมเกี่ยวกับสิ่งที่เซิร์ฟเวอร์ของคุณจะได้รับที่เซิร์ฟเวอร์การเรียกกลับของคุณ
วิธีที่ง่ายที่สุดในการตั้งค่าแอพเพื่อรับการอัพเดต Webhooks คือการใช้แผงการชำระเงินในแดชบอร์ดของแอพ โดยค้นหาแอพของคุณในแดชบอร์ด แล้วคลิกที่แท็บ Payments ซึ่งส่วนของ Webhooks จะอยู่ถัดจากส่วน "การตั้งค่า" ของบริษัทลงไปด้านล่าง

จากนั้น หน้าจอนี้จะแสดงรายการสถานะการสมัครรับข้อมูลของแอพ ไม่ว่าคุณจะเพิ่มการสมัครรับข้อมูลนั้นผ่านแผงนี้หรือผ่าน API ก็ตาม จากตรงนี้ คุณสามารถเปลี่ยนแปลง URL การเรียกกลับของการสมัครรับข้อมูลและทดสอบ URL ดังกล่าวได้
ในช่อง "การเรียกกลับ" คุณต้องระบุตำแหน่งข้อมูลของเซิร์ฟเวอร์ที่เข้าถึงได้แบบสาธารณะและถูกต้อง นี่คือที่อยู่ที่เราจะใช้ตรวจสอบยืนยันการสมัครรับข้อมูลและส่งการอัพเดต และจำเป็นต้องตอบกลับตามที่อธิบายไว้ในเซิร์ฟเวอร์การเรียกกลับของคุณ
ขั้นตอนสุดท้าย ให้ระบุ "โทเค็นการตรวจสอบยืนยัน" โดยระบบจะส่งโทเค็นนี้เฉพาะในระหว่างช่วงการลงทะเบียน เพื่อตรวจสอบยืนยันว่าการสมัครรับข้อมูลมาจากตำแหน่งที่ปลอดภัยเท่านั้น ซึ่งระบบจะไม่ส่งโทเค็นนี้ในการอัพเดต Webhook ตามปกติ
คุณควรทดสอบการตั้งค่าการเรียกกลับก่อนที่จะบันทึกการสมัครรับข้อมูล ซึ่งระบบจะออกคำขอ GET การตรวจสอบยืนยันให้กับตำแหน่งข้อมูลของคุณ โดยจะประกอบด้วยพารามิเตอร์ hub.mode, hub.challenge และ hub.verify_token และจะรับรองว่าคุณได้จัดการอย่างถูกต้องแล้ว ตัวอย่างเช่น คุณต้องแน่ใจได้ว่าตำแหน่งข้อมูลของคุณสะท้อน hub.challenge กลับมาที่ Facebook

เมื่อคุณป้อนรายละเอียดการสมัครรับข้อมูลแล้ว โปรดตรวจสอบให้แน่ใจว่าคุณได้คลิกปุ่ม "บันทึกการเปลี่ยนแปลง" ที่ด้านล่างของหน้าแล้ว ส่วนการแก้ไขการสมัครรับข้อมูลก็สามารถทำได้ง่ายๆ เพียงปรับเปลี่ยนเนื้อหาในช่อง ทดสอบซ้ำ และบันทึกแบบฟอร์มอีกครั้ง
นอกจากนี้คุณยังสามารถตั้งค่าและลงรายการการสมัครรับข้อมูลด้วยโปรแกรมผ่าน API กราฟได้อีกด้วย โดยคุณจะต้องมี access token ของแอพ ซึ่งจะพร้อมใช้งานจากเครื่องมือสร้างโทเค็นการเข้าถึง หรือโดยการใช้ตำแหน่งข้อมูล /oauth ของ API กราฟ
API การสมัครรับข้อมูลมีให้ใช้งานที่ตำแหน่งข้อมูล https://graph.facebook.com/[APP_ID]/subscriptions
ซึ่งคุณสามารถใช้ในการทำงาน 3 อย่างต่อไปนี้
POST)GET)ในการตั้งค่าการสมัครรับข้อมูล ให้ส่ง POST พร้อมพารามิเตอร์ต่อไปนี้ โปรดทราบว่าพารามิเตอร์เหล่านี้จะสอดคล้องกับช่องต่างๆ ในแบบฟอร์มที่อธิบายไว้ข้างต้น ดังนี้
object - ประเภทอ็อบเจ็กต์ที่คุณต้องการรับข้อมูลอัพเดตดังที่ระบุไว้ข้างต้น ให้ระบุ paymentsfields - รายการคุณสมบัติของประเภทอ็อบเจ็กต์ที่คั่นด้วยเครื่องหมายจุลภาคที่คุณต้องการรับข้อมูลอัพเดตเกี่ยวกับการเปลี่ยนแปลง ให้ระบุ "actions" และ "disputes"callback_url - ตำแหน่งข้อมูลของเซิร์ฟเวอร์ที่เข้าถึงได้แบบสาธารณะและถูกต้องverify_token - สตริงแบบกำหนดเองซึ่งส่งไปยังตำแหน่งข้อมูลของคุณเมื่อมีการตรวจสอบยืนยันการสมัครรับข้อมูลเมื่อเราได้รับคำขอนี้ เราจะดำเนินการ GET ไปที่การเรียกกลับของคุณเช่นเดียวกับการกำหนดค่าแบบฟอร์มข้างต้น เพื่อให้แน่ใจว่าคำขอนั้นถูกต้องและพร้อมรับการอัพเดต โดยเฉพาะอย่างยิ่ง คุณต้องแน่ใจได้ว่าตำแหน่งข้อมูลของคุณสะท้อน hub.challenge กลับมาที่ Facebook
โปรดทราบว่า เนื่องจากแอพหนึ่งๆ สามารถมีการสมัครรับข้อมูลอ็อบเจ็กต์แต่ละประเภทได้เพียง 1 รายการ หากมีการสมัครรับข้อมูลอ็อบเจ็กต์ประเภทนี้อยู่แล้ว ข้อมูลที่โพสต์ใหม่จะแทนที่ข้อมูลใดๆ ก็ตามที่มีอยู่
การออก HTTP GET ให้กับ API การสมัครรับข้อมูลจะส่งกลับเนื้อหาที่เข้ารหัสแบบ JSON ซึ่งแสดงรายการการสมัครรับข้อมูลของคุณ ตัวอย่างเช่น
[
{
"object": "payments",
"callback_url": "https://www.friendsmash.com/rtu.php",
"fields": ["actions", "disputes"],
"active": true
}
]คุณสามารถใช้ Graph Explorer เพื่อทดลองกับ API นี้ได้โดยตรง โดยอย่าลืมใช้โทเค็นการเข้าถึงของแอพ
เซิร์ฟเวอร์การเรียกกลับของคุณต้องจัดการกับคำขอ 2 ประเภท โปรดตรวจสอบให้แน่ใจว่าเซิร์ฟเวอร์อยู่บน URL สาธารณะ เพื่อให้เราสามารถสร้างคำขอเหล่านี้ได้สำเร็จ
อันดับแรก เซิร์ฟเวอร์ Facebook จะสร้าง HTTPS GET แบบเดี่ยวไปที่ URL การเรียกกลับกลับเมื่อคุณพยายามเพิ่มหรือแก้ไขการสมัครรับข้อมูล ซึ่งระบบจะนำสตริงการสืบค้นมาต่อท้าย URL การเรียกกลับของคุณโดยมีพารามิเตอร์ต่อไปนี้
| พารามิเตอร์ | คำอธิบาย |
|---|---|
| ระบบจะส่งสตริง " |
| สตริงแบบสุ่ม |
| ค่า |
ตำแหน่งข้อมูลควรตรวจสอบยืนยัน hub.verify_token เป็นอันดับแรก ซึ่งจะช่วยให้แน่ใจได้ว่าเซิร์ฟเวอร์ของคุณรู้ว่า Facebook เป็นผู้สร้างคำขอและคำขอนั้นเกี่ยวข้องกับการสมัครรับข้อมูลที่คุณเพิ่งกำหนดค่าไป
จากนั้น ตำแหน่งข้อมูลควรสะท้อนกลับเฉพาะค่า hub.challenge ซึ่งจะเป็นการยืนยันกับ Facebook ว่าเซิร์ฟเวอร์นี้ได้รับการกำหนดค่าให้ยอมรับการเรียกกลับ และป้องกันช่องโหว่การปฏิเสธบริการ (DDoS) แล้ว
หมายเหตุสำหรับผู้พัฒนา PHP: ระบบจะแปลงจุดและการเว้นวรรคในชื่อพารามิเตอร์การสืบค้นเป็นเครื่องหมายขีดล่างโดยอัตโนมัติในภาษา PHP ดังนั้น คุณควรเข้าถึงพารามิเตอร์เหล่านี้โดยใช้ $_GET['hub_mode'], $_GET['hub_challenge'] และ $_GET['hub_verify_token'] หากคุณเขียนตำแหน่งข้อมูลการเรียกกลับในภาษา PHP โปรดดูรายละเอียดเพิ่มเติมที่บันทึกนี้ในคู่มือภาษา PHP
หลังจากที่สมัครรับข้อมูลสำเร็จแล้ว เราจะออก HTTPS POST ไปยังตำแหน่งข้อมูลเซิร์ฟเวอร์ของคุณในทุกๆ ครั้งที่มีการเปลี่ยนแปลง (ต่อช่องหรือการเชื่อมต่อที่เลือกไว้) คุณต้องตอบกลับคำขอนี้ด้วยรหัส HTTP 200
หมายเหตุ - เราจะถือว่าการตอบกลับแบบ HTTP ใดๆ ก็ตามที่ไม่ใช่ 200 เป็นข้อผิดพลาด ซึ่งในสถานการณ์เหล่านี้ เราจะยังพยายามส่งการอัพเดต Webhooks อีกครั้งต่อไป หากคุณไม่ตอบกลับอย่างถูกต้อง คุณอาจได้รับการอัพเดตเดิมซ้ำกันหลายครั้ง
คำขอจะมีเนื้อหาประเภท application/json และเนื้อความจะประกอบด้วยสตริงที่เข้ารหัสแบบ JSON ที่มีการเปลี่ยนแปลง 1 รายการขึ้นไป
หมายเหตุสำหรับผู้พัฒนา PHP: หากคุณต้องการรับข้อมูลที่เข้ารหัสในภาษา PHP คุณควรใช้โค้ดต่อไปนี้
$data = file_get_contents("php://input");
$json = json_decode($data);`โปรดทราบว่าระบบจะไม่ส่งพารามิเตอร์ hub.mode, hub.challenge และ hub.verify_token อีกครั้ง เมื่อมีการยืนยันการสมัครรับข้อมูลแล้ว
ต่อไปนี้คือตัวอย่างทั่วไปของการเรียกกลับสำหรับการสมัครรับข้อมูลอ็อบเจ็กต์ payments
{
"object": "payments",
"entry": [
{
"id": "296989303750203",
"time": 1347996346,
"changed_fields": [
"actions"
]
}
]
}คุณจำเป็นต้องทราบว่าการอัพเดต Webhook จะแจ้งให้คุณทราบเมื่อการชำระเงินที่เฉพาะเจาะจงซึ่งระบุโดยช่อง id มีการเปลี่ยนแปลงเท่านั้น หลังจากที่รับการอัพเดตแล้ว คุณจะต้องสืบค้น API กราฟเพื่อดูรายละเอียดของธุรกรรม เพื่อจัดการกับการเปลี่ยนแปลงนั้นอย่างเหมาะสม
หมายเหตุ - ในขณะที่ Webhooks สำหรับอ็อบเจ็กต์ประเภทอื่นๆ สามารถรวมเป็นแบตช์ได้ แต่การอัพเดตการชำระเงินจะไม่รวมเป็นแบตช์โดยเด็ดขาด
เรารับประกันว่าคุณจะได้รับการอัพเดตใหม่ในทุกครั้งที่มีการอัพเดตธุรกรรม ไม่ว่าจะเป็นการดำเนินการของผู้ใช้หรือการดำเนินการของผู้พัฒนาก็ตาม
หากการอัพเดตไปยังเซิร์ฟเวอร์ของคุณล้มเหลว เราจะลองส่งอีกครั้งทันที จากนั้นจะลองส่งอีก 2-3 ครั้ง โดยจะลดความถี่ลงในช่วง 24 ชั่วโมงหลังจากนั้น
ในทุกคำขอ เราส่งส่วนหัว HTTP X-Hub-Signature-256 ซึ่งประกอบด้วยลายเซ็น SHA256 ของเพย์โหลดคำขอ โดยใช้ข้อมูลลับของแอพเป็นคีย์และขึ้นต้นด้วย sha256= ตำแหน่งข้อมูลการเรียกกลับของคุณสามารถตรวจสอบยืนยันลายเซ็นนี้เพื่อยืนยันความถูกต้องสมบูรณ์และต้นทางของเพย์โหลดได้
หลังจากเซิร์ฟเวอร์ของคุณได้รับการอัพเดต คุณควรสืบค้น API กราฟโดยใช้ช่อง id เพื่อดูรายละเอียดเกี่ยวกับสถานะใหม่ของธุรกรรม จากนั้นคุณควรดำเนินการตามสถานะของธุรกรรมนั้น
ส่วนต่อไปนี้จะแจกแจงการเปลี่ยนแปลงสถานะทั้งหมดที่อาจเกิดขึ้นได้ซึ่งจะทริกเกอร์ให้ระบบส่งการอัพเดต โดยจะมีการแบ่งแบบกว้างๆ ได้ดังนี้
แต่ละอ็อบเจ็กต์ payment จะมีอาร์เรย์ที่มีชื่อว่า actions ซึ่งประกอบด้วยคอลเลกชั่นการเปลี่ยนแปลงสถานะต่างๆ ที่เกิดขึ้นในระหว่างทำธุรกรรม โดยแต่ละรายการในอาร์เรย์ actions จะมีคุณสมบัติที่ชื่อ type ซึ่งอธิบายประเภทของการดำเนินการที่เกิดขึ้น ทั้งนี้ type ดังกล่าวอาจมีค่าต่างๆ ดังนี้ ได้แก่ charge, refund, chargeback, chargeback_reversal และ decline ซึ่งเราได้อธิบายไว้อย่างครบถ้วนที่นี่
ตัวอย่างการตอบกลับจาก API กราฟสำหรับอ็อบเจ็กต์การชำระเงินที่มีการดำเนินการต่างๆ ที่เกี่ยวข้องจะแสดงไว้ด้านล่างนี้
{
"id": "3603105474213890",
"user": {
"name": "Marco Alvarez",
"id": "500535225"
},
"application": {
"name": "Friend Smash",
"namespace": "friendsmashsample",
"id": "241431489326925"
},
"actions": [
{
"type": "charge",
"status": "completed",
"currency": "USD",
"amount": "0.99",
"time_created": "2013-03-22T21:18:54+0000",
"time_updated": "2013-03-22T21:18:55+0000"
},
{
"type": "refund",
"status": "completed",
"currency": "USD",
"amount": "0.99",
"time_created": "2013-03-23T21:18:54+0000",
"time_updated": "2013-03-23T21:18:55+0000"
}
],
"refundable_amount": {
"currency": "USD",
"amount": "0.00"
},
"items": [
{
"type": "IN_APP_PURCHASE",
"product": "https://www.friendsmash.com/og/friend_smash_bomb.html",
"quantity": 1
}
],
"country": "US",
"created_time": "2013-03-22T21:18:54+0000",
"payout_foreign_exchange_rate": 1,}`เนื่องจากคุณได้สมัครรับข้อมูลช่อง actions เมื่อลงทะเบียน Webhooks เราจะออกการอัพเดตเมื่ออาร์เรย์มีการเปลี่ยนแปลงดังนี้
โดยเริ่มต้นแล้ว คำสั่งซื้อทั้งหมดจะมี "status": "initiated" อยู่ในรายการเก็บค่าบริการ การชำระเงินที่เริ่มต้นแล้วเป็นการกำหนดว่าการชำระเงินดังกล่าวได้เริ่มต้นขึ้นแล้วเท่านั้นและยังดำเนินการไม่เสร็จสมบูรณ์ ซึ่งเราจะไม่ส่งการอัพเดตสำหรับการชำระเงินที่มีสถานะเป็น "initiated"
เมื่อดำเนินการชำระเงินเสร็จสมบูรณ์แล้ว "status": "initiated" จะเปลี่ยนเป็น "status": "completed" จากนั้นเราจะออกการอัพเดต เมื่อเห็นการเปลี่ยนแปลงนี้ คุณควรตรวจสอบบันทึกการชำระเงินเพื่อตรวจสอบยืนยันว่าการชำระเงินนี้เป็นธุรกรรมใหม่หรือเป็นธุรกรรมที่มีอยู่แล้ว และตอบกลับดังนี้
initiated คุณจะสามารถดำเนินการตามคำสั่งซื้อได้โดยออกสกุลเงินหรือรายการเสมือนที่เกี่ยวข้องให้กับผู้บริโภค จากนั้น คุณจะสามารถทำเครื่องหมายว่าการชำระเงินนี้เสร็จสิ้นแล้วได้อย่างปลอดภัยนอกจากนี้ คุณจะได้รับการอัพเดตสำหรับการชำระเงินที่มี "status": "failed" อีกด้วย ซึ่งคุณไม่ควรดำเนินการกับการชำระเงินเหล่านี้ต่อ
คุณจะได้รับการอัพเดตทุกครั้งที่คุณออกการคืนเงินผ่าน API กราฟ ซึ่งการคืนเงินอาจมีสถานะต่างๆ ที่คุณจะต้องทราบเช่นเดียวกับ "type": "charge" อีกด้วย โดยเฉพาะอย่างยิ่ง การคืนเงินอาจมีความเป็นไปได้ที่จะไม่สำเร็จ ซึ่งมักเกิดจากข้อผิดพลาดในการประมวลผลหรือการเชื่อมต่อ ซึ่งในกรณีนี้คุณควรพยายามออกการคืนเงินอีกครั้ง
คุณจะได้รับการแจ้งเตือนเมื่อมีการออกการคืนยอดเงิน รวมถึงการเปลี่ยนคำตัดสินหรือการปฏิเสธการคืนยอดเงินเช่นเดียวกับการคืนเงินอีกด้วย โดยระบบจะเพิ่มอ็อบเจ็กต์การคืนยอดเงิน การเปลี่ยนคำตัดสิน หรือการปฏิเสธการคืนยอดเงินไปยังอาร์เรย์ "actions" ของข้อมูลการส่งคืน API กราฟสำหรับการชำระเงิน
เราจะแจ้งให้คุณทราบโดยการออกข้อมูลอัพเดตเมื่อมีข้อโต้แย้งเริ่มต้นขึ้น ในกรณีนี้ คุณจะเห็นอาร์เรย์ "disputes" ใหม่ปรากฏเป็นส่วนหนึ่งของอ็อบเจ็กต์ payment ซึ่งอาร์เรย์นี้จะประกอบด้วยเวลาที่เริ่มข้อโต้แย้ง เหตุผลของผู้บริโภคในการเริ่มดำเนินการตอบกลับ และอีเมลของผู้บริโภค ซึ่งคุณสามารถใช้ติดต่อกับผู้บริโภคได้โดยตรงเพื่อระงับข้อโต้แย้งนั้น
ตัวอย่างการตอบกลับที่ครบถ้วนจาก API กราฟสำหรับธุรกรรมที่มีข้อโต้แย้งจะแสดงไว้ด้านล่างนี้
{
"id": "990361254213890",
"user": {
"name": "Marco Alvarez",
"id": "500535225"
},
"application": {
"name": "Friend Smash",
"namespace": "friendsmashsample",
"id": "241431489326925"
},
"actions": [
{
"type": "charge",
"status": "completed",
"currency": "USD",
"amount": "0.99",
"time_created": "2013-03-22T21:18:54+0000",
"time_updated": "2013-03-22T21:18:55+0000"
}
],
"refundable_amount": {
"currency": "USD",
"amount": "0.99"
},
"items": [
{
"type": "IN_APP_PURCHASE",
"product": "https://www.friendsmash.com/og/friend_smash_bomb.html",
"quantity": 1
}
],
"country": "US",
"created_time": "2013-03-22T21:18:54+0000",
"payout_foreign_exchange_rate": 1,
"disputes": [
{
"user_comment": "I didn't receive my item! I want a refund, please!",
"time_created": "2013-03-24T18:21:02+0000",
"user_email": "email\u0040domain.com",
"status": "resolved",
"reason": "refunded_in_cash"
}
]
}โปรดดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีตอบกลับข้อโต้แย้งและออกการคืนเงินที่คู่มือการชำระเงิน: การจัดการกับข้อโตแย้งและการคืนเงิน