1. 程式人生 > >支付寶通知notify url處理

支付寶通知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的值是否規範


某商戶設定的通知地址為https://api.xx.com/receive_notify.htm,對應接收到通知的示例如下:

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&notify_time=2016-07-19 14:10:49&subject=大樂透2.1&sign_type=RSA2&charset=utf-8&notify_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&notify_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&notify_time=2016-07-19 14:10:49&notify_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的通知觸發條件是商戶簽約的產品不支援退款功能的前提下,買家付款成功;或者,商戶簽約的產品支援退款功能的前提下,交易已經成功並且已經超過可退款期限。