微信支付V2.0-python

# -*- coding: utf-8 -*-

"""
@author: Mr_zhang
@software: PyCharm
@file: wechat_pay.py
@time: 2021/1/29 下午9:46
"""

import hashlib
import requests
from random import Random


class WeChatPay:
    """
    微信支付
    """
    def __init__(self):
        self.APP_ID = "appid"  # appid
        self.MCH_ID = "mchid"  # 商戶號
        self.API_KEY = "apikey"
        self.TRADE_TYPE = "MWEB"  # 支付類型
        self.notify_url = "https://xx.com/callback/"  # 支付成功回調接口
        self.pay_url = "https://api.mch.weixin.qq.com/pay/unifiedorder"  # 下單接口
        self.CREATE_IP = "服務器ip"

    @staticmethod
    def random_str(max_length=8):
        """
        生成隨機字符串
        :param max_length: 字符串長度
        :return:
        """
        _ = ''
        chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789'
        length = len(chars) - 1
        random = Random()
        for i in range(max_length):
            _ += chars[random.randint(0, length)]
        return _

    @staticmethod
    def get_sign(data_dict, key):
        """
        簽名函數
        :param data_dict: 需要簽名的參數,格式爲字典
        :param key: 密鑰 ,即上面的API_KEY
        :return: 字符串
        """
        params_list = sorted(data_dict.items(), key=lambda e: e[0], reverse=False)  # 參數字典倒排序爲列表
        params_str = "&".join(u"{}={}".format(k, v) for k, v in params_list) + '&key=' + key
        # 組織參數字符串並在末尾添加商戶交易密鑰
        md5 = hashlib.md5()  # 使用MD5加密模式
        md5.update(params_str.encode('utf-8'))  # 將參數字符串傳入
        sign = md5.hexdigest().upper()  # 完成加密並轉爲大寫
        return sign

    @staticmethod
    def trans_dict_to_xml(data_dict):
        """
        定義字典轉XML的函數
        :param data_dict:
        :return:
        """
        data_xml = []
        for k in sorted(data_dict.keys()):  # 遍歷字典排序後的key
            v = data_dict.get(k)  # 取出字典中key對應的value
            if k == 'detail' and not v.startswith('<![CDATA['):  # 添加XML標記
                v = '<![CDATA[{}]]>'.format(v)
            data_xml.append('<{key}>{value}</{key}>'.format(key=k, value=v))
        return '<xml>{}</xml>'.format(''.join(data_xml))  # 返回XML

    @staticmethod
    def trans_xml_to_dict(data_xml):
        """
        定義XML轉字典的函數
        :param data_xml:
        :return:
        """
        data_dict = {}
        try:
            import xml.etree.cElementTree as ET
        except ImportError:
            import xml.etree.ElementTree as ET
        root = ET.fromstring(data_xml)
        for child in root:
            data_dict[child.tag] = child.text
        return data_dict

    def wx_pay(self, order_no, order_name, order_price_detail, order_total_price):
        nonce_str = self.random_str()  # 拼接出隨機的字符串即可,我這裏是用  時間+隨機數字+5個隨機字母
        total_fee = int(float(order_total_price) * 100)  # 付款金額,單位是分,必須是整數
        params = {
            'appid': self.APP_ID,  # APPID
            'mch_id': self.MCH_ID,  # 商戶號
            'nonce_str': nonce_str,  # 隨機字符串
            'out_trade_no': order_no,  # 訂單編號,可自定義
            'total_fee': total_fee,  # 訂單總金額
            'spbill_create_ip': self.CREATE_IP,  # 自己服務器的IP地址
            'notify_url': self.notify_url,  # 回調地址,微信支付成功後會回調這個url,告知商戶支付結果
            'body': order_name,  # 商品描述
            'detail': order_price_detail,  # 商品描述
            'trade_type': self.TRADE_TYPE,  # 掃碼支付類型
        }

        sign = self.get_sign(params, self.API_KEY)  # 獲取簽名
        params['sign'] = sign  # 添加簽名到參數字典
        xml = self.trans_dict_to_xml(params)  # 轉換字典爲XML
        response = requests.post(url=self.pay_url, data=xml.encode())  # 以POST方式向微信公衆平臺服務器發起請求
        data_dict = self.trans_xml_to_dict(response.content)  # 將請求返回的數據轉爲字典
        return data_dict


wx_pay = WeChatPay()

 V3.0過幾天補上

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章