我們會透過「付款專用 Webhooks」(前身為「即時更新」)這種基本方式,告知您應用程式內透過「Facebook 付款」所下訂單的任何變更。 |
Webhooks 是一種 Facebook 和伺服器之間的訂閱型系統。透過指定的 HTTPS 端點,應用程式會進行訂閱,以便從 Facebook 接收更新。當應用程式內所下訂單有所更新時,我們會向該端點發出 HTTPS POST
要求,通知伺服器所發生的變更。
在 3 種主要情況下,更新會傳送至開發人員伺服器:
若要訂閱「付款 Webhooks」,請先建立公開端點網址,以同時接收用於訂閱驗證的 HTTPS GET
以及用於變更資料要求的 POST
。以下會說明這兩種類型要求的結構。接著,設定對應用程式 payment
物件的訂閱。有 2 種作法可供您選擇:
不管是哪一種作法,端點都會以相同方式接收到相同資料。如需深入瞭解伺服器會接收到的資料,請參閱回呼伺服器。
若要設定應用程式來接收 Webhooks 更新,最簡單的方式是使用應用程式主控板的「付款」面板。在主控板中找到應用程式,然後點擊 Payments
頁籤。「Webhooks」區塊位於公司「設定」區塊的正下方。
不論訂閱是透過這個面板或 API 所新增,這個畫面都會列出應用程式的訂閱狀態。您可從這個畫面變更訂閱回呼網址並加以測試。
您必須在「回呼」欄位中提供有效、可公開存取的伺服器端點。我們會使用這個位址來驗證訂閱與傳送更新,且這個位址必須如回呼伺服器中所述進行回應。
最後,提供「驗證權杖」。系統只有在註冊階段才會傳送這個權杖,以驗證訂閱是否來自安全的位置。一般 Webhook 更新不會傳送這個權杖。
儲存訂閱前,請務必測試回呼設定。這會向端點發出驗證 GET 要求,其中包含 hub.mode
、hub.challenge
和 hub.verify_token
參數,並確保您可正確處理這些參數。例如,您必須確保端點會將 hub.challenge
回送至 Facebook:
輸入訂閱詳細資料後,請務必點擊頁面底部的「儲存變更」按鈕。若要編輯訂閱,只需更改欄位內容、重新測試,然後再次儲存表單。
您也可透過圖形 API,以程式設計的方式設定並列出訂閱。您需要應用程式的 access token
,這可從存取權杖工具或利用圖形 API 的 /oauth
端點取得
https://graph.facebook.com/[APP_ID]/subscriptions
端點可提供訂閱 API
您可以透過此 API 執行 3 項工作:
POST
要求)GET
要求)若要設定訂閱,請傳送包含下列參數的 POST
。請注意,這些參數對應上述表單中的欄位:
object
- 同上,為您想要收到更新的物件類型。指定 payments
。fields
- 為您想要收到變更相關更新的物件類型的屬性清單(以逗號分隔)。指定「actions」和「disputes」。callback_url
- 有效、可公開存取的伺服器端點。verify_token
- 驗證訂閱時傳送至端點的任意字串。我們收到這個要求時,與上述的表單設定相同,會向回呼執行 GET
,以確定訂閱是否有效並準備好接收更新。特別的是,您必須確保端點會將 hub.challenge
回送至 Facebook。
請注意,因為應用程式對每個物件類型只能有一項訂閱,如果已經存在對這個物件類型的訂閱,則新發佈的資料會取代所有現有資料。
向訂閱 API 發出 HTTP GET
會傳回以 JSON 編碼的內容,其中會列出您的訂閱。例如:
[ { "object": "payments", "callback_url": "https://www.friendsmash.com/rtu.php", "fields": ["actions", "disputes"], "active": true } ]
回呼伺服器必須處理 2 種類型的要求。請務必將回呼伺服器置於公開網址,我們才能成功發出這些要求。
當您嘗試新增或修改訂閱時,Facebook 伺服器首先會向回呼網址發出單一 HTTPS GET
。系統會將查詢字串與下列參數一起附加至回呼網址:
參數 | 說明 |
---|---|
| 此參數會傳遞「 |
| 隨機字串 |
| 建立訂閱時指定的 |
端點應該首先驗證 hub.verify_token
。如此可確保伺服器瞭解這項要求是由 Facebook 發出,且與您剛設定的訂閱相關。
然後,端點應該只回送 hub.challenge
值,以向 Facebook 確認此伺服器已設定為可接收回呼,並防止拒絕服務(DDoS)漏洞。
PHP 開發人員注意事項:在 PHP 中,查詢參數名稱中的句點和空格會自動轉換為底線。因此,如果以 PHP 撰寫回呼端點,您應該使用 $_GET['hub_mode']
、$_GET['hub_challenge']
和 $_GET['hub_verify_token']
來存取這些參數。如需詳細資訊,請參閱 PHP 程式語言手冊中這則注意事項。
訂閱成功後,每當(所選欄位或連結)有所變更時,我們會開始向伺服器端點發出 HTTPS POST
。您必須以 HTTP 代碼 200
回應這項要求。
注意 - 我們會將所有非 200
的 HTTP 回應視為錯誤。在此情況下,我們會繼續重試傳送 Webhooks 更新。因此,如果您未正確回應,可能會多次收到相同更新。
要求的內容類型會是 application/json
,主體會包含以 JSON 編碼的字串,內含一或多項變更。
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,但絕不會批次處理付款更新。
每次交易更新時(不論是由用戶動作或開發人員動作所造成),保證您一定會收到新的更新。
如果傳送至伺服器的更新失敗,我們將立即再次重試,然後在接下來的 24 小時內,以遞減的頻率再重試幾次。
每次要求中,我們都會傳送 X-Hub-Signature-256
HTTP 標頭,其中包含要求承載的 SHA256 簽章,所使用的密鑰為應用程式密鑰,開頭則是 sha256=
。您的回呼端點可以驗證此簽章,以驗證承載的完整性和來源。
伺服器接收到更新後,您應該使用 id
欄位來查詢圖形 API,以取得新交易狀態的詳細資料。然後,您應該根據狀態來採取動作。
以下章節列舉所有會觸發更新傳送的可能狀態變更。大致上分為:
每個 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,}`
當您註冊 Webhooks 而訂閱 actions 欄位時,我們會在該陣列有所變更時發出更新,如下所示:
所有訂單一開始都會包含內容為 "status": "initiated"
的收費項目。已開始的付款表示僅開始付款但尚未全部完成,我們不會對處於已開始狀態的付款傳送更新。
當付款成功完成後,"status": "initiated"
會變更為 "status": "completed"
,我們也會發出更新。看到此變更時,您應該檢查付款記錄,確認是否為新交易或現有交易並做出回應,如下所示:
initiated
狀態,則可繼續履行訂單,將相關虛擬商品或虛擬貨幣發給消費者。然後這項付款就可放心地標示為完成。您也會收到狀態為 "status": "failed"
的付款更新。您不應該履行這些訂單。
每次透過圖形 API 發還退款,您都會收到更新。如同 "type": "charge"
,退款也可能有您必須知道的不同狀態。特別的是,退款也可能失敗,通常是因為處理或連線錯誤。在此情況下,您應該重試發放退款。
如同退款,發生刷退、退款撤銷或刷卡遭拒時,您也會收到通知。刷退、退款撤銷或刷卡遭拒物件會加入至付款之圖形 API 傳回資料的 actions 陣列中。
有異議提出時,我們會發出更新來通知您。在此情況下,您會在 payment
物件中看到出現新的 "disputes"
陣列。此陣列會包含提出異議的時間、消費者提出此回應的原因,以及消費者的電子郵件地址,您可以利用此電子郵件地址直接聯絡消費者來解決異議。
以下是針對有異議的交易,圖形 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" } ] }
如需深入瞭解如何回應異議並發放退款,請參閱付款使用說明:處理異議和退款。