成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

玩轉(zhuǎn)京東支付(python)

sydMobile / 1356人閱讀

摘要:接收到京東支付加密報(bào)文后的處理方式接收到京東支付返回的加密報(bào)文后,先判斷標(biāo)簽下的標(biāo)簽的返回碼,檢查接口調(diào)用是否正常返回。

說明

github地址

做了微信。支付寶和京東支付之后,發(fā)現(xiàn),最扯蛋的支付,肯定是京東支付,要完整開發(fā)京東支付,必須要看完京東支付開發(fā)者文檔的官網(wǎng)每一個角落,絕對不能憑你的任何經(jīng)驗(yàn)去猜測有些流程,比如公私鑰加解密(不看官網(wǎng),保證你后悔)、發(fā)送請求的方式(form表單提交,看了官網(wǎng)你會發(fā)現(xiàn)好怪異),支付同步跳轉(zhuǎn)(還是post,fk),支付成功后返回居然沒有支付訂單號(完全靠自己去維護(hù),fk)

技術(shù)描點(diǎn)

首先要去看官網(wǎng)的:http://payapi.jd.com/。 項(xiàng)目使用的是pc網(wǎng)頁支付

一. 統(tǒng)一下單的接口:https://wepay.jd.com/jdpay/sa...

參數(shù)說明:http://payapi.jd.com/docList....

一定要仔細(xì)的看這些參數(shù)的說明

特殊參數(shù)說明如下:

1) 在以上的請求參數(shù)中,商戶號是在注冊開通京東支付功能的時(shí)候,京東支付商戶管理系統(tǒng)為用戶分配的。
2) 用戶賬號是商戶系統(tǒng)的用戶賬號。
3) 交易流水號是用來標(biāo)識每次支付請求的號碼,需要商戶保證在每一次支付請求的時(shí)候交易流水號唯一,多次請求不能使用同一交易流水號,否則京東支付服務(wù)在處理后面的支付請求時(shí),會把此交易當(dāng)做重復(fù)支付處理。
4) 簽名規(guī)則詳見:“接口安全規(guī)范-簽名算法”;
5) 為保證信息安全,表單中的各個字段除了merchant(商戶號)、版本號(version)、簽名(sign)以外,其余字段全部采用3DES進(jìn)行加密。

二. 生成簽名

簽名過程分為兩步,首先是將原始參數(shù)按照規(guī)則拼接成一個字符串S1,然后再將S1根據(jù)簽名算法生成簽名字符串sign。
參數(shù)原始字符串的拼接規(guī)則:

1) 對于POST表單提交的參數(shù):所有參數(shù)按照參數(shù)名的ASCII碼順序從小到大排序(字典序),使用URL鍵值對的方式拼接成字符串S1,(如:k1=value1&k2=value2&k3=value3…)
2) 對于XML報(bào)文交互的參數(shù):將XML報(bào)文的各行去掉空格后直接拼接成一行字符串作為S1。如果報(bào)文只有一行則直接作為S1,不需要再進(jìn)行拼接。

生成簽名的過程如下:

1) 對拼接的參數(shù)字符串S1通過SHA256算法計(jì)算摘要,得到字符串S2;
2) 對字符串S2使用私鑰證書進(jìn)行加密,并進(jìn)行base64轉(zhuǎn)碼,得到簽名字符串sign; 接收方收到報(bào)文后先進(jìn)行base64解碼,再使用公鑰證書解密,然后驗(yàn)證簽名的合法性。

注意事項(xiàng):

1) 空參數(shù)不參與簽名;
2) 參數(shù)列表中的sign字段不參與簽名;
3) 為了簡化處理,標(biāo)簽也參與簽名;
4) 參數(shù)區(qū)分大小寫;
5) RSA加密的規(guī)則為:由交易發(fā)起方進(jìn)行私鑰加密,接收方進(jìn)行公鑰解密;(可以使用RSA公私鑰校驗(yàn)工具來校驗(yàn)商戶RSA公私鑰是否匹配)
6) 系統(tǒng)會對商戶公鑰證書的有效性進(jìn)行校驗(yàn)。

簽名代碼:

