123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- # coding=utf-8
- import uuid
- import os
- import requests
- import json
- import xmltodict
- import time
- from hashlib import md5
- from django.conf import settings
- from utils.exceptions import CustomError
- class WechatTenantPay():
- def __init__(self, appid, mch_id, partner_trade_no, openid, amount, merchant_key, cert, key):
- self.params = {
- 'mch_appid': appid, # 申请商户号的appid或商户号绑定的appid
- 'mchid': mch_id, # 微信支付分配的商户号
- 'nonce_str': generate_nonce_str(), # 随机字符串,不长于32位
- 'partner_trade_no': partner_trade_no, # 商户订单号,需保持唯一性
- 'openid': openid, # 商户appid下,某用户的openid
- 'check_name': 'NO_CHECK', # 校验用户姓名选项
- 'amount': amount, # 金额 企业付款金额 单位为分
- 'desc': u'佣金', # 企业付款备注
- }
- self.params['sign'] = generate_sign(self.params, merchant_key)
- self.url = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers'
- self.cert_file = cert
- self.cert_key = key
- def pay(self):
- result = send_cert_request(self.url, self.params, self.cert_file, self.cert_key)
- return result
- class PayQuery():
- def __init__(self, partner_trade_no, mch_id, appid, merchant_key, cert, key):
- self.url = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/gettransferinfo'
- self.cert_file = cert
- self.cert_key = key
- self.params = {
- 'nonce_str': generate_nonce_str(),
- 'partner_trade_no': partner_trade_no,
- 'mch_id': mch_id,
- 'appid': appid,
- }
- self.params['sign'] = generate_sign(self.params, merchant_key)
- def query(self):
- result = send_cert_request(self.url, self.params, self.cert_file, self.cert_key)
- return result
- def send_cert_request(url, param, cert_file, cert_key):
- '''
- 发送携带证书的xml请求
- '''
- xml = xmltodict.unparse({'root': param})
- response = requests.post(url, data=xml.encode('utf-8'), headers={'Content-Type': 'text/xml'}, cert=(cert_file, cert_key), verify=False)
- xmlmsg = json.loads(json.dumps(xmltodict.parse(response.content)))['xml']
- print(xmlmsg)
- return xmlmsg
- def generate_nonce_str():
- """
- 生成随机字符串
- """
- return str(uuid.uuid4()).replace('-', '')
- def generate_sign(params, merchant_key):
- """
- 生成md5签名的参数
- """
- if 'sign' in params:
- params.pop('sign')
- src = '&'.join(['%s=%s' % (k, v) for k, v in sorted(params.items())]) + '&key=%s' % merchant_key
- return md5(src.encode('utf-8')).hexdigest().upper()
- def validate_sign(resp_dict, merchant_key):
- """
- 验证微信返回的签名
- """
- if 'sign' not in resp_dict:
- return False
- wx_sign = resp_dict['sign']
- sign = generate_sign(resp_dict, merchant_key)
- if sign == wx_sign:
- return True
- return False
- def generate_response_data(resp_dict):
- """
- 字典转xml
- """
- return xmltodict.unparse({'xml': resp_dict}, pretty=True, full_document=False).encode('utf-8')
|