Ejemplo n.º 1
0
    def query_single_trade(trade_no=None, transaction_id=None, sign_type='MD5', time_out=6):
        """
        单笔订单交易查询。已经拿到支付宝交易号时请使用支付宝交易号查 询,如未拿到则使用订单号查询
        :param trade_no: 订单号
        :param transaction_id: 支付宝交易号
        :param time_out:
        :return:
        """
        # 检测必填参数
        data = {
            'partner': AliPayConfig.PID,
            '_input_charset': AliPayConfig.INPUT_CHARSET,
            'service': 'single_trade_query',
        }
        if transaction_id:
            data['trade_no'] = transaction_id
        elif trade_no:
            data['out_trade_no'] = trade_no
        else:
            raise ValueError(u'trade_no、ali_trade_no必须有一个')

        data['sign'] = makeSign(data, sign_type)   # 签名
        data['sign_type'] = sign_type
        req_body = '&'.join('{}={}'.format(k,v) for k,v in data.items())

        h = httplib2.Http(".cache", timeout=time_out)
        resp, content = h.request(AliPayApi.__ALI_PAY_URL, "POST", body=req_body,
                                  headers={'content-type': 'application/x-www-form-urlencoded'})

        result = AliPayApi.make_dict_from_resp(resp, content)

        if not checkSign(result):
            raise AliPayException(AliPayException.ERROR_SIGN, u'query_single_trade返回值签名错误')

        return result
Ejemplo n.º 2
0
    def create_form_input_value(self, trade, pay_service_type, bank_code='', sign_type='md5'):
        # total_fee = commission_buy.quantity * quantity.price

        m = {}
        ali_service = {'direct_pay': 'create_direct_pay_by_user', 'bank_pay': 'create_direct_pay_by_user', 'mobile': 'mobile.securitypay.pay'}
        m['service'] =ali_service[pay_service_type]
        m['partner'] = AliPayConfig.PID
        m['_input_charset'] = AliPayConfig.INPUT_CHARSET
        m['notify_url'] = AliPayConfig.NOTIFY_URL
        if pay_service_type in ('bank_pay', 'direct_pay'):
            m['return_url'] = AliPayConfig.RETURN_URL
            m['error_notify_url'] = AliPayConfig.ERROR_NOTIFY_URL
            m['anti_phishing_key'] = AliPayApi.query_timestamp()     # 防钓鱼时间戳  通过时间戳查询接口获取的加密支付宝系统时间戳。
        m['out_trade_no'] = trade.out_trade_no   # 商户网站唯一订单号
        m['subject'] = trade.subject if trade.subject else u'蓝图商品'   # 商品名称 商品的标题/交易标题/订单标题/订单关键字等。最长为128个汉字。
        m['payment_type'] = trade.payment_type   # 支付类型 1(商品购买)。
        m['total_fee'] = trade.total_fee   # 该笔订单的资金总额,单位为RMB-Yuan。取值范围为[0.01,100000000.00],精确到小数点后两位。
        m['seller_id'] = trade.seller_id
        m['body'] = trade.body         # 商品描述  对一笔交易的具体描述信息。(1000)

        m['it_b_pay'] = trade.it_b_pay          # 超时时间  设置未付款交易的超时时间,一旦超时,该笔交易就会自动被关闭。
                                    #取值范围:1m~15d。m-分钟,h-小时,d-天,1c-当天(1c-当天的情况下,无论交易何时创建,都在0点关闭)。
                                    #该参数数值不接受小数点,如1.5h,可转换为90m。
        if pay_service_type == 'bank_pay':
            m['paymethod'] = 'bankPay'
            m['defaultbank'] = bank_code
        elif pay_service_type == 'direct_pay':
            m['qr_pay_mode'] = ''              #  扫码支付方式  2:订单码-跳转模式
        else:
            pass
        if pay_service_type == 'mobile':
            m_t = {k: u'"{}"'.format(v) for k,v in m.items()}
            # for k, v in m.items():
            #     if isinstance(v, unicode):
            #         m[k] = u'"{}"'.format(v)
            #     else:
            #         m[k] = u'"{}"'.format(v)
        else:
            m_t = m
        m['sign'], sign_string = makeSign(m_t, sign_type)
        m['sign_type'] = sign_type

        if pay_service_type in ('bank_pay', 'direct_pay'):
            action = '{gateway}_input_charset={charset}'.format(gateway=AliPayConfig.ALI_PAY_GATEWAY_NEW,
                                                                   charset=AliPayConfig.INPUT_CHARSET)
            return {'action': action, 'params': m}
        else:
            return {'action': '', 'params': m, 'sign_string': sign_string}
