Files
suixinkan_uikit/docs/门店身份注销接口实测.md
T

19 KiB
Raw Blame History

门店身份注销接口实测

实测时间:2026-08-28 11:39;追加 13:45–13:46 零资产确认(服务端响应时间)。

环境:https://api-test.zhifly.cn。首次 11:39 使用用户明确授权的 iPhone 当前 store_user 登录 Token,仅执行 GET /eligibility 与 GET /status,当时未调用修改接口。后续额外授权的两项零资产确认见第 5 节。请求头与当前 Debug App 一致:token、X-APP-VERSION: 1.3.1、X-OS-TYPE: iOS、JSON Accept/Content-Type。

以下为真实响应;仅 store_user_id、finance_identity_id 统一替换为数值 0 脱敏,不能把该值用作有效身份。没有保存 Token。

1. 注销条件

GET /api/yf-handset-app/account-deregister/eligibility

HTTP 200,业务码 100000:

{
  "code": 100000,
  "msg": "success",
  "data": {
    "can_apply": false,
    "store_user_id": 0,
    "finance_identity_id": 0,
    "wallet_balance_fen": 0,
    "wallet_balance": "0.00",
    "points_balance": 0,
    "wallet_waived": false,
    "points_waived": false,
    "unfulfilled_count": 37,
    "fulfillment_in_progress_count": 0,
    "risk_end_at": "2026-08-27 15:47:32",
    "eligible_at": "2026-09-03 15:47:32",
    "risk_window_hours": 168,
    "blockers": [
      {
        "code": "ORDER_UNFULFILLED",
        "message": "账户仍有未履约订单或带单",
        "action": "complete_orders"
      },
      {
        "code": "RISK_WINDOW_NOT_EXPIRED",
        "message": "最后一笔业务的风险结束时间尚未超过7天",
        "action": "wait_risk_window"
      },
      {
        "code": "WALLET_WAIVER_MISSING",
        "message": "请先确认放弃现金余额",
        "action": "confirm_wallet_waiver"
      },
      {
        "code": "POINTS_WAIVER_MISSING",
        "message": "请先确认放弃积分",
        "action": "confirm_points_waiver"
      }
    ],
    "deregister": null
  },
  "time": "2026-08-28 11:39:51"
}

本次观测到的类型:

字段 JSON 类型 / 含义
can_apply 布尔值,服务端是否允许申请
store_user_id、finance_identity_id 整数
wallet_balance_fen 整数,现金余额(分)
wallet_balance 字符串,金额展示值;本次为 "0.00"
points_balance 整数,积分余额
wallet_waived、points_waived 独立布尔值,是否已确认放弃
unfulfilled_count、fulfillment_in_progress_count 整数
risk_end_at、eligible_at 时间字符串,格式 yyyy-MM-dd HH:mm:ss;时区及无历史业务时的空值形式尚未确认
risk_window_hours 整数,本次为 168
blockers 对象数组,每项有字符串 code、message、action
deregister 本次为 null,尚未观测非空结构

本次余额与积分均为零,服务端仍返回两项放弃确认缺失。客户端不能因为资产为零就省略确认。当前还有 37 项未履约订单或带单,且风险等待期未结束,不能提交注销。eligible_at 是业务风险期截止时间,不是提交申请后的冷静期截止时间;达到该时间也不代表其他条件自动满足。

2. 注销状态

GET /api/yf-handset-app/account-deregister/status

HTTP 200,业务码 100000:

{
  "code": 100000,
  "msg": "success",
  "data": {
    "deregister": null
  },
  "time": "2026-08-28 11:39:51"
}

当前查询没有返回注销申请。不能据此推断非空申请的字段名称、状态枚举或是否可撤销。

