示例#1
0
    def get(self):
        """
        查询可用的通道
        :return:
        """
        if not request.args:
            return ResponseSuccess(
                message="参数规则:?tx_id=xxxx,交易ID,必填").as_response()

        try:
            tx_id = request.args['tx_id']
        except:
            return ResponseSuccess(message="必填交易ID").as_response()

        order = OrderDeposit.query_by_tx_id(tx_id)
        if not order:
            return ResponseSuccess(message="订单不存在,请确认交易号是否正确: %s" %
                                   tx_id).as_response()

        order_detail = OrderDetailDeposit.query_by_tx_id(tx_id)

        channel = ChannelConfig.query_by_channel_id(order.channel_id)
        fee_config = MerchantFeeConfig.query_by_config_id(order.mch_fee_id)

        order_info = dict(
            order_id=order.order_id,
            create_time=order.str_create_time,
            uid=order.uid,
            sys_tx_id=order.sys_tx_id,
            mch_tx_id=order.mch_tx_id,
            channel_tx_id=order.channel_tx_id,
            amount=str(order.amount),
            tx_amount=str(order.tx_amount),
            source=order.source.desc,
            pay_method=order.pay_method.desc,
            state=order.state.desc,
            settle=order.settle.desc,
            deliver=order.deliver.desc,
            channel_id=order.channel_id,
            channel=channel.short_description,
            mch_fee_id=order.mch_fee_id,
            mch_fee=fee_config.short_description,
            in_type=order_detail.in_type.desc,
            offer=str(order_detail.offer),
            fee=str(order_detail.fee),
            cost=str(order_detail.cost),
            profit=str(order_detail.profit),
            ip=order_detail.ip,
        )

        return ResponseSuccess(bs_data=order_info).as_response()
示例#2
0
    def render_page(cls):
        """
        渲染页面
        :return:
        """
        print(request.args)

        try:
            order_id = request.args['order_id']
        except:
            return TemplateKit.render_template('deposit_simple.html', body="参数错误")

        order = DepositTransactionCtl.get_order_by_order_id(order_id)
        if not order:
            return TemplateKit.render_template('deposit_simple.html', body="订单不存在")

        cache = DepositPageRenderCache(order.order_id)
        cache_data = cache.get_content()
        print("&&&&&&&&&&&&&&", cache_data)
        if not cache_data:
            return TemplateKit.render_template('deposit_simple.html', body="订单已经过期")

        is_h5 = False
        prompt_msgs = []
        channel_enum = cache_data.get('channel_enum')
        if channel_enum:
            channel_enum = ChannelConfigEnum(int(channel_enum))
            prompt_msgs = channel_enum.get_prompt_info_detail()
            is_h5 = channel_enum.conf.payment_method.is_h5

        if cache_data['render_type'] == SdkRenderType.QR_CODE:
            merchant_config = MerchantFeeConfig.query_by_config_id(order.mch_fee_id)
            b64_img = QRCodeKit.gen_base64_qr_code_png(cache_data['render_content'])
            return TemplateKit.render_template(
                'deposit_qrcode.html',
                b64_img=b64_img,
                payment_type=merchant_config.payment_method.desc,
                sys_tx_id=order.sys_tx_id,
                amount=str(order.amount),
                valid_time=cache.EXPIRATION,
                payment_url=cache_data['render_content'] if is_h5 else None,
                prompt_msgs=prompt_msgs,
            )

        if cache_data['render_type'] == SdkRenderType.FORM:
            return TemplateKit.render_template('deposit_base.html', body=cache_data['render_content'])

        if cache_data['render_type'] == SdkRenderType.HTML:
            return TemplateKit.render_template_string(cache_data['render_content'])

        if cache_data['render_type'] == SdkRenderType.TRANSFER:
            data = json.loads(cache_data['render_content'], encoding='utf8')
            return TemplateKit.render_template(
                'bank.html',
                CardName=data['CardName'],
                CardNumber=data['CardNumber'],
                BankName=data['BankName'],
                amount=data['amount'],
                tx_id=data['tx_id'],
                start_time=data['start_time']
            )

        current_app.logger.error('failed to render page, order_id: %s, cache_data: %s', order.order_id, cache_data)

        return TemplateKit.render_template('deposit_simple.html', body="渲染失败")
