# coding=utf-8import requests
import hashlib
import xmltodict
import time
import random
importstring
fromrandom import RandomclassWX_PayToolUtil():"""微信支付工具"""def __init__(self, APP_ID, MCH_ID, API_KEY, NOTIFY_URL):
self._APP_ID=APP_ID # 小程序ID
self._MCH_ID=MCH_ID # # 商户号
self._API_KEY=API_KEY # 商户秘钥
self._UFDODER_URL= "https://api.mch.weixin.qq.com/pay/unifiedorder"# 接口链接
self._NOTIFY_URL=NOTIFY_URL # 异步通知
def generate_sign(self, param):'''生成签名'''stringA= ''ks=sorted(param.keys())# 参数按键值排序for k inks:
stringA+= (k + '=' + param[k] + '&')
# 拼接商户KEY
stringSignTemp= stringA + "key=" +self._API_KEY
# md5加密,也可以用其他方式
hash_md5= hashlib.md5(stringSignTemp.encode('utf8'))
sign=hash_md5.hexdigest().upper()returnsign
def random_str(self):"""生成随机字符串
:param randomlength: 字符串长度
:return:""" strs = ''chars= 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789'length= len(chars) - 1random=Random()for i in range(0, 30):
strs+= chars[random.randint(0, length)]returnstrs
def getPayUrl(self, orderid, openid, goodsPrice,**kwargs):"""向微信支付端发出请求,获取url"""key=self._API_KEY
nonce_str=self.random_str()# 生成随机字符串,小于32位params ={'appid': self._APP_ID, # 小程序ID'mch_id': self._MCH_ID, # 商户号'nonce_str': nonce_str, # 随机字符串"body": 'learning card', # 支付说明'out_trade_no': orderid, # 生成的订单号'total_fee': str(goodsPrice), # 标价金额'spbill_create_ip': "", # 终端IP,你服务器IP'notify_url': self._NOTIFY_URL,'trade_type': "JSAPI", # 支付类型"openid": openid, # 用户id
}
# 生成签名params['sign'] = self.generate_sign(params)
param= {'root': params}
xml=xmltodict.unparse(param)
response= requests.post(self._UFDODER_URL, data=xml.encode('utf-8'), headers={'Content-Type': 'text/xml'})
# xml2dict
msg=response.text
xmlmsg=xmltodict.parse(msg)
#4. 获取prepay_idif xmlmsg['xml']['return_code'] == 'SUCCESS':
prepay_id= xmlmsg['xml']['prepay_id']
# 时间戳
timeStamp= str(int(time.time()))
#5. 五个参数
data={"appId": self._APP_ID,"nonceStr": nonce_str,"package": "prepay_id=" +prepay_id,"signType": 'MD5',"timeStamp": timeStamp,
}
#6. paySign签名
paySign=self.generate_sign(data)
data["paySign"] =paySign # 加入签名
#7. 传给前端的签名后的参数return data