Go to file
wolter 78ba08bcff feat:邮储支付 2026-08-11 15:58:02 +08:00
app feat:邮储支付 2026-08-11 15:58:02 +08:00
bootstrap feat: 付款链接接口 2024-12-21 17:26:26 +08:00
build <fix>(解决冲突):之后会另起分支 2024-08-01 14:53:22 +08:00
config 支付配置 2024-08-06 11:09:39 +08:00
docs init项目 2024-04-29 15:13:21 +08:00
event 支付调起+订单查询 2024-08-02 13:47:52 +08:00
front/templates feat:商户只有1个支付方式时,收银台返回盖方式不校验环境,自动唤起支付页面增加按钮点击唤起 2026-06-12 16:41:26 +08:00
rpc 修改项目module 2024-07-31 17:21:03 +08:00
.env.example init项目 2024-04-29 15:13:21 +08:00
.gitignore init项目 2024-04-29 15:13:21 +08:00
Dockerfile feat: dockerfile 2024-12-06 09:29:15 +08:00
Makefile <fix>(解决冲突):之后会另起分支 2024-08-01 14:53:22 +08:00
README.md feat:邮储支付 2026-07-28 09:46:02 +08:00
go.mod <feat>修复支付宝网页支付关闭订单问题 2026-07-16 11:30:47 +08:00
go.sum <feat>修复支付宝网页支付关闭订单问题 2026-07-16 11:30:47 +08:00
main.go <feat>修复支付宝网页支付关闭订单问题 2026-07-28 15:35:27 +08:00

README.md

PaymentCenter 支付中心

一个基于 Go + Gin 的统一支付网关系统,为商户提供下单、退款、查询、收银台等支付能力,底层对接微信支付、支付宝等第三方支付平台。

代码位置:后端接口位于 app/,收银台页面模板位于 front/templates/


1. 技术栈

组件 选型
语言 Go
Web 框架 Gin
ORM xorm
第三方支付 go-pay
JSON bytedance/sonic
参数校验 go-playground/validator.v9
缓存/分布式锁 Redissnow-core/redis
数据库 MySQL
加密算法 RSA / SM2 / SM4 / AES / DES3

2. 目录结构

PaymentCenter/
├── app/
│   ├── constants/             # 常量定义错误码、公共枚举、pojo
│   │   ├── common/common.go   # 订单状态、支付渠道、路由前缀
│   │   └── errorcode/         # 错误码与中文消息
│   ├── http/
│   │   ├── routes/route.go    # 路由注册入口
│   │   ├── requestmapping/    # 路由→请求结构体映射
│   │   ├── middlewares/       # 中间件CORS、鉴权、加解密、参数校验
│   │   ├── controllers/
│   │   │   ├── base.go        # 公共Success/Error/GenRequest/ApiRes
│   │   │   ├── front/         # C 端:支付 API、收银台、回调
│   │   │   └── backend/       # 管理后台
│   │   └── entities/          # 请求/响应结构体
│   ├── services/
│   │   ├── api_request_valid.go  # App 校验 & IP 白名单
│   │   ├── order.go              # 订单 CRUD & 状态检查
│   │   ├── pay_page.go           # 收银台渠道列表、订单状态检查
│   │   ├── apicrypt/             # RSA/SM2/SM4 加解密实现
│   │   └── thirdpay/             # 第三方支付业务封装
│   │       ├── pay.go            # 下单/退款/关闭主流程
│   │       ├── pay_page.go       # 收银台业务V2 预下单、查询
│   │       ├── pay_query.go      # 三方查询
│   │       ├── do/               # 渠道策略层PayCheck、Pay、PayWay 映射)
│   │       └── thirdpay_notify/  # 回调异步通知处理
│   ├── third/paymentService/     # go-pay 封装(微信/支付宝底层调用)
│   ├── models/                   # xorm 实体orders、app、merchant、pay_channel…
│   ├── data/                     # Repository 层OrderRepo、PayChannelRepo 等)
│   ├── utils/                    # snowflake、JWT、HTTP client、useragent、DES
│   │   └── encrypt/              # AES、RSA、SM2、SM4
│   ├── caches/                   # 缓存
│   └── mq/                       # 消息队列
└── front/
    └── templates/
        ├── payPage.html          # 收银台主页面
        ├── payTemplateDefault.html # 渠道跳转模板
        ├── success.html          # 支付成功JSAPI 场景)
        └── fail.html             # 支付失败