示例#3
0
    def order_fail(cls, order):
        """
        订单失败处理
        :return:
        """
        params = copy.deepcopy(locals())
        params.pop('cls')
        params.pop('order')
        params['tx_id'] = order.sys_tx_id

        rst = dict(
            code=0,
            msg='',
        )

        # 手续费存在订单详情里面
        order_detail = OrderDetailWithdraw.query_by_order_id(
            order.merchant, order.order_id, order.create_time)
        merchant_config = MerchantFeeConfig.query_by_config_id(
            order.mch_fee_id)

        try:
            # 创建提现订单/扣商户余额/扣用户余额,在同一个事务里面
            with db.auto_commit():
                order, ref_id = OrderUpdateCtl.update_order_event(
                    order.order_id,
                    uid=order.uid,
                    merchant=order.merchant,
                    state=OrderStateEnum.FAIL,
                    commit=False,
                )
                if not order:
                    raise RuntimeError('提现订单修改失败状态失败, params: %s' % params)

                # 给商户退回提现订单的发起金额
                flag, msg = MerchantBalanceEvent.update_balance(
                    merchant=order.merchant,
                    ref_id=ref_id,
                    source=order.source,
                    order_type=PayTypeEnum.REFUND,
                    bl_type=BalanceTypeEnum.AVAILABLE,
                    # 订单发起金额
                    value=order.amount,
                    ad_type=BalanceAdjustTypeEnum.PLUS,
                    tx_id=order.sys_tx_id,
                    commit=False,
                )
                # print('update_balance', flag, msg)
                if flag < 0:
                    raise RuntimeError(msg + ", params: %s" % params)

                if merchant_config.cost_type == CostTypeEnum.MERCHANT:
                    # 给商户退回提手续费
                    flag, msg = MerchantBalanceEvent.update_balance(
                        merchant=order.merchant,
                        ref_id=OrderUtils.gen_unique_ref_id(),
                        tx_id=order.sys_tx_id,
                        source=order.source,
                        order_type=PayTypeEnum.FEE,
                        bl_type=BalanceTypeEnum.AVAILABLE,
                        # 收取商户的手续费
                        value=order_detail.fee,
                        ad_type=BalanceAdjustTypeEnum.PLUS,
                        commit=False,
                    )
                    # print('update_balance', flag, msg)
                    if flag < 0:
                        raise RuntimeError(msg + ", params: %s" % params)

                refund_fee = order.amount
                if merchant_config.cost_type == CostTypeEnum.USER:
                    # 给用户退回手续费
                    refund_fee += order_detail.fee

                # 给用户退回发起金额
                flag, msg = UserBalanceEvent.update_user_balance(
                    uid=order.uid,
                    merchant=order.merchant,
                    ref_id=ref_id,
                    source=order.source,
                    order_type=PayTypeEnum.REFUND,
                    bl_type=BalanceTypeEnum.AVAILABLE,
                    # 订单发起金额
                    value=refund_fee,
                    ad_type=BalanceAdjustTypeEnum.PLUS,
                    tx_id=order.sys_tx_id,
                    commit=False,
                )
                # print('update_user_balance', flag, msg)
                if flag < 0:
                    raise RuntimeError(msg + ", params: %s" % params)

        except APIException as e:
            current_app.logger.error(traceback.format_exc())
            return False

        cls.do_notify(order=order)

        return True
