Пример #1
0
 def get_token(self, method, app_key, app_secret, user_id, user_pwd_md5):
     # 获取通用参数
     parmse = self.get_parmse(method, app_key)
     # 增加私有参数
     parmse['user_id'] = user_id  # 用户ID
     parmse['user_pwd_md5'] = hashlib.md5(user_pwd_md5).hexdigest()  # 用户ID密码的MD5
     parmse['expires_in'] = '60'  # access token的有效期
     # 获取签名
     # 将非空字典键值按ASCII码升序排列,然后拼接起来
     _, prestr = util.params_filter(parmse)
     # 将所拼接的字符串进行MD5运算,并将结果使用十六进制表示
     parmse['sign'] = binascii.b2a_hex(hashlib.md5(app_secret + prestr + app_secret).hexdigest())
     # 访问地址
     request_url = urllib.urlencode(parmse)
     httpsClient = httplib.HTTPConnection(server_url)
     httpsClient.request('POST', '/route/rest', request_url,
                         {"Content-type": "application/x-www-form-urlencoded"})
     ret_json = httpsClient.getresponse().read()
     ret_dict = json.loads(ret_json)
     # 判断返回值
     if ret_dict.get('message') == 'success':
         accessToken = ret_dict.get('result').get('accessToken')
         return accessToken
     else:
         return ret_dict.get('message')
Пример #2
0
    def alipay_fuwu(self, **post):
        """
        支付宝服务窗开发者模式验证和消息接受地址
        """

        # 将post来的参数排除掉sign后作为待签名参数
        sign_params_dic = {}
        for post_key, post_val in post.items():
            if not post_key=='sign':
                sign_params_dic[post_key] = post_val.decode('utf8')

        # 待签名参数按key值排序,组合成query字符串
        _, sign_query_str = util.params_filter(sign_params_dic)

        # 使用支付宝公钥签名验签
        sign_verify = RSA.load_pub_key('addons-extra/wxsite/static/alipay_rsa_public_key.pem').verify(sign_query_str, post['sign'])
        # sign_by_ali_pub64 = sign_by_ali_pub.encode('base64')

        if sign_verify:
            # 待签名字符串:公钥+success
            str_to_sign_by_private = '<biz_content>MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC9vK4cSuzfGJKMJ/XQ82SMxRjbVussG+sI4lrgJLa7cbHZ19+zZRy9IyMYyvpD/gm4blgha0iOhRxPuxmvLHcNerG2u9q+X18NeJ0bLHxZRpPhOXMzgBDp78LDG1m7NtNW5Poat2JZyxSCTBbs1x3Tk9NUVr8mHLpriFO1ik4EEwIDAQAB</biz_content><success>true</success>'

            # 加载私钥进行签名
            rsa_private_key = load_privatekey(FILETYPE_PEM, open('addons-extra/wxsite/static/rsa_private_key.pem').read())
            rsa_private_sign = sign(rsa_private_key, str_to_sign_by_private, 'sha1')
            rsa_private_sign = base64.b64encode(rsa_private_sign)

            # 拼接返回给支付宝的xml内容
            response_xml = '<?xml version="1.0" encoding="GBK"?><alipay><response>'+str_to_sign_by_private+'</response><sign>'+rsa_private_sign+'</sign><sign_type>RSA</sign_type></alipay>'
            return response_xml.encode('gbk')
        else:
            return 'fail'.encode('gbk')
Пример #3
0
    def _get_weixin_signkey(self, acquirer):
        url = 'https://api.mch.weixin.qq.com/sandboxnew/pay/getsignkey'
        nonce_str = self.random_generator()
        data = {}
        data.update({'mch_id': acquirer.weixin_mch_id, 'nonce_str': nonce_str})

        _, prestr = util.params_filter(data)
        key = acquirer.weixin_key
        _logger.info("+++ prestr %s, Weixin Key %s" % (prestr, key))
        data['sign'] = util.build_mysign(prestr, key, 'MD5')

        data_xml = "<xml>" + self.json2xml(data) + "</xml>"

        request = urllib2.Request(url, data_xml)
        result = self._try_url(request, tries=3)

        _logger.info(
            "_______get_weixin_signkey_____ request to %s and the request data is %s, and request result is %s"
            % (url, data_xml, result)
        )
        return_xml = etree.fromstring(result)

        if return_xml.find('return_code').text == "SUCCESS" and return_xml.find(
            'sandbox_signkey'
        ).text != False:
            sandbox_signkey = return_xml.find('sandbox_signkey').text
        else:
            return_code = return_xml.find('return_code').text
            return_msg = return_xml.find('return_msg').text
            raise UserError("%s, %s" % (return_code, return_msg))

        return sandbox_signkey
Пример #4
0
    def _get_weixin_signkey(self, acquirer):
        url = 'https://api.mch.weixin.qq.com/sandboxnew/pay/getsignkey'
        nonce_str = self.random_generator()
        data = {}
        data.update({'mch_id': acquirer.weixin_mch_id, 'nonce_str': nonce_str})

        _, prestr = util.params_filter(data)
        key = acquirer.weixin_key
        _logger.info("+++ prestr %s, Weixin Key %s" % (prestr, key))
        data['sign'] = util.build_mysign(prestr, key, 'MD5')

        data_xml = "<xml>" + self.json2xml(data) + "</xml>"

        request = urllib2.Request(url, data_xml)
        result = self._try_url(request, tries=3)

        _logger.info(
            "_______get_weixin_signkey_____ request to %s and the request data is %s, and request result is %s"
            % (url, data_xml, result))
        return_xml = etree.fromstring(result)

        if return_xml.find(
                'return_code').text == "SUCCESS" and return_xml.find(
                    'sandbox_signkey').text != False:
            sandbox_signkey = return_xml.find('sandbox_signkey').text
        else:
            return_code = return_xml.find('return_code').text
            return_msg = return_xml.find('return_msg').text
            raise UserError("%s, %s" % (return_code, return_msg))

        return sandbox_signkey
Пример #5
0
    def search_order(self):

        weixin_appid = 'wxb3be4c9e8f1add69'
        weixin_mch_id = '1280015001'
        weixin_key = 'be9aded460e78703b889f18e2915ea6c'

        payid = self.env['payment.transaction'].search([('state', '=', 'draft')
                                                        ])
        for payid in payid:
            out_trade_no = payid.acquirer_reference
        url = 'https://api.mch.weixin.qq.com/pay/orderquery'
        nonce_str = self.random_generator()
        data_post = {
            'appid': weixin_appid,
            'mch_id': weixin_mch_id,
            'out_trade_no': out_trade_no,
            'nonce_str': nonce_str,
        }

        _, prestr = util.params_filter(data_post)
        sign = util.build_mysign(prestr, weixin_key, 'MD5')
        data_post['sign'] = sign
        data_xml = "<xml>" + self.json2xml(data_post) + "</xml>"
        request = urllib2.Request(url, data_xml)
        result = self._try_url(request, tries=3)
        json = {}
        for el in etree.fromstring(str(result)):
            json[el.tag] = el.text

        return json
Пример #6
0
    def _gen_weixin_code_url(self, post_data):
        data = {}
        data.update({
            'appid': post_data['appid'],
            'mch_id': post_data['mch_id'],
            'nonce_str': post_data['nonce_str'],
            'body': post_data['body'],
            'out_trade_no': post_data['out_trade_no'],
            'total_fee': post_data['total_fee'],
            'spbill_create_ip': post_data['spbill_create_ip'],
            'notify_url': post_data['notify_url'],
            'trade_type': post_data['trade_type'],
        })

        acquirer = self.search([('weixin_appid', '=', post_data['appid'])])
        _logger.info("--- acquirer %s" % (acquirer))

        if acquirer.environment == 'prod':
            key = acquirer.weixin_key
        else:
            key = self._get_weixin_signkey(acquirer)

        _, prestr = util.params_filter(data)

        _logger.info("+++ prestr %s, Weixin Key %s" % (prestr, key))

        data['sign'] = util.build_mysign(prestr, key, 'MD5')

        data_xml = "<xml>" + self.json2xml(data) + "</xml>"

        url = acquirer._get_weixin_urls(acquirer.environment)['weixin_url']

        request = urllib2.Request(url, data_xml)
        result = self._try_url(request, tries=3)

        _logger.info(
            "________gen_weixin_code_url_____ request to %s and the request data is %s, and request result is %s"
            % (url, data_xml, result))
        return_xml = etree.fromstring(result)

        data_json = {}

        for el in return_xml:
            data_json[el.tag] = el.text

        if data_json['return_code'] == "SUCCESS" and data_json.get(
                'code_url', False):
            return data_json['code_url']

        else:
            return_code = data_json.get('return_code')
            return_msg = data_json.get('return_msg')

            msg = "[%s] %s " % (return_code, return_msg)

            _logger.info('+++ some error occurred %s' % msg)
            # raise UserError(msg)

        return False
Пример #7
0
    def weixin_form_generate_values(self, tx_values):
        self.ensure_one()
        base_url = self.env['ir.config_parameter'].get_param('web.base.url')
        amount = int(tx_values.get('amount', 0) * 100)
        nonce_str = self.random_generator()
        data_post = {}
        now_time = time.strftime('%Y%m%d%H%M%S')
        data_post.update({
            'appid':
            self.weixin_appid,
            'body':
            tx_values['reference'],
            'mch_id':
            self.weixin_mch_id,
            'nonce_str':
            nonce_str,
            'notify_url':
            '%s' % urlparse.urljoin(base_url, WeixinController._notify_url),
            'out_trade_no':
            now_time,
            'spbill_create_ip':
            self._get_ipaddress(),
            'total_fee':
            amount,
            'trade_type':
            'NATIVE',
        })

        _, prestr = util.params_filter(data_post)
        sign = util.build_mysign(prestr, self.weixin_key, 'MD5')
        data_post['sign'] = sign
        # payid=self.env['payment.transaction'].search([('create_uid','=',self.env.uid),('state','=','draft'),('acquirer_id','=',self.id)])
        # for payid in payid:
        #     payid.acquirer_reference=data_post['out_trade_no']

        data_xml = "<xml>" + self.json2xml(data_post) + "</xml>"
        url = self._get_weixin_urls(self.environment)['weixin_url']
        request = urllib2.Request(url, data_xml)
        result = self._try_url(request, tries=3)
        data_post.update({
            'data_xml': data_xml,
        })
        return_xml = etree.fromstring(result)
        if return_xml.find(
                'return_code'
        ).text == "SUCCESS" and return_xml.find('code_url').text != False:
            qrcode = return_xml.find('code_url').text
            data_post.update({
                'qrcode': qrcode,
            })
        else:
            return_code = return_xml.find('return_code').text
            return_msg = return_xml.find('return_msg').text
            raise ValidationError("%s, %s" % (return_code, return_msg))
        tx_values = data_post
        return tx_values
Пример #8
0
 def get_didi(self, **post):
     """
     钉钉权限验证
     准备相关数据,输出页面调用钉钉客户端JSAPI来进行权限验证
     验证通过后
     """
     # 获取access_token
     corpid = 'dinge0b8fc92eb965404'
     corpsecret = 'MkKb_QDrtkwigaBar13AHo51xQLcJdnzLFiE_giow1kXeQUWLDH0K-1kC9gup7Zx'
     agentid = '10292872'
     url = 'https://oapi.dingtalk.com/gettoken?'
     args = {
         'corpid': corpid,
         'corpsecret': corpsecret
     }
     url += urlencode(args)
     response = urllib2.urlopen(url, timeout=60)
     result = json.loads(response.read())
     access_token = result.get('access_token')
     # 获取jsapi_ticket
     url_1 = 'https://oapi.dingtalk.com/get_jsapi_ticket?access_token=' + access_token + '&type=jsapi'
     response_1 = urllib2.urlopen(url_1, timeout=60)
     result_1 = json.loads(response_1.read())
     jsapi_ticket = result_1.get('ticket')
     # 生成一个随机字符串,不长于32位,主要保证签名不可预测
     nonceStr = ''
     chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789'
     chars_length = len(chars) - 1
     for i in range(1, 16, 1):
         nonceStr += chars[random.randint(0, chars_length)]
     timeStamp = int(time.time())
     url = 'http://runbot.qdodoo.com/qdoo/dd/work'
     key_valu = {
         'noncestr': nonceStr,
         'timestamp': timeStamp,
         'jsapi_ticket': jsapi_ticket,
         'url': url,
     }
     _, prestr_new = util.params_filter(key_valu)
     key_valu['signature'] = hashlib.sha1(prestr_new).hexdigest()
     key_valu['corpId'] = corpid
     key_valu['agentId'] = agentid
     key_valu['access_token'] = access_token
     return request.website.render("qdodoo_dingtalk.didi2", key_valu)
