MIT License

技术解读

以下内容由 GitRead 中文社区 编辑团队基于项目 README 与官方资料整理, 结合中文开发者的常见使用场景补充技术选型建议。具体以项目官方文档为准。

Sub2API 自托管充值支付网关 — EasyPay 技术深度分析

项目背景与痛点

在当前互联网支付日益复杂的环境下,为不同支付渠道提供一劳永逸的解决方案是一个巨大的挑战。特别是随着多个支付渠道的引入,开发和维护一套能兼容支付宝、微信支付、Stripe 等多种支付网关的系统,不仅涉及巨大的技术成本,还需要深厚的支付业务经验。项目 “sub2apipay” 正是在这个问题背景下应运而生的,为开发者提供了一个简便的支付网关解决方案。直击多渠道支付系统对接的痛点,它既降低了开发者的技术门槛,同时又保证了系统的高效稳定。

核心技术揭秘

架构剖析

Sub2API 采用模块化设计,将支付渠道、支付逻辑和支付网关分离,使得项目具有高度的扩展性。每一个支付渠道被封装为插件,聚合支付逻辑为核心模块。这一设计不仅体现了良好的软件工程原理,同时也让整个框架非常易于维护和升级。为了更加直观地展现其内部运作机制,下面是一份用 Mermaid 语法绘制的技术架构图。

graph TD A[用户请求] --> B{"参数校验"} B -->|"通过"| C[执行业务] C --> D[记录日志] D --> E[返回响应] B -->|"失败"| F[返回错误]

仔细观察上图,我们可以发现每次用户发起的支付请求会首先进入「参数校验」阶段,检查所有动态数据是否合规。一旦通过验证,系统将自动流转到「执行业务」阶段,该阶段将触发具体的支付逻辑。此逻辑将根据不同支付渠道的内部执行细节被分成若干个子流程。为了保证每笔交易的日志记录,「记录日志」环节是必经之路,为后期审计和监控奠定了基础。最后,不管交易成功还是失败,用户都会收到一个明确的「返回响应」或「返回错误」。

数据流分析

数据流方面,Sub2API 直白地定义了支付流程的起点与终点,同时也埋下了多重机制以确保存储的实时性和准确性。这里涉及的技术栈较为广泛,涵盖前端交互、异步处理和数据库操作等。前端部分借助 Web 端接口友好调用 API 目标,而异步处理如消息队列已被广泛应用以缓解瞬时负载并增强系统弹性。

功能亮点与差异

相比于同类竞品,Sub2API 更加强调 “自托管” 的概念,用户完全掌控其运行环境和服务级别,无需担心第三方服务的稳定性或兼容性问题。此外,系统为不同的 API 响应时间提供了优化策略,确保即使在高峰期也能保持高效响应能力。通过模块化设计,它还具备极高的扩展性,使得开发者可以灵活地添加新的支付渠道。

应用场景与落地建议

Sub2API 为支持各类交易提供了强大的支付后盾,无论是在线购物、数字内容销售还是企业级支付应用,都非常适合。但在生产环境下部署,需要关注以下几个方面:首先是环境配置,确保每台服务器能够高效处理请求,并保持高可用性;其次是安全管理,如敏感信息的传输、存储和使用需严格遵循行业标准。最后,基于业务的实际体量和特点,合理规划资源分配,以确保支付各个环节流畅运转。

综合评价

优点:

  • 高度自定义和扩展性:支持多种支付渠道,易于添加。
  • 稳定性和安全性:模块化架构保障交易流程的稳定和安全。
  • 易用性:提供详尽的接口文档和示例代码,学习门槛低。

缺点:

  • 服务器配置要求较高:特别是大数据量和高并发情况。
  • 文档仍需完善:部分进阶概念和使用案例描述需改进。

总体而言,Sub2API 是构建在现有支付框架上的一次升级尝试。它很好地解决了多渠道支付对接问题,提供了自托管服务的选择,但维护和优化依旧存在一定挑战。

简要分析

热度分
687
价值分
287
活跃状态
归档

语言占比

CSS
Dockerfile
JavaScript
Shell
TypeScript

Release

README

Sub2ApiPay

⚠️ 本项目已归档(Archived)

支付功能已原生集成到 Sub2API 主项目中。

本仓库不再维护,仅作为历史参考保留。如需支付功能,请使用 Sub2API 内置的支付模块。


语言 / Language: 中文(当前)| English