3. 首次只读探测后尚缺的信息(后续进展见第 5、6 节)

  • 草稿、冷静期、阻断、撤销、完成时 data.deregister 的非空结构、状态字段和值。
  • cooling_until、remaining_seconds 的实际位置及类型。
  • 无历史业务时风险时间的空值形式、时间字符串所用时区。
  • 重新登录或选择身份自动撤销的具体接口时机,以及受限 Token 是否允许切换其他身份。

这些情况需要现有后端响应样例/源码,或在获得明确授权的专用测试身份上验证。本次授权仅限只读查询,不为采样创建、撤销注销申请或确认资产放弃。

4. 后续零资产确认授权(2026-08-28 13:42)

用户随后明确允许:在测试环境重新核实现金余额与积分均为 0 后,分别调用两项资产放弃确认接口,并查询是否产生草稿。此授权不包含发送短信、提交或撤销注销申请,也不允许非零资产确认。

已确认 iPhone 11 连接,并读取本 App 的当前会话:没有登录 Token,保存的账号类型为 photog,不是旧注销接口要求的 store_user。因此此次没有发出任何接口请求或资产确认,设备偏好未修改,本地临时偏好副本已删除。需在测试版 App 登录门店身份后继续;不要为采样登录已有未完成注销申请的身份,以免触发自动撤销。

5. 已完成两项真实零资产确认(2026-08-28 13:45–13:46)

用户重新登录后,核实当前为有效 store_user。每项确认前均重新查询:身份与设备会话一致、现金余额(分和展示金额)与积分均为 0;只访问测试环境,禁止重定向,不自动重试修改请求。仅执行了已授权的 POST /waivers/wallet、POST /waivers/points 各一次,没有发送短信、提交或撤销注销申请。

本次身份初始没有未履约/交付处理中记录,risk_end_at、eligible_at 均为 JSON null,阻断仅为两项确认缺失。与第 1 节较早查询的身份情况不同,不能沿用之前的 37 项未履约记录。

阶段 wallet_waived points_waived can_apply deregister
确认前 false false false null
现金确认后 true false false status: 0 草稿
积分确认后 true true true 同一未提交草稿

两个确认请求均 HTTP 200、code: 100000,data 返回 asset_type(分别为 "wallet"、"points")、wallet_balance_fen: 0、wallet_balance: "0.00"、points_balance: 0 及两项确认时间。现金确认后 wallet_waived_at: "2026-08-28 13:45:57"、points_waived_at: null;积分确认后后者变为 "2026-08-28 13:46:42"。

两个 GET 中的 data.deregister 都返回以下结构;仅 id 脱敏为 0,实际是正整数:

{
  "id": 0,
  "status": 0,
  "status_label": "待确认",
  "reason": "",
  "apply_time": null,
  "cooling_until": null,
  "remaining_seconds": 0,
  "cancel_time": null,
  "blocked_code": "",
  "blocked_reason": "",
  "completed_at": null
}

确认结论:第一次资产确认即产生非空草稿;status 为数字,0 对应“待确认”。非空记录不等于已提交,不能一律限制普通业务或后续资产确认。两项确认后即使仍有草稿,can_apply 也会变为 true。 remaining_seconds: 0 在草稿中存在,不能单独据此认定冷静期已结束或注销已完成。

已据此修正客户端草稿判断、继续确认/验证和启动核验,并补充 Mock 测试。只将完整且无提交、撤销、阻断或完成字段冲突的 status: 0 识别为草稿;未知状态仍不推断。所有本地会话临时副本已删除,未写回设备偏好,未保存 Token。

仍缺:冷静期、撤销、阻断、完成的实际状态值及对应时间数据;确认过期响应;登录/切换自动撤销的具体时机。继续真实验证需要另行授权短信、提交与撤销操作,当前授权不包含这些操作。

6. 短信、申请与立即撤销(2026-08-28 14:16–14:24)