Пример #9
0
    def tenpay_form_generate_values(self, cr, uid, id, partner_values, tx_values, context=None):
        base_url = self.pool["ir.config_parameter"].get_param(cr, SUPERUSER_ID, "web.base.url")
        acquirer = self.browse(cr, uid, id, context=context)
        amount = int(tx_values.get("total_fee", 0) * 100)

        tenpay_tx_values = dict(tx_values)
        tenpay_tx_values.update(
            {
                "total_fee": amount,
                "spbill_create_ip": acquirer._get_ipaddress(),
                "partner": acquirer.tenpay_partner_account,
                "out_trade_no": tx_values["reference"],
                "body": "%s: %s" % (acquirer.company_id.name, tx_values["reference"]),
                "bank_type": "DEFAULT",
                "fee_type": 1,
                "input_charset": "utf-8",
                "return_url": "%s" % urlparse.urljoin(base_url, TenpayController._return_url),
                "notify_url": "%s" % urlparse.urljoin(base_url, TenpayController._notify_url),
            }
        )

        to_sign = {}
        to_sign.update(
            {
                "total_fee": amount,
                "spbill_create_ip": acquirer._get_ipaddress(),
                "partner": acquirer.tenpay_partner_account,
                "out_trade_no": tx_values["reference"],
                "body": "%s: %s" % (acquirer.company_id.name, tx_values["reference"]),
                "bank_type": "DEFAULT",
                "fee_type": 1,
                "input_charset": "utf-8",
                "return_url": "%s" % urlparse.urljoin(base_url, TenpayController._return_url),
                "notify_url": "%s" % urlparse.urljoin(base_url, TenpayController._notify_url),
            }
        )

        _, prestr = util.params_filter(to_sign)
        tenpay_tx_values["sign"] = util.build_mysign(prestr, acquirer.tenpay_partner_key, "MD5")
        tenpay_tx_values["sign_type"] = "MD5"
        context = context
        context["_data_exchange"] = tenpay_tx_values

        return partner_values, tenpay_tx_values
Пример #10
0
 def get_didi(self, **post):
     """
     钉钉权限验证
     准备相关数据,输出页面调用钉钉客户端JSAPI来进行权限验证
     验证通过后
     """
     # 获取access_token
     corpid = 'dinge0b8fc92eb965404'
     corpsecret = 'MkKb_QDrtkwigaBar13AHo51xQLcJdnzLFiE_giow1kXeQUWLDH0K-1kC9gup7Zx'
     agentid = '10292872'
     url = 'https://oapi.dingtalk.com/gettoken?'
     args = {'corpid': corpid, 'corpsecret': corpsecret}
     url += urlencode(args)
     response = urllib2.urlopen(url, timeout=60)
     result = json.loads(response.read())
     access_token = result.get('access_token')
     # 获取jsapi_ticket
     url_1 = 'https://oapi.dingtalk.com/get_jsapi_ticket?access_token=' + access_token + '&type=jsapi'
     response_1 = urllib2.urlopen(url_1, timeout=60)
     result_1 = json.loads(response_1.read())
     jsapi_ticket = result_1.get('ticket')
     # 生成一个随机字符串,不长于32位,主要保证签名不可预测
     nonceStr = ''
     chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789'
     chars_length = len(chars) - 1
     for i in range(1, 16, 1):
         nonceStr += chars[random.randint(0, chars_length)]
     timeStamp = int(time.time())
     url = 'http://runbot.qdodoo.com/qdoo/dd/work'
     key_valu = {
         'noncestr': nonceStr,
         'timestamp': timeStamp,
         'jsapi_ticket': jsapi_ticket,
         'url': url,
     }
     _, prestr_new = util.params_filter(key_valu)
     key_valu['signature'] = hashlib.sha1(prestr_new).hexdigest()
     key_valu['corpId'] = corpid
     key_valu['agentId'] = agentid
     key_valu['access_token'] = access_token
     return request.website.render("qdodoo_dingtalk.didi2", key_valu)
Пример #11
0
    def tenpay_form_generate_values(self, cr, uid, id, partner_values, tx_values, context=None):
        base_url = self.pool['ir.config_parameter'].get_param(cr, SUPERUSER_ID, 'web.base.url')
        acquirer = self.browse(cr, uid, id, context=context)
        amount = int(tx_values.get('total_fee', 0) * 100)

        tenpay_tx_values = dict(tx_values)
        tenpay_tx_values.update({
            'total_fee': amount,
            'spbill_create_ip': acquirer._get_ipaddress(),
            'partner': acquirer.tenpay_partner_account,
            'out_trade_no': tx_values['reference'],
            'body': '%s: %s' % (acquirer.company_id.name, tx_values['reference']),
            'bank_type': 'DEFAULT',
            'fee_type': 1,
            'input_charset': 'utf-8',
            'return_url': '%s' % urlparse.urljoin(base_url, TenpayController._return_url),
            'notify_url': '%s' % urlparse.urljoin(base_url, TenpayController._notify_url),
        })

        to_sign = {}
        to_sign.update({
            'total_fee': amount,
            'spbill_create_ip': acquirer._get_ipaddress(),
            'partner': acquirer.tenpay_partner_account,
            'out_trade_no': tx_values['reference'],
            'body': '%s: %s' % (acquirer.company_id.name, tx_values['reference']),
            'bank_type': 'DEFAULT',
            'fee_type': 1,
            'input_charset': 'utf-8',
            'return_url': '%s' % urlparse.urljoin(base_url, TenpayController._return_url),
            'notify_url': '%s' % urlparse.urljoin(base_url, TenpayController._notify_url),
        })

        _,prestr = util.params_filter(to_sign)
        tenpay_tx_values['sign'] = util.build_mysign(prestr, acquirer.tenpay_partner_key, 'MD5')
        tenpay_tx_values['sign_type'] = 'MD5'
        context = context
        context['_data_exchange'] = tenpay_tx_values

        return partner_values, tenpay_tx_values
Пример #12
0
    def alipay_fuwu(self, **post):
        """
        支付宝服务窗开发者模式验证和消息接受地址
        """

        # 将post来的参数排除掉sign后作为待签名参数
        sign_params_dic = {}
        for post_key, post_val in post.items():
            if not post_key == 'sign':
                sign_params_dic[post_key] = post_val.decode('utf8')

        # 待签名参数按key值排序,组合成query字符串
        _, sign_query_str = util.params_filter(sign_params_dic)

        # 使用支付宝公钥签名验签
        sign_verify = RSA.load_pub_key(
            'addons-extra/wxsite/static/alipay_rsa_public_key.pem').verify(
                sign_query_str, post['sign'])
        # sign_by_ali_pub64 = sign_by_ali_pub.encode('base64')

        if sign_verify:
            # 待签名字符串:公钥+success
            str_to_sign_by_private = '<biz_content>MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC9vK4cSuzfGJKMJ/XQ82SMxRjbVussG+sI4lrgJLa7cbHZ19+zZRy9IyMYyvpD/gm4blgha0iOhRxPuxmvLHcNerG2u9q+X18NeJ0bLHxZRpPhOXMzgBDp78LDG1m7NtNW5Poat2JZyxSCTBbs1x3Tk9NUVr8mHLpriFO1ik4EEwIDAQAB</biz_content><success>true</success>'

            # 加载私钥进行签名
            rsa_private_key = load_privatekey(
                FILETYPE_PEM,
                open('addons-extra/wxsite/static/rsa_private_key.pem').read())
            rsa_private_sign = sign(rsa_private_key, str_to_sign_by_private,
                                    'sha1')
            rsa_private_sign = base64.b64encode(rsa_private_sign)

            # 拼接返回给支付宝的xml内容
            response_xml = '<?xml version="1.0" encoding="GBK"?><alipay><response>' + str_to_sign_by_private + '</response><sign>' + rsa_private_sign + '</sign><sign_type>RSA</sign_type></alipay>'
            return response_xml.encode('gbk')
        else:
            return 'fail'.encode('gbk')
Пример #13
0
    def tenpay_form_generate_values(self,
                                    cr,
                                    uid,
                                    id,
                                    partner_values,
                                    tx_values,
                                    context=None):
        base_url = self.pool['ir.config_parameter'].get_param(
            cr, SUPERUSER_ID, 'web.base.url')
        acquirer = self.browse(cr, uid, id, context=context)
        amount = int(tx_values.get('total_fee', 0) * 100)

        tenpay_tx_values = dict(tx_values)
        tenpay_tx_values.update({
            'total_fee':
            amount,
            'spbill_create_ip':
            acquirer._get_ipaddress(),
            'partner':
            acquirer.tenpay_partner_account,
            'out_trade_no':
            tx_values['reference'],
            'body':
            '%s: %s' % (acquirer.company_id.name, tx_values['reference']),
            'bank_type':
            'DEFAULT',
            'fee_type':
            1,
            'input_charset':
            'utf-8',
            'return_url':
            '%s' % urlparse.urljoin(base_url, TenpayController._return_url),
            'notify_url':
            '%s' % urlparse.urljoin(base_url, TenpayController._notify_url),
        })

        to_sign = {}
        to_sign.update({
            'total_fee':
            amount,
            'spbill_create_ip':
            acquirer._get_ipaddress(),
            'partner':
            acquirer.tenpay_partner_account,
            'out_trade_no':
            tx_values['reference'],
            'body':
            '%s: %s' % (acquirer.company_id.name, tx_values['reference']),
            'bank_type':
            'DEFAULT',
            'fee_type':
            1,
            'input_charset':
            'utf-8',
            'return_url':
            '%s' % urlparse.urljoin(base_url, TenpayController._return_url),
            'notify_url':
            '%s' % urlparse.urljoin(base_url, TenpayController._notify_url),
        })

        _, prestr = util.params_filter(to_sign)
        tenpay_tx_values['sign'] = util.build_mysign(
            prestr, acquirer.tenpay_partner_key, 'MD5')
        tenpay_tx_values['sign_type'] = 'MD5'
        context = context
        context['_data_exchange'] = tenpay_tx_values

        return partner_values, tenpay_tx_values