Sub2ApiPay 是为 Sub2API 平台构建的自托管支付网关。支持 EasyPay 易支付聚合、支付宝官方、微信官方和 Stripe 四种支付渠道,提供按量充值与套餐订阅两种计费模式,支付成功后自动调用 Sub2API 管理接口完成到账,无需人工干预。


目录


功能特性

  • 四渠道支付 — EasyPay 易支付聚合、支付宝官方、微信官方、Stripe
  • 在线配置 — 支付服务商、凭证、限额、业务参数均可在管理后台实时配置,无需重启
  • 多实例负载均衡 — 同一服务商支持多实例,按轮询或最小金额策略分流,支持单笔/日限额
  • 双计费模式 — 按量余额充值 + 套餐订阅,灵活适配不同业务场景
  • 自动到账 — 支付回调验签后自动调用 Sub2API 充值 / 订阅接口,全程无需人工
  • 订单全生命周期 — 超时自动取消、用户主动取消、管理员取消、退款
  • 限额控制 — 单笔上限、每日用户累计上限、每日渠道全局限额,多维度风控
  • 安全设计 — Token 鉴权、RSA2 / MD5 / Webhook 签名验证、时序安全对比、完整审计日志
  • 响应式 UI — PC + 移动端自适应,暗色 / 亮色主题,支持 iframe 嵌入
  • 中英双语 — 支付页面自动适配中英文
  • 管理后台 — 数据概览、订单管理(分页/筛选/重试/退款)、渠道管理、订阅管理

