如何設置異步通知地址
不同接口接收異步通知設置方式不同,可查看 哪些接口支持觸發(fā)異步。
設置 notify_url 接收異步
對于支付產生的交易,支付寶會根據原始支付 API 中傳入的異步通知地址 notify_url,通過 POST 請求的形式將支付結果作為參數通知到商家系統,接口調用 SDK 設置 notify_url 傳參方式如下。
Alipay SDK(老版)
//Java版:
request.setNotifyUrl("商家自己的notify_url地址");
//PHP版:
$request->setNotifyUrl("商家自己的notify_url地址");
//.net版:
request.SetNotifyUrl("商家自己的notify_url地址");
//python版本:
request.notify_url="商家自己的notify_url地址"
//node.js版:
formData.addField('notifyUrl', '商家自己的notify_url地址');
Alipay Easy SDK(新版)
目前 Alipay Easy SDK 只支持 Java、PHP、.Net 語言,因此只有該 3 種語言有設置 notify_url 方式。
//Java版:
Factory.Payment.FaceToFace() // 調用asyncNotify擴展方法,可以為每次API調用,設置獨立的異步商家自己的notify_url地址");
//PHP版:
Factory::payment()->FaceToFace() // 調用asyncNotify擴展方法,可以為每次API調用,設置獨立的異步通知地址 // 此處設置的異步通知地址的優(yōu)先級高于全局Config中配置的異步通知地址 ->asyncNotify("商家自己的notify_url地址");
//.net版:
Factory.Payment.FaceToFace() // 調用AsyncNotify擴展方法,可以為每此API調用,設置獨立的異步通知地址 // 此處設置的異步通知地址的優(yōu)先級高于全局Config中配置的異步通知地址 .AsyncNotify("商加自己的notify_url地址");
From 螞蟻訂閱接收異步
生活號、口碑、現金紅包、單筆轉賬接口等異步通知發(fā)送到對應 APPID 應用的應用網關中,通過 POST 請求的形式將支付結果作為參數通知到商家系統。
如何接收可查看各產品文檔上的異步說明。
異步通知返回參數介紹
支付寶查看支付寶開放平臺文檔中各接口的異步通知參數的詳細說明。
以 App 支付為例,返回的異步通知參數如下(以下示例報文僅供參考,實際返回的詳細報文請以實際返回為準)。
total_amount=2.00&buyer_id=20****7&body=大樂透2.1&trade_no=2016071921001003030200089909&refund_fee=0.00?ify_time=2016-07-19 14:10:49&subject=大樂透2.1&sign_type=RSA2&charset=utf-8?ify_type=trade_status_sync&out_trade_no=0719141034-6418&gmt_close=2016-07-19 14:10:46&gmt_payment=2016-07-19 14:10:47&trade_status=TRADE_SUCCESS&version=1.0&sign=kPbQIjX+xQc8F0/A6/AocELIjhhZnGbcBN6G4MM/HmfWL4ZiHM6fWl5NQhzXJusaklZ1LFuMo+lHQUELAYeugH8LYFvxnNajOvZhuxNFbN2LhF0l/KL8ANtj8oyPM4NN7Qft2kWJTDJUpQOzCzNnV9hDxh5AaT9FPqRS6ZKxnzM=&gmt_create=2016-07-19 14:10:44&app_id=20151*****3&seller_id=20881021****8?ify_id=4a91b7a78a503640467525113fb7d8bg8e
異步通知驗簽
驗簽流程
為了幫助開發(fā)者調用開放接口,支付寶提供了 開放平臺服務端 SDK 和 demo,包含 Java、PHP 和 .NET 等語言版本,封裝了簽名&驗簽、HTTP 接口請求等基礎功能。為了避免驗簽出錯強烈建議先下載對應語言版本的 SDK 并引入您的開發(fā)工程進行快速接入。
驗簽步驟
- 在通知返回參數列表中,除去 sign、sign_type 兩個參數外,凡是通知返回回來的參數皆是待驗簽的參數。將剩下參數進行 url_decode,然后進行字典排序,組成字符串,得到待簽名字符串;
生活號異步通知組成的待驗簽串里需要保留 sign_type 參數。 - 將簽名參數(sign)使用 base64 解碼為字節(jié)碼串;
- 使用 RSA 的驗簽方法,通過簽名字符串、簽名參數(經過 base64 解碼)及支付寶公鑰驗證簽名。
- 驗證簽名正確后,必須再嚴格按照如下描述校驗通知數據的正確性。
在上述驗證通過后,商家必須根據支付寶不同類型的業(yè)務通知,正確的進行不同的業(yè)務處理,并且過濾重復的通知結果數據。
注意:
- 在支付寶的業(yè)務通知中,只有交易通知狀態(tài)為 TRADE_SUCCESS 或 TRADE_FINISHED 時,支付寶才會認定為買家付款成功。
- 如果簽約的產品支持退款,并且對應的產品默認支持能收到 TRADE_SUCCESS 或 TRADE_FINISHED 狀態(tài),該筆交易會先收到 TRADE_SUCCESS 交易狀態(tài),然后默認12個月該筆交易會再次收到 TRADE_FINISHED 狀態(tài)。實際該筆交易只支付了一次,切勿認為該筆交易支付兩次。
接口響應
收到異步通知后,商家輸出 success 表示消息獲取成功,支付寶就會停止發(fā)送異步,如果輸出 fail,表示消息獲取失敗,支付寶會重新發(fā)送消息到異步地址。
建議在接收異步進行驗簽,如果驗簽成功輸出 success,驗簽失敗返回 fail,重新接收異步進行處理。
響應值 | 描述 | 是否重試 |
fail | 消息獲取失敗 | 重試 |
success | 消息獲取成功 | 不重試 |
異步通知交易狀態(tài)介紹
目前支付產品的交易狀態(tài)大致分以下4種:
- WAIT_BUYER_PAY:交易創(chuàng)建,等待買家付款。
- TRADE_CLOSED:在指定時間段內未支付時關閉的交易或在交易完成全額退款成功時關閉的交易。
- TRADE_SUCCESS:商家簽約的產品支持退款功能的前提下,買家付款成功。
- TRADE_FINISHED:商家簽約的產品不支持退款功能的前提下,買家付款成功?;蛘?,商家簽約的產品支持退款功能的前提下,交易已經成功并且已經超過可退款期限。
無法接收異步通知如何處理
收不到回調原因
- 異步通知發(fā)送地址錯誤。notify_url、授權回調地址、應用網關地址弄混了。
- 異步地址無法公網訪問。
- 異步地址設置方式錯誤。notify_url 傳參,From 螞蟻消息設置地址方式。
- 接口默認不觸發(fā)相關的狀態(tài)數據通知。
- 其實已經收到(其實是驗簽失敗返回為空),但是沒有做日志記錄或者沒有記錄到通知。
核實異步地址是否正常
- 可通過目前提供的 云排查日志 查詢對應交易的異步回調數據內容。
- 模擬 post 方式把云排查日志查詢到的數據發(fā)送到接收異步回調頁面,看異步頁面能否正常接收到 post 發(fā)送過來的數據。
- 根據設置異步方式不同,可參考:
- 通過設置 notify_url 接收異步,詳情可查看 收不到 notify_url 異步。
- 通過 From 螞蟻訂閱接收異步,詳情可查看 收不到 From 螞蟻消息。
為什么重復收到異步通知
重復收到異步通知主要是由于未返回 success 或異步通知不是同一個觸發(fā)條件導致。
未返回 success
每當交易狀態(tài)改變時,服務器異步通知頁面就會收到支付寶發(fā)來的處理結果通知,程序執(zhí)行完后必須打印輸出 success,可通過 云排查 查詢是否返回支付寶 success。
如果商家反饋給支付寶的字符不是 success 這 7 個字符,支付寶服務器會不斷重發(fā)通知,直到超過 24 小時 22 分鐘。一般情況下,25 小時以內完成 8 次通知(通知的間隔頻率一般是:4m、10m、1h、2h、6h、15h)。
返回 success 示例代碼
以下僅展示 Java、PHP、.NET 語言的示例,其它開發(fā)語言也是直接輸出 success 即可。
JAVA
out.print("success");
PHP
echo "success";
.NET
Response.Write("success");
直接訪問你的異步頁面應該是輸出(如下圖)中的 success 這 7 個字符。
注意:瀏覽器上點擊查看頁面源代碼,看到的是這個 7 個字符,有空格或者其它字符都會導致重復收到通知(建議大家做一下簡單的驗證)。
特別注意:返回的是純文本內容,不要包含 html 等標簽。
異步通知不是同一個觸發(fā)條件
若在已經返回 success 后還會收到支付寶異步回調,請檢查通知內容中的觸發(fā)條件是否是相同的。
如支付產品在交易狀態(tài)發(fā)生改變后,不同交易狀態(tài)也可能會觸發(fā)異步。
案例:若退款期限是 12 個月可退款,支付成功后,支付寶會發(fā)送 trade_success 的支付成功狀態(tài)的異步通知,在 12 個月后支付寶會再次發(fā)送 trade_finished 的交易結束狀態(tài)的異步通知,表示交易結束不允許退款。
注意:TRADE_SUCCESS 觸發(fā)的異步停止后,可能受異步觸發(fā)條件影響,TRADE_CLOSED 或者 TRADE_FINISHED 也會觸發(fā)異步。
異步通知的特性
- 必須保證服務器異步通知頁面(notify_url)上無任何字符,如空格、HTML 標簽、開發(fā)系統自帶拋出的異常提示信息等。
- 支付寶是用 POST 方式發(fā)送通知信息,因此該頁面中獲取參數的方式,如:request.Form(out_trade_no)、$_POST[out_trade_no]。
- 支付寶主動發(fā)起通知,該方式才會被啟用。
- 只有在支付寶的交易管理中存在該筆交易,且發(fā)生了交易狀態(tài)的改變,支付寶才會通過該方式發(fā)起服務器通知(即時到賬交易狀態(tài)為 等待買家付款 的狀態(tài)默認是不會發(fā)送通知的)。
- 該方式的調試與運行必須在服務器上,即互聯網上能訪問。而且服務器間的交互不像頁面跳轉同步通知可以在頁面上顯示出來,這種交互方式是不可見的。
- 第一次交易狀態(tài)改變(即時到賬中此時交易狀態(tài)是交易完成)時,不僅會返回同步處理結果,而且服務器異步通知頁面也會收到支付寶發(fā)來的處理結果通知。
- 程序執(zhí)行完后必須打印輸出 success。如果商家反饋給支付寶的字符不是 success 這 7 個字符,支付寶服務器會不斷重發(fā)通知,直到超過 24 小時 22 分鐘。一般情況下,25 小時以內完成 8 次通知(通知的間隔頻率一般是:4m,10m,10m,1h,2h,6h,15h) 。
- 程序執(zhí)行完成后,該頁面不能執(zhí)行頁面跳轉。如果執(zhí)行頁面跳轉,支付寶會收不到 success 字符,會被支付寶服務器判定為該頁面程序運行出現異常,而重發(fā)處理結果通知。
- cookies、session 等在此頁面會失效,即無法獲取這些數據。
- 該方式的作用主要防止訂單丟失,即頁面跳轉同步通知沒有處理訂單更新,它則去處理。
- 當商家收到服務器異步通知并打印出 success 時,服務器異步通知參數 notify_id 才會失效。也就是說在支付寶發(fā)送同一條異步通知時(包含商家并未成功打印出 success 導致支付寶重發(fā)數次通知),服務器異步通知參數 notify_id 是不變的。
- 異步通知 header 是 Content-Type:application/x-www-form-urlencoded; text/html; charset=utf-8 ,不是按照 RFC2183 RFC1521 標準來的。