摘要:接收到京東支付加密報文后的處理方式接收到京東支付返回的加密報文后,先判斷標簽下的標簽的返回碼,檢查接口調用是否正常返回。
說明
github地址
做了微信。支付寶和京東支付之后,發現,最扯蛋的支付,肯定是京東支付,要完整開發京東支付,必須要看完京東支付開發者文檔的官網每一個角落,絕對不能憑你的任何經驗去猜測有些流程,比如公私鑰加解密(不看官網,保證你后悔)、發送請求的方式(form表單提交,看了官網你會發現好怪異),支付同步跳轉(還是post,fk),支付成功后返回居然沒有支付訂單號(完全靠自己去維護,fk)
技術描點首先要去看官網的:http://payapi.jd.com/。 項目使用的是pc網頁支付
一. 統一下單的接口:https://wepay.jd.com/jdpay/sa...參數說明:http://payapi.jd.com/docList....
一定要仔細的看這些參數的說明
特殊參數說明如下:
1) 在以上的請求參數中,商戶號是在注冊開通京東支付功能的時候,京東支付商戶管理系統為用戶分配的。
2) 用戶賬號是商戶系統的用戶賬號。
3) 交易流水號是用來標識每次支付請求的號碼,需要商戶保證在每一次支付請求的時候交易流水號唯一,多次請求不能使用同一交易流水號,否則京東支付服務在處理后面的支付請求時,會把此交易當做重復支付處理。
4) 簽名規則詳見:“接口安全規范-簽名算法”;
5) 為保證信息安全,表單中的各個字段除了merchant(商戶號)、版本號(version)、簽名(sign)以外,其余字段全部采用3DES進行加密。
簽名過程分為兩步,首先是將原始參數按照規則拼接成一個字符串S1,然后再將S1根據簽名算法生成簽名字符串sign。
參數原始字符串的拼接規則:
1) 對于POST表單提交的參數:所有參數按照參數名的ASCII碼順序從小到大排序(字典序),使用URL鍵值對的方式拼接成字符串S1,(如:k1=value1&k2=value2&k3=value3…)
2) 對于XML報文交互的參數:將XML報文的各行去掉空格后直接拼接成一行字符串作為S1。如果報文只有一行則直接作為S1,不需要再進行拼接。
生成簽名的過程如下:
1) 對拼接的參數字符串S1通過SHA256算法計算摘要,得到字符串S2;
2) 對字符串S2使用私鑰證書進行加密,并進行base64轉碼,得到簽名字符串sign; 接收方收到報文后先進行base64解碼,再使用公鑰證書解密,然后驗證簽名的合法性。
注意事項:
1) 空參數不參與簽名;
2) 參數列表中的sign字段不參與簽名;
3) 為了簡化處理,
4) 參數區分大小寫;
5) RSA加密的規則為:由交易發起方進行私鑰加密,接收方進行公鑰解密;(可以使用RSA公私鑰校驗工具來校驗商戶RSA公私鑰是否匹配)
6) 系統會對商戶公鑰證書的有效性進行校驗。
簽名代碼:
def get_sign_str(params, is_compatible=False): """ 生成簽名的字符串 Args: params: 簽名的字典數據 is_compatible: 是否是兼容模式(對字典中value值為空的也簽名) Returns: 返回簽名 """ raw = [(k, params[k]) for k in sorted(params.keys())] if is_compatible: order_str = "&".join("=".join(kv) for kv in raw) else: order_str = "&".join("=".join(kv) for kv in raw if kv[1]) return order_str def sign(self, prestr): """ 生成簽名 Args: prestr(str): 生成簽名的原字符串 Returns: 返回生成好的簽名 """ key = MRSA.load_key(self.MERCHANT_RSA_PRI_KEY) signature = key.private_encrypt(self.sha256(prestr), MRSA.pkcs1_padding) sign = base64.b64encode(signature) return sign三. DES3對每個參數進行加密(merchant(商戶號)、版本號(version)、簽名(sign)除外)
為防止明文數據在post表單提交的時候暴露,所以京東做了DES3對字段進行加密(不用表單提交不就行了,還搞這么復雜,真該學學支付寶和微信)
京東DES加密說明如下:
除特定說明外,商戶和京東支付接口調用報文采用3DES加密,再通過base64轉換為字符串。 3DES加密算法標為DESede,工作模式為電子密碼本模式ECB,不填充(DESede/ECB/NoPadding)。 注:服務端NoPadding 為不填充,所以加密的原文字節必須是8的整數倍(如果調用我們提供的加密接口API則不必處理原文字節,加密接口內部已處理)。如果自己實現加密,原文字節不夠8的整數倍,則按如下規則轉為8的整數倍。 1. 把原文字符串轉成字節數組。 2. 根據字節數組長度判斷是否需要補位。 補位邏輯為: int x = (i+ 4) % 8; int y = (x == 0) ? 0 : (8 - x); i為字節數組的長度,y為需要補位的長度。 補位值為0。 3. 將有效數據長度byte[]添加到原始byte數組的頭部。 i為字節數組的長度。 result[0] = (byte) ((i >> 24) & 0xFF); result[1] = (byte) ((i >> 16) & 0xFF); result[2] = (byte) ((i >> 8) & 0xFF); result[3] = (byte) (i & 0xFF); 4. 原文字節數組前面加上第三步的4個字節,再加上需補位的值。 例如:字符串”1”,轉換成字節數組是[49],計算補位y=3, 計算有效數據長度為[0, 0, 0, 1],最后字節數組為[0, 0, 0, 1, 49, 0, 0, 0]。 Form表單接口的加密方式: 如果商戶通過表單方式提交支付請求至收銀臺,為保證信息安全,表單中的各個字段除了merchant(商戶號)、verion(版本號)、sign(簽名)以外,其余字段全部采用3DES進行加密。 XML請求接口的加密方式: 通過XML接口方式和京東支付服務器交互的請求,應該對報文進行加密,加密方式為對整個報文整體進行3DES加密,再進行base64轉碼使其變為可讀字符串,加密后的密文置于標簽中,同時再將報文中的 (商戶號)、 (版本號)這兩個字段多帶帶置于 標簽下。 接收到京東支付加密報文后的處理方式: 接收到京東支付返回的加密報文后,先判斷 標簽下的 標簽的返回碼,檢查接口調用是否正常返回。然后再讀取 標簽的密文內容進行base64解碼,再進行3DES解密,解密后的報文即是原始報文。
示例代碼:
def des_pad(data): e = len(data) x = (e + 4) % 8 y = 0 if x == 0 else 8 - x sizeByte = struct.pack(">I", e) resultByte = range(len(sizeByte) + e + y) resultByte[0:4] = sizeByte resultByte[4:4 + e] = data for i in range(0, y): resultByte[e + 4 + i] = "x00" resultstr = "".join(resultByte) return resultstr def encode_des(to_encode_str, des_key): """ DES3加密數據 Args: to_encode_str(str): 要被加密的原字符串,這里的字符串需要被des_pad一下 des_key(str): 加密的key Returns: """ key = base64.b64decode(des_key) des3 = DES3.new(key, DES3.MODE_ECB) return des3.encrypt(ToolsClass.des_pad(to_encode_str)).encode("hex_codec")
這樣的話,簽名和加密都已完成,往后就拼到頁面里的form里
怎么組織就自己去實現好了
四. 異步回調提交之后請求之后,就會跳轉到京東的支付頁面,可登錄賬戶支付,也可用京東app或者微信掃描支付。
當用戶掃碼支付之后,京東會主動跳轉到你指定的一個網址(在提交支付請求的時候有這個字段),并且會異步post一個請求到指定的一個地址(在提交支付請求的時候有這個字段),同步跳轉是在用戶掃碼支付之后,如果京東支付頁面還在的話會跳轉。而異步是無論如何都會發支付結果通知的。對于新手來說,一定要知道這個行業潛規則(微信,支付寶or其它都是)。而且一定要以這個異步通知的結果為準。
京東返回的是xml格式的字符串
返回格式如下(沒有換行的,我這里演示換了行的):
V2.0 22294531 000000
success MWYxMjBjMzViZjgwOWM5ZDhjNjc0YmY1ZWJlY2QyODU0YTc5NmQ3ZWQxMWU1NzE3MWQ0OTUwOGI5NzllYmE4ZjM1YzRiZjlmYWE1M2ZiYjVmYzBmYTgyMDYyM2Q0YjM0NGM1ODFkZDhlYTA2Mjk0ZDE5ZDBlZDk5NTc3MmE4Nzk4OTFlYjIwZDgzMTc4MDU3NGVkZTFjNDY0MDMzNzNjZjc2OWZiMDQ0YjVhZGNhYmRhMGZmYTkyNzRhZDNhM2IxOGY5ZjZhYjBmYjhmZmI3Yzg0OTA3YzM0OGJmZTYwZTIzNzM3YjVmYzMzNmNkYTE0MjM2OWIwZDM5MjI2YWM5YmY3ZmZjZDBkNWJmM2ZkYWY4YTU3OWU4MDE3ZjQ5YmQ0ZWIyMDA0NTFmODZkNmViMDBiMDE2YTU3NTNjMzJjNDIzNWI5ZDkyYzQ3OTU4OTc2ZGIyZmNiMGUxNGRjNTM2OGZjYjQ0NmE0YWY1ZWVjZDYzNWI5ZDkyYzQ3OTU4OTc2NmIwM2QyZTU1ODJlNDNjM2M1NjA2YmQ5ZDc3MTRkMmNjN2ZiMDM3Yzg5ZDk1ODFkMWJhZmVjYjUwMzJlNTdkMTFmN2QxMDAxNjgyMzJjNTZhMmQzNTcyZGE4OTUzYWFjNTU5MDY4YWYyODE5ZDcyNmY5NmE1YTBmYWFiZTRiZTQ2OGZhMmM4M2JjMGM5NmNiMDE3ZWQ4MDkxY2FjZThiNzg4MjY5OWY1ZTJlYzBjOTIxODBhOGExNjExNGY4NWQwM2NkZjI2MTFmM2VmODcxYWM3MjUxZjMxMzZlYjFmNzI1NWE0OWM4MjMxZGY1MzBmY2Y1Mjg2NGUzMWRlMjc0M2I5ZDM5NjQzN2ZmZWQ1Y2M5NDY4ZDcwNWM1YzVhZmRlYzYwZWU3MDVhNjE0N2I1MGVlM2UyMGE2MzExNTE4YTUxOGRjMzBmMmUxZjE2NzYzNGRiNDJlODFmMDczOGYzZjMxN2NkMjkzNmU4ODc3NzJjMjkzM2ZlODlmMjUyNDVmNDI2MDA0M2VkYmUwOTlkNGEyNjU3YTM5YTE4ODU2OTBmNGQyNDcwZDE0ZWRjMmQxYjgxMzhhNjA5M2ZlNDkxYTQyMzE5YzBlNTA0MTdkYTg2ZGQ2NDQwODBmMjM4ZGI2YzIzMjNhOTE0M2VmMjZiZjczN2M5NWQwODYxMWY2OGE5MDQ0ZDZmNzE0NmIxZjQwZDdmZDMxOTQ2ZDM3YjIwNDJiODUzZGM0NTk0MzM5YzJkN2M2NDdiNGM4MzQ4MTRjZTIxZTlmYTYzNDYxNGMxMjlhZTE3NjE0ZDIzM2Q2MTQ4YzJiNWE3ZWVjMDU5MjFmNzJkNGNjNTU1NWZkNzVhN2U5Y2I1MDU1NjhlMWRlNjVhNzkyOGUxMThlODQyMGJkNzE2NjdmMDc3YmEyYTFkNmQyOTFiOGNjZTU2ZGMyYmE3ODY5ZGZiNmMyMWViYjc2ODc0Y2I3YTc4NGQ5NWY2NjY2Y2E5NjI0N2I1MGE4MTliMDBkNGIzNmViZTJlY2JmYTcwODUzYTM5ZTcwMDVmYWEzNWY2MDFhMWM2MGQ1MzEyYmQxNDU3Zjg4ZWVhNzY2YjZhOGE4ZGMxMGY3NjYwOWEzNWY2MDFhMWM2MGQ1MzFhNzA4NTNhMzllNzAwNWZhYTYxMmJmNjJiMmFlMGY5ODMxMzQ0MzQ0NjMxZDc3MTUyY2FiMjZlMjcyYmJjYmQzODVmNDY4OTA5YTdjMjlmNTI5NWFlZjE3NTI4ZmE4MzVhNzA4NTNhMzllNzAwNWZhNDk5OTQ2ZGU0OGU0NGQ2ZTE4YmRiYTBjZjNhM2ZkNjY5ODJjNGVhZjQzMjIyYWFhMWM0ZmU1ODRiNTg5OWEwYzAwNjI2NTllMDZkYzhiYTVmMjI3ZjUyYmQ3MjcyODllZmEwYzhiNDIwODc4ZjUzODY1MzAzZDkyNDM5OTRkNDczMTBjZDBhMTc4ZjAwOTIyZmM2ODk5YjkyYTJiODcwNjU4MzkzMzJkZWYzNDY1MzJlYTNiYTFhNjM0MWIwNjM4NjBjNjlmMzg1NWZjZWM5YWExMDdjZWY1MjkwZTZjMzgzOGYxNTRiNzFlN2E1YTczYWFkNzJlOTRiOWI3MmI2YWYyMTJjMjQ5Y2UzMmUxMGI4YWE0N2YzYzFmNjNiOGY4NjJlZmU1ZDM5NjcwODA3MGNjY2JjYWFkYjM3NzBmMGQzYjIyMGFmZTE3YWNjZWU1N2RmZTQxMzAxYjA2MDdlMg==
先要用DES3對encrypt節點里的串進行解密
def un_des_pad(data): resultByte = data[0:4] e = struct.unpack(">I", resultByte)[0] x = (e + 4) % 8 y = 0 if x == 0 else 8 - x return data[4:] if y == 0 else data[4:-y] def decode_des(to_decode_str, des_key): """ 解密數據 Args: to_decode_str(str): 要解密的原字符串 des_key(str): 解密的key Returns: """ key = base64.b64decode(des_key) des3 = DES3.new(key, DES3.MODE_ECB) param = to_decode_str.decode("hex_codec") if to_decode_str is bytes else base64.b64decode(to_decode_str).decode( "hex_codec") param = des3.decrypt(param) return ToolsClass.un_des_pad(param) sign_begin = xml_data.find("") sign_end = xml_data.find(" ") encrypt_str = xml_data[sign_begin + 9:sign_end] xml_str = JdPay.decode_des(encrypt_str, deskey)
解密后的明文如下:
V2.0 110290193003 000000
success 6220 SJ6qfS+9CmXkt6ghJcf9nIdHJDReTFNkRyjFh5XZAsTAtfHT4SdmKeD88t+2dMnaszJ7vVjBnSu64aJyt6SODW2FHJk0WXEvZNixmo2h8F7vHO5lTE2jEG/9uN7sqg2c7kH2Fnu5cFLCeaMfb8uZqZ8CKi+g7Aw4b6rywvoH/8M= 201704250935156041484635 0 3140 2 3 1500 CNY 20170425093516 1 1640 CNY 20170425093516 150****1596
解密之后就是驗證簽名是否正確,從上邊的串中拿到簽名和去除簽名之后的字符串
def verify_mysign(cls, sign, xml_str, jd_public_key): """ 驗證簽名 Args: sign: 簽名 xml_str: 去除簽名后的xml字符串 jd_public_key: 用于驗證的key Returns: """ xml_sha_str = SHA256.new(xml_str).hexdigest() key = MRSA.load_pub_key(jd_public_key) signature = key.public_decrypt(base64.standard_b64decode(sign), MRSA.pkcs1_padding) return signature == xml_sha_str
驗證通過之后再返回去除sign的xml字符串,并提取出里邊的內容(詳情參數所代表的含義請看官方文檔)
五. 同步跳轉同步跳轉就沒啥好說了,只是給個跳轉地址,但是這里一定要注意,這個的是一個post請求(好像京東啥都喜歡post),而非微信或者支付寶或者other什么的get請求。所以不要設置錯了
好了,到這里一個完整的在線支付就完成了。這里還要說明的是,涉及到加密和解密,就一定會有key,有DES3使用的對稱加密key,還有簽名使用的非對稱公鑰和私鑰。所以一定要配置好。
這里我的源代碼里用的都是京東提供的測試商戶號,還有一大推京東設置好的key,具體要去下載京東的【京東支付PC&H5接口文檔】,在文檔的最底部有帳號信息。
demo里邊還有申請退款,申請撤單的接口,其實寫好一個接口的完成流程,別的流程都是直接套用就可以了。
博客地址
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/41120.html
摘要:物流卡片新版的京東和淘寶有一個交互感覺不錯,待收貨訂單會有類似探探那樣的卡片效果,滑動查看下一條物流的信息,近期部門說要做這個效果,于是我就寫了一個,現在分享出來和大家交流一下。 物流卡片Demo 新版的京東和淘寶有一個交互感覺不錯, 待收貨訂單會有類似探探那樣的卡片效果, 滑動查看下一條物流的信息, 近期UI部門說要做這個效果, 于是我就寫了一個Demo, 現在分享出來和大...
摘要:現在,組委會決定公開測試開發大會視頻含資料,作為獻給社區用戶和測試從業人員的年度大禮,期待推進行業進步。自年舉辦以來,近萬名有從業經驗的測試開發工程師測試經理和質量管理人員參加了大會,好評如潮。 過去的幾年中,軟件測試與質量保障行業悄然間發生了很大變化,TesterHome 社區作為行業見證人,通過 MTSC 大會記錄了測試行業技術趨勢與人才結構的變革歷程。 showImg(https...
閱讀 1755·2021-09-23 11:34
閱讀 2477·2021-09-22 15:45
閱讀 12931·2021-09-22 15:07
閱讀 2232·2021-09-02 15:40
閱讀 4121·2021-07-29 14:48
閱讀 1078·2019-08-30 15:55
閱讀 3248·2019-08-30 15:55
閱讀 2194·2019-08-30 15:55