PayGateway: epay-compatible Go payment gateway with plugin channels and verifiable ledger
This commit is contained in:
commit
f2ae88b4e9
201 files changed
+44898
No files matched your search
+141
@@ -0,0 +1,141 @@
|
||||
# PayGateway 配置示例 —— 复制为 .env 后修改
|
||||
# cp .env.example .env && vim .env
|
||||
#
|
||||
# 配置加载顺序:.env 文件(本文件) → 运行时设置(settings 表,可由管理后台改)
|
||||
# 同名键后者覆盖前者;密钥类一律只从 .env 读取(不进 settings)。
|
||||
#
|
||||
# ⚠️ 重要:以下密钥更换会导致数据/会话不可恢复
|
||||
# - ACCOUNT_MASTER_KEY:accounts.db / upstreams.db 全部密文无法解密
|
||||
# - LEDGER_PRIVATE_KEY:旧账本条目验签失败
|
||||
# - QR_TOKEN_SECRET:旧二维码套码 token 失效,需重生成
|
||||
# - JWT_SECRET:所有登录会话失效(用户被踢下线,重新登录即可,无数据风险)
|
||||
|
||||
# ===== 网关监听 =====
|
||||
# 网关业务端口(易支付 /mq / 套码 /qr 等),对外暴露用
|
||||
GATEWAY_ADDR=:8080
|
||||
# 管理后台端口(Vue3 SPA + REST API + WebSocket)
|
||||
# 生产建议改为 127.0.0.1:8081 配合 nginx 反代,或不暴露
|
||||
ADMIN_ADDR=:8081
|
||||
|
||||
# ===== 对外地址 =====
|
||||
# 网关公网地址(用于向支付平台回调注册等)
|
||||
# 同机填 http://127.0.0.1:8080;公网填隧道/域名,留空自动推断为 http://127.0.0.1:8080
|
||||
EPAY_PUBLIC_BASE_URL=http://127.0.0.1:8080
|
||||
# 可选设备事件适配器的服务端可达地址。
|
||||
# PERSONAL_BASE_URL=
|
||||
# 通道回调地址(一般无需手动设;启动时由隧道动态更新)
|
||||
# ALIPAY_NOTIFY_URL=http://localhost:8080/alipay/notify
|
||||
# WECHAT_NOTIFY_URL=http://localhost:8080/wechat/notify
|
||||
|
||||
# ===== 上游对接(已废弃 .env 方式!)=====
|
||||
# 每个上游独立 pid + 密钥,AES-256-GCM 加密存于独立 upstreams.db。
|
||||
# 网关不再读取 EPAY_PID / EPAY_KEY,未登记的上游一律拒绝下单。
|
||||
# 配置入口:http://127.0.0.1:8081 → 上游对接 → 新增上游
|
||||
|
||||
# ===== 支付账户密钥(已废弃 .env 方式!)=====
|
||||
# 全部走管理后台 → 账户池 → 新增账户 配置;AES-256-GCM 加密存 accounts.db
|
||||
# 以下仅为历史字段注释,均不再读取:
|
||||
# ALIPAY_APP_ID / ALIPAY_PRIVATE_KEY_FILE / ALIPAY_PUBLIC_KEY_FILE
|
||||
# WECHAT_APP_ID / WECHAT_MCH_ID / WECHAT_API_KEY / WECHAT_IS_PROD
|
||||
|
||||
# ===== 订单自动关闭(动态关单窗口,docs/PLAN-DYNAMIC-CLOSE-ALLOC.md)=====
|
||||
# 【商家通道】未支付订单自动关闭时间(分钟,0=不自动关闭)。
|
||||
# 商家通道走官方 API、可主动查单、无监听延迟问题 → 固定窗口即可(默认 30min)。
|
||||
# 关单前必查单:已支付→补账;查单失败→跳过留待调度器/人工池;确认未支付→才关闭。
|
||||
ORDER_CLOSE_MINUTES=30
|
||||
# 【个人免签通道】动态窗口由设备负载驱动,clamp 在 [MIN, MAX] 之间(仅影响 personal.* 通道)。
|
||||
# 窗口 = clamp(设备一轮耗时(活跃账户数×配额×poll成本)×1.5 + 60s, MIN, MAX)
|
||||
# - 低负载(1~2 活跃账户)→ 逼近 MIN:确认快,尽早释放池配额
|
||||
# - 高负载(多账户积压)→ 逼近 MAX:给设备更多确认时间,防误关已付款订单
|
||||
# 0 或 MIN>=MAX → 个人免签退化为 ORDER_CLOSE_MINUTES 静态窗口
|
||||
# 注意:窗口只影响「未支付订单」何时关,已付款订单始终秒级入账,不受影响
|
||||
# 动态窗口下限(分钟,默认 5):下限锚点 = 用户扫码→支付操作时间(30s~2min) + 一轮完整确认
|
||||
ORDER_CLOSE_MIN=5
|
||||
# 动态窗口上限(分钟,默认 10):上限锚点 = 用户体验红线;超过转人工异常池升级处理,不是无限挂起
|
||||
ORDER_CLOSE_MAX=10
|
||||
# 关闭扫描间隔秒数(动态窗口下建议 30s 起,跟随 MAX 窗口粒度)
|
||||
ORDER_CLOSE_INTERVAL=30
|
||||
|
||||
# ===== 设备负载均衡(docs/PLAN-DYNAMIC-CLOSE-ALLOC.md §4.5/§5)=====
|
||||
# 单设备 WAIT_PAY 订单承载上限(0=按公式自动算:(MAX-60s)/(单次poll 4s)≈135)
|
||||
# 设备超限 → 均衡分配器跳过该设备,新单路由到其他健康设备
|
||||
DEVICE_LOAD_CAP=0
|
||||
# 设备降权阈值(占 DEVICE_LOAD_CAP 比例,默认 0.8):超过后该设备在分配中降权(缓冲带)
|
||||
DEVICE_OVERLOAD_RATIO=0.8
|
||||
# 单次 poll 成本估算(ms,动态窗口/设备能力计算用;埋点校准后可留 0)
|
||||
# DEVICE_POLL_COST_MS=4000
|
||||
|
||||
# ===== 存储 / 日志 =====
|
||||
# 业务库 SQLite 路径(订单/异常池/回调队列/设置)
|
||||
ORDER_DB=data/paygateway.db
|
||||
# 日志文件路径(slog JSON + 按天分文件:{date} 自动替换为当天日期,如 paygateway-2026-08-18.log)
|
||||
# 每文件 50MB 封顶、保留 10 份 × 30 天,超过自动清理;日志同时写入独立日志库 data/logs.db(长期保存)
|
||||
LOG_FILE=logs/paygateway-{date}.log
|
||||
# 日志级别:debug / info / warn / error
|
||||
LOG_LEVEL=info
|
||||
|
||||
# ===== 管理后台鉴权 =====
|
||||
# 管理员凭据已迁移到主数据库(settings 表,bcrypt 哈希),不再使用环境变量。
|
||||
# 首次启动(DB 无管理员时)访问管理后台自动进入注册页;注册后入口自动关闭。
|
||||
# 重置管理员:删除 paygateway.db settings 表中 admin_username / admin_password_hash 两行后重启。
|
||||
# JWT 签名密钥:留空 = 每次重启随机生成(重启后需重新登录)
|
||||
# 持久化方法:固定为 64 位十六进制(openssl rand -hex 32);更换会踢所有已登录用户下线
|
||||
# JWT_SECRET=
|
||||
|
||||
# ===== 加密 / 签名密钥(前 3 个缺失=服务拒绝启动;后 3 个可空)=====
|
||||
# 【必备·固定】账户加密主密钥:accounts.db / upstreams.db 全部密文用此加解密
|
||||
# 首次部署生成:openssl rand -hex 32
|
||||
# ⚠️ 一旦部署,永不能改 —— 改了等于丢掉所有已配置账户/上游密钥
|
||||
ACCOUNT_MASTER_KEY=REPLACE_WITH_openssl_rand_hex_32
|
||||
|
||||
# 【可选·推荐固定】审计账本签名私钥(ECDSA P-256 PEM 格式)
|
||||
# 留空 = 首次启动自动生成并持久化到 settings 表(重启复用)
|
||||
# 显式提供可跨实例迁移账本;更换则旧账本条目验签失败
|
||||
# LEDGER_PRIVATE_KEY=
|
||||
|
||||
# 【可选·推荐固定】个人免签套码 token 签名密钥
|
||||
# 留空 = 首次启动自动生成并持久化到 settings 表(重启复用)
|
||||
# 更换则旧"用户扫码 → /mq/{token}"链接全部失效,需在管理后台重新生成套码
|
||||
# QR_TOKEN_SECRET=
|
||||
|
||||
# ===== 个人免签风控(金额单位均为分)=====
|
||||
# 单笔限额(默认 50000 = 500 元;0 = 不限)
|
||||
# PERSONAL_MAX_AMOUNT=50000
|
||||
# 大额告警阈值(默认 20000 = 200 元;超此触发 Bark / Webhook 告警)
|
||||
# PERSONAL_BIG_AMOUNT=20000
|
||||
# 单设备每分钟收款推送上限(默认 30;超过则限流,防止监听端异常刷消息)
|
||||
# PERSONAL_MAX_PER_MIN=30
|
||||
|
||||
# ===== 告警(RESILIENCE.md P1-3)=====
|
||||
# Bark 推送 URL(https://api.day.app/<key>),空=禁用
|
||||
# ALERT_BARK_URL=
|
||||
# 通用 Webhook URL(POST JSON:掉线 / 账本异常 / 风控文案检测)
|
||||
# ALERT_WEBHOOK_URL=
|
||||
|
||||
# ===== 公网接口 IP 限流(防刷 / 防 DoS)=====
|
||||
# 窗口内单 IP 最大请求数(仅作用于 /submit.php /api.php /qr/refresh /mq/:token,不影响 /alipay/notify /wechat/notify /personal/* 签名回调),0=禁用
|
||||
# PUBLIC_RATE_MAX=60
|
||||
# 滑动窗口秒数,0=禁用
|
||||
# PUBLIC_RATE_WINDOW_SEC=60
|
||||
|
||||
# ===== 可选二维码适配器 =====
|
||||
# 具体模式由授权的业务适配器定义。
|
||||
PERSONAL_QR_MODE=direct
|
||||
|
||||
# ===== Cloudflare 命名隧道(固定域名,生产环境推荐)=====
|
||||
# 非空 = 命名隧道模式(cloudflared tunnel run --config,公网固定域名)
|
||||
# 空 = 快速隧道(trycloudflare.com 随机域名,仅测试用,重启后域名变化)
|
||||
CF_TUNNEL_HOSTNAME=your-domain.example.com
|
||||
# 隧道凭据 JSON 的 base64 编码(含 TunnelID/AccountTag/TunnelSecret)
|
||||
# 生成方法:base64 -w0 < ~/.cloudflared/paygateway.json
|
||||
CF_TUNNEL_CREDENTIALS=your_base64_encoded_tunnel_credentials
|
||||
# Cloudflare 账户邮箱(setup-domain.sh 需要)
|
||||
CF_EMAIL=your-email@example.com
|
||||
# Cloudflare Global API Key(setup-domain.sh 自动配置 zone/DNS/SSL)
|
||||
CF_GLOBAL_KEY=your_global_api_key
|
||||
|
||||
# ===== DNSHe API(de5.net 免费子域名需要;setup-domain.sh 全自动处理)=====
|
||||
# 脚本能力:子域名不存在时自动注册 + 自动把子域 NS 委派给 Cloudflare
|
||||
DNSHE_API_KEY=your_dnshe_api_key
|
||||
DNSHE_API_SECRET=your_dnshe_api_secret
|
||||
DNSHE_API_BASE=https://api005.dnshe.com
|
||||
Reference in new issue
Block a user