示例#4
0
    def manually_withdraw_failed(cls, admin_user, merchant, order_id):
        """
        手动更新提款状态为失败
        退款/审核拒绝
                流程:
            1. 获取创建订单时 扣除 用户及商户的费用
                获取订单 withdrawOrderDetail 数据, 获取 手续费 提现金额
            2. 给用户和商户新增费用
                更新 UserBalance 表
                更新 MerchantBalance表
            3. 修改订单状态
                更新 OrderUpdateCtl
        :param admin_user:
        :param merchant:
        :param order_id:
        :return:
        """
        # 查询该笔订单是否存在
        withdraw_entry = OrderWithdraw.query_by_order_id(merchant=merchant,
                                                         order_id=order_id)
        # 判断是否存在
        if not withdraw_entry:
            return OrderInfoMissingError()

        # 判断订单状态是否为 已认领 或 提现成功
        if withdraw_entry.state not in [
                OrderStateEnum.ALLOC, OrderStateEnum.SUCCESS
        ]:
            return BankOrderStateError()

        detail = OrderDetailWithdraw.query_by_order_id(
            order_id=withdraw_entry.order_id,
            merchant=merchant,
            create_time=withdraw_entry.create_time)
        if not detail:
            return NosuchOrderDetailDataError()

        # 提现订单 手续费 提现订单费用
        fee = detail.fee
        amount = detail.amount

        comment = "出款失败" if withdraw_entry.state == OrderStateEnum.SUCCESS else "系统拒绝"
        order_type = PayTypeEnum.REFUND if withdraw_entry.state == OrderStateEnum.SUCCESS else PayTypeEnum.MANUALLY

        merchant_config = MerchantFeeConfig.query_by_config_id(
            withdraw_entry.mch_fee_id)

        # 更新订单状态
        try:
            with db.auto_commit():

                order, ref_id = OrderUpdateCtl.update_order_event(
                    withdraw_entry.order_id,
                    uid=int(withdraw_entry.uid),
                    merchant=merchant,
                    state=OrderStateEnum.FAIL,
                    tx_amount=withdraw_entry.amount,
                    deliver_type=DeliverTypeEnum.MANUALLY,
                    op_account=admin_user.account,
                    commit=False)

                if not order:
                    msg = WithdrawOrderStateChangeError.message
                    current_app.logger.error(msg)
                    raise WithdrawOrderStateChangeError()

                # 加提现金额
                flag, msg = MerchantBalanceEvent.update_balance(
                    merchant=merchant,
                    ref_id=ref_id,
                    order_type=order_type,
                    bl_type=BalanceTypeEnum.AVAILABLE,
                    value=amount,
                    ad_type=BalanceAdjustTypeEnum.PLUS,
                    tx_id=order.sys_tx_id,
                    source=OrderSourceEnum.MANUALLY,
                    comment=comment,
                    commit=False,
                )
                if flag < 0:
                    msg = '%s' % ("提现退回增加商户余额失败, %s" % msg)
                    current_app.logger.error(msg)
                    raise DepositCallbackUserBalanceError()

                if merchant_config.cost_type == CostTypeEnum.MERCHANT:
                    # 给商户加手续费
                    flag, msg = MerchantBalanceEvent.update_balance(
                        merchant=merchant,
                        ref_id=OrderUtils.gen_unique_ref_id(),
                        order_type=PayTypeEnum.FEE,
                        bl_type=BalanceTypeEnum.AVAILABLE,
                        value=fee,
                        ad_type=BalanceAdjustTypeEnum.PLUS,
                        tx_id=order.sys_tx_id,
                        commit=False,
                        comment=comment,
                        source=OrderSourceEnum.MANUALLY)
                    if flag < 0:
                        msg = '%s' % ("提现退款增加商户手续费失败, %s" % msg)
                        current_app.logger.error(msg)
                        raise DepositCallbackUserBalanceError()

                refund_fee = amount
                if merchant_config.cost_type == CostTypeEnum.USER:
                    # 给用户退回手续费
                    refund_fee += fee

                # 增加用户余额
                flag, msg = UserBalanceEvent.update_user_balance(
                    uid=order.uid,
                    merchant=merchant,
                    ref_id=ref_id,
                    order_type=order_type,
                    bl_type=BalanceTypeEnum.AVAILABLE,
                    value=refund_fee,
                    ad_type=BalanceAdjustTypeEnum.PLUS,
                    tx_id=order.sys_tx_id,
                    commit=False,
                    comment=comment,
                    source=OrderSourceEnum.MANUALLY)
                if flag < 0:
                    msg = '%s' % ("提现退款增加用户余额失败, %s" % msg)
                    current_app.logger.error(msg)
                    raise DepositCallbackUserBalanceError()

        except APIException as e:
            current_app.logger.error(traceback.format_exc())
            return e

        cls.do_notify(
            order=order,
            op_account=admin_user.account,
            comment=comment,
        )

        return ResponseSuccess()
