From d77f90cb8c8c10ae07fd0f68df546fc91a64f6e1 Mon Sep 17 00:00:00 2001 From: eric Date: Sun, 8 Mar 2026 06:43:29 -0500 Subject: [PATCH] 's' --- .env.example | 18 ++- app/__pycache__/config.cpython-312.pyc | Bin 1787 -> 1839 bytes app/__pycache__/main.cpython-312.pyc | Bin 15477 -> 21237 bytes app/config.py | 4 +- app/main.py | 131 ++++++++++++++++++- app/payment/__pycache__/zpay.cpython-312.pyc | Bin 6808 -> 6767 bytes app/payment/zpay.py | 9 +- payment_notify.log | 6 + 8 files changed, 155 insertions(+), 13 deletions(-) diff --git a/.env.example b/.env.example index f833d04..286db19 100644 --- a/.env.example +++ b/.env.example @@ -1,7 +1,16 @@ -# 支付渠道:xorpay | zpay -PAYMENT_PROVIDER=xorpay +# ========== 本地调试 ========== +# BASE_URL 需为 ZPAY 可访问的回调地址。本地调试时 ZPAY 无法回调 localhost, +# 可用 ngrok 等隧道:BASE_URL=https://xxx.ngrok.io +# 或直接使用生产地址测试回调(需 payjsapi 已部署到公网) -# XorPay(默认) +# ========== 生产部署 ========== +# BASE_URL 必须为 payjsapi 实际公网地址,ZPAY 异步通知会请求此地址 +BASE_URL=https://api.hackrobot.cn + +# 支付渠道:xorpay | zpay(默认 zpay) +PAYMENT_PROVIDER=zpay + +# XorPay XORPAY_AID=8220 XORPAY_SECRET=your_secret @@ -9,9 +18,6 @@ XORPAY_SECRET=your_secret ZPAY_PID=2025121809351743 ZPAY_KEY=tpEi7wWIWI2kXiYVTpIG6j7it0mjVW89 -# 回调根地址 -BASE_URL=https://api.hackrobot.cn - # PocketBase PB_URL=https://pocketbase.hackrobot.cn PB_ADMIN_EMAIL=your@email.com diff --git a/app/__pycache__/config.cpython-312.pyc b/app/__pycache__/config.cpython-312.pyc index 57578c79fa83595835b49e425aa24e8f6cf668fd..97f31b83b86691b6496600896dd7e66085601e3e 100644 GIT binary patch delta 288 zcmey(yPl8tG%qg~0}%9Rtj%1ok=KclQDAZaqcX2xiqL8%kOTum6yL-ENoL^`k;!v_ z5~3+$a0vmBgm{X?Xl`PBiz6z)F*4rUHS(51Nr7vod3m^JxTjHeL}p}INP(xjS(bTbi9v2w zSh$7d<_KmPCMf}+i;4t6gb;`j1`#44LUeK;s|A+=kjV(d#j2Apu%95 F000seMil@6 delta 236 zcmZ3__nVjZG%qg~0}xD8UYjYqk=Kclk#BMUqcX2Rir{J{kOTum6yL-ENoJuG;mLD= z5+W(0a0vmBgjkCBTKL12R3Wrm>1Zfu_73xqCnt2A)j;1=mH>bLB)oDc;TnY@CnnMD?8007IK BH8lVL diff --git a/app/__pycache__/main.cpython-312.pyc b/app/__pycache__/main.cpython-312.pyc index 2de8ef6cfcaf9e0c924fc8dbc7defe178fcd8b31..d1f3593d0ca06399c7a3c4310af222f7d5029a5c 100755 GIT binary patch delta 7934 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 delta 639 zcmY+8PiWIn9LL{Vn{KB0-=s;lb_6TLDH~vw9dbP z4!SC=o%^aytWnRYU2UeP&1{T+6#ClPU2VRn&2KMU-_i7zxT>zGPsX;b#b)YTT58>B z8$0R3%hVh46}fS`Up(`^@})S3W;6E*mydQtKQiB8v%4j(L-+{Y&The=dtTmzcS{5r zra&ee4r3YttPmctY-ZOx{g diff --git a/app/payment/zpay.py b/app/payment/zpay.py index ce5f4b9..e19811b 100644 --- a/app/payment/zpay.py +++ b/app/payment/zpay.py @@ -115,8 +115,13 @@ class ZPayProvider(PaymentProvider): params["sign"] = self._md5_sign(params) resp = requests.post(self.MAPI_URL, data=params, timeout=15) - result = resp.json() if resp.headers.get("content-type", "").startswith("application/json") else {} - if isinstance(result, dict) and result.get("code") == 1: + try: + result = resp.json() + except Exception: + result = {} + if not isinstance(result, dict): + result = {} + if int(result.get("code", 0)) == 1: return { "status": "ok", "provider": self.name, diff --git a/payment_notify.log b/payment_notify.log index e69de29..048bd20 100644 --- a/payment_notify.log +++ b/payment_notify.log @@ -0,0 +1,6 @@ +2026-03-08 03:04:04,172 - ZPAY ѯʧ: HTTPSConnectionPool(host='zpayz.cn', port=443): Read timed out. (read timeout=10) +2026-03-08 06:25:51,919 - ZPAY ѯʧ: HTTPSConnectionPool(host='zpayz.cn', port=443): Read timed out. (read timeout=10) +2026-03-08 06:28:42,212 - ZPAY ѯʧ: HTTPSConnectionPool(host='zpayz.cn', port=443): Read timed out. (read timeout=10) +2026-03-08 06:31:18,405 - ZPAY ѯʧ: HTTPSConnectionPool(host='zpayz.cn', port=443): Read timed out. (read timeout=10) +2026-03-08 06:39:41,805 - ZPAY ѯʧ: HTTPSConnectionPool(host='zpayz.cn', port=443): Read timed out. (read timeout=10) +2026-03-08 06:40:22,362 - ZPAY ѯʧ: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))