用户另外授权在切换后的专用测试身份上发送短信、提交申请,获取状态后立即撤销。真机页面核实:现金/积分为0、两项确认已完成、无未履约及风险等待阻断。通过 iPhone 镜像发送短信,用户提供验证码后提交;未将验证码写入源码或文档。短信和申请的原始 POST 响应体没有保存,不能把后续 GET 当作 POST 原文。

  • 申请原因:API test; cancel immediately。
  • 申请时间:2026-08-28 14:23:40。
  • 查询确认:status: 1、status_label: "冷静期中",冷静期截止 2026-09-04 14:23:40。
  • 核对当前身份、同一申请及原因后只调用一次 /cancel,不自动重试。
  • 撤销成功时间:2026-08-28 14:24:04,返回 status: 9、status_label: "已撤销"。
  • 14:24:05 再次 GET /status 与 /eligibility 确认已撤销;未留下待注销申请,未执行最终注销。
  • 本地临时会话副本已删除,未编辑设备偏好,未在文档中保存 Token、手机号或真实身份 ID。

冷静期状态

{
  "code": 100000,
  "msg": "success",
  "data": {
    "deregister": {
      "id": 0,
      "status": 1,
      "status_label": "冷静期中",
      "reason": "API test; cancel immediately",
      "apply_time": "2026-08-28 14:23:40",
      "cooling_until": "2026-09-04 14:23:40",
      "remaining_seconds": 604776,
      "cancel_time": null,
      "blocked_code": "",
      "blocked_reason": "",
      "completed_at": null
    }
  },
  "time": "2026-08-28 14:24:03"
}

撤销响应

{
  "code": 100000,
  "msg": "注销申请已撤销",
  "data": {
    "deregister": {
      "id": 0,
      "status": 9,
      "status_label": "已撤销",
      "reason": "API test; cancel immediately",
      "apply_time": "2026-08-28 14:23:40",
      "cooling_until": "2026-09-04 14:23:40",
      "remaining_seconds": 0,
      "cancel_time": "2026-08-28 14:24:04",
      "blocked_code": "CANCELLED_BY_USER",
      "blocked_reason": "用户主动撤销注销",
      "completed_at": null
    }
  },
  "time": "2026-08-28 14:24:04"
}

撤销后的条件

{
  "code": 100000,
  "msg": "success",
  "data": {
    "can_apply": false,
    "store_user_id": 0,
    "finance_identity_id": 0,
    "wallet_balance_fen": 0,
    "wallet_balance": "0.00",
    "points_balance": 0,
    "wallet_waived": false,
    "points_waived": false,
    "unfulfilled_count": 0,
    "fulfillment_in_progress_count": 0,
    "risk_end_at": null,
    "eligible_at": null,
    "risk_window_hours": 168,
    "blockers": [
      {
        "code": "WALLET_WAIVER_MISSING",
        "message": "请先确认放弃现金余额",
        "action": "confirm_wallet_waiver"
      },
      {
        "code": "POINTS_WAIVER_MISSING",
        "message": "请先确认放弃积分",
        "action": "confirm_points_waiver"
      }
    ],
    "deregister": {
      "id": 0,
      "status": 9,
      "status_label": "已撤销",
      "reason": "API test; cancel immediately",
      "apply_time": "2026-08-28 14:23:40",
      "cooling_until": "2026-09-04 14:23:40",
      "remaining_seconds": 0,
      "cancel_time": "2026-08-28 14:24:04",
      "blocked_code": "CANCELLED_BY_USER",
      "blocked_reason": "用户主动撤销注销",
      "completed_at": null
    }
  },
  "time": "2026-08-28 14:24:05"
}

冷静期 GET /eligibility 已返回两项确认 false 和缺少确认的两个阻断,撤销后也是如此;冷静期不能因此重新确认资产。撤销记录保留旧冷静期时间;remaining_seconds 为0不等于注销完成。正式完成与终审阻断的状态值、自动撤销和所有身份注销后的登录响应仍未验证。此次授权操作已结束,不继续发送短信或创建申请。