Пример #14
0
    def wx_pay(self, **post):
        """
        微信JSAPI支付,调用链接如:http://www.qdodoo.com/wxsite/wxpay/20160107125945356,其中20160107125945356是订单号
        需先到微信公众号平台配置支付授权目录(如:http://www.qdodoo.com/wxsite/wxpay/)——也可以配置测试目录,但测试有一定限制,因此可以直接在正式环境中使用1分钱订单测试
        还需到微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置中设置密钥,对应本函数中的wx_key
        参考:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_1
        """
        cr, uid, context, pool = request.cr,request.uid, request.context, request.registry
        # 获取当前公司的名称(根据用户模型获取数据)
        users_obj = pool.get('res.users')
        users = users_obj.browse(cr, SUPERUSER_ID, uid)
        company_name = users.company_id.name
        partner_id = users.partner_id.id
        order_obj = pool.get('pos.order')
        if post.get('oid'):
            res_order_id = int(post.get('oid'))
            all_money = float(post.get('money'))
            all_car_num = 0
            for order in order_obj.browse(cr, SUPERUSER_ID, res_order_id).lines:
                all_car_num += order.qty
        else:
            # 生成销售订单(POS)
            order_line_obj = pool.get('pos.order.line')
            res_order_id = order_obj.create(cr, SUPERUSER_ID, {'partner_id':partner_id,'pricelist_id':1})

            # 获取加入购物车的总金额
            all_money = 0
            all_car_num = 0
            car_obj = pool.get('qdodoo.wxsite.car')
            car_ids = car_obj.search(cr, SUPERUSER_ID, [('user_id','=',uid)])
            for key_line in car_obj.browse(cr, SUPERUSER_ID, car_ids):
                all_money += key_line.number * key_line.name.lst_price #获取总金额
                all_car_num += key_line.number
                # 生成销售单明细
                order_line_obj.create(cr, SUPERUSER_ID, {'order_id':res_order_id,'product_id':key_line.name.id,
                                                         'qty':key_line.number,'price_unit':key_line.name.lst_price})
            car_obj.unlink(cr, SUPERUSER_ID, car_ids)


        wx_openid = request.session['openid']    #微信用户openid

        #下面几个变量是微信支付相关配置
        wx_appid = 'wxde2cf9dbf3c35624'    #公众号号APPID,通常是微信签约时的服务号APPID
        wx_mchid = '1294510601'  #商户号,签约微信支付后分配的商户号
        wx_key = '33132ac4f37f151dbfcbfce34f441d71'  #微信支付密钥,到微信商户平台设置并填写此处
        wx_pay_backnotify = 'http://www.qdodoo.com/shop/wx/backnotify'  #接收微信支付异步通知地址,不可携带参数

        #生成一个随机字符串,不长于32位,主要保证签名不可预测
        nonce_str = ''
        chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789'
        chars_length = len(chars) - 1
        for i in range(1, 32, 1):
            nonce_str += chars[random.randint(0, chars_length)]

        #微信统一下单接口所需参数
        wx_oparam = {
            'appid': wx_appid,   #公众号号APPID
            'mch_id': wx_mchid,  #商户号
            'nonce_str': nonce_str,
            'body': u'点餐订单',  #支付单简要描述
            'out_trade_no': res_order_id,  #商户订单号
            'total_fee': int(all_money * 100),  #支付金额,单位为“分”,所以要x100
            'spbill_create_ip': '115.28.223.85',  #用户端IP地址,此处我不知道怎么获取
            'notify_url': wx_pay_backnotify,  #异步通知地址
            'trade_type': 'JSAPI',  #交易类型
            'openid': wx_openid,  #微信用户openid,交易类型为jsapi时,此参数必传
            'attach': 'wxsite',  #附加数据,用于商户携带自定义数据,在查询API和支付通知中原样返回,可选填,但不要留空
        }

        """
        参数签名,将非空字典键值按ASCII码升序排列,然后按url键值对拼接,最后拼接上微信支付密钥key
        将所拼接的字符串进行MD5运算,再将得到的字符串中所有字母转换为大写。即是签名
        """

        _, prestr = util.params_filter(wx_oparam)
        wx_oparam['sign'] = hashlib.md5(prestr + '&key=' +wx_key).hexdigest().upper()
        data_xml = "<xml>" + self.json2xml(wx_oparam) + "</xml>"
        url = 'https://api.mch.weixin.qq.com/pay/unifiedorder'  #接口地址
        request_new = urllib2.Request(url, data_xml)
        res = urllib2.urlopen(request_new)
        return_xml = etree.fromstring(res.read())
        if return_xml.find('return_code').text == 'SUCCESS':
            if return_xml.find('result_code').text == 'SUCCESS':
                prepay_id = return_xml.find('prepay_id').text  #预下单编号

                #再生成一个随机字符串,不长于32位,仍然是保证接下来签名不可预测
                nonce_str = ''
                for i in range(1, 32, 1):
                    nonce_str += chars[random.randint(0, chars_length)]

                #JSAPI支付所需数据
                wx_pay_dict = {
                    'appId': wx_appid,  #微信公众号APPID
                    'timeStamp': str(time.time()),  #当前Unix时间戳
                    'nonceStr': nonce_str,  #随机字符串
                    'package': 'prepay_id='+prepay_id,  #订单详情扩展,主要填写统一下单接口返回的预下单编号
                    'signType': 'MD5',  #签名算法,目前仅支持MD5
                }
                _, prestr_new = util.params_filter(wx_pay_dict)
                wx_pay_dict['paySign'] = hashlib.md5(prestr_new + '&key=' +wx_key).hexdigest().upper()

                #转换成json格式,将在页面js脚本中使用该数据
                wx_pay_json = json.dumps(wx_pay_dict)

                #显示微信支付页面
                values = {
                    'pay_json': wx_pay_json,
                    'company_name':company_name,
                    'all_car_num': all_car_num,
                    'all_money':all_money,
                }
                return request.website.render("wxsite.wxpay", values)
            else:
                error_text = ''
                if return_xml.find('err_code'):
                    error_text = error_text + u'错误代码为:' + return_xml.find('err_code')
                if return_xml.find('err_code_des'):
                    error_text = error_text + '\n' + return_xml.find('err_code_des')
                else:
                    error_text = u'交易发起失败,请稍后重试!'
        else:
            if return_xml.find('return_msg'):
                error_text = return_xml.find('return_msg').text
            else:
                error_text = u'交易发起失败,请稍后重试!'
        values = {
            'company_name':company_name,
            'error_text':error_text,
            'all_car_num':all_car_num,
        }
        return request.website.render("wxsite.error", values)
Пример #15
0
    def weixin_form_generate_values(self, partner_values, tx_values):
        self.ensure_one()
        base_url = self.env['ir.config_parameter'].get_param('web.base.url')
        amount = int(tx_values.get('amount', 0) * 100)
        nonce_str = self.random_generator()

        weixin_tx_values = dict(tx_values)
        weixin_tx_values.update({
            'appid':
            self.weixin_appid,
            'mch_id':
            self.weixin_mch_id,
            'nonce_str':
            nonce_str,
            'body':
            tx_values['reference'],
            'out_trade_no':
            tx_values['reference'],
            'total_fee':
            amount,
            'spbill_create_ip':
            self._get_ipaddress(),
            'notify_url':
            '%s' % urlparse.urljoin(base_url, WeixinController._notify_url),
            'trade_type':
            'NATIVE',
            'product_id':
            tx_values['reference'],
        })

        data_post = {}
        data_post.update({
            'appid':
            self.weixin_appid,
            'mch_id':
            self.weixin_mch_id,
            'nonce_str':
            nonce_str,
            'body':
            tx_values['reference'],
            'out_trade_no':
            tx_values['reference'],
            'total_fee':
            amount,
            'spbill_create_ip':
            self._get_ipaddress(),
            'notify_url':
            '%s' % urlparse.urljoin(base_url, WeixinController._notify_url),
            'trade_type':
            'NATIVE',
            'product_id':
            tx_values['reference'],
        })

        _, prestr = util.params_filter(data_post)
        weixin_tx_values['sign'] = util.build_mysign(prestr, self.weixin_key,
                                                     'MD5')
        data_post['sign'] = weixin_tx_values['sign']

        data_xml = "<xml>" + self.json2xml(data_post) + "</xml>"

        url = self._get_weixin_urls(self.environment)['weixin_url']

        request = urllib2.Request(url, data_xml)
        result = self._try_url(request, tries=3)

        _logger.info(
            "request to %s and the request data is %s, and request result is %s"
            % (url, data_xml, result))
        return_xml = etree.fromstring(result)

        if return_xml.find(
                'return_code'
        ).text == "SUCCESS" and return_xml.find('code_url').text != False:
            qrcode = return_xml.find('code_url').text
            weixin_tx_values['qrcode'] = qrcode
        else:
            return_code = return_xml.find('return_code').text
            return_msg = return_xml.find('return_msg').text
            raise ValidationError("%s, %s" % (return_code, return_msg))

        return partner_values, weixin_tx_values
Пример #16
0
    def alipay_form_generate_values(self, tx_values):
        base_url = self.env['ir.config_parameter'
                            ].sudo().get_param('web.base.url')

        alipay_tx_values = dict(tx_values)
        alipay_tx_values.update(
            {
                'partner':
                    self.alipay_partner_account,
                'seller_email':
                    self.alipay_seller_email,
                'seller_id':
                    self.alipay_partner_account,
                '_input_charset':
                    'UTF-8',
                'out_trade_no':
                    tx_values['reference'],
                'subject':
                    tx_values['reference'],
                'body':
                    tx_values['reference'],
                'payment_type':
                    '1',
                'return_url':
                    '%s' %
                    urlparse.urljoin(base_url, AlipayController._return_url),
                'notify_url':
                    '%s' %
                    urlparse.urljoin(base_url, AlipayController._notify_url),
            }
        )

        to_sign = {}
        to_sign.update(
            {
                'partner':
                    self.alipay_partner_account,
                'seller_email':
                    self.alipay_seller_email,
                'seller_id':
                    self.alipay_partner_account,
                '_input_charset':
                    'UTF-8',
                'out_trade_no':
                    tx_values['reference'],
                'subject':
                    tx_values['reference'],
                'body':
                    tx_values['reference'],
                'payment_type':
                    '1',
                'return_url':
                    '%s' %
                    urlparse.urljoin(base_url, AlipayController._return_url),
                'notify_url':
                    '%s' %
                    urlparse.urljoin(base_url, AlipayController._notify_url),
            }
        )

        payload_direct = {
            'service': 'create_direct_pay_by_user',
            'total_fee': tx_values['amount'],
        }

        payload_escow = {
            'service': 'create_partner_trade_by_buyer',
            'logistics_type': 'EXPRESS',
            'logistics_fee': 0,
            'logistics_payment': 'SELLER_PAY',
            'price': tx_values['amount'],
            'quantity': 1,
        }

        if self.alipay_interface_type == 'create_direct_pay_by_user':
            to_sign.update(payload_direct)
            alipay_tx_values.update(payload_direct)

        if self.alipay_interface_type == 'create_partner_trade_by_buyer':
            to_sign.update(payload_escow)
            alipay_tx_values.update(payload_escow)

        _, prestr = util.params_filter(to_sign)
        alipay_tx_values['sign'] = util.build_mysign(
            prestr, self.alipay_partner_key, 'MD5'
        )
        alipay_tx_values['sign_type'] = 'MD5'

        _logger.info('----alipay tx_values is %s' % alipay_tx_values)

        return alipay_tx_values
