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): """ 充值请求 """ if not EnvironEnum.is_local_evn(current_app.config['FLASK_ENV']): # 无论如何都记录一条log current_app.logger.info('path: %s, ip: %s, args: %s, data: %s', url_for("gateway_config_get"), IpKit.get_remote_ip(), request.args, request.json) form, error = DepositConfigForm.request_validate() if error: return error.as_response() merchant = form.merchant_id.data checker = GatewayFormChecker(merchant) # 1. IP白名单校验 if not checker.verify_ip(form.client_ip.data): current_app.logger.error('msg: %s, ip: %s, white ips: %s', GatewayIPError.message, IpKit.get_remote_ip(), checker.get_white_ips()) return GatewayIPError().as_response() # 2. 签名校验 sign_fields = form.get_sign_fields() if not checker.verify_sign(form.sign.data, sign_fields): current_app.logger.error( 'msg: %s, sign: %s, fields: %s, sign_str: %s', GatewaySignError.message, form.sign.data, sign_fields, checker.get_sign_str(sign_fields)) return GatewaySignError().as_response() # 3. 返回可用的支付方式以及限额 # 充值每种支付类型的限额 payment_types = ChannelListHelper.get_channels_for_gateway( merchant, PayTypeEnum.DEPOSIT, client_ip=form.user_ip.data, ) # 提现限额 # limit_min, limit_max = ChannelLimitCacheCtl(PayTypeEnum.WITHDRAW).get_channel_limit() limit_min, limit_max = ChannelListHelper.get_channel_limit_range( merchant=merchant, payment_way=PayTypeEnum.WITHDRAW, client_ip=form.user_ip.data, ) withdraw_config = dict( limit_min=limit_min, # 最小限额列表的最小值 limit_max=limit_max, # 最大限额列表的最大值 ) return GatewayResponseConfig(bs_data=dict( payment_types=payment_types, withdraw_config=withdraw_config, )).as_response()
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 generate_token(cls, uid, **kwargs): """ 生成token :param uid: :return: 返回一个已经进行base64编码的token字符串 """ s = JSONWebSignatureSerializer(current_app.config['SECRET_KEY']) login_time = DateTimeKit.get_cur_timestamp(1000) data = dict( uid=uid, time=login_time, ip=IpKit.get_remote_ip(), ) data.update(kwargs) # 缓存登录状态 cache = cls.cache_cls(uid) cache.dumps(data) token = s.dumps(data) b64_token = base64.b64encode(token).decode('utf8') DEBUG_LOG and current_app.logger.debug( 'token generated, key: %s, ttl: %s, data: %s, token: %s, b64_token: %s', cache.get_cache_key(), cache.get_ttl(), data, token, b64_token) return b64_token
def load_request_data(cls): data = cls.get_data() # 取出IP地址 data['client_ip'] = IpKit.get_remote_ip() # 客户端的类型 data['user_agent'] = request.headers.get('User-Agent') return data
def post(self): """ 发货通知,由商户实现 :return: """ if not EnvironEnum.is_local_evn(current_app.config['FLASK_ENV']): # 无论如何都记录一条log current_app.logger.info('path: %s, ip: %s, args: %s, data: %s', url_for("gateway_demo_notify"), IpKit.get_remote_ip(), request.args, request.json) form, error = DepositNotifyForm.request_validate() if error: return error.as_response() checker = GatewayFormChecker(form.merchant_id.data) # 1. IP白名单校验 if not checker.verify_ip(form.client_ip.data): current_app.logger.error('msg: %s, ip: %s, white ips: %s', GatewayIPError.message, IpKit.get_remote_ip(), checker.get_white_ips()) return GatewayIPError().as_response() # 2. 签名校验 sign_fields = form.get_sign_fields() if not checker.verify_sign(form.sign.data, sign_fields): current_app.logger.error('msg: %s, sign: %s, fields: %s, sign_str: %s', GatewaySignError.message, form.sign.data, sign_fields, checker.get_sign_str(sign_fields)) return GatewaySignError().as_response() # 商户自己的业务逻辑处理 current_app.logger.info('notify success: %s', form.json_data) return ResponseSuccess().as_response()
def ip(self, value: str): """ 存储为整数 :param value: :return: """ self._ip = IpKit.ip_to_int(value)
def ip(self) -> str: """ 整形IP转为字符串 :return: """ if not self._ip: return '' return IpKit.int_to_ip(self._ip)
def get(self): """ 立马付充值回调 :return: """ if not EnvironEnum.is_local_evn(current_app.config['FLASK_ENV']): # 无论如何都记录一条log current_app.logger.info( 'ponypay withdraw callback, ip: %s, data: %s', IpKit.get_remote_ip(), request.args) form, error = PonyPayWithdrawForm().request_validate() if error: current_app.logger.fatal('msg: %s, data: %s', error.message, request.args) return BaseResponse('FAIlURE') # 交易订单id tx_id = form.corderid.data # 实际支付金额 tx_amount = Decimal(form.money.data) # 订单状态: 成功/失败 status = form.status.data # 签名 sign = form.sign.data # 客户端IP client_ip = form.client_ip.data order = WithdrawTransactionCtl.get_order(tx_id) if not order: return BaseResponse('FAIlURE') channel_config = ChannelConfig.query_by_channel_id(order.channel_id) controller = WithdrawCallbackPonypay(channel_config.channel_enum) # IP白名单校验 if not controller.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 controller.check_sign(tx_id, tx_amount, sign): current_app.logger.fatal('invalid sign, client_ip: %s, data: %s', client_ip, request.args) return BaseResponse('FAIlURE') if status == '1': # 支付成功 if not WithdrawTransactionCtl.order_success(order, tx_amount): return BaseResponse('FAIlURE') else: # 支付失败 if not WithdrawTransactionCtl.order_fail(order): return BaseResponse('FAIlURE') return BaseResponse('SUCCESS')
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 get_extra_params(cls): if not has_request_context() or not has_app_context(): return dict() return dict( url=request.path, module=AdminModuleEnum.get_module_by_path(), account=g.user.account if g.get('user') else '', ip=IpKit.get_remote_ip(), )
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 get(self): """ 渲染第三方跳转页面 :return: """ if not EnvironEnum.is_local_evn(current_app.config['FLASK_ENV']): # 无论如何都记录一条log current_app.logger.info('path: %s, ip: %s, args: %s, data: %s', url_for("gateway_deposit_redirect"), IpKit.get_remote_ip(), request.args, request.json) return DepositHelper.render_page()
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): 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) # form, error = YinSaoForm.request_validate() # if error: # current_app.logger.fatal('msg: %s, data: %s', error.message, request.json) # return BaseResponse('FAIlURE') 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') data = {k: v for k, v in request.form.items()} 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.fatal('invalid sign, data: %s, sign: %s, signature: %s', client_ip, data, sign, signature) return BaseResponse('FAIlURE') order = WithdrawTransactionCtl.get_order(sys_tx_id) if not order: return BaseResponse('FAIlURE') if str(data['respCode']) == '0000': # 支付成功 if not WithdrawTransactionCtl.order_success(order, tx_amount): return BaseResponse('FAILURE') else: # 支付失败 if not WithdrawTransactionCtl.order_fail(order): return BaseResponse('FAIlURE') return BaseResponse('SUCCESS')
def request_config(): merchant = MerchantEnum.TEST_API post_data = dict( merchant_id=merchant.value, user_ip=IpKit.get_remote_ip(), ) post_data['sign'] = GatewaySign(merchant).generate_sign(post_data) post_data['user_id'] = '100' domain = MerchantDomainConfig.get_gateway_domain(merchant) url = UrlKit.join_host_path(url_for('gateway_config_get'), host=domain) rsp = requests.post(url, json=post_data) if rsp.status_code != 200: return None, "http请求失败,状态码:%s, url: %s" % (rsp.status_code, url) if rsp.json()['error_code'] != 200: return None, rsp.json()['message'] return rsp.json()['data'], None
def after_request(response: Response): try: if output_log(): request_data = request.json if request.is_json else request.data.decode( 'utf8') response_data = response.json if response.is_json else response.data.decode( 'utf8') cost_time = round(time.time() - g.before_data['time'], 5) extra = dict( # request_headers=str(UrlKit.headers_to_dict(request.headers)), status_code=response.status_code, # response_headers=str(UrlKit.headers_to_dict(response.headers)), cost_time=cost_time, client_ip=IpKit.get_remote_ip(), ) print( 'flask path: %s, request_data: %s, response_data: %s, extra: %s' % (request.path, request_data, response_data, extra)) if cost_time > 2 or response.status_code == 500: app.logger.error( 'flask path: %s, request_data: %s, response_data: %s, extra: %s', request.path, request_data, response_data, extra) else: app.logger.info( 'flask path: %s, request_data: %s, response_data: %s', request.path, request_data, response_data, extra=extra) except: app.logger.error('An error occurred.', exc_info=True) return response
def get_limit_key(cls): path = request.path ip = IpKit.get_remote_ip() return f"{path}:{ip}"
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 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): if not EnvironEnum.is_local_evn(current_app.config['FLASK_ENV']): # 无论如何都记录一条log current_app.logger.info( 'onepay withdraw callback, ip: %s, headers: %s, json data: %s', IpKit.get_remote_ip(), request.headers, request.json) # form, error = YinSaoForm.request_validate() # if error: # current_app.logger.fatal('msg: %s, data: %s', error.message, request.json) # return BaseResponse('FAIlURE') current_app.logger.fatal( 'onepay withdraw callback, ip: %s, form 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') flag = request.json['flag'] if flag == 'FAILED': return BaseResponse('FAIlURE') data = {k: v for k, v in request.json['data'].items()} no_need_sign = ['totalFactorage', 'sign', 'signType', 'detailList'] signature = data.pop('sign') key_list = sorted(list(data.keys())) request_str = "&".join([ "{}={}".format(field, data[field]) for field in key_list if data.get(field, False) and field not in no_need_sign ]) flag = CallbackOnePay.check_sign(signature, request_str) if not flag: current_app.logger.fatal( 'invalid sign, data: %s, sign: %s, data: %s', client_ip, data, signature, request_str) return BaseResponse('FAIlURE') withdraw_order = request.json['data']['detailList'][0] tx_id = withdraw_order['serialNo'] tx_amount = withdraw_order['amount'] order = WithdrawTransactionCtl.get_order(tx_id) if not order: return BaseResponse('FAIlURE') if str(withdraw_order['tradeStatus']) == '1': # 支付成功 if not WithdrawTransactionCtl.order_success( order, decimal.Decimal(tx_amount)): return BaseResponse('FAILURE') elif str(withdraw_order['tradeStatus']) == '2': # 支付失败 if not WithdrawTransactionCtl.order_fail(order): return BaseResponse('FAIlURE') return BaseResponse('SUCCESS')
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 __check_ip_in_white_list(*args, **kwargs): ip = IpKit.get_remote_ip() if IpKit.is_private_ip(ip) or ip in ip_list: return func(*args, **kwargs) return Forbidden().as_response()
def post(self): merchant = MerchantEnum.TEST_API amount = Decimal(request.form['amount']) domain = MerchantDomainConfig.get_latest_domain(merchant) # 模拟商户发起支付请求 scheme_host = UrlKit.get_scheme_host(host=domain) url = scheme_host + url_for('gateway_deposit_request') if not request.form['payment_type']: return redirect( scheme_host + url_for('gateway_demo_merchant_deposit', error="请选择支付类型")) payment_type = PaymentTypeEnum.from_name(request.form['payment_type']) # 模拟商户的回调URL notify_url = UrlKit.join_host_path(url_for('gateway_demo_notify'), host=domain) post_data = dict( merchant_id=merchant.value, amount=str(amount), mch_tx_id=OrderUtils.generate_mch_tx_id( DateTimeKit.get_cur_timestamp()), payment_type=payment_type.name, notify_url=notify_url, user_ip=IpKit.get_remote_ip(), ) print('post_data:', post_data) post_data['sign'] = GatewaySign(merchant).generate_sign(post_data) post_data['redirect_url'] = "https://google.com" post_data['extra'] = json.dumps(dict(x=1, y=2)) post_data['user_id'] = "100" print('post_data:', post_data) rsp = requests.post(url, json=post_data) if rsp.status_code != 200: return redirect(scheme_host + url_for('gateway_demo_merchant_deposit', error="http请求失败,状态码:%s, url: %s" % (rsp.status_code, url))) if rsp.json()['error_code'] != 200: return redirect(scheme_host + url_for( 'gateway_demo_merchant_deposit', error=rsp.json()['message'])) sys_tx_id = rsp.json()['data']['sys_tx_id'] return redirect(scheme_host + url_for( 'gateway_demo_merchant_deposit', success=True, post_data=json.dumps(post_data), notify_url=scheme_host + url_for('demo_deposit_notify', tx_id=sys_tx_id), redirect_url=rsp.json()['data']['redirect_url'], sys_tx_id=sys_tx_id, mch_tx_id=rsp.json()['data']['mch_tx_id'], valid_time=rsp.json()['data']['valid_time'], ))
def post(self): """ 充值请求 """ if not EnvironEnum.is_local_evn(current_app.config['FLASK_ENV']): # 无论如何都记录一条log current_app.logger.info('path: %s, ip: %s, args: %s, data: %s', url_for("gateway_deposit_request"), IpKit.get_remote_ip(), request.args, request.json) form, error = DepositRequestForm.request_validate() if error: return error.as_response() checker = GatewayFormChecker(form.merchant_id.data) # 1. IP白名单校验 if not checker.verify_ip(form.client_ip.data): current_app.logger.error('msg: %s, ip: %s, white ips: %s', GatewayIPError.message, IpKit.get_remote_ip(), checker.get_white_ips()) return GatewayIPError().as_response() # 2. 签名校验 sign_fields = form.get_sign_fields() if not checker.verify_sign(form.sign.data, sign_fields): current_app.logger.error('msg: %s, sign: %s, fields: %s, sign_str: %s', GatewaySignError.message, form.sign.data, sign_fields, checker.get_sign_str(sign_fields)) return GatewaySignError().as_response() # 3. 获取对应支付方式下的充值通道 channel = ChannelListHelper.get_one_channel_by_payment_type( merchant=form.merchant_id.data, payment_type=form.payment_type.data, amount=form.amount.data, client_ip=form.user_ip.data, ) if not channel: current_app.logger.error("no channel found, request data: %s", form.get_data()) return GatewayChannelError().as_response() # # 境外IP检查 # if channel.is_ip_forbidden(form.user_ip.data): # return GatewayDepositError(message="此通道不支持境外IP,请使用VPN后重试").as_response() # 4. 获取用户对象 user = checker.get_fake_user(form.user_id.data) # 5. 发起支付 rst = DepositHelper.do_deposit_request( client_ip=form.user_ip.data, user_agent=form.user_agent.data, user=user, amount=form.amount.data, channel_enum=channel.channel_enum, notify_url=form.notify_url.data, result_url=form.result_url.data, mch_tx_id=form.mch_tx_id.data, extra=form.extra.data, source=OrderSourceEnum.TESTING if form.merchant_id.data.is_test else OrderSourceEnum.ONLINE, in_type=InterfaceTypeEnum.API, ) if rst['error']: return GatewayDepositError(message=rst['error']) # 6. 解析URL ps_rst = DepositHelper.parse_result( data=rst['data'], order_id=rst['order'].order_id, endpoint='gateway_deposit_redirect', channel_enum=channel.channel_enum, ) return GatewayResponseDeposit(bs_data=dict( redirect_url=ps_rst['redirect_url'], valid_time=ps_rst['valid_time'], sys_tx_id=rst['order'].sys_tx_id, mch_tx_id=rst['order'].mch_tx_id, )).as_response()
def post(self): merchant = MerchantEnum.TEST_API amount = Decimal(request.form['amount']) domain = MerchantDomainConfig.get_latest_domain(merchant) # 模拟商户发起支付请求 scheme_host = UrlKit.get_scheme_host(host=domain) url = scheme_host + url_for('gateway_withdraw_request') if not request.form['bank_type']: return redirect( scheme_host + url_for('gateway_demo_merchant_withdraw', error="必选选择银行类型")) bank_type = PaymentBankEnum.from_name(request.form['bank_type']) # 模拟商户的回调URL notify_url = UrlKit.join_host_path(url_for('gateway_demo_notify'), host=domain) post_data = dict( merchant_id=merchant.value, amount=str(amount), mch_tx_id=OrderUtils.generate_mch_tx_id( DateTimeKit.get_cur_timestamp()), bank_type=bank_type.name, notify_url=notify_url, card_no=request.form['card_no'], account_name=request.form['account_name'], province=request.form['province'], city=request.form['city'], user_ip=IpKit.get_remote_ip(), ) print('post_data:', post_data) post_data['sign'] = GatewaySign(merchant).generate_sign(post_data) post_data['extra'] = json.dumps(dict(x=1, y=2)) post_data['user_id'] = "100" post_data['branch'] = request.form['branch'] print('post_data:', post_data) rsp = requests.post(url, json=post_data) if rsp.status_code != 200: return redirect(scheme_host + url_for('gateway_demo_merchant_withdraw', error="http请求失败,状态码:%s, url: %s" % (rsp.status_code, url))) if rsp.json()['error_code'] != 200: return redirect(scheme_host + url_for( 'gateway_demo_merchant_withdraw', error=rsp.json()['message'])) sys_tx_id = rsp.json()['data']['sys_tx_id'] return redirect(scheme_host + url_for( 'gateway_demo_merchant_withdraw', success=True, post_data=json.dumps(post_data), notify_url=scheme_host + url_for('demo_withdraw_notify', tx_id=sys_tx_id), sys_tx_id=sys_tx_id, mch_tx_id=rsp.json()['data']['mch_tx_id'], ))
def post(self): """ 充值请求 """ if not EnvironEnum.is_local_evn(current_app.config['FLASK_ENV']): # 无论如何都记录一条log current_app.logger.info('path: %s, ip: %s, args: %s, data: %s', url_for("gateway_withdraw_request"), IpKit.get_remote_ip(), request.args, request.json) form, error = WithdrawRequestForm.request_validate() if error: return error.as_response() checker = GatewayFormChecker(form.merchant_id.data) # 1. IP白名单校验 if not checker.verify_ip(form.client_ip.data): current_app.logger.error('msg: %s, ip: %s, white ips: %s', GatewayIPError.message, IpKit.get_remote_ip(), checker.get_white_ips()) return GatewayIPError().as_response() # 2. 签名校验 sign_fields = form.get_sign_fields() if not checker.verify_sign(form.sign.data, sign_fields): current_app.logger.error( 'msg: %s, sign: %s, fields: %s, sign_str: %s', GatewaySignError.message, form.sign.data, sign_fields, checker.get_sign_str(sign_fields)) return GatewaySignError().as_response() # 3. 获取用户对象 user = checker.get_fake_user(form.user_id.data) # 银行卡信息 bank_info = BankCard.generate_model( bank_name=form.bank_type.data.desc, bank_code=form.bank_type.data.bank_code, card_no=form.card_no.data, account_name=form.account_name.data, branch=form.branch.data or '', province=form.province.data or '', city=form.city.data or '', ) # 4. 创建订单 order, error = WithdrawTransactionCtl.order_create( user=user, amount=form.amount.data, client_ip=form.user_ip.data, notify_url=form.notify_url.data, mch_tx_id=form.mch_tx_id.data, bank_info=bank_info.bank_info_dict, extra=form.extra.data, ) if error: return error.as_response() return GatewayResponseWithdraw(bs_data=dict( sys_tx_id=order.sys_tx_id, mch_tx_id=order.mch_tx_id, )).as_response()
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}')