Files
uniprop-manual/prop-acc/scenarios/prepaid/refund-full-resident-moveout.md
2026-05-25 23:27:56 +08:00

7.3 KiB

title, aliases, tags, audience, status, sub_feature, last_review, code_version
title aliases tags audience status sub_feature last_review code_version
prop-acc · prepaid · 场景 - 业户搬走全额退余
业户搬走退预存款
全额退预存款
refund-full-resident-moveout
场景-业户搬走退预存款
场景
prop-acc
预存款
退款
业户
业务人员
已发布 prepaid 2026-05-25 2026-05-22

场景:业户搬走全额退余

业户搬离社区(卖房 / 退租 / 不再使用本物业),要把预存款账户余额全额退回。退款后不自动关账(prepaid 特性),业务人员主动close-resident-moveout 流程。

典型情境

[!example] 真实情境 刘先生把 12-3-501 房子卖了,下周搬走。他在预存款账户里还有 ¥3,200(本月物业费扣完之后的余),要全额退回。

业户视角

第 1 步:告知物业搬走

  • 跟物业管家说"我下周搬走,把预存款里的钱退给我"
  • 提供退款渠道(银行卡 / 微信 / 支付宝)

第 2 步:等退款

  • 业务人员核对账户余额
  • 操作退款(走线下 + 系统)

第 3 步:收到红字收据 + 退款到账

  • 红字收据"预付款退款 ¥-3,200"
  • 银行 / 微信收到 ¥3,200

第 4 步:账户被关

  • 后续物业再发账单(若有)→ 不会自动从这个账户扣(已 Closed)
  • 业户在小程序"我的预存款" 显示 "🔒 已关闭"

业务人员视角

第 1 步:核实业户搬走情况

  • 房屋已过户(看 community_user_profile 状态)
  • 业户已结清其他费用(无未付账单)
  • 业户提供退款渠道

[!warning] 注意未付账单 如果业户还有未付账单(物业费 / 水电费等),先抵扣再退余:

  • 业户余额 ¥3,200,有未付账单 ¥800 → 先 consume-monthly-property-bill,余 ¥2,400 → 再退 ¥2,400
  • 不要直接退全部 → 否则未付账单仍挂业户身上,变成"搬走后还欠物业钱",催收困难

第 2 步:打开账户做退款

后台 → 预存款 → 找到刘先生账户(Active,balance=3200)→ 进 ViewPrepaidAccount → 点 RefundAction(标签"退款")。

[!warning] 按钮可见性 RefundAction 守护:canOperate() && balance > 0 + Policy ->authorize('refund')。Frozen / Closed / 零余额账户灰化。

Modal 表单:

字段 填什么
退款金额 ¥3,200(默认带入当前余额)
退款渠道(PaymentChannel) 选业户指定回款方式
退款备注 必填,如 "业户搬离,12-3-501 已过户,退预存款全额"

第 3 步:提交

系统调 RefundFromPrepaidAccountAction,事务内:

  1. 校验 canOperate()(Active only)
  2. 校验金额 ≤ 当前余额
  3. CollectionOrder(type=Prepaid,actual_amount=-3200 红字,Completed)
  4. PrepaidAccount::refund(3200, ...):
    • 模型层再校验 canOperate()(三层防御之模型层兜底)
    • PrepaidTransaction(type=refund,amount=3200,balance_before=3200,balance_after=0,关联红字 CO)
    • 更新 balance=0
  5. 不自动关账(prepaid 特性,与 deposit 不同 —— 见 account-state-machine "零余额不自动关账" 段)
  6. 触发 CollectionOrderCompleted → Listener 建红字 Receipt"预付款退款 ¥-3,200"

第 4 步:走线下退款

  • 银行转账:导出回款指令 → 银行办理
  • 微信:在物业微信号上做退款
  • 支付宝:同上

第 5 步:主动关账(close-resident-moveout)

退完余额后账户仍是 Active 状态,需手动走 CloseAccountAction 关掉。这是 prepaid 与 deposit 的关键差异。

详见 close-resident-moveout

第 6 步:把红字收据给业户

后台找 Receipt → 微信 / 邮件发刘先生。

系统流程

sequenceDiagram
    participant 业户
    participant 财务
    participant Filament
    participant RefundFromPrepaidAccountAction
    participant 数据库
    participant 监听器

    Note over 业户,财务: 业户搬走,余额 3200

    财务->>财务: 核实无未付账单(若有,先 consume)
    财务->>Filament: ViewPrepaidAccount → RefundAction(3200)
    Filament->>RefundFromPrepaidAccountAction: handle(account, 3200, channel)
    RefundFromPrepaidAccountAction->>RefundFromPrepaidAccountAction: canOperate()? Active=true
    RefundFromPrepaidAccountAction->>RefundFromPrepaidAccountAction: 3200 ≤ 3200 yes
    RefundFromPrepaidAccountAction->>数据库: 开启事务
    RefundFromPrepaidAccountAction->>数据库: 1. 建 CO(Prepaid, -3200 红字, Completed)
    RefundFromPrepaidAccountAction->>数据库: 2. account.refund(3200) → balance 3200→0
    RefundFromPrepaidAccountAction->>数据库: 3. balance=0, **status 仍 Active**
    RefundFromPrepaidAccountAction->>监听器: 4. 触发 CollectionOrderCompleted
    监听器->>数据库: 5. 建 Receipt("预付款退款 ¥-3,200")
    RefundFromPrepaidAccountAction->>数据库: 提交事务
    Filament-->>财务: 成功(注:account 仍 Active,需手动关账)

    Note over 财务: 接着走关账
    财务->>Filament: CloseAccountAction → status=Closed
    财务-->>业户: 银行/微信退 3200 + 红字收据

与 deposit 退款的关键差异

维度 deposit 退款(refund-full-no-damage) prepaid 退款(本场景)
余额清零后状态 自动 Closed 仍 Active(可继续充值)
关账操作 不需要 需手动 CloseAccountAction
业务背景 装修结束等业务节点 业户搬走等长期事件
是否常见 高频(每户装修都做) 低频(业户搬走才做)

常见问题

[!question] 为什么 prepaid 不自动关账? 详见 account-state-machine "零余额不自动关账" 段。简言之:预存款账户一户一账,频繁开关无意义,业户随时可能继续充值。

[!question] 退完不关账户有什么风险? 几乎无风险:

[!question] 业户搬走后又租回来或买回来,关了账户怎么办? 当前一户一账约束阻塞(unique 不允许重开)。详见 one-account-per-resident "已知设计 gap"。业务上目前用:

  • 业户重新现金 / 微信付账单(不用预存款)
  • 联系运维特殊处理(罕见)

[!question] 退款渠道与充值渠道不同可以吗? 可以,看 ../deposit/refund-with-payment-channel-switch 介绍的换渠道逻辑(deposit 模块,逻辑相同)。

[!question] 业户失联但要退预存款怎么办? 几个选项:

  • 暂留 Active:不操作,等业户出现(余额对业户仍可用)
  • freeze 账户:走 freeze-suspected-fraud 流程(reason 改"业户失联待联系")
  • 不可走 ForceClose retain(prepaid 没有 ForceClose,与 deposit 不同)
  • 长期失联(>2 年)走业务流程(类似 deposit 的 retain,但 prepaid 当前没有内建机制,需运维介入)

异常分支

相关文档