Skip to main content

你将构建什么

在你的站点上放一个管理订单按钮。已登录的顾客点击后,你的服务端向 Waffo Pancake 获取门户链接,并把浏览器重定向过去。顾客直接以已登录状态进入你店铺的客户门户,无需输入邮箱或验证码。 在门户中,顾客可以:
通过这种方式进入的顾客无法在门户中申请退款。请通过你自己的客服渠道受理退款申请,再在 Dashboard 或用 创建退款工单 API 发起退款。

前置条件

  • 一个 API Key(Dashboard → API & Development)。开发阶段使用测试 Key
  • 顾客应看到的店铺的 Store ID(STO_xxx)
  • 订单通过认证式收银台创建,带有你的 buyerIdentity
  • 你自己的登录体系:本流程信任你服务端的会话,顾客必须已在你的站点完成认证
  • 如果使用 SDK:@waffo/pancake-ts 0.26.0 及以上、@waffo/pancake-nextjs 0.9.0 及以上,或 Go SDK v0.17.0 及以上
  • 已在商店设置中填写店铺的 Website。门户会话结束时,门户会提供返回商户网站按钮,且只链接到这个地址;未填写网站时不显示该按钮

第 1 步:确定顾客身份

门户展示的是你指定店铺中、buyerIdentity 等于此处传入值的订单。请使用与创建订单时相同的稳定值。
  • 推荐: 你系统内部的顾客 ID —— 稳定,且不会再分配给其他人
  • 避免使用邮箱:顾客换邮箱后会看不到之前的订单,被回收再分配的邮箱还可能把订单暴露给别人
  • 匿名下单或以其他身份下单的订单不会出现。Waffo Pancake 不合并身份;如果你更换了标识,之前的订单仍留在旧值下
buyerIdentity 和 storeId 必须取自你服务端自己的登录会话 —— 绝不能取自浏览器可控的查询参数、表单字段、请求头或 cookie 值。谁控制了 buyerIdentity,谁就拿到那位顾客的门户。Waffo Pancake 信任你的服务端,不会验证顾客的邮箱。

第 2 步:在服务端生成链接

只在后端调用 API。API Key 绝不能到达浏览器。
  • 环境跟随 API Key。 测试 Key 打开的门户展示测试数据;生产 Key 展示生产数据。没有环境参数
  • 每次点击都重新生成链接,并在跳转前一刻生成。不要缓存、存储或通过邮件发送
  • 用 302 重定向。 在重定向响应上加 Cache-Control: no-store 和 Referrer-Policy: no-referrer,避免带 token 的链接被缓存或作为 referrer 传出
SDK 辅助函数 createCustomerPortalRedirect 接受以下选项: 辅助函数自己构造的每个响应都带 Cache-Control: no-store 和 Referrer-Policy: no-referrer。从 onError 返回的响应由你自己负责 —— 同样要加上这两个响应头。
loginUrl 应设为你自己掌控的路径。绝不要原样拷贝请求参数(例如 returnTo 查询参数)来拼接它 —— 那会让你的门户路由变成开放重定向。
不使用 SDK?以 purpose: "portal" 和 storeId 调用签发 Session Token,然后重定向到 portalUrl + "#token=" + token。

第 3 步:添加按钮

按钮指向你自己的路由,而不是 Waffo Pancake。浏览器永远看不到 API Key,链接也只在顾客点击时才生成。

会话行为

链接中的 #token= 部分是 bearer 凭证。不要把链接写入日志、埋点、错误追踪或客服工单,也不要通过邮件或聊天分享。

上线前测试

1

创建测试订单

使用测试 API Key,以某个测试顾客的 buyerIdentity 通过认证式收银台下单。
2

打开门户

以该顾客身份登录你的站点,点击管理订单。应能看到这笔测试订单。
3

检查身份边界

换一个顾客登录,确认看不到第一位顾客的订单。尝试在请求中加入别人的 ID —— 你的路由必须忽略它。
4

切换到生产

用生产 API Key 部署。此后链接打开的是生产数据。

故障排查

  1. 确认订单创建时使用的是同一个 buyerIdentity 字符串(精确匹配,区分大小写)
  2. 确认订单属于你传入的 storeId
  3. 确认 API Key 的环境:测试 Key 只显示测试订单,生产 Key 只显示生产订单
  4. 匿名收银台的订单不带 buyerIdentity,永远不会出现在这里
会话闲置超过 15 分钟,或在没有新链接的情况下打开了与该浏览器当前会话不同店铺的门户时,门户会显示请从商户网站重新进入。让顾客从你站点的管理订单重新进入,获取新链接。
顾客在同一浏览器中再次进入了门户 —— 在另一个标签页从你的站点进入、进入了其他店铺的门户,或使用了邮箱 Magic Link。最新一次进入成为该浏览器的门户会话;旧标签页会显示会话已切换,并跳转到当前会话。无需处理。
你用门户 token 调用了 Customer Portal API,但 X-Environment 与 API Key 的环境不一致。改传 Key 的环境。

检查清单

  • 链接在你的服务端生成;API Key 不会到达浏览器
  • buyerIdentity 取自你自己的登录会话,并与收银台使用的值一致
  • storeId 取自服务端配置,而不是请求
  • 路由以 302 响应,并带 Cache-Control: no-store 和 Referrer-Policy: no-referrer
  • 门户链接和 token 从不写日志、从不存储
  • 退款申请在门户之外有客服受理渠道

下一步

签发 Session Token

purpose: "portal" 的请求与响应字段。

客户门户

顾客在门户中看到的内容。