2026-08-28:补查终态契约及新申请准备

用户随后允许继续申请注销,以尝试获取缺失的终态响应。本节是新的调查记录,不代表已经创建新的申请。

查找范围 结果
本机 iOS、Android 参考工程及桌面相关文件 未找到旧注销后端的 Controller、Resource、状态枚举或 migration 源码
测试 API 的 /docs、/api/documentation、/openapi.json、/swagger.json HTTP 200,但业务体均为路由不存在,不能当作可用接口文档
Gitea 匿名仓库搜索 没有返回匹配仓库;不代表私有仓库不存在
Chrome 中已有登录的 Gitea 会话 可访问当前用户的仓库列表;代码搜索 StoreUserDeregister、deregister 均未匹配,未取得注销后端源码
已打开的飞书原始文档 页面显示最近修改为8月21日;相关规则与本地文档一致,未给出终态数字枚举、完整 JSON 或完成后的鉴权响应
真机当前 App 会话 无有效门店登录态,因此没有发起认证查询、短信、资产确认、申请或撤销

当前仍需先在真机登录一个允许最终注销的专用测试门店身份,再读取该身份的条件。若保留申请等待正式完成,需经过服务端7天冷静期;不能修改本机时间来替代服务端等待,也不能为制造终审阻断而擅自修改订单、资产或数据库。按旧文档,重新登录或选中申请中的同一身份会自动撤销申请,等待期间应避免这种操作。

“终审阻断”需要到期复核发现条件变化,单纯提交并等待不能保证得到该状态。此次只读查找未新增任何终态实测结论。

2026-08-28 15:23:按用户要求改在模拟器准备新申请

  • 用户明确要求操作其已登录的 iPhone Air 模拟器。本次是人工界面操作,不是模拟器单元测试;不改变此前真机测试结论。
  • 页面当前身份为北大科技园,显示现金0元、积分0;初始只有两项资产确认阻断,上次申请已撤销。
  • 用户授权分别确认两项零资产并发送验证码。继续操作时,现金已显示确认完成,因此没有重复提交现金确认;随后单独确认零积分。
  • 页面显示两项资产均已确认、当前条件满足;仍为未提交草稿。
  • 15:23通过页面发送一次注销验证码,界面提示已发送至当前身份绑定手机号。未保存短信 POST 原始响应,不能把界面提示当作完整接口 JSON。
  • 停留在验证码输入页,等待用户提供本次验证码;此时尚未提交新申请,也未进入新的冷静期。

2026-08-28 15:27—15:29:新申请已提交并保留

  • 用户提供本次验证码,并在最终弹窗前明确确认:只注销北大科技园身份,保留申请至服务端7天后复核,正式完成不可恢复,不像上次立即撤销。
  • 15:27:24在模拟器点击一次“确认提交申请”。原因为 Test account deregistration;验证码不写入文档或代码。
  • 页面进入冷静期核验页,显示截止时间 2026-09-04 15:27:24(服务端时间)。
  • 15:28:27只读 GET /status、/eligibility 均确认 deregister.status: 1,cancel_time、completed_at 均为 null。
  • 15:29:22以同一现有 Token GET /api/yf-handset-app/userinfo,返回 HTTP 200、业务码150015、data.status: "cooling"、相同冷静期截止时间;响应没有 time 字段。前后 GET /status 均成功且仍是同一冷静期记录。
  • 未重复发送短信、未重复申请、未执行撤销、登录或身份选择。未保留 Token 副本或修改模拟器偏好设置。

此时申请仍待注销,与14:24已撤销的旧申请不同;后续已于15:55:36因重新登录自动撤销,见文末15:56记录。 终审阻断/正式完成未发生;不能把冷静期截止当作已经注销。查询样例已加入旧接口返回数据说明。短信和申请 POST 原始响应体仍未捕获,不能用 GET 代替。