def get_sign_str(params, is_compatible=False):
    """
    生成簽名的字符串
    Args:
        params: 簽名的字典數(shù)據(jù)
        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對每個參數(shù)進(jìn)行加密(merchant(商戶號)、版本號(version)、簽名(sign)除外)

為防止明文數(shù)據(jù)在post表單提交的時(shí)候暴露,所以京東做了DES3對字段進(jìn)行加密(不用表單提交不就行了,還搞這么復(fù)雜,真該學(xué)學(xué)支付寶和微信)

京東DES加密說明如下:

   除特定說明外,商戶和京東支付接口調(diào)用報(bào)文采用3DES加密,再通過base64轉(zhuǎn)換為字符串。
   3DES加密算法標(biāo)為DESede,工作模式為電子密碼本模式ECB,不填充(DESede/ECB/NoPadding)。
注:服務(wù)端NoPadding 為不填充,所以加密的原文字節(jié)必須是8的整數(shù)倍(如果調(diào)用我們提供的加密接口API則不必處理原文字節(jié),加密接口內(nèi)部已處理)。如果自己實(shí)現(xiàn)加密,原文字節(jié)不夠8的整數(shù)倍,則按如下規(guī)則轉(zhuǎn)為8的整數(shù)倍。
    1.  把原文字符串轉(zhuǎn)成字節(jié)數(shù)組。
    2.  根據(jù)字節(jié)數(shù)組長度判斷是否需要補(bǔ)位。
        補(bǔ)位邏輯為:
        int x = (i+ 4) % 8;
        int y = (x == 0) ? 0 : (8 - x);
        i為字節(jié)數(shù)組的長度,y為需要補(bǔ)位的長度。
        補(bǔ)位值為0。
    3.  將有效數(shù)據(jù)長度byte[]添加到原始byte數(shù)組的頭部。
        i為字節(jié)數(shù)組的長度。
        result[0] = (byte) ((i >> 24) & 0xFF);
        result[1] = (byte) ((i >> 16) & 0xFF);
        result[2] = (byte) ((i >> 8) & 0xFF);
        result[3] = (byte) (i & 0xFF);

    4.  原文字節(jié)數(shù)組前面加上第三步的4個字節(jié),再加上需補(bǔ)位的值。
        例如:字符串”1”,轉(zhuǎn)換成字節(jié)數(shù)組是[49],計(jì)算補(bǔ)位y=3, 計(jì)算有效數(shù)據(jù)長度為[0, 0, 0, 1],最后字節(jié)數(shù)組為[0, 0, 0, 1, 49, 0, 0, 0]。
Form表單接口的加密方式:
如果商戶通過表單方式提交支付請求至收銀臺,為保證信息安全,表單中的各個字段除了merchant(商戶號)、verion(版本號)、sign(簽名)以外,其余字段全部采用3DES進(jìn)行加密。

XML請求接口的加密方式:
通過XML接口方式和京東支付服務(wù)器交互的請求,應(yīng)該對報(bào)文進(jìn)行加密,加密方式為對整個報(bào)文整體進(jìn)行3DES加密,再進(jìn)行base64轉(zhuǎn)碼使其變?yōu)榭勺x字符串,加密后的密文置于標(biāo)簽中,同時(shí)再將報(bào)文中的(商戶號)、(版本號)這兩個字段多帶帶置于標(biāo)簽下。

接收到京東支付加密報(bào)文后的處理方式:
接收到京東支付返回的加密報(bào)文后,先判斷標(biāo)簽下的標(biāo)簽的返回碼,檢查接口調(diào)用是否正常返回。然后再讀取標(biāo)簽的密文內(nèi)容進(jìn)行base64解碼,再進(jìn)行3DES解密,解密后的報(bào)文即是原始報(bào)文。

示例代碼:

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加密數(shù)據(jù)
    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里

 












怎么組織就自己去實(shí)現(xiàn)好了

四. 異步回調(diào)

提交之后請求之后,就會跳轉(zhuǎn)到京東的支付頁面,可登錄賬戶支付,也可用京東app或者微信掃描支付。

當(dāng)用戶掃碼支付之后,京東會主動跳轉(zhuǎn)到你指定的一個網(wǎng)址(在提交支付請求的時(shí)候有這個字段),并且會異步post一個請求到指定的一個地址(在提交支付請求的時(shí)候有這個字段),同步跳轉(zhuǎn)是在用戶掃碼支付之后,如果京東支付頁面還在的話會跳轉(zhuǎn)。而異步是無論如何都會發(fā)支付結(jié)果通知的。對于新手來說,一定要知道這個行業(yè)潛規(guī)則(微信,支付寶or其它都是)。而且一定要以這個異步通知的結(jié)果為準(zhǔn)。

京東返回的是xml格式的字符串

返回格式如下(沒有換行的,我這里演示換了行的):



V2.0
22294531
 000000 success 
MWYxMjBjMzViZjgwOWM5ZDhjNjc0YmY1ZWJlY2QyODU0YTc5NmQ3ZWQxMWU1NzE3MWQ0OTUwOGI5NzllYmE4ZjM1YzRiZjlmYWE1M2ZiYjVmYzBmYTgyMDYyM2Q0YjM0NGM1ODFkZDhlYTA2Mjk0ZDE5ZDBlZDk5NTc3MmE4Nzk4OTFlYjIwZDgzMTc4MDU3NGVkZTFjNDY0MDMzNzNjZjc2OWZiMDQ0YjVhZGNhYmRhMGZmYTkyNzRhZDNhM2IxOGY5ZjZhYjBmYjhmZmI3Yzg0OTA3YzM0OGJmZTYwZTIzNzM3YjVmYzMzNmNkYTE0MjM2OWIwZDM5MjI2YWM5YmY3ZmZjZDBkNWJmM2ZkYWY4YTU3OWU4MDE3ZjQ5YmQ0ZWIyMDA0NTFmODZkNmViMDBiMDE2YTU3NTNjMzJjNDIzNWI5ZDkyYzQ3OTU4OTc2ZGIyZmNiMGUxNGRjNTM2OGZjYjQ0NmE0YWY1ZWVjZDYzNWI5ZDkyYzQ3OTU4OTc2NmIwM2QyZTU1ODJlNDNjM2M1NjA2YmQ5ZDc3MTRkMmNjN2ZiMDM3Yzg5ZDk1ODFkMWJhZmVjYjUwMzJlNTdkMTFmN2QxMDAxNjgyMzJjNTZhMmQzNTcyZGE4OTUzYWFjNTU5MDY4YWYyODE5ZDcyNmY5NmE1YTBmYWFiZTRiZTQ2OGZhMmM4M2JjMGM5NmNiMDE3ZWQ4MDkxY2FjZThiNzg4MjY5OWY1ZTJlYzBjOTIxODBhOGExNjExNGY4NWQwM2NkZjI2MTFmM2VmODcxYWM3MjUxZjMxMzZlYjFmNzI1NWE0OWM4MjMxZGY1MzBmY2Y1Mjg2NGUzMWRlMjc0M2I5ZDM5NjQzN2ZmZWQ1Y2M5NDY4ZDcwNWM1YzVhZmRlYzYwZWU3MDVhNjE0N2I1MGVlM2UyMGE2MzExNTE4YTUxOGRjMzBmMmUxZjE2NzYzNGRiNDJlODFmMDczOGYzZjMxN2NkMjkzNmU4ODc3NzJjMjkzM2ZlODlmMjUyNDVmNDI2MDA0M2VkYmUwOTlkNGEyNjU3YTM5YTE4ODU2OTBmNGQyNDcwZDE0ZWRjMmQxYjgxMzhhNjA5M2ZlNDkxYTQyMzE5YzBlNTA0MTdkYTg2ZGQ2NDQwODBmMjM4ZGI2YzIzMjNhOTE0M2VmMjZiZjczN2M5NWQwODYxMWY2OGE5MDQ0ZDZmNzE0NmIxZjQwZDdmZDMxOTQ2ZDM3YjIwNDJiODUzZGM0NTk0MzM5YzJkN2M2NDdiNGM4MzQ4MTRjZTIxZTlmYTYzNDYxNGMxMjlhZTE3NjE0ZDIzM2Q2MTQ4YzJiNWE3ZWVjMDU5MjFmNzJkNGNjNTU1NWZkNzVhN2U5Y2I1MDU1NjhlMWRlNjVhNzkyOGUxMThlODQyMGJkNzE2NjdmMDc3YmEyYTFkNmQyOTFiOGNjZTU2ZGMyYmE3ODY5ZGZiNmMyMWViYjc2ODc0Y2I3YTc4NGQ5NWY2NjY2Y2E5NjI0N2I1MGE4MTliMDBkNGIzNmViZTJlY2JmYTcwODUzYTM5ZTcwMDVmYWEzNWY2MDFhMWM2MGQ1MzEyYmQxNDU3Zjg4ZWVhNzY2YjZhOGE4ZGMxMGY3NjYwOWEzNWY2MDFhMWM2MGQ1MzFhNzA4NTNhMzllNzAwNWZhYTYxMmJmNjJiMmFlMGY5ODMxMzQ0MzQ0NjMxZDc3MTUyY2FiMjZlMjcyYmJjYmQzODVmNDY4OTA5YTdjMjlmNTI5NWFlZjE3NTI4ZmE4MzVhNzA4NTNhMzllNzAwNWZhNDk5OTQ2ZGU0OGU0NGQ2ZTE4YmRiYTBjZjNhM2ZkNjY5ODJjNGVhZjQzMjIyYWFhMWM0ZmU1ODRiNTg5OWEwYzAwNjI2NTllMDZkYzhiYTVmMjI3ZjUyYmQ3MjcyODllZmEwYzhiNDIwODc4ZjUzODY1MzAzZDkyNDM5OTRkNDczMTBjZDBhMTc4ZjAwOTIyZmM2ODk5YjkyYTJiODcwNjU4MzkzMzJkZWYzNDY1MzJlYTNiYTFhNjM0MWIwNjM4NjBjNjlmMzg1NWZjZWM5YWExMDdjZWY1MjkwZTZjMzgzOGYxNTRiNzFlN2E1YTczYWFkNzJlOTRiOWI3MmI2YWYyMTJjMjQ5Y2UzMmUxMGI4YWE0N2YzYzFmNjNiOGY4NjJlZmU1ZDM5NjcwODA3MGNjY2JjYWFkYjM3NzBmMGQzYjIyMGFmZTE3YWNjZWU1N2RmZTQxMzAxYjA2MDdlMg==

先要用DES3對encrypt節(jié)點(diǎn)里的串進(jìn)行解密

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):
    """
    解密數(shù)據(jù)
    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
   
  