示例#5
0
    def success_order_process(cls,
                              order,
                              tx_amount,
                              channel_tx_id=None,
                              comment: str = '',
                              op_account=None,
                              commit=True):
        """
        处理充值成功的订单
        :param order:
        :param tx_amount: 实际支付金额
        :param channel_tx_id: 通道订单号
        :param comment: 备注
        :param op_account: 备注
        :param commit: 是否立即提交事务
        :return:
        """
        params = copy.deepcopy(locals())
        params.pop('cls')
        params.pop('order')
        params['tx_id'] = order.sys_tx_id

        rst = dict(
            code=0,
            msg='',
        )

        # 计算一笔订单的各种费用
        channel_config = ChannelConfig.query_by_channel_id(order.channel_id)
        merchant_config = MerchantFeeConfig.query_by_config_id(
            order.mch_fee_id)
        order_fee = OrderFeeHelper.calc_order_fee(order, tx_amount,
                                                  channel_config,
                                                  merchant_config)

        try:
            with db.auto_commit(commit):
                order, ref_id = OrderUpdateCtl.update_order_event(
                    order.order_id,
                    uid=order.uid,
                    merchant=order.merchant,
                    state=OrderStateEnum.SUCCESS,
                    channel_tx_id=channel_tx_id,
                    tx_amount=tx_amount,
                    offer=order_fee['offer'],  # 优惠金额
                    fee=order_fee['merchant_fee'],  # 手续费
                    cost=order_fee['channel_cost'],  # 成本金额
                    profit=order_fee['profit'],  # 利润(收入)金额
                    commit=False,
                    pay_method=channel_config.channel_enum.
                    conf['payment_method'],
                    comment=comment,
                    op_account=op_account,
                )
                if not order:
                    msg = '订单更新失败, params: %s' % params
                    raise RuntimeError(msg)

                # 给用户充值
                code, msg = UserBalanceEvent.update_user_balance(
                    uid=order.uid,
                    merchant=order.merchant,
                    ref_id=ref_id,
                    source=order.source,
                    order_type=order.order_type,
                    bl_type=BalanceTypeEnum.AVAILABLE,
                    value=order.amount,
                    ad_type=BalanceAdjustTypeEnum.PLUS,
                    comment=comment,
                    tx_id=order.sys_tx_id,
                    commit=False,
                )
                if code != 0:
                    raise RuntimeError(msg)

                # 根据结算类型获取商户余额变更类型
                balance_type = SettleHelper.get_balance_type_by_settle(
                    channel_config.settlement_type)

                # 更新商户余额,加用户充值金额
                code, msg = MerchantBalanceEvent.update_balance(
                    merchant=order.merchant,
                    ref_id=ref_id,
                    source=order.source,
                    order_type=order.order_type,
                    bl_type=balance_type,
                    value=order.amount,
                    ad_type=BalanceAdjustTypeEnum.PLUS,
                    tx_id=order.sys_tx_id,
                    comment=comment,
                    commit=False,
                )
                if code != 0:
                    raise RuntimeError(msg)

                # 更新商户余额,扣手续费
                ref_id = OrderUtils.gen_unique_ref_id()
                code, msg = MerchantBalanceEvent.update_balance(
                    merchant=order.merchant,
                    ref_id=ref_id,
                    source=order.source,
                    order_type=PayTypeEnum.FEE,
                    bl_type=balance_type,
                    value=order_fee['merchant_fee'],
                    ad_type=BalanceAdjustTypeEnum.MINUS,
                    tx_id=order.sys_tx_id,
                    comment=comment,
                    commit=False,
                )
                if code != 0:
                    raise RuntimeError(msg)

        except RuntimeError as e:
            current_app.logger.error('An error occurred.', exc_info=True)
            return False

        # 累计当天通道充值额度
        ChannelLimitCacheCtl.add_day_amount(channel_config.channel_enum,
                                            order.amount)

        cls.do_notify(order)

        return True