def post(self): """ 给商户发通知 :return: """ form, error = OrderStateNotifyFrom().request_validate() if error: return error.as_response() order_id = form.order_id.data order_type = form.order_type.data if order_type == PayTypeEnum.WITHDRAW: order = WithdrawTransactionCtl.get_order_by_order_id(order_id) rst = WithdrawTransactionCtl.do_notify( order=order, op_account=g.user.account, comment="后台人工状态通知", ) else: order = DepositTransactionCtl.get_order_by_order_id(order_id) rst = DepositTransactionCtl.do_notify( order=order, op_account=g.user.account, comment="后台人工状态通知", ) return ResponseSuccess(message=rst['msg'])
def post(self): client_ip = IpKit.get_remote_ip() if not EnvironEnum.is_local_evn(current_app.config['FLASK_ENV']): # 无论如何都记录一条log current_app.logger.info('Gpay deposit callback, ip: %s, data: %s', IpKit.get_remote_ip(), request.form) sys_tx_id = request.form['company_order_num'] tx_amount = request.form['amount'] pw_trade_id = request.form['mownecum_order_num'] if not CallbackGpay.check_ip(client_ip): current_app.logger.fatal( 'ip not allow, client_ip: %s, data: %s, body: %s', client_ip, request.args, request.form) return BaseResponse( '{"company_order_num":"%s", "mownecum_order_num":"%s", "status":"1", "error_msg":"%s"}' % (sys_tx_id, pw_trade_id, "订单状态已更新")) order = DepositTransactionCtl.get_order(sys_tx_id) if not order: current_app.logger.error('gpay: no found order, order id: %s' % (sys_tx_id)) return BaseResponse( '{"company_order_num":"%s", "mownecum_order_num":"%s", "status":"0", "error_msg":"%s"}' % (sys_tx_id, pw_trade_id, "查不到该订单")) if order.state.name != OrderStateEnum.INIT.name: return BaseResponse( '{"company_order_num":"%s", "mownecum_order_num":"%s", "status":"1", "error_msg":"%s"}' % (sys_tx_id, pw_trade_id, "订单状态已更新")) sorted_fields = [ "pay_time", "bank_id", "amount", "company_order_num", "mownecum_order_num", "pay_card_num", "pay_card_name", "channel", "area", "fee", "transaction_charge", "deposit_mode" ] request_str = "".join([request.form.get(k, "") for k in sorted_fields]) sign = request.form['key'] flag = CallbackGpay.check_sign(sign, request_str) if not flag: current_app.logger.fatal( 'invalid sign, client_ip: %s, data: %s, body: %s', client_ip, request.args, request_str) return BaseResponse( '{"company_order_num":"%s", "mownecum_order_num":"%s", "status":"0", "error_msg":"%s"}' % (sys_tx_id, pw_trade_id, "更新订单状态失败")) if not DepositTransactionCtl.success_order_process( order, decimal.Decimal(tx_amount), pw_trade_id): return BaseResponse( '{"company_order_num":"%s", "mownecum_order_num":"%s", "status":"0", "error_msg":"%s"}' % (sys_tx_id, pw_trade_id, "更新订单状态失败")) return BaseResponse( '{"company_order_num":"%s", "mownecum_order_num":"%s", "status":"1", "error_msg":""}' % (sys_tx_id, pw_trade_id))
def post(self): """ 极付,充值回调,极付的回调只会只订单成功后才通知,如果处理失败,通道侧会每隔十秒重新请求一次,共请求十次 :return: """ if not EnvironEnum.is_local_evn(current_app.config['FLASK_ENV']): # 无论如何都记录一条log current_app.logger.info('jifu deposit callback, ip: %s, data: %s', IpKit.get_remote_ip(), request.form) form, error = JifuCallbackForm().request_validate() if error: current_app.logger.fatal('msg: %s, data: %s', error.message, request.form) return BaseResponse(error.message) # 交易订单id sys_tx_id = form.remark.data # 通道订单id channel_tx_id = form.id.data # 实际支付金额 tx_amount = Decimal(form.money.data) # 客户端IP client_ip = form.client_ip.data # IP白名单校验 checker = DepositCallbackJifu(ChannelConfigEnum.CHANNEL_7001) if not checker.check_ip(client_ip): current_app.logger.fatal('ip not allow, client_ip: %s, data: %s', client_ip, form.form_data) return BaseResponse('ip not allow') # 签名验证 if not checker.check_sign(form.get_sign_fields(), form.get_raw_sign()): current_app.logger.fatal('invalid sign, client_ip: %s, data: %s', client_ip, form.form_data) return BaseResponse('invalid sign') order = DepositTransactionCtl.get_order(sys_tx_id) if not order: return BaseResponse('no order found for sys_tx_id: %s', sys_tx_id) if order.channel_tx_id != channel_tx_id: # 根据API文档的建议,之前已经将code放入数据库的channel_tx_id中,等回调时拿来比对 current_app.logger.fatal( 'invalid channel_tx_id, client_ip: %s, channel_tx_id: %s, data: %s', client_ip, order.channel_tx_id, form.form_data) return BaseResponse('invalid channel_tx_id') # 支付成功 if not DepositTransactionCtl.success_order_process( order, tx_amount, channel_tx_id): return BaseResponse('order process failed, sys_tx_id: %s', sys_tx_id) # 成功返回小写字符串success return BaseResponse('success')
def get(self): """ 立马付,充值回调 :return: """ if not EnvironEnum.is_local_evn(current_app.config['FLASK_ENV']): # 无论如何都记录一条log current_app.logger.info( 'ponypay deposit callback, ip: %s, data: %s', IpKit.get_remote_ip(), request.args) form, error = PonyPayForm().request_validate() if error: current_app.logger.fatal('msg: %s, data: %s', error.message, request.args) return BaseResponse(error.message) # 交易订单id tx_id = form.orderid.data # 充值通道 订单id channel_tx_id = form.porder.data # 实际支付金额 tx_amount = Decimal(form.money.data) # 订单状态: 成功/失败 status = form.status.data # 客户端IP client_ip = form.client_ip.data # IP白名单校验 if not CallbackPonypay.check_ip(client_ip): current_app.logger.fatal('ip not allow, client_ip: %s, data: %s', client_ip, request.args) return BaseResponse('FAIlURE') # 签名验证 if not CallbackPonypay.check_sign(form): current_app.logger.fatal('invalid sign, client_ip: %s, data: %s', client_ip, request.args) return BaseResponse('FAIlURE') order = DepositTransactionCtl.get_order(tx_id) if not order: return BaseResponse('FAIlURE') if status == '1': # 支付成功 if not DepositTransactionCtl.success_order_process( order, tx_amount, channel_tx_id): return BaseResponse('FAIlURE') else: # 支付失败 if not DepositTransactionCtl.failed_order_process( order, tx_amount, channel_tx_id): return BaseResponse('FAIlURE') return BaseResponse('SUCCESS')
def post(self): client_ip = IpKit.get_remote_ip() third_config = ThirdPayConfig.EpayTong_PAY_DEPOSIT.value if not EnvironEnum.is_local_evn(current_app.config['FLASK_ENV']): # 无论如何都记录一条log current_app.logger.info( 'epaytong deposit callback, ip: %s, data: %s', IpKit.get_remote_ip(), request.form) if not CallbackEpayTong.check_ip(client_ip): current_app.logger.fatal( 'ip not allow, client_ip: %s, data: %s, body: %s', client_ip, request.args, request.form) return BaseResponse('FAIlURE') sys_tx_id = request.form['order_no'] order = DepositTransactionCtl.get_order(sys_tx_id) if not order: current_app.logger.error('epaytong: no found order, order id: %s' % (sys_tx_id)) return BaseResponse('FAILURE') no_need_field = ['signType', 'sign'] sorted_fields = sorted([k for k in request.form.keys()]) request_str = "&".join([ "{}={}".format(k, request.form[k]) for k in sorted_fields if (request.form[k] == 0 or request.form[k] == "0" or request.form[k]) and k not in no_need_field ]) sign = request.form['sign'] sign_str = request_str + third_config['secret_key'] flag = CallbackEpayTong.check_sign(sign, sign_str) if not flag: current_app.logger.fatal( 'invalid sign, client_ip: %s, data: %s, body: %s', client_ip, request.args, request_str) return ResponseSuccess(code=500, message='签名错误').as_response() tx_amount = request.form['price'] pwTradeId = request.form['notify_id'] status = request.form['is_success'] trade = request.form['trade_status'] if status == 'T' and trade == "TRADE_FINISHED": if not DepositTransactionCtl.success_order_process( order, decimal.Decimal(tx_amount), pwTradeId): return BaseResponse('FAIlURE') else: if not DepositTransactionCtl.failed_order_process( order, decimal.Decimal(tx_amount), pwTradeId): return BaseResponse('FAIlURE') return BaseResponse('success')
def post(self): if not EnvironEnum.is_local_evn(current_app.config['FLASK_ENV']): # 无论如何都记录一条log current_app.logger.info( 'one pay deposit callback, ip: %s, data: %s, headers: %s, json data:%s', IpKit.get_remote_ip(), request.form, request.headers, request.json) client_ip = IpKit.get_remote_ip() if not CallbackOnePay.check_ip(client_ip): current_app.logger.fatal('ip not allow, client_ip: %s, data: %s', client_ip, request.args) return BaseResponse('FAIlURE') sys_tx_id = request.form['merchantTradeId'] order = DepositTransactionCtl.get_order(sys_tx_id) if not order: current_app.logger.error('OnePay: no found order, order id: %s' % (sys_tx_id)) return BaseResponse('FAILURE') no_need_field = ['signType', 'sign'] sorted_fields = sorted([k for k in request.form.keys()]) request_str = "&".join([ "{}={}".format(k, request.form[k]) for k in sorted_fields if k not in no_need_field and request.form[k] ]) sign = request.form['sign'] flag = CallbackOnePay.check_sign(sign, request_str) if not flag: current_app.logger.fatal( 'invalid sign, client_ip: %s, data: %s, body: %s', client_ip, request.args, request_str) return ResponseSuccess(code=500, message='签名错误').as_response() tx_amount = request.form['amountFee'] pwTradeId = request.form['pwTradeId'] status = request.form['tradeStatus'] if status == 'PS_PAYMENT_FAIL': if not DepositTransactionCtl.failed_order_process( order, decimal.Decimal(tx_amount), pwTradeId): return BaseResponse('FAIlURE') elif status == 'PS_PAYMENT_SUCCESS': if not DepositTransactionCtl.success_order_process( order, decimal.Decimal(tx_amount), pwTradeId): return BaseResponse('FAIlURE') return BaseResponse('SUCCESS')
def post(self): """ best pay 交易通知 :return: """ form, error = BestPayNotifyForm().request_validate() if error: return error.as_response() # 判断订单号是否存在 不存在 或状态不为Init 则返回无效的订单号 order_id = form.tx_id.data order = DepositTransactionCtl.get_order_by_order_id(order_id=order_id) if not order or order.state.name != OrderStateEnum.INIT.name: return InvalidOrderIdError().as_response() # 收款银行卡号 # 发起人姓名 # 充值金额 # 备注 # 充值时间 # 状态 if not OrderTransferLog.insert_transfer_log( order_id=order_id, amount='{:.2f}'.format(float(form.amount.data)), in_account=form.card_number.data, out_name=form.user_name.data): return InvalidOrderIdError(message="新增转账信息有误").as_response() return ResponseSuccess().as_response()
def get(self): """ Tong yi Pay,充值回调 :return: """ if not EnvironEnum.is_local_evn(current_app.config['FLASK_ENV']): # 无论如何都记录一条log current_app.logger.info('tong yi deposit callback, ip: %s, data: %s', IpKit.get_remote_ip(), request.args) client_ip = IpKit.get_remote_ip() if not CallbackTongYiPay.check_ip(client_ip): current_app.logger.error('ip not allow, client_ip: %s, data: %s, body: %s', client_ip, request.args, request.json) sign = request.args.get("sign") keys = sorted(list(request.args.keys())) sign_str = "&".join(["{}={}".format(k, request.args.get(k)) for k in keys if k not in ['sign'] and request.args.get(k, False)]) flag = CallbackTongYiPay.check_sign(sign, sign_str) if not flag: current_app.logger.error('invalid sign, client_ip: %s, data: %s, body: %s', client_ip, request.args, sign_str) return BaseResponse('error') order_id = request.args.get('order') order = DepositTransactionCtl.get_order(order_id) if not order: current_app.logger.error('invalid order: order_id: %s', order_id) return BaseResponse('FAIlURE') if order.state.name == OrderStateEnum.SUCCESS.name: return BaseResponse('SUCCESS') channel_tx_id = request.args.get('orderId', False) state = request.args.get('status', 0) tx_amount = request.args.get('money', 0) if str(state) == "2" or str(state) == "3": if not DepositTransactionCtl.success_order_process(order, Decimal(tx_amount), channel_tx_id): return BaseResponse('FAIlURE') return BaseResponse('SUCCESS')
def create_one_deposit_order(cls): user = InitData.get_user() channel_config = InitData.get_deposit_channel() amount = Decimal("300") order, error = DepositTransactionCtl.order_create( user=user, amount=amount, channel_enum=channel_config.channel_enum, source=OrderSourceEnum.TESTING, in_type=InterfaceTypeEnum.CASHIER_H5, client_ip='127.0.0.1', ) assert order is not None assert error is None return DepositTransactionCtl.get_order(order.sys_tx_id)
def get(self): """ 手动通知商户 :return: """ if not request.args: return ResponseSuccess(message="参数规则:?tx_id=xx").as_response() try: tx_id = request.args['tx_id'] except: return ResponseSuccess(message="请输入 tx_id=,系统交易ID").as_response() order = DepositTransactionCtl.get_order(tx_id) rst = DepositTransactionCtl.do_notify( order=order, op_account='somebody', comment="后台人工状态通知", ) return ResponseSuccess(message=rst['msg']).as_response()
def post(self): if not EnvironEnum.is_local_evn(current_app.config['FLASK_ENV']): # 无论如何都记录一条log current_app.logger.info('yinsao withdraw callback, ip: %s, data: %s, headers: %s', IpKit.get_remote_ip(), request.form, request.headers) data = {k: v for k, v in request.form.items()} client_ip = IpKit.get_remote_ip() if not CallbackYinSao.check_ip(client_ip): current_app.logger.fatal('ip not allow, client_ip: %s, data: %s', client_ip, request.args) return BaseResponse('FAIlURE') tx_amount = Decimal(data['transAmt']) / Decimal('100') sys_tx_id = data['orderNo'] signature = data.pop('signature') key_list = sorted(list(data.keys())) request_str = "&".join(["{}={}".format(field, data[field]) for field in key_list if field != "risk"]) sign = CallbackYinSao.generate_sign(request_str) flag = CallbackYinSao.check_sign(signature, sign) if not flag: current_app.logger.error('invalid sign, data:%s, sign:%s, signature:%s', data, sign, signature) return BaseResponse('FAIlURE') order = DepositTransactionCtl.get_order(sys_tx_id) if not order: current_app.logger.error('YinSao: no found order, order id: %s' % (sys_tx_id)) return BaseResponse('FAILURE') if str(data['respCode']) == '0000': # 支付成功 if not DepositTransactionCtl.success_order_process(order, tx_amount, ''): return BaseResponse('FAILURE') else: # 支付失败 if not DepositTransactionCtl.failed_order_process(order, tx_amount, ''): return BaseResponse('FAIlURE') return BaseResponse('SUCCESS')
def post(self): """ 给商户发通知 :return: """ form, error = OrderStateNotifyFrom().request_validate() if error: return error.as_response() order_id = str(form.order_id.data) if form.type.data == PayTypeEnum.WITHDRAW: order = WithdrawTransactionCtl.get_order(order_id) rst = WithdrawTransactionCtl.do_notify(order=order, op_account=g.user.account, comment="商户后台手动通知") elif form.type.data == PayTypeEnum.DEPOSIT: order = DepositTransactionCtl.get_order(order_id) rst = DepositTransactionCtl.do_notify( order=order, op_account=g.user.account, comment="商户后台手动通知", ) return ResponseSuccess(message=rst['msg'])
def post(self): client_ip = IpKit.get_remote_ip() current_app.logger.info('vpay deposit callback, ip: %s, data: %s', IpKit.get_remote_ip(), request.json) if not CallbackVpay.check_ip(client_ip): current_app.logger.fatal('ip not allow, client_ip: %s, data: %s, body: %s', client_ip, request.args, request.form) return BaseResponse('{"code": "00"}') resp_body = request.json sign = resp_body.pop("sign") sorted_params = sorted(list(resp_body.keys())) ac_amount = "{:.2f}".format(resp_body['actual_amount']) tx_amount = "{:.2f}".format(resp_body['original_amount']) resp_body['actual_amount'] = ac_amount resp_body['original_amount'] = tx_amount sign_str = "&".join(["{}={}".format(k, resp_body[k]) for k in sorted_params if resp_body.get(k, False)]) flag = CallbackVpay.check_sign(sign, sign_str) if not flag: current_app.logger.fatal('invalid sign, data: %s, sign: %s, data: %s', client_ip, sign, sign_str) return BaseResponse('{"code": "01"}') tx_id = resp_body['company_order_id'] order = DepositTransactionCtl.get_order(tx_id) if not order: return BaseResponse('{"code": "00"}') tx_amount = request.json['actual_amount'] channel_tx_id = request.json['order_no'] if not DepositTransactionCtl.success_order_process(order, decimal.Decimal(tx_amount), channel_tx_id): return BaseResponse('{"code": "00"}') return BaseResponse('{"code": "200"}')
def post(self): """ 人工完成充值订单 :return: """ form, error = OrderIdCommentForm().request_validate() if error: return error.as_response() order_id = form.order_id.data g_order_id = GlobalOrderId.query_global_id(order_id) order = OrderDeposit.query_by_order_id(merchant=g_order_id.merchant, order_id=order_id) if DepositTransactionCtl.success_order_process( order, order.amount, comment=form.comment.data, op_account=g.user.account): return ResponseSuccess(message="处理成功") else: return ResponseSuccess(message="处理失败")
def do_deposit_request( cls, user, channel_enum, amount, source: OrderSourceEnum, in_type: InterfaceTypeEnum, client_ip, user_agent, notify_url=None, mch_tx_id=None, result_url=None, extra=None, ): """ 创建充值订单,发起充值请求 :return: """ rst = dict( order=None, data=None, error=None ) # 创建订单 order, error = DepositTransactionCtl.order_create( user=user, amount=amount, channel_enum=channel_enum, client_ip=client_ip, source=source, in_type=in_type, notify_url=notify_url, result_url=result_url, mch_tx_id=mch_tx_id, extra=extra, ) if error: rst['error'] = error.message return rst # 发起第三方支付请求 launch_pay = channel_enum.get_launch_pay_func(PayTypeEnum.DEPOSIT) launch_rst = launch_pay(order, params=dict( channel_enum=channel_enum, client_ip=client_ip, user_agent=user_agent, # 如果通道需要,可以在用户支付完成后,重定向至这个页面 result_url=result_url, user=user, )) if launch_rst['code'] != 0: current_app.logger.error( "do_deposit_request failed, merchant: %s, channel: %s, sys_tx_id: %s, client_ip: %s, launch_rst: %s", order.merchant.name, channel_enum.desc, order.sys_tx_id, client_ip, launch_rst) # 发起失败,直接把订单状态改成失败 DepositTransactionCtl.order_create_fail(order) # 把第三方的错误信息提示出来 rst['error'] = launch_rst['msg'] return rst # 如果返回了通道订单号,那么更新订单保存起来 channel_tx_id = launch_rst['data'].get('channel_tx_id') if channel_tx_id: DepositTransactionCtl.order_update(order, channel_tx_id) rst['order'] = order rst['data'] = launch_rst['data'] # 解析跳转URL return rst
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 post(self): if not EnvironEnum.is_local_evn(current_app.config['FLASK_ENV']): # 无论如何都记录一条log current_app.logger.info( 'zhuanyifu deposit callback, ip: %s, data: %s, headers: %s', IpKit.get_remote_ip(), request.json, request.headers) event = request.headers.get('ChinaRailway-Event') signature = request.headers.get('ChinaRailway-Signature') form, error = ZhuanYeFuWithdrawForm().request_validate() if error: current_app.logger.fatal('msg: %s, data: %s', error.message, request.args) return BaseResponse('FAIlURE') client_ip = form.client_ip.data tx_amount = Decimal(form.amount.data) fee = Decimal(form.fee.data) channel_tx_id = form.transaction.data # if not CallbackZYF.check_ip(client_ip): # current_app.logger.fatal('ip not allow, client_ip: %s, data: %s, body: %s', client_ip, request.args, # request.json) # return ResponseSuccess(code=500, message='ip not allow').as_response() pp = signature.split('.') if event != "Charge.Succeeded": return ResponseSuccess(code=500).as_response() order = DepositTransactionCtl.get_order(form.order.data) if not order: return ResponseSuccess( code=500, message='curr order no found').as_response() curr_status = order.state if curr_status != OrderStateEnum.INIT: return ResponseSuccess( code=500, message='curr order status must be DEALING').as_response() channel_config = ChannelConfig.query_by_channel_id(order.channel_id) # 检查通道手续费与系统计算出的手续费 channel_cost = FeeCalculator.calc_cost(order.amount, channel_config.fee_type, channel_config.fee) if Decimal(fee) != channel_cost: current_app.logger.error( "ZYF deposit fee info order_id:{}, channel_fee: {}, channel_cost:{}" .format(order.order_id, Decimal(fee), channel_cost)) flag = CallbackZYF.check_sign(pp=pp, channel_config=channel_config) if not flag: current_app.logger.fatal( 'invalid sign, client_ip: %s, data: %s, body: %s', client_ip, request.args, request.json) return ResponseSuccess(code=500, message='签名错误').as_response() status = form.status.data if str(status) == '1': if not DepositTransactionCtl.success_order_process( order, tx_amount, channel_tx_id, client_ip): return ResponseSuccess(code=500, message='订单状态更新失败').as_response() else: return ResponseSuccess(code=500, message='签名错误').as_response() elif str(status) == '2': if not DepositTransactionCtl.failed_order_process( order, tx_amount, channel_tx_id, client_ip): return ResponseSuccess(code=500, message='订单状态更新失败').as_response() elif str(status) == '0': pass return ResponseSuccess(code=204).as_response()
def post(self): """ RuKouMy,充值回调 :return: """ client_ip = IpKit.get_remote_ip() if not EnvironEnum.is_local_evn(current_app.config['FLASK_ENV']): # 无论如何都记录一条log current_app.logger.info( 'RuKouMy deposit callback, ip: %s, json: %s', IpKit.get_remote_ip(), request.json) if not CallbackRuKouMy.check_ip(client_ip): current_app.logger.error( 'ip not allow, client_ip: %s, data: %s, body: %s', client_ip, request.args, request.json) return BaseResponse('error') resp_body = request.json sign = resp_body.pop("sign") sorted_params = sorted(list(resp_body.keys())) resp_body['real_amount'] = "{:.2f}".format( int(resp_body['real_amount'])) resp_body['pay_amount'] = "{:.2f}".format(int(resp_body['pay_amount'])) sign_str = "&".join([ "{}={}".format(k, resp_body[k]) for k in sorted_params if resp_body.get(k, False) or k in ["code"] ]) flag = CallbackRuKouMy.check_sign(sign, sign_str) if not flag: current_app.logger.error( 'invalid sign, data: %s, sign: %s, data: %s', client_ip, sign, sign_str) return BaseResponse('error') order_id = resp_body['order_id'] order = DepositTransactionCtl.get_order(order_id) if not order: return BaseResponse('success') if order.state.name == OrderStateEnum.SUCCESS.name: return BaseResponse('success') tx_amount = Decimal(str(request.json['real_amount'])) channel_tx_id = request.json['order_no'] code = resp_body['code'] if code == 0: # 支付成功 if not DepositTransactionCtl.success_order_process( order, tx_amount, channel_tx_id): return BaseResponse('error') else: # 支付失败 if not DepositTransactionCtl.failed_order_process( order, tx_amount, channel_tx_id): return BaseResponse('error') return BaseResponse('success')
def __test_deposit_fail(): tx_amount = Decimal('299.99') channel_tx_id = '29828239239238298' order = InitData.create_one_deposit_order() DepositTransactionCtl.failed_order_process(order, tx_amount, channel_tx_id)
def __test_deposit_success(self): tx_amount = Decimal('299.99') channel_tx_id = '29828239239238298' order = InitData.create_one_deposit_order() ret = DepositTransactionCtl.success_order_process(order, tx_amount, channel_tx_id) self.assertTrue(ret)
def post(self): """ 手动补单 :return: """ form, error = CreateDepositOrderForm().request_validate() if error: return error.as_response() ''' 根据商户查询用户是否存在 构造数据 创建充值订单 更改订单状态为完成 ''' # 根据商户查询用户是否存在 user = User.query_user(form.merchant.data, uid=form.uid.data) if not user: return AccountNotExistError().as_response() # 构造数据 client_ip = form.client_ip.data channel_enum = form.channel_id.data payment_type = form.payment_type.data amount = Decimal(form.amount.data) # 判断当前传入的支付类型是否该渠道支持 if payment_type != channel_enum.conf['payment_type']: return InvalidDepositPaymentTypeError() merchant = form.merchant.data # 找出最新版本的商户费率配置 channel_config = ChannelConfig.query_latest_one(query_fields=dict( channel_enum=channel_enum)) if not channel_config: return InvalidDepositChannelError().as_response() if not channel_config.is_channel_valid(merchant.is_test): return ChannelNoValidityPeriodError().as_response() if ChannelListHelper.is_amount_out_of_range( amount=amount, merchant=merchant, payment_way=PayTypeEnum.DEPOSIT, client_ip=client_ip): return DepositOrderAmountInvalidError().as_response() # limit_min, limit_max = ChannelLimitCacheCtl( # PayTypeEnum.DEPOSIT).get_channel_limit() # try: # if limit_min > amount or limit_max < amount: # return DepositOrderAmountInvalidError().as_response() # except Exception as e: # return MustRequestDepositLimitError().as_response() # 找出最新版本的商户费率配置 merchant_fee = MerchantFeeConfig.query_latest_one( query_fields=dict(merchant=merchant, payment_way=PayTypeEnum.DEPOSIT, payment_method=channel_enum.conf.payment_method)) if not merchant_fee: return MerchantConfigDepositError().as_response() try: with db.auto_commit(): # 创建待支付订单 order, _ = OrderCreateCtl.create_order_event( uid=user.uid, merchant=merchant, amount=amount, channel_id=channel_config.channel_id, mch_fee_id=merchant_fee.config_id, order_type=PayTypeEnum.DEPOSIT, source=OrderSourceEnum.MANUALLY, in_type=InterfaceTypeEnum.CASHIER_H5, ip=client_ip, pay_method=channel_enum.conf.payment_method, op_account=g.user.account, # 后台管理员账号,后台人工修改数据时必填 comment=form.remark.data, # 管理后台修改备注,后台人工修改数据时必填 mch_tx_id=form.mch_tx_id.data, commit=False, ) if not order: raise Exception('order create failed') # 支付成功 if not DepositTransactionCtl.success_order_process( order=order, tx_amount=amount, channel_tx_id=form.mch_tx_id.data, comment="手动补单订单", commit=False, ): raise Exception('order process failed') except Exception as e: if str(e).find("Duplicate entry") >= 0: return PreOrderCreateError(message="商户订单号重复: {}".format( form.mch_tx_id.data)).as_response() return PreOrderCreateError(message=str(e)).as_response() return ResponseSuccess().as_response()
def post(self): """ BestPay,充值回调 :return: """ if not EnvironEnum.is_local_evn(current_app.config['FLASK_ENV']): # 无论如何都记录一条log current_app.logger.info('BestPay deposit callback, ip: %s, data: %s', IpKit.get_remote_ip(), request.form) client_ip = IpKit.get_remote_ip() if not CallbackBestPay.check_ip(client_ip): current_app.logger.error('ip not allow, client_ip: %s, data: %s, body: %s', client_ip, request.args, request.form) return BaseResponse('error') data = request.form['deposit_result'] resp_body = json.loads(data) third_config = ThirdPayConfig.BESTPAY_DEPOSIT.value sign = resp_body["sign"] resp_type = resp_body["type"] if resp_type != "deposit_result": return BaseResponse('error') data = resp_body["data"] print(data) if isinstance(data, list): sign_str = json.dumps(data) else: sign_str = data sign_str += third_config['secret_key'] flag = CallbackBestPay.check_sign(sign, sign_str) if not flag: current_app.logger.error('invalid sign, client_ip: %s, data: %s, body: %s', client_ip, request.args, sign_str) return BaseResponse('error') data_list = json.loads(data) flag = 'error' for data_dict in data_list: order_id = data_dict['client_postscript'] tx_amount = data_dict['amount'] channel_tx_id = data_dict['order_number'] client_transtype = data_dict['client_transtype'] deposit_cardnumber = data_dict['deposit_cardnumber'] user_name = data_dict['client_accountname'] deposit_time = data_dict['deposit_time'] try: order_id = int(order_id) except Exception as e: if client_transtype == '微信转账': DateTimeKit.time_delta() log = OrderTransferLog.query_transfer_log_by_user_info( deposit_cardnumber=deposit_cardnumber, amount='{:.2f}'.format(float(tx_amount)), deposit_time=deposit_time ) else: log = OrderTransferLog.query_transfer_log_by_user_info( deposit_cardnumber=deposit_cardnumber, amount='{:.2f}'.format(float(tx_amount)), client_accountname=user_name, deposit_time=deposit_time ) current_app.logger.info("转账信息数据", log) if log: for o in log: order = DepositTransactionCtl.get_order_by_order_id(order_id=o.order_id) if not order or order.state.name != OrderStateEnum.INIT.name: continue if DepositTransactionCtl.success_order_process(order, Decimal(str(tx_amount)), channel_tx_id): OrderTransferLog.update_transfer_log(order_id=order.order_id) flag = "success" else: log = OrderTransferLog.query_transfer_log(order_id=order_id) if not log: continue order = DepositTransactionCtl.get_order_by_order_id(order_id=log.order_id) if not order or order.state.name != OrderStateEnum.INIT.name: continue if DepositTransactionCtl.success_order_process(order, Decimal(str(tx_amount)), channel_tx_id): OrderTransferLog.update_transfer_log(order_id=order.order_id) flag = "success" return BaseResponse(flag)
def post(self): """ 快汇支付,充值回调 :return: """ if not EnvironEnum.is_local_evn(current_app.config['FLASK_ENV']): # 无论如何都记录一条log current_app.logger.info( 'kuaihui deposit callback, ip: %s, args: %s, data: %s', IpKit.get_remote_ip(), request.args, request.json) form, error = KhpayForm().request_validate() if error: current_app.logger.fatal('msg: %s, args: %s, data: %s', error.message, request.args, request.json) return BaseResponse(error.message) # 交易订单id tx_id = form.client_ordid.data # 充值通道 订单id channel_tx_id = form.ordid.data # 实际支付金额 tx_amount = Decimal(form.amount.data) # 订单状态: 成功/失败 status = form.status.data # 客户端IP client_ip = form.client_ip.data custid = form.custid.data kuai_hui_dict = { "PAY5f34c380-b8e6-11e9-9edc-511803f475f9": ThirdPayConfig.KUAIHUI.value, "PAY5f34c380-b8e6-11e9-9edc-511803f475f9": ThirdPayConfig.KUAIHUI_0bd0d8.value } # 签名验证 if not CallbackKhpay.check_sign(form, kuai_hui_dict[custid]): current_app.logger.fatal('invalid sign, client_ip: %s, data: %s', client_ip, request.json) return BaseResponse('FAIlURE') # IP白名单校验 if not CallbackKhpay.check_ip(client_ip): current_app.logger.fatal('ip not allow, client_ip: %s, data: %s', client_ip, request.json) return BaseResponse('FAIlURE') order = DepositTransactionCtl.get_order(tx_id) if not order: return BaseResponse('FAIlURE') if order.state.is_final_state: # 已经通知了就返回成功 return BaseResponse('{"status_code": 200}') if status == 'waiting': return BaseResponse('FAIlURE') if status == 'finish': # 支付成功 if not DepositTransactionCtl.success_order_process( order, tx_amount, channel_tx_id): return BaseResponse('FAIlURE') else: # 支付失败 if not DepositTransactionCtl.failed_order_process( order, tx_amount, channel_tx_id): return BaseResponse('FAIlURE') return BaseResponse('{"status_code": 200}')
def __test_create_failed(): order = InitData.create_one_deposit_order() DepositTransactionCtl.order_create_fail(order)
def __test_create_failed(self): order = InitData.create_one_deposit_order() rst = DepositTransactionCtl.order_create_fail(order) self.assertTrue(rst)