# -*- encoding: utf-8 -*-
# -----------------------------------------------------------------------------
# @File Name  : wx_jsapi_pay.py
# @Time       : 2020/12/12 上午10:00
# @Author     : X. Peng
# @Email      : acepengxiong@163.com
# @Software   : PyCharm
# -----------------------------------------------------------------------------

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

from app.api.engine import config, env


def genNonce_str():
    """."""
    sss = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
    s = ''
    for i in range(32):
        s = s + random.choice(sss)
    return s

class WXPay(object):
    """微信公众号支付."""
    def __init__(self, openid, out_trade_no, body, total_fee, remote_addr, notify_url):
        """."""
        self.timeStamp = int(time.time())
        self.req_url = 'https://api.mch.weixin.qq.com/pay/unifiedorder'
        self.appid = config[env]['wx_jsapi_appid']
        self.mch_id = '1515329071'
        self.openid = openid
        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)
        self.spbill_create_ip = remote_addr
        self.notify_url = notify_url
        self.trade_type = 'JSAPI'
        self.key = 'eqwor3wquevncz9384ssp438oarefskl'
        self.getStringSign()
        self.getData()
        self.getPrepayId()
        self.getPaySign()

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

    def getPrepayId(self):
        """."""
        res = requests.post(self.req_url, data=self.dict2xml(self.data))
        res = self.xml2dict(res.content)
        self.prepay_id = res['prepay_id']

    def getPaySign(self):
        """."""
        sign_string = 'appId={0}&nonceStr={1}&package=prepay_id={2}&signType={3}&timeStamp={4}&key={5}'.format(
            self.appid, self.nonce_str, self.prepay_id, self.sign_type, self.timeStamp, self.key)
        self.paySign = hashlib.md5(sign_string.encode("utf-8")).hexdigest().upper()

    def getReturnParams(self):
        """."""
        params = {'appId': self.appid, 'timeStamp': self.timeStamp, 'nonceStr':self.nonce_str, 'package': 'prepay_id='+self.prepay_id,
                  'signType': self.sign_type, 'paySign': self.paySign}
        return params

if __name__ == '__main__':
    openid = 'oHyIO00TC3vwgxuJKLXeKFrpNnEI'
    out_trade_no = '201812102324324134120'
    body = '微信公众号支付测试'
    total_fee = 1
    remote_addr = '101.95.188.178'
    notify_url = 'https://devtamper.tanpuyun.com/tamp_order/micro_shop/consumeOrderNotify'
    wx = WXPay(openid, out_trade_no, body, total_fee, remote_addr, notify_url)
    print(wx.getReturnParams())