Files
pay/docs/上线状态与部署Runbook.html
T
wangjia 6da6964451 初始提交:岩美 pay 收款服务(支付宝当面付 + 多商户多渠道架构)
- Go/Gin/GORM + 纯 Go SQLite(无 cgo)
- Channel 多渠道接口:支付宝当面付(precreate)/电脑网站支付(page.pay) 已实现,微信占位
- 多商户 merchants 表,回调验签+金额核对+幂等+查单兜底
- 收款页/结果页/二维码端点;docs/ 设计文档与部署 Runbook
- 密钥走环境变量/Bitwarden,不入库

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 07:21:48 +08:00

163 lines
12 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>pay · 上线状态与部署 Runbook</title>
<style>
:root{--bg:#0d1117;--card:#161b22;--card-2:#1c2330;--border:#283041;--fg:#e6edf3;--fg-soft:#aeb9c7;--muted:#7d8896;--accent:#58a6ff;--green:#3fb950;--orange:#d29922;--red:#f85149;--radius:14px}
*{box-sizing:border-box}
body{margin:0;background:radial-gradient(1200px 600px at 80% -10%,rgba(88,166,255,.08),transparent 60%),var(--bg);color:var(--fg);font:15px/1.7 -apple-system,BlinkMacSystemFont,"PingFang SC","Microsoft YaHei",sans-serif;-webkit-font-smoothing:antialiased}
.wrap{max-width:1000px;margin:0 auto;padding:44px 22px 90px}
.eyebrow{color:var(--accent);font-weight:600;letter-spacing:.12em;font-size:12px;text-transform:uppercase}
h1{font-size:28px;margin:10px 0 8px}
.lead{color:var(--fg-soft);margin:0 0 26px}
h2{font-size:19px;margin:38px 0 12px;color:var(--accent);border-bottom:1px solid var(--border);padding-bottom:8px}
h3{font-size:16px;margin:22px 0 8px;color:var(--fg)}
p{color:var(--fg-soft)}
code{background:var(--card-2);border:1px solid var(--border);border-radius:5px;padding:1px 6px;font-size:13px;color:#e6edf3;font-family:"SF Mono",Menlo,Consolas,monospace}
pre{background:var(--card-2);border:1px solid var(--border);border-radius:10px;padding:14px 16px;overflow-x:auto;font-size:12.5px;line-height:1.6}
pre code{background:none;border:0;padding:0}
a{color:var(--accent);text-decoration:none}a:hover{text-decoration:underline}
table{width:100%;border-collapse:collapse;margin:14px 0;font-size:14px}
th,td{border:1px solid var(--border);padding:9px 11px;text-align:left;vertical-align:top}
th{background:var(--card-2);color:var(--fg);font-weight:600}
td{color:var(--fg-soft)}
.callout{border-left:3px solid var(--accent);background:var(--card-2);border-radius:0 8px 8px 0;padding:12px 16px;margin:16px 0;color:var(--fg-soft)}
.callout.warn{border-left-color:var(--orange)}
.callout.ok{border-left-color:var(--green)}
.callout.bad{border-left-color:var(--red)}
.ok{color:var(--green);font-weight:600}.wait{color:var(--orange);font-weight:600}.no{color:var(--red);font-weight:600}
.tag{display:inline-block;font-size:12px;padding:1px 9px;border-radius:20px;border:1px solid var(--border);background:var(--card-2);color:var(--fg-soft)}
ul{color:var(--fg-soft)}
svg{display:block;margin:8px auto;max-width:100%}
</style>
</head>
<body>
<div class="wrap">
<div class="eyebrow">pay · Status & Runbook</div>
<h1>上线状态与部署 Runbook</h1>
<p class="lead">岩美 pay 收款服务(支付宝当面付)在阿里云的部署现状、运维手册,以及微信支付的规划与硬前提。更新于 2026-06-25。</p>
<h2>一、当前状态总览</h2>
<table>
<thead><tr><th style="width:34%">事项</th><th style="width:14%">状态</th><th>说明</th></tr></thead>
<tbody>
<tr><td>pay 服务部署到阿里云</td><td class="ok">✅ 完成</td><td>systemd 守护、开机自启、health OK</td></tr>
<tr><td>支付宝密钥(生产)</td><td class="ok">✅ 完成</td><td>存 Bitwarden「ali pay key」→ rbw 灌入服务器 env,私钥不落明文/不进聊天</td></tr>
<tr><td>下单 + RSA2 加签</td><td class="ok">✅ 验证</td><td>测试下单返回「应用未上线」= 密钥/加签/网关全通,只差审核</td></tr>
<tr><td>支付宝应用审核(当面付)</td><td class="wait">⏳ 审核中</td><td>1 天内出结果;通过后下单即出码,无需再改</td></tr>
<tr><td>阿里云安全组开 8080</td><td class="wait">⏳ 待操作</td><td>用户在 ECS 控制台开:TCP 8080 / 源 0.0.0.0/0</td></tr>
<tr><td>1 分钱真实实测</td><td class="wait">⏳ 待</td><td>审核过 + 端口开后,真支付宝扫码付</td></tr>
<tr><td>微信支付</td><td class="no">⛔ 阻塞</td><td>V3 回调强制 HTTPS → 需先备案+域名+证书(见第四节)</td></tr>
</tbody>
</table>
<h2>二、部署架构</h2>
<svg viewBox="0 0 940 250" xmlns="http://www.w3.org/2000/svg" font-family="-apple-system,PingFang SC,sans-serif" font-size="12.5">
<defs><marker id="a" markerWidth="10" markerHeight="10" refX="8" refY="3" orient="auto"><path d="M0,0 L9,3 L0,6 Z" fill="#58a6ff"/></marker></defs>
<!-- 客户 -->
<rect x="20" y="100" width="130" height="50" rx="9" fill="#1c2330" stroke="#58a6ff"/><text x="85" y="122" fill="#e6edf3" text-anchor="middle">客户</text><text x="85" y="139" fill="#7d8896" text-anchor="middle" font-size="11">支付宝扫码</text>
<!-- 收款页/QR -->
<line x1="150" y1="125" x2="198" y2="125" stroke="#58a6ff" stroke-width="2" marker-end="url(#a)"/>
<text x="174" y="118" fill="#aeb9c7" text-anchor="middle" font-size="10.5">扫码</text>
<!-- pay服务 -->
<rect x="200" y="80" width="220" height="92" rx="10" fill="#161b22" stroke="#3fb950"/>
<text x="310" y="104" fill="#e6edf3" text-anchor="middle" font-weight="600">pay 服务(阿里云)</text>
<text x="310" y="124" fill="#aeb9c7" text-anchor="middle" font-size="11">182.92.213.171:8080</text>
<text x="310" y="142" fill="#7d8896" text-anchor="middle" font-size="11">systemd · Go · SQLite</text>
<text x="310" y="159" fill="#7d8896" text-anchor="middle" font-size="11">当面付 precreate / 回调验签 / 查单</text>
<!-- 支付宝 -->
<line x1="420" y1="110" x2="528" y2="110" stroke="#58a6ff" stroke-width="2" marker-end="url(#a)"/>
<text x="474" y="103" fill="#aeb9c7" text-anchor="middle" font-size="10.5">下单(加签)</text>
<line x1="528" y1="140" x2="420" y2="140" stroke="#7d8896" stroke-width="1.8" stroke-dasharray="5 4" marker-end="url(#a)"/>
<text x="474" y="155" fill="#aeb9c7" text-anchor="middle" font-size="10.5">notify(验签)</text>
<rect x="530" y="90" width="150" height="70" rx="10" fill="#1c2330" stroke="#3fb950"/>
<text x="605" y="120" fill="#e6edf3" text-anchor="middle" font-weight="600">支付宝</text>
<text x="605" y="138" fill="#7d8896" text-anchor="middle" font-size="11">正式网关</text>
<!-- Bitwarden -->
<rect x="200" y="200" width="220" height="40" rx="9" fill="#1c2330" stroke="#283041"/>
<text x="310" y="225" fill="#aeb9c7" text-anchor="middle" font-size="11.5">🔑 Bitwarden「ali pay key」→ rbw → /etc/pay/pay.env</text>
<line x1="310" y1="200" x2="310" y2="174" stroke="#7d8896" stroke-width="1.5" stroke-dasharray="3 3" marker-end="url(#a)"/>
<!-- 备注 -->
<text x="760" y="118" fill="#7d8896" font-size="11">notify 用 IP:8080http</text>
<text x="760" y="136" fill="#7d8896" font-size="11">支付宝当面付不校验备案</text>
</svg>
<h2>三、服务器部署详情</h2>
<table>
<thead><tr><th style="width:30%"></th><th></th></tr></thead>
<tbody>
<tr><td>服务器</td><td><code>ssh ali</code> → 182.92.213.171Alibaba Cloud Linux 3, x86_64</td></tr>
<tr><td>二进制</td><td><code>/opt/pay/payd</code>Go 交叉编译 linux/amd64,纯静态无 cgo</td></tr>
<tr><td>前端页面</td><td><code>/opt/pay/web/</code>pay.html / result.html</td></tr>
<tr><td>配置</td><td><code>/opt/pay/config.yaml</code>production:true、app_id、base_url、enabled:true</td></tr>
<tr><td>数据库</td><td><code>/opt/pay/pay.db</code>SQLite</td></tr>
<tr><td>密钥 env</td><td><code>/etc/pay/pay.env</code>600,含 ALIPAY_APP_PRIVATE_KEY / ALIPAY_PUBLIC_KEY,来自 rbw</td></tr>
<tr><td>systemd 单元</td><td><code>/etc/systemd/system/pay.service</code></td></tr>
<tr><td>商户</td><td>code=<code>yanmei</code> · APPID <code>2021006166629060</code> · 当面付 · 正式网关</td></tr>
<tr><td>notify_url</td><td><code>http://182.92.213.171:8080/api/v1/notify/alipay</code></td></tr>
<tr><td>查单兜底</td><td>每 30s 主动 query 待支付订单(防回调丢失)</td></tr>
</tbody>
</table>
<div class="callout"><strong>密钥来源(Bitwarden):</strong>条目 <code>ali pay key</code>,字段 <code>app_private_key</code> / <code>alipay_public_key</code> / <code>appid</code>。部署时 <code>rbw get</code> 管道直灌服务器 env,明文不落盘到仓库、不进聊天。</div>
<h2>四、运维 Runbook(常用命令)</h2>
<pre><code># 状态 / 健康
ssh ali 'systemctl status pay'
ssh ali 'curl -s localhost:8080/health'
# 重启 / 看日志
ssh ali 'systemctl restart pay'
ssh ali 'journalctl -u pay -f'
# 更新密钥(从 Bitwarden 重新灌)
{ printf 'ALIPAY_APP_PRIVATE_KEY='; rbw get "ali pay key" --field app_private_key | tr -d '\r\n'; \
printf '\nALIPAY_PUBLIC_KEY='; rbw get "ali pay key" --field alipay_public_key | tr -d '\r\n'; printf '\n'; } \
| ssh ali 'umask 077; cat > /etc/pay/pay.env; chmod 600 /etc/pay/pay.env'
ssh ali 'systemctl restart pay'
# 更新程序(本地改完代码后)
cd /Users/wangjia/code/pay && GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o /tmp/payd .
scp /tmp/payd ali:/opt/pay/payd && ssh ali 'systemctl restart pay'
# 查订单(服务器上)
ssh ali 'sqlite3 -header -column /opt/pay/pay.db "SELECT out_trade_no,amount,status,trade_no,paid_at FROM orders ORDER BY id DESC LIMIT 10;"'</code></pre>
<div class="callout ok"><strong>审核通过后无需任何改动</strong>——商户已 enabled、密钥已就位。支付宝应用一上线,下单即出码。直接开 <code>http://182.92.213.171:8080</code> 测 1 分钱即可。</div>
<h2>五、上线检查清单(支付宝当面付)</h2>
<ul>
<li>☑ 服务部署、systemd 自启、health OK</li>
<li>☑ 生产密钥灌入(Bitwarden → env</li>
<li>☑ 下单加签验证通过(「应用未上线」是预期)</li>
<li><span class="wait">支付宝应用 + 当面付审核通过</span>1 天内)</li>
<li><span class="wait">阿里云安全组开 8080</span>TCP / 0.0.0.0/0</li>
<li><span class="wait">1 分钱真实扫码实测</span> → 订单变 paid</li>
<li>☐ 把测试套餐(0.01/0.02)换成真实授权套餐(¥99/¥268/¥888…)</li>
<li>☐ 配服务器 IP 白名单(资金接口加固,可选)</li>
</ul>
<h2>六、微信支付规划</h2>
<div class="callout warn"><strong>硬前提:微信支付 V3 回调强制 HTTPS</strong>——必须 <code>https://域名/notify</code>,不能像支付宝当面付那样用 <code>http://IP:8080</code>。HTTPS 要域名+证书,域名+大陆服务器又要 <strong>ICP 备案</strong>。所以<strong>微信必须等备案好才能上线</strong></div>
<h3>不依赖备案、可现在并行申请</h3>
<ul>
<li>申请<strong>微信支付商户号</strong>pay.weixin.qq.com,企业+营业执照+对公账户,审核约 1~7 天)</li>
<li>注册一个<strong>认证的公众号/服务号或小程序</strong>(当 APPID 用;服务号认证约 300/年)</li>
<li><strong>API 证书 + APIv3 密钥 + 微信支付公钥</strong>(商户平台 → 账户中心 → API 安全)</li>
</ul>
<h3>依赖备案</h3>
<ul>
<li>域名转入 + ICP 备案 → 服务器配 HTTPS(域名+证书)→ 微信 notify 才能用</li>
</ul>
<h3>代码侧(待我实现)</h3>
<ul>
<li><code>internal/channel/wechat.go</code> 现为占位;需实现微信支付 V3:Native 下单 / 回调 AES-GCM 解密+验签 / 查单</li>
<li>架构已预留:<code>Channel</code> 接口 + <code>merchants</code> 多渠道表,补实现 + 加一条商户即可,主流程不变</li>
</ul>
<div class="callout"><strong>节奏:</strong>现在支付宝当面付先收钱(不等备案);并行申请微信商户号+公众号;备案+域名+HTTPS 就绪后,我实现微信 V3 渠道并 1 分钱实测(微信无沙箱)。届时支付宝电脑网站支付(网页收款页)也能一并上。</div>
</div>
</body>
</html>