164 Commits

Author SHA1 Message Date
f87b915cdd bugfix 2026-07-17 11:30:29 +08:00
6e5911ad46 bugfix 2026-07-17 11:21:28 +08:00
befa093a30 bugfix 2026-07-17 11:11:22 +08:00
68eff9086b bugfix 2026-07-17 11:03:42 +08:00
8972085696 bugfix 2026-07-17 10:58:28 +08:00
0b6d5e1695 bugfix 2026-07-17 10:57:52 +08:00
d6aa61795a bugfix 2026-07-17 10:56:39 +08:00
0cebfd140f bugfix 2026-07-17 10:50:51 +08:00
df6aa60006 ui: transfer_info display as flat text rows instead of read-only Form 2026-07-17 10:49:52 +08:00
68ca493840 bugfix 2026-07-17 10:36:15 +08:00
3617403201 bugfix 2026-07-16 18:58:54 +08:00
9d0f9c568e fix(wechat): payload.subject → payment_name fallback, amount ×100 yuan→fen 2026-07-16 18:45:52 +08:00
9939ccf5ef fix: transfer_info.ui 子控件从 options.children 改为 subwidgets 2026-07-16 18:22:26 +08:00
baf84725e0 fix: transfer opens NewWindow like wechat/alipay, not replace main content 2026-07-16 17:52:29 +08:00
2cac8fe4be fix(wechat): revert to H5 payment — h5_url is directly browser-openable, no tenpay conversion needed 2026-07-16 17:49:29 +08:00
d4c9568673 fix(wechat): use wx.tenpay.com/f2f for web payment, weixin:// is not browser-openable 2026-07-16 17:40:20 +08:00
403cdd5de1 revert: 恢复原始支付流程——获取支付URL后直接新窗口跳转,移除QR码 2026-07-16 17:33:46 +08:00
149092a3a0 security: 移除第三方 qrserver.com,改用本地 qrcode 生成 QR 码 2026-07-16 17:25:34 +08:00
e83e8e4d8d fix: 实现转账邮件轮询后台任务,自动匹配转账码并完成入账 2026-07-16 16:32:02 +08:00
abd7b49b79 feat: 转账充值增加收款户名(ACCOUNT_NAME)字段 2026-07-16 15:51:59 +08:00
4ba232805b feat: 添加线下转账充值信息展示页 transfer_info.ui 2026-07-16 15:31:38 +08:00
067510df65 fix(unipay): transfer shows bank info page directly instead of QR code 2026-07-16 15:09:32 +08:00
be119368c5 fix(unipay): register transfer_info.ui in load_path.py RBAC permissions 2026-07-16 12:58:30 +08:00
e64bfe81ea feat(unipay): transfer popup displays bank_name and bank_branch from env vars
- init.py: add BANK_NAME/BANK_BRANCH to CONF_ENV['transfer']
- transfer.py: TransferGateway accepts and forwards bank_name/bank_branch
- transfer_info.ui: conditionally display 收款银行/开户行 rows
2026-07-16 12:06:01 +08:00
a0bd6fb24f revert: QR code is required for Native payment, weixin:// is not a web URL
Native payment code_url uses weixin:// protocol which is a WeChat deep link,
not openable in browsers. QR code is the standard approach - user scans
with WeChat and completes payment within the app.
2026-07-16 11:57:36 +08:00
a95c548f84 feat(wechat): use wx.tenpay.com payment page instead of third-party QR 2026-07-16 10:50:06 +08:00
c96da0af11 feat(transfer): add transfer_info.ui page for bank transfer info 2026-07-15 18:16:57 +08:00
4f61f48cc4 fix(transfer): str+int TypeError in gen_mailcode 2026-07-15 17:58:47 +08:00
526c93ada7 fix(transfer): fix parameter name mismatch in CONF_ENV and TransferGateway
- CONF_ENV had 'mail' but TransferGateway.__init__ expects 'email'
- TransferGateway had 'from_email' typo (undefined NameError) → 'from_mail'
2026-07-15 17:53:40 +08:00
97524da74d fix(wechat): use Response instead of missing json_response in callback
ServerEnv().json_reponse does not exist, causing 'NoneType' object
is not callable. Align with alipay_notify pattern: use aiohttp Response
directly with JSON string body.
2026-07-15 17:43:06 +08:00
7e37b00672 fix(wechat): don't block init on missing WXP_API_V3_KEY
API v3 key is only needed for callback verification, not payment creation.
- Remove init-time validation (was blocking all wechat payments)
- Gracefully degrade: set api_v3_key=None if invalid, warn at startup
- Raise clear error at callback time if key still missing
2026-07-15 17:40:27 +08:00
bf916b98ff fix(wechat): validate WXP_API_V3_KEY at init time
AES-256-GCM requires 32-byte key. 'None' placeholder is only 4 bytes,
causing ValueError during callback decryption instead of at startup.
Now fails fast with clear error if key is missing/invalid.
2026-07-15 17:29:19 +08:00
cae22f84be fix(wechat): convert yuan to fen for WeChat amount (×100)
WeChat amount.total is in fen (分), but user enters yuan (元).
int(0.01) = 0 which fails WeChat's minimum 1 fen validation.
Fix: int(amount * 100)
2026-07-15 17:25:47 +08:00
1a2d8f8f2d feat(wechat): switch from H5 to Native payment (QR code scan)
- Change API endpoint from /v3/pay/transactions/h5 to /v3/pay/transactions/native
- Remove scene_info (not needed for native mode)
- Return code_url instead of h5_url
- recharge.dspy: display QR code image via api.qrserver.com
- user_recharge.dspy: return both code_url and qr_url
2026-07-15 17:22:40 +08:00
0266f9fb65 fix(wechat): handle API errors instead of silently returning null h5_url
- Check HTTP status code, raise exception on non-200
- Raise exception if h5_url missing from response
- Fix description field to use .get() instead of direct key access
- Remove unreachable return None