Ejemplo n.º 3
0
    def query_trade(gmt_start_time=None, gmt_end_time=None, page_size=5000, time_out=6, **kwargs):
        """
        账目明细分页查询
        :param gmt_start_time: 账务查询开始时间,格式为 yyyy-MM-dd HH:mm:ss.
            开始时间不能大于当前时间 和查询结束时间,并且与账 务查询结束时间的间隔不能 大于 1 天。 开始时间最早为当前时间前 3 年。
            当查询条件含有账务流水号、支付宝交易号、商户订单号、充值网银流水号中任意一个时,本参数可空,否则不可空。
            查询结果数据包含该时间点数据。
        :param gmt_end_time: 账务查询结束时间,格式为 yyyy-MM-dd HH:mm:ss.
            当查询条件含有账务流水 号、支付宝交易号、商户订 单号、充值网银流水号中任 意一个时,本参数可空,否则不可空。
            查询结果数据不包含该时间点数据。
        :prarm trans_code: 交易类型代码。多个交易类型代码之间以半角逗号“,”分隔。
                            3011 转账(含红包、集分宝等)
                            3012 收费
                            4003 充值
                            5004 提现
                            5103 退票
                            6001 在线支付
        :param page_size:每页记录数。 小于等于5000的正整数.
        :param time_out:
        :param kwargs: logon_id:交易收款账户.查询的收款账户,需要联系 支付宝绑定与商户 PID 的对 应关系。 若为空,表示查 PID 所属交易.
                        iw_account_log_id:账务流水号.
                        transaction_id:业务流水号.业务流水号字段对于交易数 据为交易号,对于转账、充值、提现等资金操作,此处为业务流水号。
                        merchant_out_order_no:商户订单号 .
                        deposit_bank_no:充值网银流水号.
                        查询优先级如下:账务流水号>业务流水号>商户订单号>充值网银流水号。当存在优先级高的参数时,优先级 低的参数无效。

        :return:
        """

        #正常返回的情况下,需要签名的参数是节点account_log_list、has_next_page、 page_no、page_size。
        # 参数 has_next_page、page_no、page_size 的值分 别是各个节点的值,参数 account_log_list 的值则是包含节点本身在内所有数据
        # accountLogList节点XML片段解析时需要expand empty element,如<memo/> 展开为<memo></memo>。
        # <response>
        #     <account_page_query_result>
        #         <account_log_list>
        #             <AccountQueryAccountLogVO>…..</AccountQueryAccountLogVO>
        #         </account_log_list>
        #         <has_next_page>F</has_next_page>
        #         <page_no>1</page_no>
        #         <page_size>5000</page_size>
        #     </account_page_query_result>
        # </response>
        # account_log_list :<account_log_list><Account QueryAccountLogVO>...</A ccountQueryAccountLogVO ></account_log_list>
        # has_next_page: F
        # page_no: 1
        # page_size: 5000

        data = {
            'partner': AliPayConfig.PID,
            '_input_charset': AliPayConfig.INPUT_CHARSET,
            'service': 'account.page.query',
        }
        k = {'logon_id', 'iw_account_log_id', 'transaction_id', 'merchant_out_order_no', 'deposit_bank_no',}
        if not k.intersection(kwargs.keys()) and (not gmt_end_time or not gmt_start_time):
            raise ValueError(u'缺少必要的查询参数')

        for ele in k.intersection(kwargs.keys()):
            if ele == 'transaction_id':
                data['trade_no'] = kwargs[ele]
            else:
                data[ele] = kwargs[ele]

        if gmt_start_time and gmt_end_time:
            data['gmt_start_time'] = gmt_start_time
            data['gmt_end_time'] = gmt_end_time

        page_no = 1
        while True:
            data['page_no'] = page_no
            data['sign'] = makeSign(data)   # 签名
            data['sign_type'] = AliPayConfig.SIGN_TYPE
            req_body = '&'.join('{}={}'.format(k,v) for k,v in data.items())

            h = httplib2.Http(".cache", timeout=time_out)
            resp, content = h.request(AliPayApi.__ALI_PAY_URL, "POST", body=req_body,
                                      headers={'content-type': 'application/x-www-form-urlencoded'})

            # 验证签名
            sign_m = {}
            start = content.find('<account_log_list>')
            end = content.find('</account_log_list>')
            if start!= -1 and end != -1:
                end += len('</account_log_list>')
                sign_m['account_log_list'] = content[start: end]

            result = AliPayApi.make_dict_from_resp(resp, content, xml_handler=QueryOrderXMLHandler)
            for ele in ['has_next_page', 'page_no', 'page_size', 'sign', 'sign_type']:
                sign_m[ele] = result.get(ele, '')

            if not checkSign(sign_m):
                raise AliPayException(AliPayException.ERROR_SIGN, u'query_single_trade返回值签名错误')

            yield result.get('bills', [])

            if result['has_next_page'] != 'T':
                break

            page_no = int(result['page_no'])