提现业务逻辑:
1.检查金额数量
2.检查余额是否充足
3.生成生成提现记录
4.对用户进行打款
5.打款成功,对提现记录进行修改并记录相关内容
以下内容是WechatPay类的全部内容:
#########################################################
def sign(key, params):
""" 签名 """
return sign_md5(sorted_str(params, key))
def sign_md5(s, upper=True):
""" md5 """
if upper:
return hashlib.md5(s.encode("utf-8")).hexdigest().upper()
else:
return hashlib.md5(s.encode("utf-8")).hexdigest()
def sorted_str(params, key, null=False):
""" key按照ASCII排序 """
if null:
s = '&'.join((str(k) + '=' + str(params[k])) for k in sorted(params))
else:
s = '&'.join((str(k) + '=' + str(params[k])) for k in sorted(params) if params[k])
return s + '&key={}'.format(key)
def request_post(api, data, cert=None, timeout=2):
data = to_xml(data)
ret = requests.post(api, data=data, timeout=timeout, cert=cert)
ret = to_dict(ret.content)
if ret['return_code'] == 'SUCCESS' and ret.get('result_code') == 'SUCCESS':
return True, ret
else:
return False, ret
def to_xml(params, cdata=True, encoding='utf-8'):
""" dict转xml """
tag = '{0}>' if cdata else '{1}{0}>'
s = ''.join(tag.format(k, v) for k, v in params.items())
return '{}'.format(s).encode(encoding)
def to_dict(content):
""" xml转dict """
data = xmltodict.parse(content).get('xml')
if '#text' in data:
del data['#text']
return data
class WechatPay:
def __init__(self, app_id, mch_id, key, cert_file=None, cert_key=None):
""":param app_id: appid:param mch_id: 商户号:param key: 签名key:param cert_file: 证书路径:param cert_key: 证书key路径"""
self.app_id = app_id
self.mch_id = mch_id
self.key = key
self.cert_file = cert_file
self.cert_key = cert_key
def promotion_transfers(self, params):
""" 企业付款 """
api = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers'
params.update({
'mch_appid': self.app_id,
'mchid': self.mch_id,
})
params['sign'] = sign(self.key, params)
result, ret = request_post(api, params, cert=(self.cert_file, self.cert_key))
# 检查其他参数
if result and ret['mch_appid'] == self.app_id and ret['mchid'] == self.mch_id:
return True, ret
return False, ret
#########################################################
# WechatPay类需要初始化的内容
wechat_withdraw_conf = {
'mch_id': '****', # 支付商户号
'key': '****',
'app_id': '****', # 公众号appid
'cert_file': '/home/cert/apiclient_cert.pem',
'cert_key': '/home/cert/apiclient_key.pem',
}
# 创建WechatPay实例,并将需要初始化的内容传递进去
wechat_withdraw = wechat.WechatPay(**wechat_withdraw_conf)
##########################################################
定义企业付款函数,调用WechatPay创建的wechat_withdraw实例进行付款:
def wechat_transfer(openid, amount, ip, order_id, **params):
""" 企业付款 """
data = {
'nonce_str': uuid4_hex(), 生成随机字符串
'partner_trade_no': order_id,
'openid': openid,
'check_name': 'NO_CHECK',
'amount': int(amount), # 单位:分
'desc': '余额提现',
'spbill_create_ip': ip,
}
data.update(**params)
###########################################################
在需要用到企业付款的地方调用上面的函数进行付款:
ret, res = wechat_transfer(用户openid, 金额(分), 用户ip, 提现订单号)
例:
ret, res = wechat_transfer('sdasdasdas', 100, '192.168.1.1', '123456789')
print(ret, res)
这里我展示一段提款失败的信息:
False OrderedDict([('return_code', 'SUCCESS'), ('return_msg', '商户号与商户appid不匹配'), ('mch_appid', '****'), ('mchid', '****'), ('result_code', 'FAIL'), ('err_code', 'PARAM_ERROR'), ('err_code_des', '商户号与商户appid不匹配')])