摆摊AI 产品实战手册

数字商品与会员交付

把订单、权益和访问控制分开设计,让付款以后真的拿得到东西。含摆摊自己的付费墙实现和七项交付验收。

收款成功不等于交易完成。

用户买的是结果:文件能下载、课程能打开、会员页面能访问、积分能使用。支付只是交付流程的触发器,不是终点。很多项目的第一批售后全部来自这一段——钱收到了,东西没到。

快速版

  1. 先写清你卖的权益是什么(一次购买 / 期限会员 / 余额),再选技术。
  2. 订单和权益分两张表存,不要用"最近一笔订单"判断权限。
  3. 访问控制必须在服务端,前端隐藏不算门禁。
  4. 交付必须可恢复:换设备、清缓存、回调晚到都要能拿到。
  5. 退款和撤销规则在购买前就写在页面上。
  6. 用一笔真实订单跑完七项验收,任何一步需要你手改数据库就是没做完。

先定义卖的是什么

不同商品需要不同的权益模型。搞混这一步,后面所有代码都要重写。

商品权益记录常见失效方式
文件或模板一次购买记录 + 下载权限退款、商品下架
付费文章用户与内容的访问关系退款、人工撤销
期限会员会员截止时间到期、退款
积分或次数可用余额 + 流水消耗、退款冲正
人工服务订单 + 履约状态取消、完成、退款

先把权益写清楚,再选交付技术。 不要让支付平台的商品模型反过来决定你的业务——平台的"商品"概念通常比你的权益模型粗糙得多。

订单和权益必须分开

这是这一页最重要的一条。

  • 订单回答"发生了什么交易":谁、什么时候、付了多少、状态是什么。它是历史,不该被修改。
  • 权益回答"这个用户现在能做什么":会员到期时间、剩余积分、可访问的内容。它是当前状态,会被多种事件改变。

一个用户可能续费多次、用兑换码开通、被人工赠送、退款后撤销。如果页面直接判断"最近一笔订单是否成功",这些情况全都会出错。

摆摊的做法:支付订单和会员有效期分两处保存。订单结算成功后延长会员时间,而不是覆盖。带来两个直接好处:

  • 重复回调不会重复延长(幂等)
  • 会员到期不需要回头修改历史订单
订单表:order_id, user_id, amount, status, created_at   ← 只追加,不改
权益表:user_id, membership_expires_at                  ← 随事件更新

结算成功 → expires_at = max(now, expires_at) + 有效期

max(now, expires_at) 这一下处理的是两种情况:还没过期的续费要接着算,已经过期的重新从今天算。

访问控制必须在服务端

只在页面上隐藏正文、模糊文字,或者靠前端请求判断会员状态,都不是门禁。用户仍然能从 HTML 源码、接口响应或搜索引擎缓存里拿到内容。

摆摊把会员内容放在独立路由里,每次请求先在服务端读会话和会员状态:

  • 有权限 → 服务端渲染正文
  • 无权限 → 只返回标题、摘要和付费墙

正文不会先发到浏览器再隐藏。这个区别可以直接验证:

# 用未登录的身份抓一次会员页,搜正文里的任意一句话
curl -s https://你的域名/members/某篇 | grep "正文里的某句话"
# 期望:什么都搜不到

如果这条命令能搜到内容,你的付费墙是假的。这是唯一可靠的自查方式,比人眼看页面可信。

顺带一个工程上的提醒:会员路由需要动态渲染(读会话),公开文档可以全静态。把两者放在不同的路由段里,各自配置渲染策略,比在一个页面里做条件判断干净得多。

交付要能恢复

用户会付款后关掉页面、换设备登录、清理浏览器缓存,回调也可能晚到几分钟。所以权益必须绑定账号或可靠的购买凭证,并且提供恢复入口:

  • 登录后能看到已购内容
  • 能重新查询订单状态
  • 下载失败能再次获取
  • 联系支持时能用订单号定位

"支付成功页只显示一次下载链接"看起来最省事,实际上会制造大量售后——而每一个都要你手工处理。

退款和撤销要提前想

数字商品无法像实体商品一样真正收回,所以规则必须在购买前说清楚。至少定义这五条:

要定义的不定义的后果
退款后是否立即失去访问权用户退款后仍能用,或申诉说"我还没看完"
已消耗的积分怎么处理用完再退款,等于白送
已下载的文件是否还能收回技术上不能,写清楚避免争议
期限会员按整单撤销还是按剩余时间用了 11 个月要求全额退款
人工赠送权益由谁操作、是否留记录对不上账,也查不出是谁给的

什么时候不该自建

如果你还不确定有没有人买,先别做交付系统。

现成的内容付费平台、发卡寄售平台、二手交易平台的自动发货,都自带支付、库存、订单查询和售后记录。用它们卖一版,比先写一套后台快得多。

自建的时机是这三件事至少发生一件:

  • 你需要用户的联系方式来做产品迭代(平台不给)
  • 商品形态被平台限制住了
  • 已经有稳定复购,客服成本值得用系统降下来

选平台的部分见收款通道怎么选的方案二。

常见卡点

卡在哪可能原因试试这样
付了钱但没开通权限回调没收到,或没做主动查单兜底见支付接入的必测场景
重复回调导致会员被延长两次发放不幂等按订单号去重,用 max(now, expires_at) 累加
换设备就没有权益了权益绑在浏览器(cookie/localStorage)上权益必须绑账号
会员内容能被搜到前端隐藏而非服务端拦截用上面的 curl 自查,改成服务端渲染分支
退款后用户还能访问退款没有触发权益撤销退款回调也要改权益,不只是改订单状态
每天都要手工帮人恢复权益没有恢复入口加"已购内容"页和订单号查询

验收标准

用一笔真实订单依次跑完:

  • 支付成功后,不需要人工刷新就能看到权益
  • 换浏览器登录同一账号,权益仍然在
  • 未登录和非会员的响应里不含受限正文(用 curl 验证)
  • 重复支付回调不重复发货
  • 历史订单能追踪到对应的权益变化
  • 退款、到期、人工赠送都有明确状态和记录
  • 下载或内容服务出故障时可以重试

本章动作

从一笔真实订单出发,依次测试:付款 → 关闭页面 → 换设备登录 → 重复触发回调 → 权益到期。

如果任何一步需要你直接改数据库,交付链路就还没有完成。 这一句是唯一的判断标准。

下一步

  1. 支付接入——订单状态机、回调验签、幂等发放
  2. 支付合规、退款与争议——退款规则和争议处理
  3. 发票、税务与交易台账——订单、资金、交付三方对账

On this page