EasyPay 推荐:个人推荐 ZPay(https://z-pay.cn/?uid=23808)作为 EasyPay 服务商(链接含作者邀请码,介意可去掉)。ZPay 支持个人用户(无营业执照)每日 1 万元以内交易;拥有营业执照则无限额。支付渠道的安全性、稳定性及合规性请自行鉴别,本项目不对任何第三方支付服务商做担保或背书。

ZPay 申请二维码

ZPay 预览


技术栈

类别 技术
框架 Next.js 16 (App Router)
语言 TypeScript 5 + React 19
样式 TailwindCSS 4
ORM Prisma 7(adapter-pg 模式)
数据库 PostgreSQL 16
容器 Docker + Docker Compose
包管理 pnpm

快速开始

使用 Docker Hub 镜像(推荐)

无需本地安装 Node.js 或 pnpm,服务器上只需 Docker。

mkdir -p /opt/sub2apipay && cd /opt/sub2apipay

# 下载 Compose 文件和环境变量模板
curl -O https://raw.githubusercontent.com/touwaeriol/sub2apipay/main/docker-compose.hub.yml
curl -O https://raw.githubusercontent.com/touwaeriol/sub2apipay/main/.env.example
cp .env.example .env

# 填写必填环境变量
nano .env

# 启动(含自带 PostgreSQL)
docker compose -f docker-compose.hub.yml up -d

从源码构建

git clone https://github.com/touwaeriol/sub2apipay.git
cd sub2apipay
cp .env.example .env
nano .env
docker compose up -d --build

环境变量

完整模板见 .env.example。

核心(必填)

变量 说明
SUB2API_BASE_URL Sub2API 服务地址,如 https://sub2api.com
SUB2API_ADMIN_API_KEY Sub2API 管理 API 密钥
ADMIN_TOKEN 管理后台访问令牌(自定义强密码)
NEXT_PUBLIC_APP_URL 本服务的公网地址,如 https://pay.example.com

DATABASE_URL 使用自带数据库时由 Compose 自动注入,无需手动填写。

支付服务商与支付方式

支付服务商和支付参数支持两种配置方式,任选其一即可:

方式一:通过管理后台在线配置(推荐)

在管理后台的 支付配置 页面(/admin/payment-config)中,可以直接在界面上完成所有支付相关配置,无需修改环境变量或重启服务:

  • 覆盖环境变量 — 开启后,数据库配置将覆盖环境变量。首次开启时会自动从环境变量导入现有配置
  • 服务商管理 — 添加 / 编辑 / 删除支付实例,配置凭证、启用状态、渠道、负载均衡策略
  • 多实例支持 — 同一服务商可创建多个实例,配合轮询或最小金额策略实现负载均衡
  • 实例限额 — 每个实例可独立配置每个渠道的单笔最小 / 单笔最大 / 每日总限额
  • 业务参数 — 充值金额范围、每日限额、订单超时、取消频率限制等均可在线调整

提示:通过管理后台修改的配置即时生效,无需重启容器。支付配置页面入口:Sub2API 管理后台 → 支付配置,或直接访问 https://pay.example.com/admin/payment-config?token=YOUR_ADMIN_TOKEN。

方式二:通过环境变量配置

适用于首次部署或偏好配置文件管理的场景。环境变量配置的值会作为默认值,可随时在管理后台覆盖。

第一步:通过 PAYMENT_PROVIDERS 声明启用哪些支付服务商(逗号分隔):

# 可选值: easypay, alipay, wxpay, stripe
# 示例:仅使用 EasyPay 易支付聚合
PAYMENT_PROVIDERS=easypay
# 示例:同时启用支付宝官方 + 微信官方 + Stripe
PAYMENT_PROVIDERS=alipay,wxpay,stripe

支付宝官方 / 微信官方与 EasyPay 可以共存。官方渠道直接对接支付宝/微信 API,资金直达商户账户,手续费更低;EasyPay 通过第三方平台代收/转发官方,接入门槛更低。使用 EasyPay 时请尽量选择资金直接走转发官方直达自己账户的形式,而非第三方代收的服务商。

EasyPay(支付宝 / 微信支付聚合)

任何兼容易支付(EasyPay)协议的支付服务商均可接入。

变量 说明
EASY_PAY_PID EasyPay 商户 ID
EASY_PAY_PKEY EasyPay 商户密钥
EASY_PAY_API_BASE EasyPay API 地址
EASY_PAY_NOTIFY_URL 异步回调地址,填 ${NEXT_PUBLIC_APP_URL}/api/easy-pay/notify
EASY_PAY_RETURN_URL 支付完成跳转地址,填 ${NEXT_PUBLIC_APP_URL}/pay/result
EASY_PAY_CID_ALIPAY 支付宝通道 ID(可选)
EASY_PAY_CID_WXPAY 微信支付通道 ID(可选)
支付宝官方

直接对接支付宝开放平台,支持 PC 页面支付(alipay.trade.page.pay)和手机网站支付(alipay.trade.wap.pay),自动根据终端类型切换。

变量 说明
ALIPAY_APP_ID 支付宝应用 AppID
ALIPAY_PRIVATE_KEY 应用私钥(内容或文件路径)
ALIPAY_PUBLIC_KEY 支付宝公钥(内容或文件路径)
ALIPAY_NOTIFY_URL 异步回调地址
ALIPAY_RETURN_URL 同步跳转地址(可选)
微信官方

直接对接微信支付 APIv3,支持 Native 扫码支付和 H5 支付,移动端优先尝试 H5,自动 fallback 到扫码。

变量 说明
WXPAY_APP_ID 微信支付 AppID
WXPAY_MCH_ID 商户号
WXPAY_PRIVATE_KEY 商户 API 私钥(内容或文件路径)
WXPAY_CERT_SERIAL 商户证书序列号
WXPAY_API_V3_KEY APIv3 密钥
WXPAY_PUBLIC_KEY 微信支付公钥(内容或文件路径)
WXPAY_PUBLIC_KEY_ID 微信支付公钥 ID
WXPAY_NOTIFY_URL 异步回调地址
Stripe
变量 说明
STRIPE_SECRET_KEY Stripe 密钥(sk_live_...)
STRIPE_PUBLISHABLE_KEY Stripe 可公开密钥(pk_live_...)
STRIPE_WEBHOOK_SECRET Stripe Webhook 签名密钥(whsec_...)

Stripe Webhook 端点:${NEXT_PUBLIC_APP_URL}/api/stripe/webhook 需订阅事件:payment_intent.succeeded、payment_intent.payment_failed

业务规则

以下参数可通过环境变量设置默认值,也可在管理后台 支付配置 页面中在线修改(开启"覆盖环境变量"后生效):

变量 说明 默认值
MIN_RECHARGE_AMOUNT 单笔最低充值金额(元) 1
MAX_RECHARGE_AMOUNT 单笔最高充值金额(元) 1000
MAX_DAILY_RECHARGE_AMOUNT 每日每用户累计最高充值(元,0 = 不限) 10000
MAX_DAILY_AMOUNT_ALIPAY 易支付支付宝渠道每日全局限额(可选) 由提供商默认
MAX_DAILY_AMOUNT_ALIPAY_DIRECT 支付宝官方渠道每日全局限额(可选) 由提供商默认
MAX_DAILY_AMOUNT_WXPAY 微信支付渠道每日全局限额(可选) 由提供商默认
MAX_DAILY_AMOUNT_STRIPE Stripe 渠道每日全局限额(可选) 由提供商默认
ORDER_TIMEOUT_MINUTES 订单超时分钟数 5
PRODUCT_NAME 充值商品名称(显示在支付页) Sub2API Balance Recharge

UI 定制(可选)

在充值页面右侧可展示客服联系方式、说明图片等帮助内容。

变量 说明
PAY_HELP_IMAGE_URL 帮助图片地址(支持外部 URL 或本地路径,见下方说明)
PAY_HELP_TEXT 帮助说明文字,用 \n 换行,如 扫码加微信\n工作日 9-18 点在线

图片地址两种方式:

  • 外部 URL(推荐,无需改 Compose 配置):直接填图片的公网地址,如 OSS / CDN / 图床链接。

    PAY_HELP_IMAGE_URL=https://cdn.example.com/help-qr.jpg
    
  • 本地文件:将图片放到 ./uploads/ 目录,通过 /uploads/文件名 引用。 需在 docker-compose.app.yml 中挂载目录(默认已包含):

    volumes:
      - ./uploads:/app/public/uploads:ro
    
    PAY_HELP_IMAGE_URL=/uploads/help-qr.jpg
    

点击帮助图片可在屏幕中央全屏放大查看。

Docker Compose 专用

变量 说明 默认值
APP_PORT 宿主机映射端口 3001
DB_PASSWORD PostgreSQL 密码(使用自带数据库时) password(生产请修改)

部署指南

方案一:Docker Hub 镜像 + 自带数据库

使用 docker-compose.hub.yml,最省事的部署方式:

docker compose -f docker-compose.hub.yml up -d

镜像:touwaeriol/sub2apipay:latest

方案二:Docker Hub 镜像 + 外部数据库

适用于已有 PostgreSQL 实例(如与其他服务共用):

  1. 在 .env 中填写 DATABASE_URL
  2. 使用 docker-compose.app.yml(仅启动应用,不含 DB):
docker compose -f docker-compose.app.yml up -d

方案三:从源码构建

适用于自定义修改后自行构建:

# 在构建服务器上
docker compose build
docker tag sub2apipay-app:latest touwaeriol/sub2apipay:latest
docker push touwaeriol/sub2apipay:latest

# 在部署服务器上
docker compose -f docker-compose.hub.yml pull
docker compose -f docker-compose.hub.yml up -d

端口与反向代理

默认宿主机端口为 3001(可通过 APP_PORT 修改)。建议使用 Nginx/Caddy 作反向代理并配置 HTTPS:

server {
    listen 443 ssl;
    server_name pay.example.com;

    location / {
        proxy_pass http://127.0.0.1:3001;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

数据库迁移

容器启动时自动执行 prisma migrate deploy,无需手动操作。如需手动执行:

docker compose exec app npx prisma migrate deploy

集成到 Sub2API

假设本服务部署在 https://pay.example.com。

用户端页面

在 Sub2API 管理后台的充值设置中配置以下链接,用户即可从 Sub2API 平台跳转到充值和订单页面:

配置项 URL 说明
充值页面 https://pay.example.com/pay 用户充值、购买订阅套餐入口
我的订单 https://pay.example.com/pay/orders 用户查看自己的充值/订阅记录

Sub2API v0.1.88 及以上版本会自动拼接以下参数,无需手动添加:

参数 说明
user_id Sub2API 用户 ID
token 用户登录 Token(有 token 才能查看订单历史)
theme light(默认)或 dark
lang 界面语言,zh(默认)或 en
ui_mode standalone(默认)或 embedded(iframe 嵌入)

管理后台

管理后台通过 URL 参数 token 鉴权(值为环境变量 ADMIN_TOKEN)。在 Sub2API 中集成时只需配置路径,无需附加任何查询参数——Sub2API 会自动拼接 token 等参数:

页面 URL 说明
管理总览 https://pay.example.com/admin 聚合入口,卡片式导航到各管理模块
订单管理 https://pay.example.com/admin/orders 按状态筛选、分页浏览、订单详情、重试/取消/退款
数据概览 https://pay.example.com/admin/dashboard 收入统计、订单趋势、支付方式分布
支付配置 https://pay.example.com/admin/payment-config 服务商管理、实例配置、限额、业务参数在线调整
渠道管理 https://pay.example.com/admin/channels 配置 API 渠道与倍率,支持从 Sub2API 同步
订阅管理 https://pay.example.com/admin/subscriptions 管理订阅套餐与用户订阅

提示:若独立访问(不通过 Sub2API 跳转),需手动在 URL 后添加 ?token=YOUR_ADMIN_TOKEN。管理后台所有页面间共享同一个 token,进入任一页面后可通过侧边导航切换。


支付流程

用户选择充值 / 订阅套餐
       │
       ▼
  创建订单 (PENDING)
  ├─ 校验用户状态 / 待支付订单数 / 每日限额 / 渠道限额
  └─ 调用支付提供商获取支付链接
       │
       ▼
  用户完成支付
  ├─ EasyPay   → 扫码 / H5 跳转
  ├─ 支付宝官方 → PC 页面支付 / H5 手机网站支付
  ├─ 微信官方   → Native 扫码 / H5 支付
  └─ Stripe    → Payment Element (PaymentIntent)
       │
       ▼
  支付回调(RSA2 / MD5 / Webhook 签名验证)→ 订单 PAID
       │
       ▼
  自动调用 Sub2API 充值 / 订阅接口
  ├─ 成功 → COMPLETED,余额到账 / 订阅生效
  └─ 失败 → FAILED(管理员可重试)

API 端点

所有 API 路径前缀为 /api。

公开 API

用户侧接口,通过 URL 参数 user_id + token 鉴权。

方法 路径 说明
GET /api/user 获取当前用户信息
GET /api/users/:id 获取指定用户信息
POST /api/orders 创建充值 / 订阅订单
GET /api/orders/:id 查询订单详情
POST /api/orders/:id/cancel 用户取消待支付订单
GET /api/orders/my 查询当前用户的订单列表
GET /api/channels 获取渠道列表(前端展示用)
GET /api/subscription-plans 获取在售订阅套餐列表
GET /api/subscriptions/my 查询当前用户的订阅状态
GET /api/limits 查询充值限额与支付方式可用状态

支付回调

由支付服务商异步调用,签名验证后触发到账流程。

方法 路径 说明
GET /api/easy-pay/notify EasyPay 异步回调(GET)
POST /api/alipay/notify 支付宝官方异步回调
POST /api/wxpay/notify 微信官方异步回调
POST /api/stripe/webhook Stripe Webhook 回调

管理 API

需通过 token 参数传递 ADMIN_TOKEN 鉴权。

方法 路径 说明
GET /api/admin/orders 订单列表(分页、状态筛选)
GET /api/admin/orders/:id 订单详情(含审计日志)
POST /api/admin/orders/:id/cancel 管理员取消订单
POST /api/admin/orders/:id/retry 重试失败的充值 / 订阅
POST /api/admin/refund 发起退款
GET /api/admin/dashboard 数据概览(收入统计、趋势)
GET /api/admin/channels 渠道列表
POST /api/admin/channels 创建渠道
PUT /api/admin/channels/:id 更新渠道
DELETE /api/admin/channels/:id 删除渠道
GET /api/admin/subscription-plans 订阅套餐列表
POST /api/admin/subscription-plans 创建订阅套餐
PUT /api/admin/subscription-plans/:id 更新订阅套餐
DELETE /api/admin/subscription-plans/:id 删除订阅套餐
GET /api/admin/subscriptions 用户订阅记录列表
GET /api/admin/config 获取系统配置
PUT /api/admin/config 更新系统配置
GET /api/admin/sub2api/groups 从 Sub2API 同步渠道分组
GET /api/admin/sub2api/search-users 搜索 Sub2API 用户

开发指南

环境要求

  • Node.js 22+
  • pnpm
  • PostgreSQL 16+

本地启动

pnpm install
cp .env.example .env
# 编辑 .env,填写 DATABASE_URL 和其他必填项
pnpm prisma migrate dev
pnpm dev

常用命令

pnpm dev                      # 开发服务器(热重载)
pnpm build                    # 生产构建
pnpm test                     # 运行测试
pnpm typecheck                # TypeScript 类型检查
pnpm lint                     # ESLint 代码检查
pnpm format                   # Prettier 格式化

pnpm prisma generate          # 生成 Prisma 客户端
pnpm prisma migrate dev       # 创建迁移(开发)
pnpm prisma migrate deploy    # 应用迁移(生产)
pnpm prisma studio            # 可视化数据库管理

License

MIT

评论

暂无评论