from flask import Flask, request, redirect, abort, session, jsonify from utils import * from FuiouPay import H5Main import logging from logging.handlers import TimedRotatingFileHandler import datetime import os, _thread, urllib, re from flask_cors import CORS app = Flask(__name__) app.config['SECRET_KEY'] = os.urandom(24) CORS(app, supports_credentials=True) def setup_logging(): """配置日志系统,按天分割日志文件""" # 创建日志目录 log_dir = "logs" os.makedirs(log_dir, exist_ok=True) # 设置日志格式 log_format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s' formatter = logging.Formatter(log_format) # 创建按天轮转的文件处理器 file_handler = TimedRotatingFileHandler( filename=os.path.join(log_dir, 'payapp.log'), when='midnight', # 每天午夜轮转 interval=1, # 每天一个文件 backupCount=30, # 保留30天的日志 encoding='utf-8' ) file_handler.setFormatter(formatter) file_handler.setLevel(logging.INFO) # 创建控制台处理器 console_handler = logging.StreamHandler() console_handler.setFormatter(formatter) console_handler.setLevel(logging.DEBUG) # 获取根logger并配置 logger = logging.getLogger() logger.setLevel(logging.DEBUG) logger.addHandler(file_handler) logger.addHandler(console_handler) # 初始化日志配置 setup_logging() # 获取当前模块的 logger logger = logging.getLogger(__name__) logger.info(f"PayApp started") # 会输出到文件和控制台 @app.route('/queryUserId', methods=['GET']) def queryUserId(): # 获取支付明细 try: code = request.args.get('code') data = query_wx_userid(code) if len(data) <= 13: res = query_wx_fj_info(data) data = res logger.info(f'http://web.jiyuankeshang.com/#/pay?user={data}&appid={corpid}&agentid={agentid}') return redirect(f'http://web.jiyuankeshang.com/#/pay?user={data}&appid={corpid}&agentid={agentid}') except Exception as e: logger.error("====================获取支付明细失败====================",e) return jsonify(error=str(e)), 500 @app.route('/queryUser', methods=['GET']) def queryUserApi(): # 获取支付明细 try: id = request.args.get('user') data = queryUser(id) for item in data['pay_detail']: if 'charge_amount' in item: item['price'] = item.pop('charge_amount') if 'charge_time' in item: item['time'] = item.pop('charge_time') logger.info(f"===================queryUserdata{data}") return data except Exception as e: return {} @app.route('/getZXPaymentDetails', methods=['GET']) def getZXPaymentDetails(): try: id = request.args.get('user','') id = id.replace(" ", "") if not id: return {} data = query_zxpay_details(id) for item in data: if item == "amount": continue for detail in data[item]['data']: if 'month1' in detail: detail['yuefen'] = detail.pop('month1') if 'money' in detail: detail['jine'] = detail.pop('money') if 'no_money' in detail: detail['unpay'] = detail.pop('no_money') return data except Exception as e: logger.error(e) return {} @app.route('/getPaymentDetails', methods=['GET']) def getPaymentDetails(): try: id = request.args.get('user', '') id = id.replace(" ", "") if not id: return {} data = query_fzxpay_details(id) for key in list(data.keys()): if key != 'amount': for detail in data[key]['data']: if 'month1' in detail: detail['yuefen'] = detail.pop('month1') if 'money' in detail: detail['jine'] = detail.pop('money') if 'no_money' in detail: detail['unpay'] = detail.pop('no_money') data[key]['data'].sort(key=lambda x: x['sort']) return data except Exception as e: logger.error(e) return {} @app.route('/getReasons', methods=['GET']) def getReasons(): try: reasons_data = query_reasons_for_payment() # 使用字典推导式创建reason为键,dktype为值的字典 # 初始化字典,包含两个空列表作为值 dktype_to_reasons_dict = { '非专项扣除': [], '专项扣除': [] } # 遍历数据,根据dktype的值将reason添加到对应的列表中 for item in reasons_data: dktype = item['dktype'] reason = item['reason'] if dktype in dktype_to_reasons_dict: dktype_to_reasons_dict[dktype].append(reason) return dktype_to_reasons_dict except Exception as e: logger.error(e) return {} @app.route('/paymentCallBack', methods=['POST']) def paymentCallBack(): # 充值成功后回调 {"pay_amount": 20000, "id": "18515367096"} try: logger.info(f"====================================paymentCallBack=========================================") msg = request.data.decode('UTF-8') logger.info(f"回调参数为===={msg}") msg = eval(msg) logger.info(f"eval参数为===={msg}") if msg['resp_desc'] == '成功': logger.info(f"=================================充值回调SUCCESS==========================================") # rsa_key = RSA.importKey(open('E:/YinJian/银建支付对接维护说明/富友/enterprise-wechat-payment-push/priv_key.pem').read()) rsa_key = RSA.importKey(open('priv_key.pem').read()) logger.info(f"msg==={msg['message']}") whp = rsa_long_decrypt(rsa_key, msg['message']) logger.info(f"报文已解密{whp}") whp_dict = json.loads(whp) # 打印字典中的所有键 logger.info(f"1111111{whp_dict.keys()}") # 获取'order_id'键的值并取前18个字符 id = whp_dict['order_id'][:18] # 查询机构、分司 res = filter_jdy_ht(id) logger.info(f"whp_dict{whp_dict}") transaction_id = whp_dict['pay_ssn'] amount = float(whp_dict['order_amt']) order_pay_type = whp_dict['order_pay_type'] # 判断支付类型 if order_pay_type[:2] == "We": pay_type = "微信支付" elif order_pay_type[:3] == "Ali": pay_type = "支付宝支付" elif order_pay_type == "0000000000": pay_type = "云闪付支付" amount = amount / 100 #查询支付详情 query_url = f'{base_path}/api/v5/app/entry/data/list' _query_tmp = { "app_id": cw_app, "entry_id": "67f38facbaccd58c66bd7db2", "filter": { "rel": "and", "cond": [ { "field": "order_id", "method": "eq", "value": [whp_dict['order_id']] } ] } } logger.info(f"开始查询支付信息{_query_tmp}") res1 = req_tool_jdy(query_url, _query_tmp) info1 = {"pay_amount": amount, "id": id, "fs": res[1], "jg": res[0], "name": res[4], "fsfz": res[6],"shfid": res[7], "hphm": res[5], "transaction_id": transaction_id, "pay_type": pay_type,"paymentdetails": res1['data'][0]['paymentdetails']} logger.info(f"充值回调处理{info1}") if res1['data'][0]['paymentdetails'] == ["非专项"]: _thread.start_new_thread(add_payment, ({"pay_amount": amount, "id": id, "fs": res[1], "jg": res[0], "name": res[4], "fsfz": res[6],"shfid": res[7], "hphm": res[5], "transaction_id": transaction_id, "pay_type": pay_type, "paymentdetails": ""},)) else: _thread.start_new_thread(add_payment, ({"pay_amount": amount, "id": id, "fs": res[1], "jg": res[0], "name": res[4], "fsfz": res[6], "shfid": res[7], "hphm": res[5], "transaction_id": transaction_id, "pay_type": pay_type, "paymentdetails": res1['data'][0]['paymentdetails']},)) return {"code": 200} except Exception as e: logger.error(e) return jsonify(error=str(e)), 500 @app.route('/test', methods=['POST']) def test(): # 新增未收付明细 {"pay_amount": 20000, "id": "18515367096"} try: data = request.data.decode("utf-8") print(data) return {} except Exception as e: logger.error(e) return {} @app.route('/addUnPayment', methods=['POST']) def addUnPayment(): # 新增未收付明细 {"pay_amount": 20000, "id": "18515367096"} try: data = request.data.decode("utf-8") data = data.replace("null", "None") data = eval(data) data = data['data'] if data['shgid'] == "" and data['mode_type'] == "自营" and data['lydunjiao'] != "趸交" and data['fukuanshiyou'] != "安全统筹": res = filter_jdy_ht(data['id_card']) _thread.start_new_thread(add_payment, ({"pay_amount": 0, "id": data['id_card'], "fs": res[1], "jg": res[0], "name": res[4], "fsfz": res[6],"shfid": res[7], "hphm": res[5],"paymentdetails": []}, 1)) return {} else: return {} except Exception as e: logger.error(f"addUnPayment,e{e}, res{res}") return {} @app.route('/addPayment', methods=['POST']) def addPayment(): # 新增充值明细 {"pay_amount": 20000, "id": "18515367096"} try: data = request.data.decode("utf-8") logger.info(f"addPayment{data}") data = data.replace("null", "None") data = eval(data) data = data['data'] if data['mode_type'] == "自营": res = filter_jdy_ht(data['id_card']) if not data['charge_amount']: data['charge_amount'] = 0 if not res: # 合同表单未有数据 fsfz = data['fsfz']['dept_no'] if data['fsfz'] else "" _thread.start_new_thread(add_payment, ({"pay_amount": data['charge_amount'], "id": data['id_card'],"shfid":data['shfid'], "fs": data['fs'], "jg": data['jg'], "name": data['name'], "fsfz": fsfz, "hphm": data['hphm'],"paymentdetails": []}, 1)) else: _thread.start_new_thread(add_payment, ({"pay_amount": data['charge_amount'], "id": data['id_card'], "fs": res[1], "jg": res[0], "name": res[4], "fsfz": res[6],"shfid": res[7], "hphm": res[5],"paymentdetails": []}, 1)) return {} else: return {} except Exception as e: logger.error(f"addPayment,e{e}, data{data}") return {} @app.route('/transactions', methods=['GET']) def transactions(): # 调起h5支付 try: id = request.args.get('user') price= request.args.get('price') payment_details = request.args.get('paymentdetails') if not payment_details: return {} else: paymentdetails = payment_details.split(',') add_url = f'{base_path}/api/v5/app/entry/data/create' if not float(price): res = filter_jdy_ht(id) _thread.start_new_thread(add_payment, ({"pay_amount": 0, "id": id, "fs": res[1], "jg": res[0], "name": res[4], "fsfz": res[6],"shfid": res[7], "hphm": res[5],"paymentdetails": paymentdetails}, 1)) return {} else: res = filter_jdy_ht(id) if not res: return "error" # fy = H5Main(res[2]) 安全统筹修改 if any("安全统筹" in detail for detail in paymentdetails): pattern = r"安全统筹\s*\d{4}-\d{2}" paymentdetails = [payment for payment in paymentdetails if re.search(pattern, payment)] if find_pay_details(id, paymentdetails) == 0: return "paymentdetails is not exist" fy = H5Main("0001000F7589577") else: fy = H5Main(res[2]) # 到此截止 price = float(price) * 100 # url = fy.unified_order(f"{id}{int(time.time())}", int(price), "订单支付").text # url = eval(url) order_id = f"{id}{int(time.time())}" add_info = { "app_id": cw_app, "entry_id": "67f38facbaccd58c66bd7db2", "is_start_trigger": True, "is_start_workflow": True, "data": { "mode_type": {"value": "自营"},"name": {"value": res[4]}, "shfid": {"value": res[7]}, "id": {"value": id},"hphm": {"value": res[5]}, "jg": {"value": res[0]}, "fs": {"value": res[1]},"fsfz": {"value": res[6]}, "pay_amount": {"value": price}, "order_id": {"value": order_id},"paymentdetails": {"value": paymentdetails} } } logger.info(f"add_info{add_info}") req_tool_jdy(add_url, add_info) message = fy.unified_order(order_id, int(price), "订单支付") return message except Exception as e: if "could not convert string to float" in str(e): err_str = "输入的金额必须为数字格式" return jsonify(error=str(err_str)), 500 logger.error(f"error{e}") return jsonify(error=str(e)), 500 @app.route('/paymentSuccess', methods=['POST']) def paymentsuccess(): try: logger.info(f"====================================machinepaymentSuccess=========================================") msg = request.data.decode('UTF-8') logger.info(f"机器返回回调参数为====",msg) msg = eval(msg) logger.info(f"=================================机器充值回调SUCCESS==========================================") # 获取'order_id'键的值并取前18个字符 id = msg['id_card'] # 查询机构、分司 res = filter_jdy_ht(id) transaction_id = msg['pay_ssn'] amount = float(msg['order_amt']) order_pay_type = msg['order_pay_type'] # 判断支付类型 if order_pay_type[:2] == "We": pay_type = "微信支付" elif order_pay_type[:3] == "Ali": pay_type = "支付宝支付" elif order_pay_type == "0000000000": pay_type = "云闪付支付" elif order_pay_type == "JSAPI": pay_type = "一体机支付" amount = amount / 100 info2 = {"pay_amount": amount, "id": id, "fs": res[1], "jg": res[0], "name": res[4], "fsfz": res[6],"shfid": res[7], "hphm": res[5], "transaction_id": transaction_id, "pay_type": pay_type,"paymentdetails": msg['paymentdetails']} logger.info(f"充值回调处理{info2}") if msg['paymentdetails'] == ["非专项"]: _thread.start_new_thread(add_payment, ({"pay_amount": amount, "id": id, "fs": res[1], "jg": res[0], "name": res[4], "fsfz": res[6],"shfid": res[7], "hphm": res[5], "transaction_id": transaction_id, "pay_type": pay_type, "paymentdetails": ""},)) else: _thread.start_new_thread(add_payment, ({"pay_amount": amount, "id": id, "fs": res[1], "jg": res[0], "name": res[4], "fsfz": res[6], "shfid": res[7], "hphm": res[5], "transaction_id": transaction_id, "pay_type": pay_type, "paymentdetails": msg['paymentdetails']},)) return {"code": 200} except Exception as e: logger.error(e) return jsonify(error=str(e)), 500 if __name__ == '__main__': app.run(host="0.0.0.0", port=3003, processes=True)