zoukankan      html  css  js  c++  java
  • Python实现微信刷卡支付(条码支付)MicroPay

        转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/7686765.html

        一:资料阅读

        场景介绍:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=5_1

        支付流程:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=5_4

        提交刷卡支付:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_10&index=1

        查询订单支付结果:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_2

        二:配置信息准备

    # ========支付相关配置信息===========
        _APP_ID = "";  # 公众账号appid
        _MCH_ID = "";  # 商户号
        _API_KEY = "";  # 微信商户平台(pay.weixin.qq.com) -->账户设置 -->API安全 -->密钥设置,设置完成后把密钥复制到这里
        _host_name = socket.gethostname()
        _ip_address = socket.gethostbyname(_host_name)
        _CREATE_IP = _ip_address;  # 发起支付ip
    
        # 有关url
        _MICROPAY_URL = "https://api.mch.weixin.qq.com/pay/micropay"; #刷卡支付api
        _QUERY_URL = "https://api.mch.weixin.qq.com/pay/orderquery"; #查询订单支付结果api

        

        三:编写刷卡支付工具类

        1:辅助函数

        def get_sign_for_wx(self, para, key):
            '''
            根据算法, 生成微信支付签名
            :param cr:
            :param uid:
            :param para:
            :param context:
            :return:
            '''
            keylist = list(para.keys())
            keylist.sort()
            s = ''
            for i in range(len(keylist)):
                s += str(keylist[i]) + '=' + str(para[keylist[i]])
                if i != len(keylist) - 1:
                    s += '&'
            s += '&key=' + key
            signmd5 = hashlib.md5()
            signmd5.update(s)
            sign = (signmd5.hexdigest()).upper()
            return sign
    
        #拼接xml字符串
        def get_xml_data(self, doc, para):
            root = doc.createElement('xml')
            doc.appendChild(root)
            for key, value in sorted(para.items()):
                new_node = doc.createElement(key)
                node_value = doc.createTextNode(str(value))
                new_node.appendChild(node_value)
                root.appendChild(new_node)
            return doc

        2:提交刷卡支付

        def do_micropay(self,orderid,goodsName,goodsPrice,authCode,**kwargs):
            '''
            刷卡支付
            '''
            appid = self._APP_ID
            mch_id = self._MCH_ID
            key = self._API_KEY
            nonce_str = str(int(round(time.time() * 1000))) + str(random.randint(1, 999)) + string.join(random.sample(
                ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u',
                 'v', 'w', 'x', 'y', 'z'], 5)).replace(" ", "")
            spbill_create_ip = self._CREATE_IP
    
            params = {}
            params['appid'] = appid
            params['mch_id'] = mch_id
            params['nonce_str'] = nonce_str
            params['out_trade_no'] = orderid.encode('utf-8')  # 客户端生成并传过来,参数必须用utf8编码,否则报错
            params['total_fee'] = goodsPrice  # 单位是分,必须是整数
            params['spbill_create_ip'] = spbill_create_ip
            params['body'] = goodsName.encode('utf-8')  # 中文必须用utf-8编码,否则xml格式错误
            params['auth_code'] = authCode
    
            doc = dom.Document()
            self.get_xml_data(doc, params)
            sign = self.get_sign_for_wx(params, self._API_KEY)
            params['sign'] = sign
            signnode = doc.createElement('sign')
            signvalue = doc.createTextNode(sign)
            signnode.appendChild(signvalue)
            doc.getElementsByTagName('xml')[0].appendChild(signnode)
    
            # 向微信刷卡支付发出请求
            req = urllib2.Request(self._MICROPAY_URL)
            req.headers['Content-Type'] = 'text/xml'
            req.data = doc.toprettyxml()
            res_data = urllib2.urlopen(req)
    
            # 提取支付结果
            res_read = res_data.read()
            doc = xmltodict.parse(res_read)
            return_code = doc['xml']['return_code']
    
            # 结果分析
            # 此字段是通信标识,非交易标识,交易是否成功需要查看result_code来判断
            if return_code == 'SUCCESS':
                result_code = doc['xml']['result_code']
                # 业务结果
                if result_code == 'SUCCESS':
                        buyer = doc['xml']['openid'] #支付者id
                        return (True, 'SUCCESS', u'支付成功 ',buyer)
                elif result_code == 'FAIL':
                    error_code =  doc['xml']['err_code']
                    error_code_des =  doc['xml']['err_code_des']
                    return (False, error_code, error_code_des,'')
            else:
                return_msg = doc['xml']['return_msg']
                return (False, return_code, return_msg,'')

        3:根据订单号查询支付结果

        def do_micropay_query(self,orderid):
            appid = self._APP_ID
            mch_id = self._MCH_ID
            key = self._API_KEY
            out_trade_no = orderid.encode('utf-8')  # 客户端生成并传过来,参数必须用utf8编码,否则报错
            nonce_str = str(int(round(time.time() * 1000))) + str(random.randint(1, 999)) + string.join(random.sample(
                ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u',
                 'v', 'w', 'x', 'y', 'z'], 5)).replace(" ", "")
    
            params = {}
            params['appid'] = appid
            params['mch_id'] = mch_id
            params['nonce_str'] = nonce_str
            params['out_trade_no'] = out_trade_no
    
            doc = dom.Document()
            self.get_xml_data(doc, params)
            sign = self.get_sign_for_wx(params, self._API_KEY)
            params['sign'] = sign
            signnode = doc.createElement('sign')
            signvalue = doc.createTextNode(sign)
            signnode.appendChild(signvalue)
            doc.getElementsByTagName('xml')[0].appendChild(signnode)
    
            # 发出查询请求
            req = urllib2.Request(self._QUERY_URL)
            req.headers['Content-Type'] = 'text/xml'
            req.data = doc.toprettyxml()
            res_data = urllib2.urlopen(req)
    
            # 返回查询结果
            res_read = res_data.read()
            doc = xmltodict.parse(res_read)
            return_code = doc['xml']['return_code']
    
            if return_code == 'SUCCESS':
                result_code = doc['xml']['result_code']
                # 业务结果
                if result_code == 'SUCCESS':
                    trade_state = doc['xml']['trade_state']
                    #支付成功
                    if trade_state == 'SUCCESS':
                        buyer = doc['xml']['openid']
                        return (True, 'SUCCESS', u'支付成功 ',buyer)
                    #未支付、支付中
                    elif trade_state == 'NOTPAY':
                        return (False, 'NOTPAY', u'未支付','')
                    elif trade_state == 'USERPAYING':
                        return (False, 'USERPAYING', u'支付中','')
                    #支付关闭、撤销、失败
                    elif trade_state == 'CLOSED':
                        return (False, 'CLOSED', u'支付关闭','')
                    elif trade_state == 'REVOKED':
                        return (False, 'REVOKED', u'支付撤销','')
                    elif trade_state == 'PAYERROR':
                        return (False, 'PAYERROR', u'支付失败','')
                else:
                    error_code =  doc['xml']['err_code']
                    error_code_des =  doc['xml']['err_code_des']
                    return (False, error_code, error_code_des,'')
            else:
                return_msg = doc['xml']['return_msg']
                return (False, return_code, return_msg,'')

        

        

  • 相关阅读:
    [原创] 毕设---在myeclipes中安装Hadoop开发插件
    [转]Linux下RPM软件包的安装及卸载 yum操作
    [转]结构化、半结构化和非结构化数据
    [转]这5种必知的大数据处理框架技术
    [转]浅谈Hive vs. HBase 区别在哪里
    前端资源整理
    每个程序员都应该知道的10大基础算法
    Python Day14(HTML)
    Python Day13(yaml)
    Python Day12(补充)
  • 原文地址:https://www.cnblogs.com/ygj0930/p/7686765.html
Copyright © 2011-2022 走看看