Пример #17
0
    def wxpay_backnotify(self, **post):
        """
        微信支付异步通知地址
        当用户成功支付后,微信服务器会POST一份xml格式的支付信息到该地址,通过商户订单号和支付状态进行处理
        处理后需返回一个xml信息,格式示例:
        <xml>
            <return_code><![CDATA[success]]></return_code>
            <return_msg><![CDATA[OK]]></return_msg>
        </xml>
        参考:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_7
        """
        cr, uid, context, pool = request.cr, request.uid, request.context, request.registry
        config = pool.get('ir.config_parameter')
        #下面几个变量是微信支付相关配置
        wx_key = config.get_param(cr, uid, 'wx_key')  #微信支付密钥,到微信商户平台设置并填写此处
        order_obj = pool.get('pos.order')
        payment_obj = pool.get('pos.make.payment')
        config_obj = pool.get('pos.config')
        print_list_obj = pool.get('qdodoo.print.list')
        dict_post_ip = self.pos_id()
        config_id = config_obj.search(cr, SUPERUSER_ID, [('iface_print_via_proxy','=',True)])
        if config_id:
            proxy_ip = config_obj.browse(cr, SUPERUSER_ID, config_id[0]).proxy_ip
        # 有返回结果
        if post:
            #解析post过来的xml数据,获取必要的信息
            post_dict = json.loads(post)  #解析json为dict

            #需返回给微信的参数,默认处理成功
            ret_dict = {
                'return_code': 'SUCCESS',
                'return_msg': 'OK',
            }

            #如果支付成功,则进行处理
            if post_dict['return_code'] == 'SUCCESS':
                #对post过来的数据进行签名,与post参数中的签名sign进行对比
                post_sign_dict = {}  #捡取非空参数,不包含签名sign
                for key, val in post_dict.items():
                    if not val == '' and not key == 'sign':
                        post_sign_dict[key] = val

                post_sign_dict = sorted(post_sign_dict.iteritems(), key=lambda d:d[0])
                post_sign_keyval = ''
                for key, val in post_sign_dict.items():
                    post_sign_keyval += key+'='+val+'&'
                post_sign_keyval += 'key='+wx_key
                post_sign = hashlib.new("md5", post_sign_keyval).hexdigest().upper()  #根据微信post来的参数计算出的签名

                if post_sign == post_dict['sign']:  #自己计算出来的签名与微信post过来的sign签名一致,则验签通过
                    oid = post_dict['out_trade_no']  #商户订单号,与发起微信支付时填写的out_trade_no一致,可据此处理对应订单
                    if oid[0] == '0':
                        oid = oid[1:]
                    wxpay_qid = post_dict['transaction_id']  #微信支付交易流水号,可据此对账
                    wxpay_sum = int(post_dict['total_fee'])/100  #实际支付金额,单位:分,除以100转换成元

                    #基本以上参数足够处理订单,以下也是post中必含的参数,可酌情使用
                    wxpay_openid = post_dict['openid']  #支付的微信用户openid,原则上与发起支付的openid一致
                    wxpay_tradetype = post_dict['trade_type']  #支付方式,原则上与发起支付的方式一致,如JSAPI
                    wxpay_appid = post_dict['appid']  #公众号APPID
                    wxpay_mch_id = post_dict['mch_id']  #商户号
                    wxpay_banktype = post_dict['bank_type']  #银行类型,标识所代表的银行可参考官方说明
                    wxpay_endtime = post_dict['time_end']  #支付完成时间,格式:yyyyMMddHHmmss,如:20160108124035

                    """
                    下面可以根据以上获取的参数对订单进行处理
                    小提示:微信可能多次发送同一笔支付通知,因此需先检验该订单支付是否已经处理过,未处理过的才进行处理
                    比如更改订单状态、财务出入帐等
                    """
                    order_obj.signal_workflow(cr, SUPERUSER_ID, [int(oid)], 'paid')

                else:  #验签失败
                    ret_dict['code'] = 'fail'
                    ret_dict['desc'] = 'sign valid fail'

            #最终,要返回处理结果的xml格式数据
            wxpay_ret_xml = Element('xml')
            for key, val in ret_dict.items():
                xml_child = Element(key)
                xml_child.text = str(val)
                wxpay_ret_xml.append(xml_child)
            return wxpay_ret_xml
        else:
            # 没有返回结果,执行查询方法
            wx_add = 'https://api.mch.weixin.qq.com/pay/orderquery'
            wx_appid = config.get_param(cr, uid, 'wx_appid')    #公众号号APPID,通常是微信签约时的服务号APPID
            wx_mchid = config.get_param(cr, uid, 'wx_mchid')  #商户号,签约微信支付后分配的商户号
            wx_fix = config.get_param(cr, uid, 'wx_fix') #付款订单号前缀
            # 查询所有未完成的订单
            order_ids = order_obj.search(cr, SUPERUSER_ID, [('state','=','draft'),('partner_id','!=',False)])
            for order_id in order_ids:
                #生成一个随机字符串,不长于32位,主要保证签名不可预测
                nonce_str = ''
                chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789'
                chars_length = len(chars) - 1
                for i in range(1, 32, 1):
                    nonce_str += chars[random.randint(0, chars_length)]
                out_trade_no = wx_fix + str(order_id)
                #微信查询接口所需参数
                wx_search = {
                    'appid': wx_appid,   #公众号号APPID
                    'mch_id': wx_mchid,  #商户号
                    'nonce_str': nonce_str,
                    'out_trade_no': out_trade_no,  #商户订单号
                }

                """
                参数签名,将非空字典键值按ASCII码升序排列,然后按url键值对拼接,最后拼接上微信支付密钥key
                将所拼接的字符串进行MD5运算,再将得到的字符串中所有字母转换为大写。即是签名
                """

                _, prestr_select = util.params_filter(wx_search)
                wx_search['sign'] = hashlib.md5(prestr_select + '&key=' +wx_key).hexdigest().upper()
                data_xml = "<xml>" + self.json2xml(wx_search) + "</xml>"
                request_new = urllib2.Request(wx_add, data_xml)
                res = urllib2.urlopen(request_new)
                return_xml = etree.fromstring(res.read())
                if return_xml.find('return_code').text == "SUCCESS" and return_xml.find('result_code').text != 'FAIL':
                    pay_state = return_xml.find('trade_state').text #交易状态
                    pos_obj = order_obj.browse(cr, SUPERUSER_ID, int(order_id))
                    date_order = pos_obj.date_order
                    if pay_state == 'SUCCESS':
                        try:
                            res_id = payment_obj.create(cr, SUPERUSER_ID, {'journal_id':pos_obj.session_id.config_id.journal_ids[0].id,
                                                                  'amount':pos_obj.amount_total,'payment_name':u'微信支付',
                                                                  'payment_date':datetime.now().date()})
                            payment_obj.check(cr, SUPERUSER_ID, [res_id], context={'active_id':pos_obj.id})
                            # 组织后台打印数据
                            infomation_new = """<receipt align="center" value-thousands-separator="" width="40">
                                <div font="b">
                                    <div><pre>订单号 %s</pre></div>
                                    <div><pre>%s</pre></div>
                                </div>
                                <br/><br/>
                                <div line-ratio="0.6">++++++"""%(pos_obj.name,datetime.now())
                            # 组织前台打印数据
                            infomation = """<receipt align="center" value-thousands-separator="" width="40">
                            <div font="b">
                                    <div>微信支付-结账单</div>
                                    <div>订单号:%s</div>
                                    <div>时间:%s</div>
                                    <div>==============================================</div>
                            <br/><br/>
                            ++++++<div>产品      数量    单价    金额    @@@@@%s@@@@@</div>++++++"""%(pos_obj.name,datetime.now(),pos_obj.session_id.config_id.front_desk)
                            for line in pos_obj.lines:
                                infomation_new += """<line size="double-height">
                                    <left><pre>%s</pre></left>
                                    <right><value>%s</value></right>
                                    @@@@@%s@@@@@
                                    </line>++++++"""%(line.product_id.name,line.qty,dict_post_ip.get(line.product_id.pos_categ_id.id))
                                product_id_name = line.product_id.name
                                if len(product_id_name) < 8:
                                    product_id_name += (' ' * (8-len(product_id_name)))
                                else:
                                    product_id_name = product_id_name[:8]
                                product_qty = str(line.qty)
                                if len(product_qty) < 6:
                                    product_qty += (' ' * 4)
                                else:
                                    product_qty = product_qty[:6]
                                product_list = str(line.product_id.list_price)
                                if len(product_list) < 6:
                                    product_list += (' ' * 4)
                                else:
                                    product_list = product_list[:6]
                                product_subtotal = str(line.price_subtotal_incl)
                                if len(product_subtotal) < 6:
                                    product_subtotal += (' ' * 4)
                                else:
                                    product_subtotal = product_subtotal[:6]
                                infomation += """<div>
                                %s
                                %s
                                %s
                                %s
                                @@@@@%s@@@@@
                                </div>++++++"""%(product_id_name,product_qty,product_list,
                                product_subtotal, pos_obj.session_id.config_id.front_desk)
                            infomation_new += """</div>
                                    <br/><br/><br/>
                                    <div size="double-height">
                                        <left><pre>备注:%s号桌 %s</pre></left>
                                    </div>
                                    </receipt>"""%(pos_obj.customer_count, pos_obj.note)
                            amount_total = str(pos_obj.amount_total)
                            if len(amount_total) < 6:
                                amount_total += (' ' * 4)
                            else:
                                amount_total = amount_total[:6]
                            note = u'号桌:'+str(pos_obj.customer_count)+'  备注:'+ pos_obj.note
                            infomation += """
                                <br/><br/><br/>
                                <div size="double-height">
                                    合计                 %s
                                </div>
                                <br/>
                                <div size="double-height">
                                    %s
                                </div>
                                <br/><br/>
                                <div>==============================================</div>
                                <div>%s</div>
                                <div>电话:%s</div>
                                <div>%s</div>
                                </div>
                            </receipt>"""%(amount_total, note, pos_obj.company_id.name, pos_obj.company_id.phone, pos_obj.company_id.website)
                            print_list_obj.create(cr, SUPERUSER_ID, {'name':infomation,'is_print':False})
                            print_list_obj.create(cr, SUPERUSER_ID, {'name':infomation_new,'is_print':False})
                        except Exception,e:
                            _logger.info('ERROR------------------------:%s'%e)
                        order_obj.write(cr, SUPERUSER_ID, [int(order_id)], {'is_payment':True})
                    elif pay_state == 'USERPAYING':
                        pass
                    elif pay_state == 'PAYERROR':
                        order_obj.signal_workflow(cr, SUPERUSER_ID, [int(order_id)], 'cancel')
                    else:
                        if date_order[:10] < datetime.now().date().strftime('%Y-%m-%d'):
                            order_obj.signal_workflow(cr, SUPERUSER_ID, [int(order_id)], 'cancel')
                else:
                    pass
            return 'SUCCESS'
Пример #18
0
    def _gen_weixin_code_url(self, post_data):
        data = {}
        data.update(
            {
                'appid': post_data['appid'],
                'mch_id': post_data['mch_id'],
                'nonce_str': post_data['nonce_str'],
                'body': post_data['body'],
                'out_trade_no': post_data['out_trade_no'],
                'total_fee': post_data['total_fee'],
                'spbill_create_ip': post_data['spbill_create_ip'],
                'notify_url': post_data['notify_url'],
                'trade_type': post_data['trade_type'],
            }
        )

        acquirer = self.search([('weixin_appid', '=', post_data['appid'])])
        _logger.info("--- acquirer %s" % (acquirer))

        if acquirer.environment == 'prod':
            key = acquirer.weixin_key
        else:
            key = self._get_weixin_signkey(acquirer)

        _, prestr = util.params_filter(data)

        _logger.info("+++ prestr %s, Weixin Key %s" % (prestr, key))

        data['sign'] = util.build_mysign(prestr, key, 'MD5')

        data_xml = "<xml>" + self.json2xml(data) + "</xml>"

        url = acquirer._get_weixin_urls(acquirer.environment)['weixin_url']

        request = urllib2.Request(url, data_xml)
        result = self._try_url(request, tries=3)

        _logger.info(
            "________gen_weixin_code_url_____ request to %s and the request data is %s, and request result is %s"
            % (url, data_xml, result)
        )
        return_xml = etree.fromstring(result)

        data_json = {}

        for el in return_xml:
            data_json[el.tag] = el.text

        if data_json['return_code'] == "SUCCESS" and data_json.get(
            'code_url', False
        ):
            return data_json['code_url']

        else:
            return_code = data_json.get('return_code')
            return_msg = data_json.get('return_msg')

            msg = "[%s] %s " % (return_code, return_msg)

            _logger.info('+++ some error occurred %s' % msg)
            # raise UserError(msg)

        return False
