支付寶通知notify url處理
1) 獲取APPID
notify_url是非同步介面,支付寶會發多次,直到收到你的響應;
至於你說的重複問題,你的後臺需要根據流水號、訂單號等資訊判斷是否已經接收過請求併成功處理(insert 支付流水,update訂單狀態等),處理過就直接返回;
另外notify_url是有次數限制的,如果系統上線後有嚴重bug或宕機了,恢復之後可能無法再收到通知,所以支付寶還提供了一個介面“單筆查詢介面”-查詢單筆交易是否支付成功;
支付這一塊有很多異常情況必須考慮:比如防止一筆訂單使用者多次支付,多次支付後的退款處理等等;
排除常見錯誤的方法:
1:錯誤資訊提示為:ILLEGAL_SIGN,屬於簽名驗證出錯
CreatUrl的方式引數不一致,編碼問題都可以引起這個錯誤
2:錯誤資訊提示為:ILLEGAL_ARGUMENT,屬於引數格式有問題
檢視介面傳送頁的引數是不是符合要求
3:錯誤資訊提示為:ILLEGAL_SERVICE,屬於無效介面名稱
檢視service引數
4:錯誤資訊提示為ILLEGAL_PARTNER,屬於無效合作伙伴ID
檢視partner引數
5:錯誤資訊提示為ILLEGAL_SIGN_TYPE,屬於無效簽名方式
sign_type是加密型別,一般為md5
6:錯誤資訊提示為DIRECT_PAY_AMOUNT_OUT_OF_RANGE,屬於快速付款交易總金額超出最大值限制
快速付款餘額支付最大限制為:2000,用卡沒限制
7:錯誤資訊提示為HASH_NO_PRIVILEGE,屬於沒有許可權訪問該服務
檢視service引數和賣家支付寶帳號所擁有的許可權是不是一致
8:錯誤資訊提示為DONATE_GREATER_THAN_MAX,屬於小額捐贈總金額超出最大值限制
小額捐贈一般現在為100
9:錯誤資訊提示為OUT_TRADE_NO_EXIST,屬於外部交易號已經存在
外部交易號重複
10:錯誤資訊提示為TRADE_NOT_EXIST,屬於交易不存在
11:錯誤資訊提示為ILLEGAL_PAYMENT_TYPE,屬於無效支付型別
檢視有沒有PAYMENT_TYPE引數,是不是對的
12:錯誤資訊提示為BUYER_NOT_EXIST,屬於買家不存在
檢視buyer_email的帳號是不是支付寶帳號
13:錯誤資訊提示為SELLER_NOT_EXIST,屬於賣家不存在
seller_email的帳號是不是支付寶帳號
14:錯誤資訊提示為BUYER_SELLER_EQUAL,屬於買家、賣家是同一帳戶
同一個支付寶帳號不能同為買家和賣家
15:錯誤資訊提示為ILLEGAL_LOGISTICS_FORMAT,屬於無效物流格式
只有三種物流型別:EMS,POST,EXPRESS,即為EMS,平郵,其他快遞
16:錯誤資訊提示為TOTAL_FEE_LESSEQUAL_ZERO,屬於交易總金額小於等於0
price或者total_fee不能小於等於0
17:錯誤資訊提示為TOTAL_FEE_OUT_OF_RANGE,屬於交易總金額超出範圍
18:錯誤資訊提示為ILLEGAL_FEE_PARAM,屬於非法交易金額格式
price或者total_fee的值是否規範
1 |
https: //api.xx.com/receive_notify.htm?total_amount=2.00&buyer_id=2088102116773037&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=2015102700040153&seller_id=2088102119685838¬ify_id=4a91b7a78a503640467525113fb7d8bg8e |
第一步: 在通知返回引數列表中,除去sign、sign_type兩個引數外,凡是通知返回回來的引數皆是待驗籤的引數。
第二步: 將剩下引數進行url_decode, 然後進行字典排序,組成字串,得到待簽名字串:
1 |
body=大樂透 2.1 &buyer_id= 2088102116773037 &charset=utf- 8 &gmt_close= 2016 - 07 - 19
14 : 10 : 46 &gmt_payment= 2016 - 07 - 19
14 : 10 : 47 ¬ify_time= 2016 - 07 - 19
14 : 10 : 49 ¬ify_type=trade_status_sync&out_trade_no= 0719141034 - 6418 &refund_fee= 0.00 &subject=大樂透 2.1 &total_amount= 2.00 &trade_no= 2016071921001003030200089909 &trade_status=TRADE_SUCCESS&version= 1.0
|
第三步: 將簽名引數(sign)使用base64解碼為位元組碼串。
第四步: 使用RSA的驗籤方法,通過簽名字串、簽名引數(經過base64解碼)及支付寶公鑰驗證簽名。
第五步:在步驟四驗證簽名正確後,必須再嚴格按照如下描述校驗通知資料的正確性。
1、商戶需要驗證該通知資料中的out_trade_no是否為商戶系統中建立的訂單號,2、判斷total_amount是否確實為該訂單的實際金額(即商戶訂單建立時的金額),3、校驗通知中的seller_id(或者seller_email) 是否為out_trade_no這筆單據的對應的操作方(有的時候,一個商戶可能有多個seller_id/seller_email),4、驗證app_id是否為該商戶本身。上述1、2、3、4有任何一個驗證不通過,則表明本次通知是異常通知,務必忽略。在上述驗證通過後商戶必須根據支付寶不同型別的業務通知,正確的進行不同的業務處理,並且過濾重複的通知結果資料。在支付寶的業務通知中,只有交易通知狀態為TRADE_SUCCESS或TRADE_FINISHED時,支付寶才會認定為買家付款成功。驗簽過程程式碼描述【這裡列舉java示例,按照服務端SDK中提供的工具類】:
1 2 3 4 5 6 7 8 |
Map<String,
String> paramsMap = ... //將非同步通知中收到的待驗證所有引數都存放到map中
boolean
signVerified = AlipaySignature.rsaCheckV1(paramsMap, ALIPAY_PUBLIC_KEY, CHARSET)
//呼叫SDK驗證簽名
if (signVerfied){
//
TODO 驗籤成功後
//按照支付結果非同步通知中的描述,對支付結果中的業務內容進行1\2\3\4二次校驗,校驗成功後在response中返回success,校驗失敗返回failure
} else {
//
TODO 驗籤失敗則記錄異常日誌,並在response中返回failure.
}
|
注意:
- 狀態TRADE_SUCCESS的通知觸發條件是商戶簽約的產品支援退款功能的前提下,買家付款成功;
- 交易狀態TRADE_FINISHED的通知觸發條件是商戶簽約的產品不支援退款功能的前提下,買家付款成功;或者,商戶簽約的產品支援退款功能的前提下,交易已經成功並且已經超過可退款期限。