Объяснение
Сделал для WeChat, Alipay и JD Pay. После оплаты через WeChat и Alipay выяснилось, что самая сложная оплата — это JD Pay, и чтобы полностью разработать оплату через JD Pay, нужно внимательно изучить документацию на официальном сайте разработчика JD Pay. Нельзя полагаться на свой опыт, чтобы угадать некоторые процессы, такие как шифрование с открытым и закрытым ключом (без изучения документации вы пожалеете об этом), способ отправки запроса (форма отправляется через HTML-форму, после изучения документации вы поймёте, насколько это странно), переход после успешной оплаты (всё ещё POST, чёрт побери) и отсутствие номера платёжного поручения после успешной оплаты (вам придётся поддерживать его самостоятельно, чёрт побери).
Технические детали
Сначала посетите официальный сайт: http://payapi.jd.com/. Проект использует веб-платформу для оплаты.
Создание единого заказа: https://wepay.jd.com/jdpay/saveOrder.
Генерация подписи
Пример кода:
def get_sign_str(params, is_compatible=False):
"""
Генерирует строку подписи
Args:
params: словарь данных для подписи
is_compatible: режим совместимости (подписывает пустые значения в словаре)
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
Чтобы предотвратить раскрытие данных при отправке формы, JD Pay использует DES3 для шифрования всех полей, за исключением указанных выше.
Описание шифрования JD Pay:
Пример кода:
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): ключ шифрования
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')
Таким образом, создание подписи и шифрование завершены, и теперь можно перейти к размещению данных в HTML-форме. Как организовать и реализовать это самостоятельно.
4. Асинхронный обратный вызов
После отправки запроса происходит переход на платёжную страницу JD, где можно оплатить с помощью учётной записи, приложения JD или сканирования QR-кода через WeChat.
Когда пользователь оплачивает с помощью сканирования QR-кода, JD автоматически переходит по указанному вами URL (этот параметр задаётся при отправке платёжного запроса) и асинхронно отправляет POST-запрос на указанный адрес (также задаётся в запросе). Синхронный переход происходит после оплаты со сканированием QR-кода: если страница оплаты JD всё ещё открыта, произойдёт переход. Асинхронная отправка уведомления о результате оплаты происходит всегда. Начинающим важно знать об этом негласном правиле в отрасли (оно также применимо к WeChat, Alipay и другим сервисам). Результаты асинхронного уведомления обязательны для учёта.
Ответ от JD возвращается в формате XML:
<?xml version="1.0" encoding="UTF-8" ?>
<jdpay>
<version>V2.0</version>
<merchant>22294531</merchant>
<result>
<code>000000</code>
<desc>success</desc>
</result>
``` ```
<?xml version="1.0" encoding="UTF-8" >
<jdpay>
<version>V2.0</version>
<merchant>110290193003</merchant>
<result>
<code>000000</code>
<desc>success</desc>
</result>
<device>6220</device>
<sign>SJ6qfS+9CmXkt6ghJcf9nIdHJDReTFNkRyjFh5XZAsTAtfHT4SdmKeD88t+2dMnaszJ7vVjBnSu64aJyt6SODW2FHJk0WXEvZNixmo2h8F7vHO5lTE2jEG/9uN7sqg2c7kH2Fnu5cFLCeaMfb8uZqZ8CKi+g7Aw4b6rywvoH/8M=</sign>
<tradeNum>201704250935156041484635</tradeNum>
<tradeType>0</tradeType>
<amount>3140</amount>
<status>2</status>
<payList>
<pay>
<payType>3</payType>
<amount>1500</amount>
<currency>CNY</currency>
<tradeTime>20170425093516</tradeTime>
</pay>
<pay>
<payType>1</payType>
<amount>1640</amount>
<currency>CNY</currency>
<tradeTime>20170425093516</tradeTime>
<detail>
<cardHolderMobile>150****1596</cardHolderMobile>
</detail>
</pay>
</payList>
</jdpay>
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )