wx_app_pay.py 4.84 KB
Newer Older
1
# -----------------------------------------------------------------------------
2
# File Name: wx_app_pay.py
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
# Author:    X. Peng
# -----------------------------------------------------------------------------

# -----------------------------------------------------------------------------
# Imports
# -----------------------------------------------------------------------------

# -----------------------------------------------------------------------------
# Constants
# -----------------------------------------------------------------------------

# -----------------------------------------------------------------------------
# Functions
# -----------------------------------------------------------------------------

# -----------------------------------------------------------------------------
# Classes
# -----------------------------------------------------------------------------
import requests
import hashlib
import time
from xml.etree import cElementTree as etree
import random
from urllib import parse

28 29 30
from app.api.engine import config, env


31 32 33 34 35 36 37 38 39 40
def genNonce_str():
    """."""
    sss = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
    s = ''
    for i in range(32):
        s = s + random.choice(sss)
    return s

class WXPay(object):
    """微信H5支付."""
41
    def __init__(self, out_trade_no, body, total_fee, remote_addr, notify_path='/webservice/notify'):
42 43 44 45
        """线上:tamper.tanpuyun.com
            测试:testtamper.tanpuyun.com"""
        self.timeStamp = int(time.time())
        self.req_url = 'https://api.mch.weixin.qq.com/pay/unifiedorder'
46
        self.url_prefix = config[env]['pay_url_prefix']
47
        self.appid = 'wx3ad4c5856975a2c4'
48 49 50 51 52 53 54 55 56
        self.mch_id = '1515329071'
        self.nonce_str = genNonce_str()
        self.sign = None
        self.sign_type = 'MD5'
        self.body = body
        self.out_trade_no = out_trade_no
        self.total_fee = int(total_fee * 100)
        self.spbill_create_ip = remote_addr
        self.notify_url = self.url_prefix + notify_path
57
        self.trade_type = 'APP'
58 59 60
        self.key = 'eqwor3wquevncz9384ssp438oarefskl'
        self.getStringSign()
        self.getData()
61 62
        self.getPrepayId()
        self.getPaySign()
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113


    def getStringSign(self):
        """."""
        self.string_sign_temp = 'appid={0}&body={1}&mch_id={2}&nonce_str={3}&notify_url={4}&out_trade_no={5}&sign_type={6}&spbill_create_ip={7}&total_fee={8}&trade_type={9}&key={10}'.format(
            self.appid,
            self.body,
            self.mch_id,
            self.nonce_str,
            self.notify_url,
            self.out_trade_no,
            self.sign_type,
            self.spbill_create_ip,
            self.total_fee,
            self.trade_type,
            self.key
        )

    def getData(self):
        """."""
        self.sign = hashlib.md5(self.string_sign_temp.encode("utf-8")).hexdigest().upper()
        self.data = {
            'appid': self.appid,
            'body': self.body,
            'mch_id': self.mch_id,
            'nonce_str': self.nonce_str,
            'notify_url': self.notify_url,
            'out_trade_no': self.out_trade_no,
            'sign_type': self.sign_type,
            'spbill_create_ip': self.spbill_create_ip,
            'total_fee': self.total_fee,
            'trade_type': self.trade_type,
            'sign': self.sign
        }

    def dict2xml(self, dict_):
        """将dict转为要发送到微信服务器的xml格式."""
        s = ""
        for k, v in dict_.items():
            s += "<{0}>{1}</{0}>".format(k, v)
        s = "<xml>{0}</xml>".format(s)
        return s.encode("utf-8")

    def xml2dict(self, content):
        """将从微信服务器接收到的xml转为dict."""
        raw = {}
        root = etree.fromstring(content)
        for child in root:
            raw[child.tag] = child.text
        return raw

114
    def getPrepayId(self):
115 116 117
        """."""
        res = requests.post(self.req_url, data=self.dict2xml(self.data))
        res = self.xml2dict(res.content)
118 119 120 121
        self.prepay_id = res['prepay_id']

    def getPaySign(self):
        """."""
122 123
        sign_string = 'appid={0}&noncestr={1}&package={2}&partnerid={3}&prepayid={4}&timestamp={5}&key={6}'.format(
            self.appid, self.nonce_str, 'Sign=WXPay', self.mch_id, self.prepay_id, self.timeStamp, self.key)
124
        self.paySign = hashlib.md5(sign_string.encode("utf-8")).hexdigest().upper()
125

126 127
    def getReturnParams(self):
        """."""
128 129
        params = {'appid': self.appid, 'noncestr': self.nonce_str, 'package': 'Sign=WXPay', 'partnerid': self.mch_id, 'prepayid': self.prepay_id,
                'timestamp': self.timeStamp, 'sign': self.paySign}
130 131
        return params

132
if __name__ == '__main__':
133
    out_trade_no = '201812102324324134112'
134
    body = 'APP支付测试'
135 136 137
    total_fee = 0.01
    remote_addr = '101.95.188.178'
    wx = WXPay(out_trade_no, body, total_fee, remote_addr)
138
    print(wx.getReturnParams())