Пример #19
0
    def alipay_form_generate_values(self, cr, uid, id, partner_values, tx_values, context=None):
        base_url = self.pool['ir.config_parameter'].get_param(cr, SUPERUSER_ID, 'web.base.url')
        acquirer = self.browse(cr, uid, id, context=context)

        alipay_tx_values = dict(tx_values)
        alipay_tx_values.update({
            'partner': acquirer.alipay_partner_account,
            'seller_email': acquirer.alipay_seller_email,
            'seller_id': acquirer.alipay_partner_account,
            '_input_charset': 'utf-8',
            'out_trade_no': tx_values['reference'],
            'subject': tx_values['reference'],
            'body': '%s: %s' % (acquirer.company_id.name, tx_values['reference']),
            'payment_type': '1',
            'return_url': '%s' % urlparse.urljoin(base_url, AlipayController._return_url),
            'notify_url': '%s' % urlparse.urljoin(base_url, AlipayController._notify_url),
        })

        to_sign = {}
        to_sign.update({
            'partner': acquirer.alipay_partner_account,
            'seller_email': acquirer.alipay_seller_email,
            'seller_id': acquirer.alipay_partner_account,
            '_input_charset': 'utf-8',
            'out_trade_no': tx_values['reference'],
            'subject': tx_values['reference'],
            'body': '%s: %s' % (acquirer.company_id.name, tx_values['reference']),
            'payment_type': '1',
            'return_url': '%s' % urlparse.urljoin(base_url, AlipayController._return_url),
            'notify_url': '%s' % urlparse.urljoin(base_url, AlipayController._notify_url),
        })

        payload_direct = {
            'service': 'create_direct_pay_by_user',
            'total_fee': tx_values['amount'],
        }

        payload_escow = {
            'service': 'create_partner_trade_by_buyer',
            'logistics_type': 'EXPRESS',
            'logistics_fee': 0,
            'logistics_payment': 'SELLER_PAY',
            'price': tx_values['amount'],
            'quantity': 1,
        }

        payload_dualfun = {
            'service': 'trade_create_by_buyer',
            'logistics_type': 'EXPRESS',
            'logistics_fee': 0,
            'logistics_payment': 'SELLER_PAY',
            'price': tx_values['amount'],
            'quantity': 1,
        }

        if acquirer.alipay_interface_type == 'create_direct_pay_by_user':
            to_sign.update(payload_direct)
            alipay_tx_values.update(payload_direct)

        if acquirer.alipay_interface_type == 'create_partner_trade_by_buyer':
            to_sign.update(payload_escow)
            alipay_tx_values.update(payload_direct)

        if acquirer.alipay_interface_type == 'trade_create_by_buyer':
            to_sign.update(payload_dualfun)
            alipay_tx_values.update(payload_direct)

        _, prestr = util.params_filter(to_sign)
        alipay_tx_values['sign'] = util.build_mysign(prestr, acquirer.alipay_partner_key, 'MD5')
        alipay_tx_values['sign_type'] = 'MD5'

        return partner_values, alipay_tx_values
Пример #20
0
    def weixin_form_generate_values(self, partner_values, tx_values):
        self.ensure_one()
        base_url = self.env['ir.config_parameter'].get_param('web.base.url')
        amount = int(tx_values.get('amount', 0) * 100)
        nonce_str = self.random_generator()

        weixin_tx_values = dict(tx_values)
        weixin_tx_values.update(
            {
                'appid': self.weixin_appid,
                'mch_id': self.weixin_mch_id,
                'nonce_str': nonce_str,
                'body': tx_values['reference'],
                'out_trade_no': tx_values['reference'],
                'total_fee': amount,
                'spbill_create_ip': self._get_ipaddress(),
                'notify_url': '%s' % urlparse.urljoin(base_url, WeixinController._notify_url),
                'trade_type': 'NATIVE',
                'product_id': tx_values['reference'],
            }
        )

        data_post = {}
        data_post.update(
            {
                'appid': self.weixin_appid,
                'mch_id': self.weixin_mch_id,
                'nonce_str': nonce_str,
                'body': tx_values['reference'],
                'out_trade_no': tx_values['reference'],
                'total_fee': amount,
                'spbill_create_ip': self._get_ipaddress(),
                'notify_url': '%s' % urlparse.urljoin(base_url, WeixinController._notify_url),
                'trade_type': 'NATIVE',
                'product_id': tx_values['reference'],
            }
        )

        _, prestr = util.params_filter(data_post)
        weixin_tx_values['sign'] = util.build_mysign(prestr, self.weixin_key, 'MD5')
        data_post['sign'] = weixin_tx_values['sign']

        data_xml = "<xml>" + self.json2xml(data_post) + "</xml>"

        url = self._get_weixin_urls(self.environment)['weixin_url']

        request = urllib2.Request(url, data_xml)
        result = self._try_url(request, tries=3)

        _logger.info("request to %s and the request data is %s, and request result is %s" % (url, data_xml, result))
        return_xml = etree.fromstring(result)

        if return_xml.find('return_code').text == "SUCCESS" and return_xml.find('code_url').text <> False:
            qrcode = return_xml.find('code_url').text
            weixin_tx_values['qrcode'] = qrcode
        else:
            return_code = return_xml.find('return_code').text
            return_msg = return_xml.find('return_msg').text
            raise ValidationError("%s, %s" % (return_code, return_msg))

        return partner_values, weixin_tx_values
