From b739553f06e62e1ea7f723dbd18e31de33e00846 Mon Sep 17 00:00:00 2001 From: eric Date: Wed, 17 Dec 2025 06:36:07 -0600 Subject: [PATCH] 's' --- app/__pycache__/__init__.cpython-312.pyc | Bin 134 -> 132 bytes app/__pycache__/main.cpython-312.pyc | Bin 4486 -> 3039 bytes app/main.py | 162 +++++++++-------------- 3 files changed, 62 insertions(+), 100 deletions(-) diff --git a/app/__pycache__/__init__.cpython-312.pyc b/app/__pycache__/__init__.cpython-312.pyc index 720495a3abc1420fe49998eeb993b19e92c16a65..79cb13c5e104653372cc4a5ca3acf057fd148f49 100644 GIT binary patch delta 48 zcmZo;Y+>X+&CAQh00j0W?G6vRx7)CB-V CHxE$& delta 50 zcmZo+Y-8j;&CAQh00hGKZ%pJimR8j-FE0n-qWt_4{er~Gtm4FiO#Q@y0{w~Mx&UoL B5D)+W diff --git a/app/__pycache__/main.cpython-312.pyc b/app/__pycache__/main.cpython-312.pyc index e3f955926d3c6e5e4d634278c0e0a7ec73b834c6..e951125e238a7b3b40ec6a36b6ed83241a481a70 100644 GIT binary patch literal 3039 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 Hj6?W0hgtSh literal 4486 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 str: + raw = name + pay_type + price + order_id + notify_url + SECRET + return hashlib.md5(raw.encode('utf-8')).hexdigest().lower() @app.post("/payh5") async def payh5(item: dict): - print('item', item) - # 时间戳 - timenew = str(int(time.time())) - order = { - "mchid": mchid, - "body": timenew, # 订单标题 - "out_trade_no": timenew, # 订单号 - "total_fee": item['total_fee'], # 金额,单位:分 - # "openid": "o7LFAwWu3OhSrs49-1x5cSlFm0D8", # 通过openid接口获取到的openid - # "notify_url": "" - # "callback_url":'https://aiimg.hackrobot.cn/api' + print('payh5 item:', item) + + total_fee_yuan = f"{item['total_fee'] / 100:.2f}" + + random_suffix = ''.join(random.choices(string.hexdigits.lower(), k=8)) + order_id = f"order_{int(time.time())}_{random_suffix}" + + type_map = { + "book": "购买书籍", + "meetup": "活动报名", + "video": "视频解锁", + "vip": "VIP会员充值", + } + name = type_map.get(item.get('type'), "商品支付") + + notify_url = "https://www.hackrobot.cn".rstrip("/") + + # 临时不传 return_url,避免 ngrok 干扰 + # return_url = item.get('callback_url') + + params = { + "name": name, + "pay_type": "jsapi", + "price": total_fee_yuan, + "order_id": order_id, + "notify_url": notify_url, } - order["callback_url"] = item['callback_url'] - order["openid"] = item['openid'] - order["sign"] = sign(order) + # if return_url: + # params["return_url"] = return_url - request_url = "https://payjs.cn/api/jsapi" - # 返回结果中包含`jsapi`字段,该字段的值即是前端发起时所需的6个支付参数 - headers = {"content-type": "application/x-www-form-urlencoded"} - response = requests.post(request_url, data=order, headers=headers) - print('response.json()----',response.json()) - if response: - print(response.json()) - return response.json() + params["sign"] = xorpay_sign( + params["name"], + params["pay_type"], + params["price"], + params["order_id"], + params["notify_url"] + ) + print("生成的参数:", params) - -class CreateUserRequest(BaseModel): - username: str = None - password: str = None - -@app.post("/create_user") -async def create_user(item: CreateUserRequest): - timenew = str(int(time.time())) - memos_data = { - "username": item.username or f"user{timenew}", - "password": item.password or "123456", - "role": "USER", - "state": "NORMAL" + # 返回参数字典,前端用 form POST + return { + "status": "ok", + "xorpay_params": params, + "xorpay_url": f"https://xorpay.com/api/cashier/{AID}" } - memos_headers = { - "Content-Type": "application/json", - "Authorization": f"Bearer {MEMOS_TOKEN}" - } - memos_resp = requests.post(MEMOS_API, json=memos_data, headers=memos_headers) - memos_result = memos_resp.json() - print('memos_result-',memos_result) - return memos_result - +# 异步通知回调 +@app.post("/xorpay_notify") +async def xorpay_notify(request: dict): + print("XorPay 异步通知:", request) + # TODO: 正式上线后加验签和订单处理 + return {"status": "ok"} \ No newline at end of file