Files
gitlab-instance-0a899031_no…/docs/PAYJSAPI_NOMADVIP_SPEC.md
2026-03-13 03:43:50 -05:00

6.5 KiB
Raw Permalink Blame History

payjsapi nomadvip 对接规范

问题:支付成功后,页面显示账号,但 PocketBase payments 表和 Memos 账户均无记录,导致会员验证失败。

原因payjsapi 支付回调未正确写入 PocketBase 及创建 Memos 账号。


一、nomadvip 调用流程

用户点击「立即加入」
  → nomadvip POST /api/pay (user_id, site_id: "vip", ...)
  → nomadvip 调用 payjsapi POST /nomadvip/payh5
  → payjsapi 返回支付参数,用户完成支付
  → 支付渠道回调 payjsapi
  → 【payjsapi 必须】写入 PocketBase payments + site_vip创建 Memos 账号
  → nomadvip 轮询 GET /api/pay/status?order_id=xxx
  → nomadvip 调用 payjsapi GET /nomadvip/order_status?order_id=xxx
  → payjsapi 返回 { paid: true }

二、payjsapi 支付回调必须完成

2.1 写入 PocketBase payments

字段 说明 示例
user_id 订单中的 user_id匿名格式 user1773315608560 或 PB 用户 ID user1773315608560
type 产品类型 vip
order_id 支付订单号 渠道返回的 out_trade_no
total_fee 金额(分) 8800
channel 支付渠道 wxpay / alipay
created 创建时间 自动

nomadvip 依赖app/page.tsxcheckPaymentFromPBuser_id 查询 payments 判断是否 VIP。不写入则会员验证失败

2.2 写入 PocketBase site_vip

字段 说明 示例
user_id 同 payments.user_id user1773315608560
site_id 固定 vip vip
order_id 支付订单号 可选
expires_at 到期时间null 表示永久 null

nomadvip 依赖/api/vip/checkuser_id + site_id = "vip" 校验 Cookie 登录用户的 VIP 状态。

2.3 创建 Memos 账号

  • Memos 地址qun.hackrobot.cn
  • 账号格式user + 时间戳,如 user1773315608560
  • 默认密码12345678

payjsapi 在支付成功后,需调用 Memos API 或内部服务创建账号,账号名与订单中的 user_id 一致(匿名用户即为 user1773315608560 格式)。

nomadvip 依赖:首页「星球登录信息」展示的账号即为此格式,用户需用该账号登录 qun.hackrobot.cn。


三、payjsapi 接口要求

3.1 订单创建 POST /nomadvip/payh5

请求体nomadvip 已传递):

{
  "user_id": "user1773315608560",
  "site_id": "vip",
  "total_fee": 8800,
  "type": "vip",
  "channel": "wxpay",
  "return_url": "https://vip.hackrobot.cn/paid",
  "client_ip": "可选"
}

要求:订单存储时需保存 user_idsite_id,供支付回调使用。

3.2 订单状态 GET /nomadvip/order_status?order_id=xxx

响应

{ "paid": true }

{ "paid": false }

要求:支付回调完成写入 payments/site_vip 后,此接口应返回 paid: true。nomadvip 据此判断支付成功并刷新页面。


四、order_status 接口(关键)

nomadvip 依赖支付成功后nomadvip 轮询 order_status,若返回 paid: true 则调用 /api/pay/confirm 写入 PocketBase 和 Memos。若 order_status 返回 false 或接口不存在,则 confirm 失败payments/site_vip/Memos 均无记录

payjsapi 必须实现:

GET /nomadvip/order_status?order_id=xxx
响应: { "paid": true } 或 { "paid": false }
  • 参数名必须为 order_id(与 nomadvip 传递一致)
  • 支付渠道回调完成后,必须返回 paid: true
  • 若 payh5/redirect 返回 301-308 重定向,建议响应头带上 x-pay-order-id,以便 nomadvip 正确轮询

五、已有账号登录(可选,优先于 PocketBase 查询)

nomadvip 会优先调用 payjsapi 验证 VIP若接口不存在或失败则回退到 PocketBase。

5.1 按 user_id 查 VIP GET /nomadvip/check_vip?user_id=xxx

响应

{ "vip": true, "email": "user@example.com" }

{ "vip": false }

说明payjsapi 需查 users/payments/site_vip 关联,返回是否 VIP若已关联邮箱可返回 email 供前端不再显示绑定表单。

5.2 按邮箱+密码查 VIP POST /nomadvip/check_vip_by_email

请求体

{ "email": "user@example.com", "password": "xxx" }

响应

{
  "vip": true,
  "token": "PB token",
  "record": { "id": "xxx", "email": "xxx" },
  "effectiveUserId": "user1773315608560"
}

{ "vip": false }

说明payjsapi 需验证邮箱密码PB users再查 payments/site_vip 关联,返回 VIP 状态及 PB token/record。


六、检查清单payjsapi 侧)

  • 支付回调写入 PocketBase payments
  • 支付回调写入 PocketBase site_vipsite_id = "vip"
  • 支付回调创建 Memos 账号user_id 格式,密码 12345678
  • order_status 在支付成功后返回 paid: true(否则 nomadvip confirm 失败)
  • 订单创建时正确保存 user_idsite_id
  • (可选)GET /nomadvip/check_vip?user_id=xxx 按 user_id 查 VIP
  • (可选)POST /nomadvip/check_vip_by_email 按邮箱密码查 VIP

七、PocketBase 配置

payjsapi 需配置:


八、日志要求(排查 VIP 登录问题)

payjsapi 需在以下接口打印日志,便于排查「已有账号登录」失败:

接口 建议日志
GET /nomadvip/check_vip?user_id=xxx 请求 user_id、查询结果 vip
POST /nomadvip/check_vip_by_email 请求 email、PB 登录结果、vip 查询结果
GET /nomadvip/order_status?order_id=xxx 请求 order_id、返回 paid
支付回调 写入 payments/site_vip 的 user_id、order_id

示例Node/Express

// check_vip
console.log("[payjsapi] check_vip user_id=%s vip=%s", user_id, vip);

// check_vip_by_email
console.log("[payjsapi] check_vip_by_email email=%s pbLogin=%s vip=%s", email, !!token, vip);

// order_status
console.log("[payjsapi] order_status order_id=%s paid=%s", order_id, paid);

九、Memos 集成

Memos 账号创建方式取决于现有架构,可选:

  1. 直接调用 Memos API 创建用户
  2. 通过内部服务/队列异步创建
  3. 与 PocketBase users 表联动(若 Memos 与 PB 共享用户)

账号名必须与 user_id 一致,以便 nomadvip 页面展示与登录流程一致。