Пример #21
0
    def alipay(self, **post):
        """
        支付宝wap支付
        """
        cr, uid, context, pool = request.cr, request.uid, request.context, request.registry

        #  获取当前公司的名称(根据用户模型获取数据)
        users_obj = pool.get('res.users')
        product_obj = pool.get('product.product')
        taste_obj = pool.get('qdodoo.product.taste')
        session_obj = pool.get('pos.session')
        users = users_obj.browse(cr, SUPERUSER_ID, uid)
        taste_ids = taste_obj.search(cr, SUPERUSER_ID, [])
        tastes = taste_obj.browse(cr, SUPERUSER_ID, taste_ids)
        company_name = users.company_id.name
        company_id = users.company_id.id
        partner_id = users.partner_id.id
        order_obj = pool.get('pos.order')

        if post.get('oid'):
            res_order_id = int(post.get('oid'))
            all_money = float(post.get('money'))
            wx_fix = order_obj.browse(cr, uid, int(res_order_id)).session_id.config_id.en_name
        else:
            session_id = session_obj.search(cr, SUPERUSER_ID, [('config_id.company_id','=',company_id),('state','=','opened')])
            if not session_id:
                values = {
                    'company_name':company_name,
                    'error_text':u'支付宝暂停收款,请联系服务员点餐',
                }
                return request.website.render("wxsite.error", values)
            else:
                #  获取负责人
                session_ids = session_obj.browse(cr, SUPERUSER_ID, session_id[0])
                wx_fix = session_ids.config_id.en_name
                uid_session = session_ids.user_id.id
                car_obj = pool.get('qdodoo.wxsite.car')
                car_ids = car_obj.search(cr, SUPERUSER_ID, [('user_id','=',uid)])
                if car_ids:
                    #  生成销售订单(POS)
                    order_line_obj = pool.get('pos.order.line')
                    res_order_id = order_obj.create(cr, uid_session, {'partner_id':partner_id,'pricelist_id':1,'company_id':company_id})

                    #  获取加入购物车的总金额
                    all_money = 0
                    for key_line in car_obj.browse(cr, SUPERUSER_ID, car_ids):
                        #  根据产品模板id获取产品id
                        product_ids = product_obj.search(cr, SUPERUSER_ID, [('product_tmpl_id','=',key_line.name.id)])
                        all_money += key_line.number * key_line.name.lst_price # 获取总金额
                        #  生成销售单明细
                        order_line_obj.create(cr, uid_session, {'company_id':company_id,'order_id':res_order_id,'product_id':product_ids[0],
                                                                 'qty':key_line.number,'price_unit':key_line.name.lst_price})
                    car_obj.unlink(cr, SUPERUSER_ID, car_ids)
                else:
                    values = {
                        'company_name':company_name,
                        'error_text':u'不能支付空的订单',
                    }
                    return request.website.render("wxsite.error", values)


        config = pool.get('ir.config_parameter')

        # 下面几个变量是支付宝支付相关配置
        alipay_config_dict = {
            'partner': '2088121266041788',  # 合作身份者id,以2088开头的16位纯数字
            'sign_type': 'MD5',  # 签名方式
            'key': '4nzm1m9udzhvi7clurk2k9s6rs0e0cv5',  # 安全检验码,以数字和字母组成的32位字符,如果签名方式设置为“MD5”时,请设置该参数
            'private_key_path': '',  # 商户的私钥(.pem文件)相对路径,如果签名方式设置为“0001”时,请设置该参数
            'ali_public_key_path': '',  # 支付宝公钥(.pem文件)相对路径,如果签名方式设置为“0001”时,请设置该参数
            'input_charset': 'utf-8',  # 字符编码格式 支持 gbk 或 utf-8
            'transport': 'http',  # 访问模式,根据自己的服务器是否支持ssl访问,若支持请选择https;若不支持请选择http
            'cacert': '',  # ca证书路径地址,如果访问模式是https,则填写此处
        }

        """
        组织参数,调用授权接口alipay.wap.trade.create.direct获取授权码token
        """
        oid = str(wx_fix) + str(res_order_id)
        param_dict = {
            'format': 'xml',  # 要求返回格式
            'v': '2.0',  # 返回格式版本
            'req_id': (datetime.datetime.now()+datetime.timedelta(hours=8)).strftime('%Y%m%d%H%M%S'),  # 请求号。使用年月日时分秒,保证每次请求都是唯一
            'notify_url': config.get_param(cr, uid, 'web.base.url') + '/shop/wx/alipay/backnotify',  # 服务器异步通知页面路径
            'call_back_url': config.get_param(cr, uid, 'web.base.url') + '/shop/wx/alipay/frontreturn',  # 页面跳转同步通知页面路径
            'merchant_url': config.get_param(cr, uid, 'web.base.url') + '/shop/wx/alipay/interrupt',  # 操作中断返回地址,用户付款中途退出返回商户的地址。
            'seller_email': '*****@*****.**',  # 卖家支付宝帐户
            'out_trade_no': oid,  # 商户订单号,此处如果用str(wx_fix)会返回False
            'subject': '订单',  # 订单名称
            'body': str(wx_fix),  # 订单号前缀,期望在后台通知中能原样返回以便解析出订单ID
            'total_fee': str(all_money),  # 付款金额,单位:元
        }

        # 请求业务参数明细
        token_req = '<direct_trade_create_req><notify_url>'+param_dict['notify_url']+'</notify_url><call_back_url>'+param_dict['call_back_url']+'</call_back_url><seller_account_name>'+param_dict['seller_email']+'</seller_account_name><out_trade_no>'+param_dict['out_trade_no']+'</out_trade_no><subject>'+param_dict['subject']+'</subject><total_fee>'+param_dict['total_fee']+'</total_fee><merchant_url>'+param_dict['merchant_url']+'</merchant_url></direct_trade_create_req>'

        # 请求参数组
        req_param_dict = {
            'service': 'alipay.wap.trade.create.direct',
            'partner': alipay_config_dict['partner'],
            'sec_id': alipay_config_dict['sign_type'],
            'format': param_dict['format'],
            'v': param_dict['v'],
            'req_id': param_dict['req_id'],
            'req_data': token_req,
            '_input_charset': alipay_config_dict['input_charset'],
        }

        # 签名
        _, sign_query_str = util.params_filter(req_param_dict)
        alipay_md5_sign = hashlib.md5(sign_query_str + alipay_config_dict['key']).hexdigest()

        # 签名和签名方式加入请求参数中
        req_param_dict['sign'] = alipay_md5_sign
        req_param_dict['sign_type'] = alipay_config_dict['sign_type']

        # 发送post请求,获取token
        alipay_gateway_new = 'http://wappaygw.alipay.com/service/rest.htm?_input_charset='+alipay_config_dict['input_charset']
        post_param_query = urllib.urlencode(req_param_dict)

        http_client = httplib.HTTPConnection('wappaygw.alipay.com', 80, timeout=6000)
        http_client.request('POST', '/service/rest.htm?_input_charset='+alipay_config_dict['input_charset'], post_param_query, {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/html"})
        ret_query = http_client.getresponse().read()
        ret_query = urllib.unquote(ret_query)  # urldecode
        http_client.close()

        """
        支付宝返回的数据格式,一般只需要request_token
        res_data=<?xml version="1.0" encoding="utf-8"?><direct_trade_create_res><request_token>20160304cfe8ccddf25e82eeded3e36d17a1ed1e</request_token></direct_trade_create_res>&service=alipay.wap.trade.create.direct&sec_id=MD5&partner=2088901494850295&req_id=20160304032846&sign=43fb3101321eeb7f928170502e5d1948&v=2.0
        """
        # 截取出其中的request_token
        alipay_request_token = ret_query[ret_query.index('<request_token>')+15:ret_query.index('</request_token>')]

        # 构建请求跳转数组
        form_input_dict ={
            'service': 'alipay.wap.auth.authAndExecute',
            'partner': alipay_config_dict['partner'],
            "sec_id": alipay_config_dict['sign_type'],
            'format': param_dict['format'],
            'v': param_dict['v'],
            'req_id': param_dict['req_id'],
            'req_data': '<auth_and_execute_req><request_token>'+alipay_request_token+'</request_token></auth_and_execute_req>',
            '_input_charset': alipay_config_dict['input_charset'],
        }

        # 再签名
        _, sign_query_str = util.params_filter(form_input_dict)
        alipay_md5_sign = hashlib.md5(sign_query_str + alipay_config_dict['key']).hexdigest()

        # 签名和签名方式等加入请求参数中
        form_input_dict['sign'] = alipay_md5_sign
        form_input_dict['sign_type'] = alipay_config_dict['sign_type']
        form_input_dict['oid'] = res_order_id
        form_input_dict['all_money'] = all_money
        form_input_dict['company_name'] = company_name
        form_input_dict['tastes'] = tastes

        # 调用页面form跳转到支付宝支付
        return request.website.render("wxsite.alipay", form_input_dict)
Пример #22
0
    def ali_oauth(self, **post):
        """
        支付宝用户授权回调地址,在此处根据auth_code来获取支付宝用户信息,进行登录/注册处理
        """
        cr, uid, context, pool = request.cr, request.uid, request.context, request.registry
        ali_code = post['auth_code']  # 授权code,属于GET参数
        _logger.info('----->auth_code:%s'%ali_code)

        """
        根据code获取支付宝用户ID和access_token, Python方法
        """
        sign_params_dic = {
            'app_id': '2016030201177117',  # 支付宝APPID
            'method': 'alipay.system.oauth.token',
            'charset': 'UTF-8',
            'sign_type': 'RSA',
            'timestamp': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
            'version': '1.0',
            'grant_type': 'authorization_code',
            'code': ali_code,
        }

        # 待签名参数按key值排序,组合成待加密串
        _, sign_query_str = util.params_filter(sign_params_dic)
        #  sign_query_str = util.sort(sign_params_dic)
        rsa_private_key = RSA.importKey(open('addons-extra/wxsite/static/rsa_private_key.pem','r').read())
        rsa_private_sign=util.sign(sign_query_str, rsa_private_key)
        sign_params_dic['sign'] = rsa_private_sign

        # post到支付宝,获取userId(类似微信的OpenId)
        post_param_query = urllib.urlencode(sign_params_dic)

        httpsClient = httplib.HTTPSConnection('openapi.alipay.com', 443, timeout=6000)
        httpsClient.request('POST', '/gateway.do', post_param_query, {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/html","charset":"utf8"})
        ret_json = httpsClient.getresponse().read()
        ret_dict = json.loads(ret_json.decode('GB2312').encode('UTF-8'))  # 解析json
        ali_userid = ret_dict['alipay_system_oauth_token_response']['user_id']  # 获取userid
        ali_access_token = ret_dict['alipay_system_oauth_token_response']['access_token']  # 获取access_token

        """
        在此处根据支付宝userId判断用户是否已存在数据库中
        """
        users_obj = pool.get('res.users')
        company_id = request.session['company_id']
        login = str(company_id)+ali_userid
        # company_id = 1  # 支付宝授权链接中不能带自定义参数,不能像微信授权那样传递company_id,此处暂默认为1

        wx_user_exists = users_obj.search(cr, SUPERUSER_ID, [('login','=',login),('company_id','=',int(company_id))])
        if not wx_user_exists:
            # 获取用户详细信息如用户名等
            sign_params_dic = {
                'app_id': '2016030201177117',  # 支付宝APPID
                'method': 'alipay.user.userinfo.share',
                'charset': 'UTF-8',
                'sign_type': 'RSA',
                'timestamp': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),  # 不知为什么,now()总是晚8小时
                'version': '1.0',
                'auth_token': ali_access_token,
            }

            _, sign_query_str = util.params_filter(sign_params_dic)
            rsa_private_key = RSA.importKey(open('addons-extra/wxsite/static/rsa_private_key.pem','r').read())
            rsa_private_sign=util.sign(sign_query_str, rsa_private_key)
            sign_params_dic['sign'] = rsa_private_sign

            # post到支付宝,获取用户名等信息,用于注册
            post_param_query = urllib.urlencode(sign_params_dic)
            httpsClient = httplib.HTTPSConnection('openapi.alipay.com', 443, timeout=6000)
            httpsClient.request('POST', '/gateway.do', post_param_query, {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/html","charset":"utf8"})
            ret_json = httpsClient.getresponse().read()

            ret_dict = json.loads(ret_json.decode('GB2312').encode('UTF-8'))  # 解析json

            if 'nick_name' in ret_dict['alipay_user_userinfo_share_response']:
                ali_username = ret_dict['alipay_user_userinfo_share_response']['nick_name']  # 获取支付宝用户昵称
            else:
                ali_username = ret_dict['alipay_user_userinfo_share_response']['alipay_user_id']

            # 注册用户
            users_obj.create(cr, SUPERUSER_ID, {'login':login,'name':ali_username,'password':'******','oauth_provider_id':'','company_id':int(company_id),'company_ids':[[6, False, [int(company_id)]]]})

        request.session['alipay_userid'] = ali_userid

        return request.redirect("/login?db=%s&login=%s&key=%s&redirect=%s"%(request.session.db,login, 'qdodoo', 'shop/wx/main'))
Пример #23
0
    def ali_oauth(self, **post):
        """
        支付宝用户授权回调地址,在此处根据auth_code来获取支付宝用户信息,进行登录/注册处理
        """
        cr, uid, context, pool = request.cr, request.uid, request.context, request.registry
        ali_code = post['auth_code']  # 授权code,属于GET参数
        _logger.info('----->auth_code:%s' % ali_code)
        """
        根据code获取支付宝用户ID和access_token, Python方法
        """
        sign_params_dic = {
            'app_id': '2016030201177117',  # 支付宝APPID
            'method': 'alipay.system.oauth.token',
            'charset': 'UTF-8',
            'sign_type': 'RSA',
            'timestamp': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
            'version': '1.0',
            'grant_type': 'authorization_code',
            'code': ali_code,
        }

        # 待签名参数按key值排序,组合成待加密串
        _, sign_query_str = util.params_filter(sign_params_dic)
        #  sign_query_str = util.sort(sign_params_dic)
        rsa_private_key = RSA.importKey(
            open('addons-extra/wxsite/static/rsa_private_key.pem', 'r').read())
        rsa_private_sign = util.sign(sign_query_str, rsa_private_key)
        sign_params_dic['sign'] = rsa_private_sign

        # post到支付宝,获取userId(类似微信的OpenId)
        post_param_query = urllib.urlencode(sign_params_dic)

        httpsClient = httplib.HTTPSConnection('openapi.alipay.com',
                                              443,
                                              timeout=6000)
        httpsClient.request(
            'POST', '/gateway.do', post_param_query, {
                "Content-type": "application/x-www-form-urlencoded",
                "Accept": "text/html",
                "charset": "utf8"
            })
        ret_json = httpsClient.getresponse().read()
        ret_dict = json.loads(
            ret_json.decode('GB2312').encode('UTF-8'))  # 解析json
        ali_userid = ret_dict['alipay_system_oauth_token_response'][
            'user_id']  # 获取userid
        ali_access_token = ret_dict['alipay_system_oauth_token_response'][
            'access_token']  # 获取access_token
        """
        在此处根据支付宝userId判断用户是否已存在数据库中
        """
        users_obj = pool.get('res.users')
        company_id = request.session['company_id']
        login = str(company_id) + ali_userid
        # company_id = 1  # 支付宝授权链接中不能带自定义参数,不能像微信授权那样传递company_id,此处暂默认为1

        wx_user_exists = users_obj.search(
            cr, SUPERUSER_ID, [('login', '=', login),
                               ('company_id', '=', int(company_id))])
        if not wx_user_exists:
            # 获取用户详细信息如用户名等
            sign_params_dic = {
                'app_id': '2016030201177117',  # 支付宝APPID
                'method': 'alipay.user.userinfo.share',
                'charset': 'UTF-8',
                'sign_type': 'RSA',
                'timestamp': datetime.datetime.now().strftime(
                    '%Y-%m-%d %H:%M:%S'),  # 不知为什么,now()总是晚8小时
                'version': '1.0',
                'auth_token': ali_access_token,
            }

            _, sign_query_str = util.params_filter(sign_params_dic)
            rsa_private_key = RSA.importKey(
                open('addons-extra/wxsite/static/rsa_private_key.pem',
                     'r').read())
            rsa_private_sign = util.sign(sign_query_str, rsa_private_key)
            sign_params_dic['sign'] = rsa_private_sign

            # post到支付宝,获取用户名等信息,用于注册
            post_param_query = urllib.urlencode(sign_params_dic)
            httpsClient = httplib.HTTPSConnection('openapi.alipay.com',
                                                  443,
                                                  timeout=6000)
            httpsClient.request(
                'POST', '/gateway.do', post_param_query, {
                    "Content-type": "application/x-www-form-urlencoded",
                    "Accept": "text/html",
                    "charset": "utf8"
                })
            ret_json = httpsClient.getresponse().read()

            ret_dict = json.loads(
                ret_json.decode('GB2312').encode('UTF-8'))  # 解析json

            if 'nick_name' in ret_dict['alipay_user_userinfo_share_response']:
                ali_username = ret_dict['alipay_user_userinfo_share_response'][
                    'nick_name']  # 获取支付宝用户昵称
            else:
                ali_username = ret_dict['alipay_user_userinfo_share_response'][
                    'alipay_user_id']

            # 注册用户
            users_obj.create(
                cr, SUPERUSER_ID, {
                    'login': login,
                    'name': ali_username,
                    'password': '******',
                    'oauth_provider_id': '',
                    'company_id': int(company_id),
                    'company_ids': [[6, False, [int(company_id)]]]
                })

        request.session['alipay_userid'] = ali_userid

        return request.redirect(
            "/login?db=%s&login=%s&key=%s&redirect=%s" %
            (request.session.db, login, 'qdodoo', 'shop/wx/main'))
Пример #24
0
    def alipay(self, **post):
        """
        支付宝wap支付
        """
        cr, uid, context, pool = request.cr, request.uid, request.context, request.registry

        #  获取当前公司的名称(根据用户模型获取数据)
        users_obj = pool.get('res.users')
        product_obj = pool.get('product.product')
        taste_obj = pool.get('qdodoo.product.taste')
        session_obj = pool.get('pos.session')
        users = users_obj.browse(cr, SUPERUSER_ID, uid)
        taste_ids = taste_obj.search(cr, SUPERUSER_ID, [])
        tastes = taste_obj.browse(cr, SUPERUSER_ID, taste_ids)
        company_name = users.company_id.name
        company_id = users.company_id.id
        partner_id = users.partner_id.id
        order_obj = pool.get('pos.order')

        if post.get('oid'):
            res_order_id = int(post.get('oid'))
            all_money = float(post.get('money'))
            wx_fix = order_obj.browse(
                cr, uid, int(res_order_id)).session_id.config_id.en_name
        else:
            session_id = session_obj.search(
                cr, SUPERUSER_ID, [('config_id.company_id', '=', company_id),
                                   ('state', '=', 'opened')])
            if not session_id:
                values = {
                    'company_name': company_name,
                    'error_text': u'支付宝暂停收款,请联系服务员点餐',
                }
                return request.website.render("wxsite.error", values)
            else:
                #  获取负责人
                session_ids = session_obj.browse(cr, SUPERUSER_ID,
                                                 session_id[0])
                wx_fix = session_ids.config_id.en_name
                uid_session = session_ids.user_id.id
                car_obj = pool.get('qdodoo.wxsite.car')
                car_ids = car_obj.search(cr, SUPERUSER_ID,
                                         [('user_id', '=', uid)])
                if car_ids:
                    #  生成销售订单(POS)
                    order_line_obj = pool.get('pos.order.line')
                    res_order_id = order_obj.create(
                        cr, uid_session, {
                            'partner_id': partner_id,
                            'pricelist_id': 1,
                            'company_id': company_id
                        })

                    #  获取加入购物车的总金额
                    all_money = 0
                    for key_line in car_obj.browse(cr, SUPERUSER_ID, car_ids):
                        #  根据产品模板id获取产品id
                        product_ids = product_obj.search(
                            cr, SUPERUSER_ID,
                            [('product_tmpl_id', '=', key_line.name.id)])
                        all_money += key_line.number * key_line.name.lst_price  # 获取总金额
                        #  生成销售单明细
                        order_line_obj.create(
                            cr, uid_session, {
                                'company_id': company_id,
                                'order_id': res_order_id,
                                'product_id': product_ids[0],
                                'qty': key_line.number,
                                'price_unit': key_line.name.lst_price
                            })
                    car_obj.unlink(cr, SUPERUSER_ID, car_ids)
                else:
                    values = {
                        'company_name': company_name,
                        'error_text': u'不能支付空的订单',
                    }
                    return request.website.render("wxsite.error", values)

        config = pool.get('ir.config_parameter')

        # 下面几个变量是支付宝支付相关配置
        alipay_config_dict = {
            'partner': '2088121266041788',  # 合作身份者id,以2088开头的16位纯数字
            'sign_type': 'MD5',  # 签名方式
            'key':
            '4nzm1m9udzhvi7clurk2k9s6rs0e0cv5',  # 安全检验码,以数字和字母组成的32位字符,如果签名方式设置为“MD5”时,请设置该参数
            'private_key_path':
            '',  # 商户的私钥(.pem文件)相对路径,如果签名方式设置为“0001”时,请设置该参数
            'ali_public_key_path':
            '',  # 支付宝公钥(.pem文件)相对路径,如果签名方式设置为“0001”时,请设置该参数
            'input_charset': 'utf-8',  # 字符编码格式 支持 gbk 或 utf-8
            'transport':
            'http',  # 访问模式,根据自己的服务器是否支持ssl访问,若支持请选择https;若不支持请选择http
            'cacert': '',  # ca证书路径地址,如果访问模式是https,则填写此处
        }
        """
        组织参数,调用授权接口alipay.wap.trade.create.direct获取授权码token
        """
        oid = str(wx_fix) + str(res_order_id)
        param_dict = {
            'format':
            'xml',  # 要求返回格式
            'v':
            '2.0',  # 返回格式版本
            'req_id': (datetime.datetime.now() + datetime.timedelta(hours=8)
                       ).strftime('%Y%m%d%H%M%S'),  # 请求号。使用年月日时分秒,保证每次请求都是唯一
            'notify_url':
            config.get_param(cr, uid, 'web.base.url') +
            '/shop/wx/alipay/backnotify',  # 服务器异步通知页面路径
            'call_back_url':
            config.get_param(cr, uid, 'web.base.url') +
            '/shop/wx/alipay/frontreturn',  # 页面跳转同步通知页面路径
            'merchant_url':
            config.get_param(cr, uid, 'web.base.url') +
            '/shop/wx/alipay/interrupt',  # 操作中断返回地址,用户付款中途退出返回商户的地址。
            'seller_email':
            '*****@*****.**',  # 卖家支付宝帐户
            'out_trade_no':
            oid,  # 商户订单号,此处如果用str(wx_fix)会返回False
            'subject':
            '订单',  # 订单名称
            'body':
            str(wx_fix),  # 订单号前缀,期望在后台通知中能原样返回以便解析出订单ID
            'total_fee':
            str(all_money),  # 付款金额,单位:元
        }

        # 请求业务参数明细
        token_req = '<direct_trade_create_req><notify_url>' + param_dict[
            'notify_url'] + '</notify_url><call_back_url>' + param_dict[
                'call_back_url'] + '</call_back_url><seller_account_name>' + param_dict[
                    'seller_email'] + '</seller_account_name><out_trade_no>' + param_dict[
                        'out_trade_no'] + '</out_trade_no><subject>' + param_dict[
                            'subject'] + '</subject><total_fee>' + param_dict[
                                'total_fee'] + '</total_fee><merchant_url>' + param_dict[
                                    'merchant_url'] + '</merchant_url></direct_trade_create_req>'

        # 请求参数组
        req_param_dict = {
            'service': 'alipay.wap.trade.create.direct',
            'partner': alipay_config_dict['partner'],
            'sec_id': alipay_config_dict['sign_type'],
            'format': param_dict['format'],
            'v': param_dict['v'],
            'req_id': param_dict['req_id'],
            'req_data': token_req,
            '_input_charset': alipay_config_dict['input_charset'],
        }

        # 签名
        _, sign_query_str = util.params_filter(req_param_dict)
        alipay_md5_sign = hashlib.md5(sign_query_str +
                                      alipay_config_dict['key']).hexdigest()

        # 签名和签名方式加入请求参数中
        req_param_dict['sign'] = alipay_md5_sign
        req_param_dict['sign_type'] = alipay_config_dict['sign_type']

        # 发送post请求,获取token
        alipay_gateway_new = 'http://wappaygw.alipay.com/service/rest.htm?_input_charset=' + alipay_config_dict[
            'input_charset']
        post_param_query = urllib.urlencode(req_param_dict)

        http_client = httplib.HTTPConnection('wappaygw.alipay.com',
                                             80,
                                             timeout=6000)
        http_client.request(
            'POST', '/service/rest.htm?_input_charset=' +
            alipay_config_dict['input_charset'], post_param_query, {
                "Content-type": "application/x-www-form-urlencoded",
                "Accept": "text/html"
            })
        ret_query = http_client.getresponse().read()
        ret_query = urllib.unquote(ret_query)  # urldecode
        http_client.close()
        """
        支付宝返回的数据格式,一般只需要request_token
        res_data=<?xml version="1.0" encoding="utf-8"?><direct_trade_create_res><request_token>20160304cfe8ccddf25e82eeded3e36d17a1ed1e</request_token></direct_trade_create_res>&service=alipay.wap.trade.create.direct&sec_id=MD5&partner=2088901494850295&req_id=20160304032846&sign=43fb3101321eeb7f928170502e5d1948&v=2.0
        """
        # 截取出其中的request_token
        alipay_request_token = ret_query[ret_query.index('<request_token>') +
                                         15:ret_query.index('</request_token>'
                                                            )]

        # 构建请求跳转数组
        form_input_dict = {
            'service':
            'alipay.wap.auth.authAndExecute',
            'partner':
            alipay_config_dict['partner'],
            "sec_id":
            alipay_config_dict['sign_type'],
            'format':
            param_dict['format'],
            'v':
            param_dict['v'],
            'req_id':
            param_dict['req_id'],
            'req_data':
            '<auth_and_execute_req><request_token>' + alipay_request_token +
            '</request_token></auth_and_execute_req>',
            '_input_charset':
            alipay_config_dict['input_charset'],
        }

        # 再签名
        _, sign_query_str = util.params_filter(form_input_dict)
        alipay_md5_sign = hashlib.md5(sign_query_str +
                                      alipay_config_dict['key']).hexdigest()

        # 签名和签名方式等加入请求参数中
        form_input_dict['sign'] = alipay_md5_sign
        form_input_dict['sign_type'] = alipay_config_dict['sign_type']
        form_input_dict['oid'] = res_order_id
        form_input_dict['all_money'] = all_money
        form_input_dict['company_name'] = company_name
        form_input_dict['tastes'] = tastes

        # 调用页面form跳转到支付宝支付
        return request.website.render("wxsite.alipay", form_input_dict)
Пример #25
0
    def wxpay_backnotify(self, **post):
        """
        微信支付异步通知地址
        当用户成功支付后,微信服务器会POST一份xml格式的支付信息到该地址,通过商户订单号和支付状态进行处理
        处理后需返回一个xml信息,格式示例:
        <xml>
            <return_code><![CDATA[success]]></return_code>
            <return_msg><![CDATA[OK]]></return_msg>
        </xml>
        参考:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_7
        """
        cr, uid, context, pool = request.cr, request.uid, request.context, request.registry

        #下面几个变量是微信支付相关配置
        wx_key = '33132ac4f37f151dbfcbfce34f441d71'  #微信支付密钥,到微信商户平台设置并填写此处
        order_obj = pool.get('pos.order')
        payment_obj = pool.get('pos.make.payment')
        config_obj = pool.get('pos.config')
        print_list_obj = pool.get('qdodoo.print.list')
        dict_post_ip = self.pos_id()
        config_id = config_obj.search(cr, SUPERUSER_ID, [('iface_print_via_proxy','=',True)])
        if config_id:
            proxy_ip = config_obj.browse(cr, SUPERUSER_ID, config_id[0]).proxy_ip
        # 有返回结果
        if post:
            #解析post过来的xml数据,获取必要的信息
            post_dict = json.loads(post)  #解析json为dict

            #需返回给微信的参数,默认处理成功
            ret_dict = {
                'return_code': 'SUCCESS',
                'return_msg': 'OK',
            }

            #如果支付成功,则进行处理
            if post_dict['return_code'] == 'SUCCESS':
                #对post过来的数据进行签名,与post参数中的签名sign进行对比
                post_sign_dict = {}  #捡取非空参数,不包含签名sign
                for key, val in post_dict.items():
                    if not val == '' and not key == 'sign':
                        post_sign_dict[key] = val

                post_sign_dict = sorted(post_sign_dict.iteritems(), key=lambda d:d[0])
                post_sign_keyval = ''
                for key, val in post_sign_dict.items():
                    post_sign_keyval += key+'='+val+'&'
                post_sign_keyval += 'key='+wx_key
                post_sign = hashlib.new("md5", post_sign_keyval).hexdigest().upper()  #根据微信post来的参数计算出的签名

                if post_sign == post_dict['sign']:  #自己计算出来的签名与微信post过来的sign签名一致,则验签通过
                    oid = post_dict['out_trade_no']  #商户订单号,与发起微信支付时填写的out_trade_no一致,可据此处理对应订单
                    wxpay_qid = post_dict['transaction_id']  #微信支付交易流水号,可据此对账
                    wxpay_sum = int(post_dict['total_fee'])/100  #实际支付金额,单位:分,除以100转换成元

                    #基本以上参数足够处理订单,以下也是post中必含的参数,可酌情使用
                    wxpay_openid = post_dict['openid']  #支付的微信用户openid,原则上与发起支付的openid一致
                    wxpay_tradetype = post_dict['trade_type']  #支付方式,原则上与发起支付的方式一致,如JSAPI
                    wxpay_appid = post_dict['appid']  #公众号APPID
                    wxpay_mch_id = post_dict['mch_id']  #商户号
                    wxpay_banktype = post_dict['bank_type']  #银行类型,标识所代表的银行可参考官方说明
                    wxpay_endtime = post_dict['time_end']  #支付完成时间,格式:yyyyMMddHHmmss,如:20160108124035

                    """
                    下面可以根据以上获取的参数对订单进行处理
                    小提示:微信可能多次发送同一笔支付通知,因此需先检验该订单支付是否已经处理过,未处理过的才进行处理
                    比如更改订单状态、财务出入帐等
                    """
                    order_obj.signal_workflow(cr, SUPERUSER_ID, [int(oid)], 'paid')

                else:  #验签失败
                    ret_dict['code'] = 'fail'
                    ret_dict['desc'] = 'sign valid fail'

            #最终,要返回处理结果的xml格式数据
            wxpay_ret_xml = Element('xml')
            for key, val in ret_dict.items():
                xml_child = Element(key)
                xml_child.text = str(val)
                wxpay_ret_xml.append(xml_child)
            return wxpay_ret_xml
        else:
            # 没有返回结果,执行查询方法
            wx_add = 'https://api.mch.weixin.qq.com/pay/orderquery'
            wx_appid = 'wxde2cf9dbf3c35624'    #公众号号APPID,通常是微信签约时的服务号APPID
            wx_mchid = '1294510601'  #商户号,签约微信支付后分配的商户号
            wx_key = '33132ac4f37f151dbfcbfce34f441d71'  #微信支付密钥,到微信商户平台设置并填写此处
            # 查询所有未完成的订单
            order_ids = order_obj.search(cr, SUPERUSER_ID, [('state','=','draft')])
            for order_ids in order_ids:
                #生成一个随机字符串,不长于32位,主要保证签名不可预测
                nonce_str = ''
                chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789'
                chars_length = len(chars) - 1
                for i in range(1, 32, 1):
                    nonce_str += chars[random.randint(0, chars_length)]
                #微信查询接口所需参数
                wx_search = {
                    'appid': wx_appid,   #公众号号APPID
                    'mch_id': wx_mchid,  #商户号
                    'nonce_str': nonce_str,
                    'out_trade_no': order_ids,  #商户订单号
                }

                """
                参数签名,将非空字典键值按ASCII码升序排列,然后按url键值对拼接,最后拼接上微信支付密钥key
                将所拼接的字符串进行MD5运算,再将得到的字符串中所有字母转换为大写。即是签名
                """

                _, prestr_select = util.params_filter(wx_search)
                wx_search['sign'] = hashlib.md5(prestr_select + '&key=' +wx_key).hexdigest().upper()
                data_xml = "<xml>" + self.json2xml(wx_search) + "</xml>"
                request_new = urllib2.Request(wx_add, data_xml)
                res = urllib2.urlopen(request_new)
                return_xml = etree.fromstring(res.read())
                if return_xml.find('return_code').text == "SUCCESS" and return_xml.find('result_code').text != 'FAIL':
                    pay_state = return_xml.find('trade_state').text #交易状态
                    pos_id = return_xml.find('out_trade_no').text #订单号
                    pos_obj = order_obj.browse(cr, SUPERUSER_ID, int(pos_id))
                    if pay_state == 'SUCCESS':
                        res_id = payment_obj.create(cr, SUPERUSER_ID, {'journal_id':pos_obj.session_id.config_id.journal_ids[0].id,
                                                              'amount':pos_obj.amount_total,'payment_name':u'微信支付',
                                                              'payment_date':datetime.now().date()})
                        payment_obj.check(cr, SUPERUSER_ID, [res_id], context={'active_id':pos_obj.id})
                        infomation = """<receipt align="center" value-thousands-separator="" width="40">
                            <div font="b">
                                    <div>%s</div>
                                    <div>电话:%s</div>
                                    <div>%s</div>
                                    <div>%s</div>
                                    <div>--------------------------------</div>
                                    <div>被服务于 %s</div>
                            </div>
                            <br/><br/>
                            <div line-ratio="0.6">"""%(pos_obj.company_id.name,pos_obj.company_id.phone,pos_obj.company_id.email,
                                                       pos_obj.company_id.website,pos_obj.user_id.name)
                        # 循环订单明细
                        for line in pos_obj.lines:
                            infomation += """++++++<line><left>%s</left></line>
                            <line indent="1">
                                <left>
                                    <value value-autoint="on" value-decimals="3">
                                        %s
                                    </value>
                                        %s

                                    x

                                    <value value-decimals="2">

                                        %s

                                    </value>
                                    ===%s===
                                </left>
                                <right>
                                    <value>%s</value>
                                </right>
                            </line>++++++"""%(line.product_id.name,line.qty,line.product_id.uom_id.name,line.product_id.list_price,
                           dict_post_ip.get(line.product_id.pos_categ_id.id), line.product_id.list_price)

                        infomation += """</div>
                            <line><right>--------</right></line>
                            <line size="double-height">
                                <left><pre>        合计</pre></left>
                                <right><value>%s</value></right>
                            </line>
                            <br/><br/>
                                <line>
                                    <left>现金 (CNY)</left>
                                    <right><value>%s</value></right>
                                </line>
                            <br/>
                            <line size="double-height">
                                <left><pre>        CHANGE</pre></left>
                                <right><value>0</value></right>
                            </line>
                            <br/>
                            <br/>
                            <div font="b">
                                <div>Order %s</div>
                                <div>%s</div>
                            </div>
                        </receipt>"""%(pos_obj.amount_total,pos_obj.amount_total,pos_obj.name,datetime.now())
                        print_list_obj.create(cr, SUPERUSER_ID, {'name':infomation,'is_print':False})
                    elif pay_state == 'USERPAYING':
                        pass
                    else:
                        order_obj.signal_workflow(cr, SUPERUSER_ID, [int(pos_id)], 'cancel')
                else:
                    pass
            return 'SUCCESS'
Пример #26
0
    def alipay_form_generate_values(self,
                                    cr,
                                    uid,
                                    id,
                                    partner_values,
                                    tx_values,
                                    context=None):
        base_url = self.pool['ir.config_parameter'].get_param(
            cr, SUPERUSER_ID, 'web.base.url')
        acquirer = self.browse(cr, uid, id, context=context)

        alipay_tx_values = dict(tx_values)
        alipay_tx_values.update({
            'partner':
            acquirer.alipay_partner_account,
            'seller_email':
            acquirer.alipay_seller_email,
            'seller_id':
            acquirer.alipay_partner_account,
            '_input_charset':
            'utf-8',
            'out_trade_no':
            tx_values['reference'],
            'subject':
            tx_values['reference'],
            'body':
            '%s: %s' % (acquirer.company_id.name, tx_values['reference']),
            'payment_type':
            '1',
            'return_url':
            '%s' % urlparse.urljoin(base_url, AlipayController._return_url),
            'notify_url':
            '%s' % urlparse.urljoin(base_url, AlipayController._notify_url),
        })

        to_sign = {}
        to_sign.update({
            'partner':
            acquirer.alipay_partner_account,
            'seller_email':
            acquirer.alipay_seller_email,
            'seller_id':
            acquirer.alipay_partner_account,
            '_input_charset':
            'utf-8',
            'out_trade_no':
            tx_values['reference'],
            'subject':
            tx_values['reference'],
            'body':
            '%s: %s' % (acquirer.company_id.name, tx_values['reference']),
            'payment_type':
            '1',
            'return_url':
            '%s' % urlparse.urljoin(base_url, AlipayController._return_url),
            'notify_url':
            '%s' % urlparse.urljoin(base_url, AlipayController._notify_url),
        })

        payload_direct = {
            'service': 'create_direct_pay_by_user',
            'total_fee': tx_values['amount'],
        }

        payload_escow = {
            'service': 'create_partner_trade_by_buyer',
            'logistics_type': 'EXPRESS',
            'logistics_fee': 0,
            'logistics_payment': 'SELLER_PAY',
            'price': tx_values['amount'],
            'quantity': 1,
        }

        payload_dualfun = {
            'service': 'trade_create_by_buyer',
            'logistics_type': 'EXPRESS',
            'logistics_fee': 0,
            'logistics_payment': 'SELLER_PAY',
            'price': tx_values['amount'],
            'quantity': 1,
        }

        if acquirer.alipay_interface_type == 'create_direct_pay_by_user':
            to_sign.update(payload_direct)
            alipay_tx_values.update(payload_direct)

        if acquirer.alipay_interface_type == 'create_partner_trade_by_buyer':
            to_sign.update(payload_escow)
            alipay_tx_values.update(payload_direct)

        if acquirer.alipay_interface_type == 'trade_create_by_buyer':
            to_sign.update(payload_dualfun)
            alipay_tx_values.update(payload_direct)

        _, prestr = util.params_filter(to_sign)
        alipay_tx_values['sign'] = util.build_mysign(
            prestr, acquirer.alipay_partner_key, 'MD5')
        alipay_tx_values['sign_type'] = 'MD5'

        return partner_values, alipay_tx_values
Пример #27
0
    def alipay_form_generate_values(self, tx_values):
        base_url = self.env['ir.config_parameter'].sudo().get_param(
            'web.base.url')

        alipay_tx_values = dict(tx_values)
        alipay_tx_values.update({
            'partner':
            self.alipay_partner_account,
            'seller_email':
            self.alipay_seller_email,
            'seller_id':
            self.alipay_partner_account,
            '_input_charset':
            'UTF-8',
            'out_trade_no':
            tx_values['reference'],
            'subject':
            tx_values['reference'],
            'body':
            tx_values['reference'],
            'payment_type':
            '1',
            'return_url':
            '%s' % urlparse.urljoin(base_url, AlipayController._return_url),
            'notify_url':
            '%s' % urlparse.urljoin(base_url, AlipayController._notify_url),
        })

        to_sign = {}
        to_sign.update({
            'partner':
            self.alipay_partner_account,
            'seller_email':
            self.alipay_seller_email,
            'seller_id':
            self.alipay_partner_account,
            '_input_charset':
            'UTF-8',
            'out_trade_no':
            tx_values['reference'],
            'subject':
            tx_values['reference'],
            'body':
            tx_values['reference'],
            'payment_type':
            '1',
            'return_url':
            '%s' % urlparse.urljoin(base_url, AlipayController._return_url),
            'notify_url':
            '%s' % urlparse.urljoin(base_url, AlipayController._notify_url),
        })

        payload_direct = {
            'service': 'create_direct_pay_by_user',
            'total_fee': tx_values['amount'],
        }

        payload_escow = {
            'service': 'create_partner_trade_by_buyer',
            'logistics_type': 'EXPRESS',
            'logistics_fee': 0,
            'logistics_payment': 'SELLER_PAY',
            'price': tx_values['amount'],
            'quantity': 1,
        }

        if self.alipay_interface_type == 'create_direct_pay_by_user':
            to_sign.update(payload_direct)
            alipay_tx_values.update(payload_direct)

        if self.alipay_interface_type == 'create_partner_trade_by_buyer':
            to_sign.update(payload_escow)
            alipay_tx_values.update(payload_escow)

        _, prestr = util.params_filter(to_sign)
        alipay_tx_values['sign'] = util.build_mysign(prestr,
                                                     self.alipay_partner_key,
                                                     'MD5')
        alipay_tx_values['sign_type'] = 'MD5'

        _logger.info('----alipay tx_values is %s' % alipay_tx_values)

        return alipay_tx_values