需求背景
09-23-artist-fee-breakdown-refinement(费用明细契约细化:弹窗改后端供数)。POST /api/artist_center/work_tasks/fee_estimate(费用明细唯一出口)。本次不改用户端、不改列表、不改结算服务与模拟器本体、无迁移、无新增错误码。WorkTask(委托);净额 net_paid_amount(= 弹窗「已支付金额」)口径见《约稿详情净已支付金额》(2026-09-22)。更新记录
2026-09-23 首次发布:新增画师端费用试算接口 fee_estimate——费用明细唯一出口,按入参金额估算平台服务费 / 支付手续费 / 预计收入(开发阶段契约,后端未发版)。2026-09-24 Q2 口径迭代(就地更新):请求体移除 amount,费基改服务端派生(= net_paid_amount,不接受任意金额试算);payment_fee 由费率估算改为结算扣减口径逐单实际网关手续费(canceled 时为 0,语义=本次无需额外扣除、费基已内扣,非「实际手续费为 0」);新增 payment_fee_issues(原语 issues 原样透出,非空=金额信息不完整);fee_rates 移除 pay_fee_ratio;补充全退场景合法输出与前端标注义务(后端未发版,开发阶段契约就地更新,无兼容负担)。2026-09-24 钱包抵扣迭代(就地更新):新增 plat_fee_wallet_offset(手续费抵扣钱包 WalletUsage::PlatFee 预计抵扣,单列、不折进 platform_fee);estimated_income 公式加入 + plat_fee_wallet_offset;tips 改为显式抵扣数字口径(替代旧「实际收入可能会因手续费抵扣等发生微调」被动文案);弹窗绑定表新增「手续费抵扣钱包抵扣」行(> 0 时展示);钱包余额本身不进弹窗,仅输出预计抵扣金额(后端未发版,开发阶段契约就地更新)。2026-09-24 费基取数修正(就地更新):弹窗「已支付金额(费基行)」由详情 data.net_paid_amount 改绑试算响应 data.fee_base——费基与全部费用行同一次请求取数(一次请求内自洽);同源计算不代表跨请求恒等,详情与试算两次请求之间发生付款 / 退款 / 改价会错配新旧口径,禁止混读(纯前端绑定口径修正,接口契约不变)。2026-09-28 错误契约实测核对与排查补充(就地更新):422 示例对齐 Laravel 实际输出(含 errors 对象);补两类 404 排查区分(路径拼错 vs 业务不存在/非本人,按 message 区分);注明测试环境 APP_DEBUG=true 会附带 exception trace、生产仅 message。经测试库复现确认接口契约无缺口,2026-09-28 会议中的 422/404 为前端调用路径错误,接口无改动。建议阅读顺序:第 1 章(一分钟上手)→ 第 2 章(接口变更)→ 第 3 章(接口示例)→ 第 4 章(字段与弹窗绑定)→ 第 5 章(兼容性)。
| 章 | 内容 | 什么时候看 |
|---|---|---|
| 1. 一分钟上手 | 取数流程 + 取值来源 + 对接要点 | 刚拿到文档 |
| 2. 接口变更 | 试算接口变更摘要 | 找接口 |
| 3. 接口示例 | 请求参数、响应示例、响应字段说明、错误语义 | 对接具体接口 |
| 4. 字段与弹窗绑定 | 弹窗行项 ↔ 字段绑定与前端对接说明 | 联调对接 |
| 5. 兼容性说明 | 兼容项与发布协同 | 发布前确认 |
状态与口径:开发阶段契约、后端未发版;纯新增试算接口,无破坏性变更、无错误码变化。 费用明细是画师端专属概念,用户端详情与两端列表不输出任何费用明细字段。 面向前端(画师端)、联调、测试。
平台服务费率取画师数据库实际配置(响应
fee_rates.platform_fee_ratio同步返回);支付手续费不是费率估算,而是结算扣减口径的逐单实际网关手续费(缺费时以payment_fee_issues标注不完整);手续费抵扣钱包仅输出预计抵扣金额(plat_fee_wallet_offset,余额不展示)。前端不做本地费率与取整计算。
id,不传金额;响应 fee_base 由服务端派生(口径同详情 net_paid_amount,合同覆盖口径),弹窗「已支付金额」行直接读该响应字段。不支持任意金额试算。fee_base ≥ platform_fee + payment_fee − plat_fee_wallet_offset 时「费用行净额」等于费基;费用净合计超过费基时 estimated_income 截为 0(超支差额不向画师追收,也不折入其他字段),此时加和不等于费基——不要用加和反推费基,以 fee_base 为准。estimated_income 恒为 max(0, fee_base − platform_fee − payment_fee + plat_fee_wallet_offset)(与结算公式 income = total − payFee − feeAfterWaiver + platFeeRefund 逐项同构)。全退场景是合法输出:fee_base = 0 而 payment_fee > 0(手续费是已发生的常驻事实,退款后仍可能保留)时,费用净合计必然大于费基、estimated_income 为 0——这不是错误,不表示向画师追收。plat_fee_wallet_offset):单列字段,与 Open Call 减免同构展示;platform_fee 语义不变(减免后金额),抵扣不折进 platform_fee。上限 = platform_fee;无钱包 / 零余额 / platform_fee = 0 时为 0;canceled 态照常模拟(取消结算同走抵扣)。余额本身不展示(会议拍板),只展示预计抵扣金额;tips 口径见第 4.2 节。fee_rates:响应自带 platform_fee_ratio 实际配置值(pay_fee_ratio 已移除,支付手续费不再按费率计算),展示平台费率时读它,不本地写死。payment_fee_issues 非空 ⟹ 金额信息不完整:此时 payment_fee 为部分和(缺费订单按 0 计入合计),金额是下界估计而非精准值——前端必须标注提示,不得宣称精准。issues 原样透出共享原语的 code / message / order_id,不重定义错误码;canceled 且 payment_fee = 0 时照常输出,不因本次不扣费而隐藏。payment_fee = 0 表示本次计算无需额外扣除支付手续费(费基已内扣同源手续费),不表示实际手续费为 0;实际手续费真实值见详情净额字段组 non_refundable_fee。is_estimate: true 标注:恒为估算结果;对外展示建议保留「估算」语义提示。404(commission 不存在或非当前画师)、422(id 校验失败);无业务错误码分支。POST /api/artist_center/work_tasks/fee_estimate
费用明细是画师端专属:用户端详情与两端列表不输出任何费用明细字段。
POST /api/artist_center/work_tasks/fee_estimatenet_paid_amount)与逐单实际网关手续费,估算当前画师一笔 commission 的平台服务费 / 支付手续费 / 手续费抵扣钱包预计抵扣 / 预计收入。只读、无状态、不写库。| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
id | integer | 是 | commission id(work_tasks.id),必须属于当前画师 |
id >= 1,整数。net_paid_amount),历史字段 amount 已移除,传入会被忽略且不参与计算。缺费时 payment_fee 为部分和并透出 issues(前端据此标注「金额信息不完整」):
| 字段 | 类型 | 说明 |
|---|---|---|
fee_base | integer | 服务端派生费基 = 详情 net_paid_amount(working = min(retained, price),canceled = max(0, retained − nonRefundableFee),业务币种最小单位);展示以「已支付金额」为准 |
currency | object / null | commission 业务币种:id / code / symbol / is_zero_decimal |
platform_fee_gross | integer | 减免前平台服务费 = ceil(round(fee_base × worktask_plat_fee_ratio, 2)) |
platform_fee_waiver | integer | Open Call 减免金额;无减免为 0 |
platform_fee | integer | 减免后平台服务费 = platform_fee_gross − platform_fee_waiver |
payment_fee | integer | 本次计算需额外扣除的支付手续费:working 态 = 结算扣减口径 Σ 逐单实际网关手续费(共享原语派生);canceled = 0(费基已内扣同源手续费,非「实际手续费为 0」;实际手续费见详情净额字段组 non_refundable_fee) |
payment_fee_issues | array | 逐单手续费完整性问题,原语 issues 原样透出(code / message / order_id),不重定义错误码;canceled 且 payment_fee = 0 时照常输出。非空 ⟹ payment_fee 为部分和、金额信息不完整,前端须标注、不得宣称精准 |
plat_fee_wallet_offset | integer | 本次预计用手续费抵扣钱包(WalletUsage::PlatFee)抵扣的平台费(业务币种最小单位);上限 = platform_fee;无钱包 / 零余额 / platform_fee = 0 时为 0;canceled 态照常模拟(取消结算同走抵扣);取数复用结算侧同一换算/取整口径(余额折算 floor)。单列字段、不折进 platform_fee;只输出预计抵扣金额,钱包余额本身不输出 |
estimated_income | integer | 预计收入 = max(0, fee_base − platform_fee − payment_fee + plat_fee_wallet_offset)(与结算公式逐项同构);费用净合计超费基时为 0(见第 1 章对接要点 3,全退场景 fee_base = 0 / payment_fee > 0 / income = 0 是合法输出) |
fee_rates | object | 画师 DB 实际费率,仅 platform_fee_ratio(pay_fee_ratio 已移除:支付手续费按实际费计算,不按费率估算),展示平台费率用 |
policy_code | string / null | Open Call 减免政策标识;无减免为 null(此时 platform_fee_waiver 为 0) |
is_estimate | boolean | 恒为 true,估算语义标注 |
以下 JSON 均为测试库实测输出(生产 APP_DEBUG=false 形态;测试环境 APP_DEBUG=true 时 404 会额外附带 exception / file / line / trace 调试字段,属框架行为,不要据此误判)。
422:id 缺失或校验失败(框架级字段校验)。实测输出:id 非整数时:"message": "The id field must be an integer."(errors 结构同上,Laravel 实际校验文案为准)。
404:两类来源需区分排查:| 触发原因 | 实测 message | 排查方向 |
|---|---|---|
请求路径拼错(如 fees_estimate) | The route api/artist_center/work_tasks/fees_estimate could not be found.(直接点名拼错的路径) | 前端调用路径写错,改用 POST /api/artist_center/work_tasks/fee_estimate;接口本身无故障 |
| commission 不存在或不属于当前画师 | Work task not found | 检查 id 是否真实存在、是否属于当前登录画师 |
无新增 ErrorCode:本接口无业务失败分支,以上均为 HTTP 级错误语义。
收入详情弹窗(预计收入弹窗)与顶部卡片的逐行取值;行名统一用「已支付金额」(不叫「净已支付金额」):
| 弹窗行项 / 元素 | 取值字段 |
|---|---|
| 稿酬(参考行) | 详情 data.price(仅参考,不得与费用行混源解读) |
| 已支付金额(费基行) | 响应 data.fee_base(与全部费用行同一次请求取数;费基由服务端派生、无入参) |
| 平台服务费 | 响应 data.platform_fee |
| 平台服务费费率 tooltip | 响应 data.fee_rates.platform_fee_ratio |
| 平台服务费减免提示 | 响应 data.platform_fee_waiver(> 0 时附「已减免 X」) |
| 手续费抵扣钱包抵扣 | 响应 data.plat_fee_wallet_offset(> 0 时展示;钱包余额不展示,仅展示预计抵扣金额) |
| 支付手续费 | 响应 data.payment_fee(实际手续费口径;canceled=0 表示本次无需额外扣除) |
| 支付手续费说明 tooltip | 「按实际支付手续费计算」(不展示固定费率,见第 4.2 节 tips 口径) |
| 金额完整性标注 | 响应 data.payment_fee_issues(非空时标注「金额信息不完整」) |
| 预计收入(高亮行 + 顶部卡片) | 响应 data.estimated_income |
| 估算标注 | 响应 data.is_estimate |
「详情」= 画师端约稿详情接口字段;「响应」=
fee_estimate试算响应data。费基与全部费用行同读本次试算响应(一次请求内自洽),详情字段仅用于稿酬参考行。同源计算不代表跨请求恒等:详情与试算两次请求之间发生付款 / 退款 / 改价,会「旧费基配新费用」错配新旧口径,禁止混读(不得用详情
data.net_paid_amount充当费基与试算费用行拼表)。行名仍统一叫「已支付金额」。平台服务费展示链:
platform_fee_gross→platform_fee_waiver(Open Call 减免)→plat_fee_wallet_offset(手续费抵扣钱包,> 0 时展示)→ 画师实际承担的平台费(=platform_fee − plat_fee_wallet_offset);钱包抵扣单列,不改写platform_fee行数值。
priceCalcData),改读试算响应。data.fee_base(与费用行同一次请求取数;费基服务端派生、无入参),位置在稿酬行之后(作为费基)。不要绑定详情 data.net_paid_amount——它与试算响应是两次请求,期间发生付款 / 退款 / 改价会错配新旧口径。fee_rates.platform_fee_ratio:删除前端兜底写死费率(0.04 / 0.05)。支付手续费行不展示固定费率:tooltip 文案用「按实际支付手续费计算」;演示/联调用指定样本的实际手续费数值,不把通道费率(alipay-CNY 为 0、Stripe 约 3.x%)写成普遍保证。plat_fee_wallet_offset > 0 时 tips 用「预计收入已含手续费抵扣钱包预计抵扣 X;余额与汇率到结算时可能变化,以最终结算为准」,替代旧「实际收入可能会因手续费抵扣等发生微调,以最终结算为准」被动口径;抵扣为 0 时不追加该句;钱包余额本身不展示(会议拍板),只展示预计抵扣金额;payment_fee_issues 非空 ⟹ 金额信息不完整(payment_fee 为部分和),前端须标注提示、不得宣称精准;ac.worktask_info.total_income_tips,前端仓库维护)。payment_fee = 0 时如需说明,措辞为「本次无需额外扣除支付手续费」(费基已内扣);实际手续费引导用户查看详情净额字段组 non_refundable_fee,不要写「无手续费」。is_estimate 恒为 true,弹窗保留「估算」提示。payment_fee_issues 非空 → 金额完整性标注(必做,见 tips 口径);platform_fee + payment_fee − plat_fee_wallet_offset)> 费基 → estimated_income 截 0,加和 ≠ 费基,禁止用加和反推费基,以 fee_base 为准;全退场景 fee_base = 0 / payment_fee > 0 / income = 0 是合法输出,不按异常处理;settlement_preview 字段)。POST /work_tasks/fee_estimate { id }(只传 id,金额由服务端派生),渲染函数入参为响应估算对象;详情不再内嵌 fee_breakdown,单一取数路径无双源漂移。fee_estimate 只读、无状态、无存量消费方(后端未发版;amount 入参与费率口径在首发前就地迭代,无已上线消费方)。404 / 422;试算接口只读、不写库。SettlementSimulator 与结算服务行为不变;估算层自 2026-09-24 起包含手续费抵扣钱包预计抵扣(plat_fee_wallet_offset,只读模拟、不写库),取数复用结算侧同一 PlatFeeWalletService::minus() 原语,不旁路、不复制换算/取整规则。