免充值功能接口升级脚本,基于python3,运行测试用例为1001+1002+1005
import time
from xml.dom import minidom
import requests
import hashlib
from heapq import heappush, heappop
from collections import OrderedDict
SANDBOX_URL = 'https://api.mch.weixin.qq.com/sandboxnew/pay/getsignkey'
PAY_URL = "https://api.mch.weixin.qq.com/sandboxnew/pay/micropay"
QUERY_PAY_URL = "https://api.mch.weixin.qq.com/sandboxnew/pay/orderquery"
REFUND_URL = "https://api.mch.weixin.qq.com/sandboxnew/pay/refund"
QUERY_REFUND_URL = "https://api.mch.weixin.qq.com/sandboxnew/pay/refundquery"
DOWNLOAD_BILL_URL = "https://api.mch.weixin.qq.com/sandboxnew/pay/downloadbill"
def get_sign_key(mch_id, key):
# 请求模板
template = "<xml><mch_id><![CDATA[{0}]]></mch_id>" \
"<nonce_str><![CDATA[{1}]]></nonce_str>" \
"<sign><![CDATA[{2}]]></sign></xml>"
# 随机字符串
nonce_str = "5K8264ILTKCH16CQ2502SI8ZNMTM67VA"
# 待加密字符串
encrypted_str = "mch_id=" + mch_id + "&nonce_str=" + nonce_str + "&key=" + key
# md5加密
m = hashlib.md5()
m.update(encrypted_str.encode('utf-8'))
# 请求数据
sign_key_request_data = template.format(mch_id, nonce_str, m.hexdigest().upper())
result = requests.post(SANDBOX_URL, sign_key_request_data)
dom = minidom.parseString(result.content)
root = dom.documentElement
sandbox_signkey = ''
if root.getElementsByTagName("return_code")[0].childNodes[0].nodeValue == "FAIL":
retmsg = root.getElementsByTagName("return_msg")[0].childNodes[0].nodeValue
raise RuntimeError("请求错误:" + retmsg)
else:
sandbox_signkey = root.getElementsByTagName("sandbox_signkey")[0].childNodes[0].nodeValue
print("沙箱签名key:" + sandbox_signkey)
return sandbox_signkey
def to_tree_map(param_map):
keys = param_map.keys()
heap = []
for item in keys:
heappush(heap, item)
sort = []
while heap:
sort.append(heappop(heap))
res_map = OrderedDict()
for key in sort:
res_map[key] = param_map.get(key)
return res_map
def build_xml(param, wechat_key):
tree_map = to_tree_map(param)
encrypted_str = ""
for k in tree_map:
encrypted_str += "{}={}&".format(k, tree_map[k])
encrypted_str = encrypted_str + "key=" + wechat_key
# md5加密
m = hashlib.md5()
m.update(encrypted_str.encode('utf-8'))
sign = m.hexdigest().upper()
param.update(sign=sign)
complete_tree_map = to_tree_map(param)
xml = "<xml>"
for k in complete_tree_map:
xml += "<{}><![CDATA[{}]]></{}>".format(k, complete_tree_map[k], k)
xml += "</xml>"
return xml
def request_handler(url, xml, desc):
result = requests.post(url, xml)
# dom = minidom.parseString(result.content)
# root = dom.documentElement
# if root.getElementsByTagName("return_code")[0].childNodes[0].nodeValue == "FAIL":
# retmsg = root.getElementsByTagName("return_msg")[0].childNodes[0].nodeValue
# raise RuntimeError("请求错误:" + retmsg)
# else:
print(desc + "请求结果:\n" + result.content.decode("utf-8"))
def upgrade(mch_id, wechat_key):
if mch_id == "":
raise RuntimeError("商户号不能为空")
if wechat_key == "":
raise RuntimeError("key不能为空")
# 获取签名key
key = get_sign_key(mch_id, wechat_key)
# 用例编号1001========================start
# 支付接口
out_trade_no = round(time.time())
pay_param = {'appid': "wxc96ec7843231eb21", 'auth_code': "134697870936780415", 'body': "test", 'detail': "test",
'goods_tag': "14_delivery", 'mch_id': mch_id, 'nonce_str': mch_id, 'out_trade_no': out_trade_no,
'spbill_create_ip': "127.0.0.1", 'time_expire': (round(time.time()) + 100) * 1000, 'total_fee': "501",
'version': "1.0"}
pay_xml = build_xml(pay_param, key)
request_handler(PAY_URL, pay_xml, "用例编号1001支付")
time.sleep(1)
# 支付查询接口
query_pay_param = {'appid': "wxc96ec7843231eb21",
'mch_id': mch_id, 'nonce_str': mch_id, 'out_trade_no': out_trade_no,
'version': "1.0"}
query_pay_xml = build_xml(query_pay_param, key)
request_handler(QUERY_PAY_URL, query_pay_xml, "用例编号1001支付查询")
time.sleep(1)
# 用例编号1001========================end
# 用例编号1002========================start
# 支付接口
out_trade_no_2 = round(time.time())
print(out_trade_no_2)
pay_param = {'appid': "wxc96ec7843231eb21", 'auth_code': "134697870936780415", 'body': "test", 'detail': "test",
'goods_tag': "14_delivery", 'mch_id': mch_id, 'nonce_str': mch_id, 'out_trade_no': out_trade_no_2,
'spbill_create_ip': "127.0.0.1", 'time_expire': (round(time.time()) + 100) * 1000, 'total_fee': "502",
'version': "1.0"}
pay_xml = build_xml(pay_param, key)
request_handler(PAY_URL, pay_xml, "用例编号1002支付")
time.sleep(1)
# 支付查询接口
query_pay_param = {'appid': "wxc96ec7843231eb21",
'mch_id': mch_id, 'nonce_str': mch_id, 'out_trade_no': out_trade_no_2,
'version': "1.0"}
query_pay_xml = build_xml(query_pay_param, key)
request_handler(QUERY_PAY_URL, query_pay_xml, "用例编号1002支付查询")
time.sleep(1)
refund_param = {'appid': "wxc96ec7843231eb21", 'mch_id': mch_id, 'nonce_str': mch_id,
'out_refund_no': out_trade_no_2,
'refund_fee': "501", 'total_fee': "502", 'transaction_id': "4200000178201809190796617116",
'version': "1.0"}
refund_xml = build_xml(refund_param, key)
request_handler(REFUND_URL, refund_xml, "用例编号1002退款")
time.sleep(1)
query_refund_param = {'appid': "wxc96ec7843231eb21", 'mch_id': mch_id, 'nonce_str': mch_id,
'out_trade_no': out_trade_no_2, }
query_refund_xml = build_xml(query_refund_param, key)
request_handler(QUERY_REFUND_URL, query_refund_xml, "用例编号1002退款查询")
time.sleep(1)
# 用例编号1002========================end
# 用例编号1005========================start
download_bill_param = {'appid': "wxc96ec7843231eb21", 'mch_id': mch_id, 'nonce_str': mch_id,
'bill_date': "2019-01-09", 'bill_type': "ALL"}
download_bill_xml = build_xml(download_bill_param, key)
request_handler(DOWNLOAD_BILL_URL, download_bill_xml, "下载对账单")
# 用例编号1005========================end
if __name__ == '__main__':
#商户号
mch_id = ""
#key
wechat_key = ""
upgrade(mch_id, wechat_key)