本轮脱敏证据:

  • /private/tmp/suixinkan-contract-discovery-20260828/152826-simulator-status-redacted.json
  • /private/tmp/suixinkan-contract-discovery-20260828/152826-simulator-eligibility-redacted.json
  • /private/tmp/suixinkan-contract-discovery-20260828/152921-simulator-userinfo-cooling-redacted.json
  • /private/tmp/suixinkan-contract-discovery-20260828/152921-simulator-status-before-auth-redacted.json
  • /private/tmp/suixinkan-contract-discovery-20260828/152921-simulator-status-after-auth-redacted.json

2026-08-28 15:45:真实响应回归与源码补查

  • 将本轮150015及对应status响应整理为Swift测试夹具;逐字段对比采样JSON,仅注销记录ID替换为测试值301。
  • 在iPhone 11上完成全量792项测试:782通过、10项既有失败,无跳过;失败用例集合与原始基线一致。注销相关73项全部通过,包括真实userinfo限制响应经API、通知和路由进入冷静期页面的新增Mock集成测试。
  • 本轮仅更新测试与文档,未操作模拟器中的真实申请;未变更工程配置、版本号或依赖。
  • 补查已保存项目列表,未发现相关后端工程;Android工程现有Git主机的HTTP网页根返回空响应,未取得源码。未猜测后端仓库路径、修改服务器或扩展访问权限。
  • 结果:/private/tmp/suixinkan-deregister-real-contract-20260828.xcresult。终态样例仍缺,不能将测试通过作为正式注销完成的证据。

2026-08-28 15:48—15:50:最终只读复核与冷启动尝试

  • 15:48:04查询仍为申请时间15:27:24的冷静期1。
  • 仅终止并重启iPhone Air中的App进程;未卸载、清空数据、登录或选择身份。工具未能切换至正确模拟器窗口,故冷启动UI没有验证完成。
  • 15:50:51用原会话再次GET /status、/eligibility,均返回同一申请的冷静期1,截止时间不变,remaining_seconds: 603392,撤销时间与完成时间均为null。
  • 证据:/private/tmp/suixinkan-contract-discovery-20260828/155050-simulator-status-redacted.json及同前缀的eligibility-redacted.json。
  • 未产生新的终态依据,不继续重复轮询或制造业务变化;待服务端到期状态或已有源码可用后再推进。

2026-08-28 15:56:重新登录自动撤销

用户告知已进入后,只读查询发现15:27:24申请已于15:55:36自动撤销。两次GET均返回status9、CANCELLED_BY_LOGIN、用户重新登录自动撤销的说明,completed_at仍为null。没有调用cancel或重新申请;未采集触发撤销的具体登录请求,因此不能断言具体接口时机。

证据:/private/tmp/suixinkan-contract-discovery-20260828/155633-simulator-status-redacted.json及同前缀eligibility文件。此前待注销记录的截止时间已失效,不再等待该申请于9月4日完成。用户随后要求UI简化,本轮仅使用Mock测试,不再操作真实注销。

2026-08-28 17:01:验证资产确认接口的false参数

用户单独授权尝试现金、积分接口传accepted: false。使用iPhone 11当前已登录门店身份和测试环境,先只读确认两项标记均为true、金额均为0、状态为未提交草稿0,再分别调用一次两个确认接口。

  • 现金:17:01:14返回HTTP 200、业务码100099、msg: 请明确确认自愿放弃对应资产、data: []。
  • 积分:17:01:32返回同样结果。
  • 每次调用后重新GET查询:wallet_waived和points_waived仍为true,草稿仍为0,金额未变化,没有进入冷静期。
  • 结论:当前接口不接受false作为撤回确认;本轮没有调用true、短信、申请、撤销或登录接口。未重试POST。

完整返回及前后状态见旧接口返回数据说明4.4节。脱敏证据目录:/private/tmp/suixinkan-waiver-false-20260828/。