跳转至

支付服务 Runbook(微信 Native / 支付宝网站支付)

权威产品契约见 membership-agent-sales-guide.md。 范围:会员方案支付(微信 V3 Native 扫码 + 支付宝电脑/手机网站收银台);不含当面付扫码、日账单对账。

1. 本地联调(一分钱)

  1. 将商户证书放到 src/backend/cert/(已 gitignore),例如:
  2. apiclient_key.pem / pub_key.pem(微信)
  3. alipayPriveKey_RSA2.txt / alipayPublicKey_RSA2.txt(支付宝,密钥模式
  4. src/backend/.env 配置(对照 .env.example):
  5. PAYMENT_ENABLED=true
  6. PAYMENT_TEST_AMOUNT_FEN=1(联调强制 0.01 元)
  7. WECHAT_* / ALIPAY_* 与回调 URL
  8. 微信商户平台「Native 支付回调」填:https://<公网域名>/wepayapi/notifyWECHAT_NOTIFY_URL 保持一致(后端 wepay_router)。
  9. 支付宝异步通知填:https://<公网域名>/api/payment/notify/alipay(或 ALIPAY_NOTIFY_URL)。
  10. 支付宝同步回跳:PAYMENT_RETURN_URL 填前端落地页(如 https://tuxianai.com/account?tab=ledger 充值记录)。 不要把带 ? 的前端地址直接当作支付宝 return_url——官方禁止自定义 query, 会出现「付款成功,3 秒后自动返回商户」却永不跳转。 后端会按 ALIPAY_NOTIFY_URL 推导 https://<公网域名>/api/payment/return 传给支付宝, 再 302 到 PAYMENT_RETURN_URL
  11. 下单后前端应轮询 GET /api/billing/orders/{id},或调用 POST /api/billing/orders/{id}/sync-pay(回调丢失时的标准兜底)。
  12. 上线前必须PAYMENT_TEST_AMOUNT_FEN=0APP_ENV=production 且该项 >0 时启动失败。

1.1 支付宝加签方式:密钥模式(本仓库唯一支持)

开放平台「开发设置 → 接口加签方式」须选 密钥(普遍适用),不要选「证书」。

开放平台操作 本地文件 / 配置
生成/上传「应用公钥」后得到「支付宝公钥」 cert/alipayPublicKey_RSA2.txt(支付宝公钥,非应用公钥)
应用私钥(仅本地保存,勿上传) cert/alipayPriveKey_RSA2.txt
应用 AppID ALIPAY_APP_ID

文件可为 PEM 全文,或仅 Base64 正文(启动时自动补 BEGIN/END)。后端用 RSA2:app_private_key_string + alipay_public_key_string使用应用公钥证书 / 支付宝根证书。

2. 证书与镜像

规则 说明
禁止进 Git src/backend/cert/*(除 .gitkeep
禁止进镜像 .dockerignore 已排除 src/backend/cert/**
本地加载 WECHAT_*_PATH / ALIPAY_*_PATH 相对 src/backend/
内联备选 也可把 PEM 全文写入 Secret / .env(勿提交)

PAYMENT_ENABLED=true 时应用启动会校验:至少微信或支付宝凭证齐全,且存在回调 URL。

3. ACK Secret 挂载约定

3.1 推荐:Secret stringData 注入密钥(无文件)

deploy/ACK/secrets.example/backend-secrets.yaml 中预留支付相关键;make ack-secrets / create-secrets.ps1 可从 src/backend/.env 同步:

  • PAYMENT_ENABLED / PAYMENT_NOTIFY_URL / PAYMENT_RETURN_URL / PAYMENT_ORDER_EXPIRE_MINUTES
  • PAYMENT_TEST_AMOUNT_FEN(生产必须 0
  • WECHAT_* / ALIPAY_*(含内联 PEM 或 PATH)

若使用 PATH,须同时挂载证书文件(见下)。

3.2 可选:文件型 Secret 挂载到 /app/src/backend/cert

kubectl -n harness-app create secret generic harness-payment-certs \
  --from-file=apiclient_key.pem=./apiclient_key.pem \
  --from-file=pub_key.pem=./pub_key.pem \
  --from-file=alipayPriveKey_RSA2.txt=./alipayPriveKey_RSA2.txt \
  --from-file=alipayPublicKey_RSA2.txt=./alipayPublicKey_RSA2.txt

在 backend Deployment 增加(示例,勿把明文写进仓库):

volumeMounts:
  - name: payment-certs
    mountPath: /app/src/backend/cert
    readOnly: true
volumes:
  - name: payment-certs
    secret:
      secretName: harness-payment-certs

并保证 env 中:

WECHAT_MCH_PRIVATE_KEY_PATH=cert/apiclient_key.pem
WECHAT_PUBLIC_KEY_PATH=cert/pub_key.pem
ALIPAY_PRIVATE_KEY_PATH=cert/alipayPriveKey_RSA2.txt
ALIPAY_PUBLIC_KEY_PATH=cert/alipayPublicKey_RSA2.txt

4. 回调排查

现象 排查
通道反复通知 验签失败或履约失败返回 FAIL;查 backend 日志字段 order_no / transaction_id / error
用户已付本地未开通 POST .../sync-pay;核对金额与 PAYMENT_TEST_AMOUNT_FEN
订单变 cancelled PAYMENT_ORDER_EXPIRE_MINUTES(默认 30)惰性关单;可重新下单
Mock 不可用 PAYMENT_ENABLED=true 时禁止 mock;开发期置 false
支付宝跳转报 insufficient-isv-permissions 不是代码签名错误。开放平台 AppID 未签约/未添加「电脑网站支付」或「手机网站支付」能力,或状态非「生效」。见下方 §4.1
付款成功显示 3 秒回商户但不跳转 return_url 带了自定义 ? 参数(如 .../account?tab=ledger)。须走 /api/payment/return 中转;确认 ALIPAY_NOTIFY_URL 已配且 backend 已重启

日志关键字:支付回调查单同步支付退款超时关单(无密钥原文)。

4.1 支付宝 insufficient-isv-permissions

本仓库默认调用 alipay.trade.page.payALIPAY_PAY_MODE=page,产品码 FAST_INSTANT_TRADE_PAY)。

开放平台控制台 对 AppID ALIPAY_APP_ID 逐项确认:

  1. 应用已创建并上线/审核通过
  2. 「能力列表」中已添加 电脑网站支付,状态为 生效(没有则「添加能力」搜索添加)
  3. 商家中心「产品中心」对应产品已签约且生效
  4. 若只签约了手机网站支付:.envALIPAY_PAY_MODE=wap 后重启 backend
  5. 当面付未签约时不要扫码;网站支付只能浏览器打开收银台

官方说明:ISV 权限不足

5. 退款

Admin:POST /api/admin/billing/orders/{id}/refund 通道侧使用订单实付作为微信 total,本次退款金额作为 refund;成功后 payment_records.status=refunded