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()
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="渲染失败")
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
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()
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