解密之后就是驗(yàn)證簽名是否正確,從上邊的串中拿到簽名和去除簽名之后的字符串

def verify_mysign(cls, sign, xml_str, jd_public_key):
    """
    驗(yàn)證簽名
    Args:
        sign: 簽名
        xml_str: 去除簽名后的xml字符串
        jd_public_key: 用于驗(yàn)證的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

驗(yàn)證通過之后再返回去除sign的xml字符串,并提取出里邊的內(nèi)容(詳情參數(shù)所代表的含義請看官方文檔)

五. 同步跳轉(zhuǎn)

同步跳轉(zhuǎn)就沒啥好說了,只是給個跳轉(zhuǎn)地址,但是這里一定要注意,這個的是一個post請求(好像京東啥都喜歡post),而非微信或者支付寶或者other什么的get請求。所以不要設(shè)置錯了

好了,到這里一個完整的在線支付就完成了。這里還要說明的是,涉及到加密和解密,就一定會有key,有DES3使用的對稱加密key,還有簽名使用的非對稱公鑰和私鑰。所以一定要配置好。
這里我的源代碼里用的都是京東提供的測試商戶號,還有一大推京東設(shè)置好的key,具體要去下載京東的【京東支付PC&H5接口文檔】,在文檔的最底部有帳號信息。

demo里邊還有申請退款,申請撤單的接口,其實(shí)寫好一個接口的完成流程,別的流程都是直接套用就可以了。

博客地址

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/41120.html

相關(guān)文章

  • 簡單玩轉(zhuǎn)ViewPager+Fragment動畫效果,實(shí)現(xiàn)京東淘寶物流卡片效果 (附源碼)

    摘要:物流卡片新版的京東和淘寶有一個交互感覺不錯,待收貨訂單會有類似探探那樣的卡片效果,滑動查看下一條物流的信息,近期部門說要做這個效果,于是我就寫了一個,現(xiàn)在分享出來和大家交流一下。 物流卡片Demo 新版的京東和淘寶有一個交互感覺不錯, 待收貨訂單會有類似探探那樣的卡片效果, 滑動查看下一條物流的信息, 近期UI部門說要做這個效果, 于是我就寫了一個Demo, 現(xiàn)在分享出來和大...

    fox_soyoung 評論0 收藏0
  • MTSC2018 測試開發(fā)大會視頻公開(含 PPT)| 年度福利

    摘要:現(xiàn)在,組委會決定公開測試開發(fā)大會視頻含資料,作為獻(xiàn)給社區(qū)用戶和測試從業(yè)人員的年度大禮,期待推進(jìn)行業(yè)進(jìn)步。自年舉辦以來,近萬名有從業(yè)經(jīng)驗(yàn)的測試開發(fā)工程師測試經(jīng)理和質(zhì)量管理人員參加了大會,好評如潮。 過去的幾年中,軟件測試與質(zhì)量保障行業(yè)悄然間發(fā)生了很大變化,TesterHome 社區(qū)作為行業(yè)見證人,通過 MTSC 大會記錄了測試行業(yè)技術(shù)趨勢與人才結(jié)構(gòu)的變革歷程。 showImg(https...

    yanbingyun1990 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<