3. 架构分层与调用链

Gin 路由
   │
   ▼
MiddlewareCORS → ValidateRequest / ValidatePayRequest → 加解密)
   │
   ▼
Controllerfront/ 或 backend/
   │
   ▼
services/(业务编排 + services/thirdpay/
   │
   ▼
services/thirdpay/do/PayCheck → Pay → PayWay 策略)
   │
   ▼
third/paymentService/go-pay 底层调用)→ 微信 / 支付宝
   │
   ▼
data/Repository→ models/xorm ORM→ MySQL
  • 控制器层:只做 HTTP 层的事(绑定请求、调用 service、封装返回
  • 服务层:核心业务(状态机、幂等、分布式锁、渠道路由)
  • Repositorydata/:只做数据库 CRUD不包含业务逻辑

4. C 端接口清单

接口前缀:/pay/front/api/v1/pay/front/api/v2

方法 路由 中间件 功能
POST /notify/wx/:payChannelId - 微信支付回调
POST /notify/ali/:payChannelId - 支付宝支付回调
POST /pay/url (V1) ValidatePayRequest 下单,同步返回支付 URL / JsInfo
POST /pay/url (V2) ValidatePayRequest 预下单,仅创建订单,返回收银台 URL
POST /pay/refund ValidatePayRequest 退款
POST /pay/query ValidatePayRequest 查询订单状态
POST /pay/close ValidatePayRequest 关闭订单
GET /payPage?no={id} - 收银台 HTML 页面入口
POST /payPage/list ValidateRequest 获取可用支付渠道列表
GET /payPage/submit ValidateRequest 获取支付跳转链接(渲染 payTemplateDefault.html
POST /payPage/query - 收银台页面轮询订单状态
POST /ali/getOauth ValidateRequest 支付宝小程序获取 openId
POST/GET /wx/* ValidateRequest 微信授权 / openId / JSAPI / 小程序支付

5. 两种下单模式

5.1 模式一V1 直接下单(POST /pay/front/api/v1/pay/url

适用于商户自己管理收银台页面:

  1. 商户构造请求 RequestBody{ app_id, timestamp, data, key },加密后发起
  2. 中间件 ValidatePayRequest():查 App 配置 → 解密 → 反序列化为 PayReqs
  3. 控制器调用 thirdpay.ThirdPayInfoCheck()thirdpay.ThirdPayUrl()
  4. 同步返回 ApiResponse{ Order, Url, JsInfo }

5.2 模式二V2 预下单 + 收银台(推荐)

适用于商户跳转至我方收银台页面:

  1. 商户调用 POST /pay/front/api/v2/pay/url
  2. PayUrlV2Service()
    • Redis 分布式锁(payUrl:{out_trade_no}3 秒)
    • 检查商户是否有可用支付渠道
    • out_trade_no + app_id 查询订单;不存在则新建订单(状态 WAITPAY
    • 返回收银台 URLhttps://pay-host/pay/front/api/v1/payPage?no={orders.id}
  3. 商户将用户浏览器跳转到收银台
  4. 收银台页面payPage.html
    • 读取 URL 参数 no订单自增 ID不是 out_trade_no
    • POST /payPage/list?id=xxx 拉取渠道列表
    • 单渠道直接跳转 /payPage/submit,多渠道让用户选择
    • 选择后跳转到第三方支付页面
    • 支付完成后轮询 /payPage/query,成功后跳转到商户 return_url

6. 收银台页面流程

商户后台
  │ POST /v2/pay/url ─────┐
  │                        ▼
  │                 支付中心创建订单
  │                        │
  │                        ▼
  │           返回 payPage?no={orderId}
  │
  └── 用户浏览器 ───► GET payPage.html
                       │
                       ├── JS 调 POST /payPage/list 获取渠道
                       │
                       ├── GET /payPage/submit 获取跳转链接
                       │       └──► payTemplateDefault.html window.location
                       │
                       ├── POST /payPage/query 轮询订单状态
                       │
                       └── 支付成功 → 跳转 return_url

页面文件:

前端注意:payPage.html 中的 API_BASE_URL 默认写死为 http://localhost:7081,部署时需要替换为生产地址。


7. 请求加解密体系

7.1 两个核心中间件

中间件 路由 说明
ValidateRequest() 收银台列表、授权、小程序等 普通参数解析form/json+ validator 校验 + 可选日志
ValidatePayRequest() /pay/url/pay/refund/pay/query/pay/close 支付专用:app_id 查表 → 按 key_type 解密 data → 二次解析校验

中间件代码:app/http/middlewares/base.go

7.2 支付请求结构(加密封装)

{
  "app_id":    123,        // 应用 ID查表得 KeyType
  "timestamp": 1700000000, // 时间戳
  "data":      "...",      // 真实业务参数的密文PayReqs JSON → 加密 → Base64
  "key":       "..."       // 部分算法所需对称密钥密文
}

解密后 data 对应的业务结构,在 requestmapping.FrontRequestMap 中按路由映射。

7.3 加密算法(由 app.key_type 决定)

类型 实现文件
NO_CRYPT 明文(不加密)
RSA services/apicrypt/rsa.go
SM2 services/apicrypt/sm2.go
SM4 services/apicrypt/sm4.go

注册处:services/apicrypt/types.go 中的 ApiCryptMap

7.4 响应加密

  • 非生产环境:controllers.Success/Error 直接返回 { code, message, data } JSON
  • 生产环境(config.GetConf().Env == "production"):整体 JSON 用 DES3 + Base64 加密后以纯文本返回
  • 对应方法:controllers.EncriptJson()

8. 订单模型 & 状态机

8.1 Orders 表

字段定义:app/models/ordersmodel/orders.go

字段 类型 说明
id int64 主键snowflake 生成
merchant_id int64 商户
pay_channel_id int64 支付渠道实例
app_id int64 应用
out_trade_no string(50) 外部/商户订单号
order_type tinyint 1=支付, 2=退款
refund_order_id int64 退款关联的原订单
amount int 订单金额,单位:
actual_amount int 实际金额,单位:
payer_total int 付款方金额,单位:
ext_json string(1024) 扩展 JSON
desc string(100) 商品描述
status tinyint 订单状态(见下)
create_time / update_time datetime 自动维护

8.2 订单状态(constants/common/common.go

常量 说明
ORDER_STATUS_WAITPAY 1 待支付(刚创建)
ORDER_STATUS_PAYING 2 支付中(已调第三方下单)
ORDER_STATUS_PAYED 3 支付成功
ORDER_STATUS_FAILED 4 支付失败
ORDER_STATUS_CLOSE 5 已关闭

8.3 状态流转

WAITPAY(1) ──► PAYING(2) ──┬──► PAYED(3)
  │                         │
  └─────► CLOSE(5)          └──► FAILED(4)

状态检查方法:services.OrderStatusCheck(order),位置 app/services/pay_page.go


9. 支付渠道体系

9.1 渠道类型枚举

定义在 constants/common/common.go

常量 含义
PAY_CHANNEL_WECHAT_JSAPI 1 微信公众号 JSAPI
PAY_CHANNEL_WECHAT_H5 2 微信 H5
PAY_CHANNEL_WECHAT_APP 3 微信 APP
PAY_CHANNEL_WECHAT_NATIVE 4 微信 Native 扫码
PAY_CHANNEL_WECHAT_MINI 5 微信小程序
PAY_CHANNEL_ALIPAY_WEB 6 支付宝网页/移动应用
PAY_CHANNEL_ALIPAY_MINI 7 支付宝小程序
PAY_CHANNEL_ALIPAY_JSAPI 8 支付宝 JSAPI
PAY_CHANNEL_ALIPAY_PC 9 支付宝 PC 网站

9.2 策略映射(渠道 → 实现方法)

  • 下单:services/thirdpay/do/pay_way.goPayWayList[channelType]
  • 退款:services/thirdpay/do/refund_way.goRefundWayList[channelType]
  • 底层统一入口:third/paymentService/payment_service.goPaymentService(ctx, req)
    • 根据 req.ChannelType 路由到 AliPayService()WechatPayService()

9.3 客户端环境 → 可用渠道

  • 微信浏览器内 → JSAPI需要 openId收银台会自动先走授权
  • PC 浏览器 → 微信 Native、支付宝 PC
  • 手机浏览器(非微信内)→ 微信 H5、支付宝 Web

实现:services.PayPageChannelList() + services.ClientEnvCheck(ua)


10. 新增功能的操作清单

10.1 新增一个 C 端 API

  1. app/http/entities/front/ 定义 Request/Response 结构体
  2. app/http/requestmapping/front.go 的两个 map 中添加路由 → 结构体映射
  3. app/http/routes/route.go 注册路由,挂上合适的中间件
  4. app/http/controllers/front/ 对应文件新增 handlercontrollers.GetRequest(c).(*front.XXX) 取参数)
  5. app/services/app/services/thirdpay/ 实现业务逻辑

10.2 新增一个支付渠道

  1. constants/common/common.go 增加 PAY_CHANNEL_XXX 常量和 PayChannelName/PayChannelList 条目
  2. services/thirdpay/do/pay_way.goPayWayList 注册实现方法
  3. third/paymentService/wechat_service.goali_service.go 增加对应分支
  4. 若需区分客户端环境,更新 OpenInPayChannelMap

10.3 新增一个页面模板

  1. front/templates/ 下新增 .html
  2. 路由里通过 c.HTML(http.StatusOK, "文件名.html", gin.H{...}) 渲染
  3. router.LoadHTMLGlob("./front/templates/*") 已在 routes 中注册

10.4 新增一个错误码

  1. constants/errorcode/error_code.go 定义 const并在 ErrCodeMap 注册中文消息
  2. 使用:controllers.Error(c, errorcode.XXX)controllers.ApiRes(c, nil, code)

10.5 新增数据模型 / Repository

  1. app/models/xxxmodel/ 定义结构体xorm tag + TableName + GetInstance 单例)
  2. app/data/ 新增 XxxRepo 封装 xorm 操作(推荐配合 builder.Cond 拼装条件)
  3. app/services/ 新增 XxxFindOne / XxxList 等服务方法

11. 编码规范与注意事项

  • 金额单位:全链路使用 int前端展示时 /100 转元;不得出现 float64 金额
  • 订单 ID vs out_trade_no
    • orders.id = 雪花自增 ID支付中心内部、收银台查询使用
    • out_trade_no = 商户外部订单号(商户下单、查询使用)
    • 不要混用
  • 幂等性V2 下单通过 Redis 分布式锁key=payUrl:{out_trade_no}3 秒)+ 数据库 (out_trade_no, app_id) 唯一约束保证
  • 中间件选型
    • 加密支付接口 → ValidatePayRequest()
    • 收银台、授权、小程序等 → ValidateRequest()
    • 回调接口 → 直接在 controller 解析(走第三方验签)
  • 统一返回controllers.Success/Error/ApiRes/HandCodeRes,不要手写 JSON
  • 错误码来源constants/errorcode/error_code.go,不要硬编码数字
  • 日志utils.Log(ctx, tag, ...);支付链路关键节点必须有日志
  • 单元测试工具类、加解密、snowflake 等均有 _test.go,新工具函数建议配套

12. 关键文件速查

功能 文件
路由注册 app/http/routes/route.go
路由→结构体映射 app/http/requestmapping/front.go
中间件 app/http/middlewares/base.go
公共返回/参数解析 app/http/controllers/base.go
支付接口 controller app/http/controllers/front/api.go
收银台 controller app/http/controllers/front/pay_page.go
回调/微信/支付宝 controller app/http/controllers/front/payment_controller.go
请求结构体 app/http/entities/front/pay.go
订单服务 app/services/order.go
收银台服务(渠道列表/状态检查) app/services/pay_page.go
App 校验 app/services/api_request_valid.go
第三方支付主流程 app/services/thirdpay/pay.go
收银台/V2 下单 app/services/thirdpay/pay_page.go
加解密类型注册 app/services/apicrypt/types.go
错误码 app/constants/errorcode/error_code.go
公共常量 app/constants/common/common.go
Orders 模型 app/models/ordersmodel/orders.go
Order Repository app/data/orders.go
底层 go-pay 调用入口 app/third/paymentService/payment_service.go
收银台页面 front/templates/payPage.html
跳转模板 front/templates/payTemplateDefault.html
雪花 ID 生成 app/utils/snowflake/snow_flake.go