Previously WeChat API errors (param errors, amount issues, etc.)
would return None, causing the frontend to show:
  https://token.opencomputing.cn/null
Now errors are properly raised and shown to the user.
2026-07-15 17:04:21 +08:00
ccee3ba12b feat: 启用微信支付和转账支付渠道
- recharge.ui: 下拉列表添加微信支付和转账支付选项
- user_recharge.dspy: 扩展provider校验,支持wechat/transfer
- wechat.py: 修复description字段兼容payment_name
- transfer.py: 导入DBPools + 修复tcode拼写错误
2026-07-15 13:45:21 +08:00
7a0e87e735 fix: get_pay_fee 返回 fee_rate 而非 fee_rate*amount,修复双重乘法
get_pay_fee() 返回 fee_rate*amount,但 create_payment()
又把返回值当 feerate 传给 new_log(),new_log() 内部又乘
一次 amount,导致 pay_fee = fee_rate * amount²。

修复:
- get_pay_fee() 改为只返回 fee_rate
- create_payment() 自己计算 fee = feerate * amount
- new_log() 传 feerate 而非 fee
2026-07-01 11:51:20 +08:00
a9c99305fc Revert "fix: sor_get_pay_feerate 加 ORDER BY + LIMIT 1 防非确定性取值"
This reverts commit 4ec1f12396fd2e2b697d473911a8d0f846caaf4d.
2026-07-01 11:49:46 +08:00
4ec1f12396 fix: sor_get_pay_feerate 加 ORDER BY + LIMIT 1 防非确定性取值
无 ORDER BY 时 MySQL 可能返回非确定的行顺序,
两次同参数调用取到不同费率。
2026-06-30 18:29:03 +08:00
69d503051f fix: payfee.fee_rate 费率精度 2→4 位小数
DB 迁移:
  ALTER TABLE payfee MODIFY COLUMN fee_rate DOUBLE(18,4) NOT NULL;
2026-06-30 18:06:33 +08:00
854a0fdc12 fix: payment_log.json 移除 Jinja2 {% if %} 块,CRUD json 文件必须为纯 JSON 2026-06-29 18:12:55 +08:00
50566ed576 fix: payment_log.json JSON 语法错误导致 xls2ui 崩溃
两处修复:
1. logined_userorgid 从 browserfields 内移到 params 层级
2. binds[0] 缺少开头 { 导致 JSON 解析失败 (line 25 column 9)
2026-06-29 17:31:19 +08:00
Hermes Agent
a6d0380903 feat: add i18n translations (zh/en/jp/ko) for all modules 2026-06-19 15:01:45 +08:00
Hermes Agent
9b2e414af5 chore: 添加json/build.sh脚本 2026-06-17 17:26:32 +08:00
1773bce216 feat: disable wechat payment channel, keep alipay only
- Remove wechat from provider options
- Set alipay as default payment channel
- Only alipay is currently enabled for unipay
2026-05-30 13:27:23 +08:00
1ae077df93 refactor(models): convert to json format per database-table-definition-spec 2026-05-27 13:23:34 +08:00
5a452c0052 feat: add load_path.py RBAC permission registration script 2026-05-27 13:16:11 +08:00
a688d3d562 fix: defer payment provider init to load_unipay(), graceful failure
- Move env var reading and key file open() from import-time CONF dict
  into _build_provider_conf() called during load_unipay()
- Each provider is wrapped in try/except — if env vars are missing,
  key files don't exist, or instantiation fails, the provider is
  set to None (disabled) and a warning is printed
- Program continues to start even if all payment channels fail
- Existing code already checks PROVIDERS[name] is None in all
  business functions (create_payment, notify handlers, etc.)
- Existing get_provider() in notify.py already returns None on
  instantiation error
2026-05-26 16:47:46 +08:00
b40300ad35 feat: add json table definitions for all models (converted from xlsx) 2026-05-21 12:46:36 +08:00
1dfa144611 bugfix 2026-03-25 11:51:14 +08:00