Files

5.4 KiB

pay v2 — pangolin1 部署脚手架

pangolin1(103.119.13.48,Debian 12,root,内存 ~960Mi)上单独跑一份 payd 实例(pay-v2),只走 crypto(USDT-TRC20)+ 哪吒(nezha,CNY)双渠道,MOCK 关。 与阿里云那份 pay(仓库根 deploy.sh,支付宝+微信)彻底分开:不同 systemd 服务名(pay-v2)、不同端口(8090,旧 USDT watcher 已下线释放)、不同二进制/数据/ 配置路径(/opt/pay-v2 /var/lib/pay-v2 /etc/pay-v2)、不同系统用户(payv2)。

文件清单

文件 用途
pay-v2.service systemd unit,装到 pangolin1 的 /etc/systemd/system/pay-v2.service
pay.env.example env 模板,人工填真值后存到 pangolin1 的 /etc/pay-v2/pay.env(不进 git)
config.yaml 非密钥配置源,deploy.sh 首次部署会拷到 /etc/pay-v2/config.yaml
deploy.sh 部署脚本(交叉编译 + 上传 + 装 unit/config + 重启 + 探活回滚)

部署步骤

  1. 先手工准备凭证(pangolin1 上,或本机 rbw get 取值后 scp/粘贴):

    ssh pangolin1 'mkdir -p /etc/pay-v2'
    # 把 pay.env.example 拷一份改名 pay.env,逐项填真值,再传上去:
    scp pay.env pangolin1:/etc/pay-v2/pay.env
    ssh pangolin1 'chmod 640 /etc/pay-v2/pay.env'
    

    需要人工填的 env(全部走 Bitwarden,建议条目命名见括号):

    • PANGOLIN_CRYPTO_1_ADDRESS —— TRC20 收款地址(Bitwarden:pay-v2 pangolin1 crypto-1)
    • TRONGRID_API_KEY —— TronGrid API key(同上条目,或单独 pay-v2 trongrid-key)
    • PANGOLIN_NEZHA_1_PID —— 哪吒商户号(Bitwarden:pay-v2 pangolin1 nezha-1)
    • PANGOLIN_NEZHA_1_PRIVATE_KEY —— 商户 RSA 私钥 PEM(同上条目)
    • PANGOLIN_NEZHA_1_PLATFORM_PUBLIC_KEY —— 哪吒平台 RSA 公钥 PEM(同上条目)
    • BIZ_PANGOLIN_SECRET —— 与 pangolin-server 的 PAY_BIZ_SECRET 同值 (Bitwarden:pay-v2 BIZ_PANGOLIN_SECRET,两边必须手工同步同一个值)
  2. config.yaml 里的占位域名(部署前,本地改好再让 deploy.sh 上传首个版本):

    • biz.pangolin.callback_url<pangolin-server-域名占位> 换成真实域名。
  3. 跑部署脚本(pay 仓根目录,本机执行):

    ./deploy/pangolin1/deploy.sh
    

    首次会:建 payv2 系统用户 → 建 /opt/pay-v2 /var/lib/pay-v2 /etc/pay-v2 → 装 unit → 拷 config.yaml(仅当远端还没有时)→ 传二进制 → enable --now → 探活 curl 127.0.0.1:8090/health。之后重跑只刷新二进制,config.yaml/pay.env 都不会被覆盖(改配置要单独 scpsystemctl restart pay-v2)。

  4. 验证:

    ssh pangolin1 'systemctl status pay-v2 --no-pager'
    ssh pangolin1 'journalctl -u pay-v2 -n 50 --no-pager'
    ssh pangolin1 'curl -s 127.0.0.1:8090/health'
    

seed 生产套餐(占位命令,按需调整价格/名称)

pay 目前套餐通过代码里的 seed()/seedWechat() 之类函数在启动时 upsert,或者用 管理接口/直接写库。crypto 结算币种是 USDT,nezha 结算币种是 CNY——两个渠道各需 一套独立的 ProductPrice(同一 Product 下按币种分别挂价,不能共用一条同金额 不同币种硬凑)。生产 seed 前先确认落地方式(建代码里的 seed 函数,还是走管理接口), 以下只是占位:

# 占位:crypto(USDT)套餐价 —— 具体走哪个接口/表待定,先别直接照抄执行
# INSERT INTO product_prices (product_id, currency, amount, ...) VALUES (..., 'USDT', ...);

# 占位:nezha(CNY)套餐价
# INSERT INTO product_prices (product_id, currency, amount, ...) VALUES (..., 'CNY', ...);

渠道说明

  • crypto:method 名为 crypto。地址 watch-only,payd 不做归集——收到的 USDT 一直留在 PANGOLIN_CRYPTO_1_ADDRESS 这个地址上,不会自动转出。定期手动 归集/转出是运营动作,不在 payd 职责内。
  • nezha:method 名预期为 nezha(哪吒 provider 正在另一分支开发,尚未合并 进 internal/providerbuild/registry.goBuildRegistry)。本仓 config.yaml 已经把 pangolin-nezha-1 账户和 credential_env_prefix 结构定好,但在 provider 代码合并前,该渠道不会真正被注册(BuildRegistry 只认识 crypto/alipay/stripe/fake,未知 channel 的 enabled 账户会被静默忽略, 不会 fatal,只是收不到这个渠道)。provider 分支合并后需确认:
    • env 变量名是否确实是 PID / PRIVATE_KEY / PLATFORM_PUBLIC_KEY(本文档 按任务描述推导,以 provider 代码实际 accts.Credential(accountID, "KEY") 调用为准);
    • PEM 私钥/公钥在 pay.env 里是单行原始换行还是 \n 转义,需和 provider 的 解析方式对齐(pay.env.example 里留了两种可能的说明)。

已知易错点

  • QUERY_SYNC_ENABLED 不是 QUERYSYNC_ENABLED——viper 的 "." → "_" 替换对 query_sync.enabled 展开成 QUERY_SYNC_ENABLED(带下划线),已用本地 viper 用例验证过。pay.env.example 里已经用对的名字。
  • 绝对不要pay.envconfig.yaml 里设置 MOCK_CHANNEL_ENABLED=true / mock_channel_enabled: true——会注册 fake 渠道并挂载 /api/v2/dev/orders/:order_no/mark-paid 这类联调专用端点,生产环境绝不能开。
  • 阿里云那份 pay(仓库根 deploy.sh)服务名是 pay、端口 8080、路径 /opt/pay;这份是 pay-v2 / 8090 / /opt/pay-v2,两者互不干扰,别把 两个 deploy.sh 搞混执行