Files
pay/README.md
T
wangjia fd5f56f7de feat: 微信V3 + 支付宝手机站/UA自适应 + 业务对接(签名下单/webhook) + 通用多业务
- 微信支付 V3 Native 渠道 (wechat.go):Native下单/回调AES-GCM解密验签/查单
- 支付宝:手机网站支付 wap.pay + 按 UA 自适应(PC page.pay扫码 / 手机拉App);qr_pay_mode=2 完整扫码收银台
- 业务对接:下单接口扩展(biz_system/biz_ref/return_url)+ HMAC 签名鉴权;支付成功 webhook 主动推送业务方 + 60s 重试 + BizNotifyLog
- 通用多业务:config.biz 改 map,加业务只改配置(BIZ_<SYS>_SECRET/_CALLBACK_URL)
- seedPlans:四档真实套餐 + promo_first_month(¥1) + test_liandiao(0.01),均挂 biz_code;/products 暴露 biz_code
- 删除沙箱 pay.html;对接设计文档入 docs

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019UQmqWmV67sXGLrb3U1XXn
2026-07-03 22:44:34 +08:00

68 lines
3.6 KiB
Markdown
Raw Permalink 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.
# pay — 独立支付服务
多业务 × 多渠道的收款服务。**支付宝(电脑网站支付)+ 微信(V3 Native 扫码)**(微信无沙箱,待真实商户号配置后可用)。
栈:Go 1.26 · Gin · GORMSQLite 纯 Go 驱动,零 cgo)。
## 目录结构
```
pay/
├── main.go # 启动:配置→DB→迁移→seed→路由→查单兜底
├── config/ # viper 配置(config.yaml + 环境变量覆盖)
├── internal/
│ ├── model/ # Merchant 商户凭证 / Product 套餐 / Order 订单 / NotifyLog 回调日志
│ ├── channel/ # Channel 渠道统一接口 + alipay 实现 + wechat 占位 + Registry 缓存
│ ├── service/ # OrderService:下单 / 回调验签入账 / 查单兜底
│ ├── handler/ # HTTP:收款页·套餐·下单·回调·查状态
│ ├── router/ # 路由装配
│ └── util/ # 响应 / 金额(分) / 订单号生成
├── web/ # result.html 支付结果页 · qrcode 二维码渲染
└── docs/ # 设计文档(index.html 索引)
```
## 核心约定
- **金额以服务端套餐价为准**,绝不信任前端传值。
- **回调必验签**(支付宝公钥)+ **核对金额** + **幂等防重**;成功才回 `success`
- **到账以异步通知(notify)为准**,同步跳转仅展示;另有 `query_sync` 主动查单兜底。
- 多商户 / 多渠道:往 `merchants` 表加行即可,主流程不变。
## 接口
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | `/result?out_trade_no=` | 结果页(return_url 落地) |
| GET | `/qrcode?text=` | 把码串渲染成二维码 PNG(微信 code_url / 支付宝扫码) |
| GET | `/health` | 健康检查 |
| GET | `/api/v1/products` | 上架套餐列表 |
| POST | `/api/v1/orders` | 网页支付下单,返回 `pay_url`(支付宝电脑网站支付跳转) |
| POST | `/api/v1/orders/qr` | 扫码下单,返回 `qr_code` 码串(微信 Native / 支付宝当面付) |
| GET | `/api/v1/orders/:out_trade_no` | 查订单状态(结果页轮询) |
| POST | `/api/v1/notify/alipay` | 支付宝异步回调 |
| POST | `/api/v1/notify/wechat` | 微信异步回调(V3 解密验签) |
## 沙箱联调步骤
1. 到 [支付宝沙箱](https://open.alipay.com/develop/sandbox/app) 拿 **APPID / 应用私钥 / 支付宝公钥**(公钥模式)。
2. 编辑 `config/config.yaml``alipay_sandbox``enabled: true`,填好 `app_id`,私钥/公钥建议走环境变量:
```bash
export ALIPAY_APP_PRIVATE_KEY="...应用私钥..."
export ALIPAY_PUBLIC_KEY="...支付宝公钥..."
```
3. 启动:
```bash
go run .
```
首次会自动建库、upsert 沙箱商户、补两个测试套餐(0.01 / 0.02 元)。
4. 浏览器开 `http://localhost:8080` → 选套餐 → 跳支付宝沙箱收银台 → 用**沙箱买家账号**扫码/登录付款。
> ⚠️ **异步回调需公网可达**:`notify_url` 由 `server.base_url` 拼成。本机只测「下单→跳收银台」用 `localhost` 即可;要验证 `notify` 回调到账,需把 `base_url` 换成内网穿透域名(frp/ngrok 映射到本机 8080),或部署到有公网的服务器。本机看不到回调时,`query_sync` 主动查单会兜底补记到账。
## 构建部署
```bash
go build -o payd . # 纯 Go,无需 gcc,可直接拷到阿里云 Linux 运行
```
生产改 `config.yaml``server.mode: release`、`base_url` 为正式 HTTPS 域名、商户 `production: true` 并换正式密钥。