主题
平台运营商品价格逻辑
更新日期:2026-09-21
代码基准:1520c9be(修复平台运营商品统一底价及售价校验)
适用对象:业务运营、产品、开发和测试人员。
本文描述仓库当前实现,不代表相关版本已经部署上线。
一、核心结论与适用范围
商户提供一个固定结算底价,平台决定活动售价和适用的日期售价;商户按底价形成结算基础,平台取得销售额与结算基础之间的差价。
这里的“固定”是指同一商品使用统一底价,不按活动、日期分别报价;不是指底价永远不能调整。平台可以通过商品级入口统一修改底价。
本文针对商户供给、交由平台运营的商品:
- 运营模式:
operationMode = PLATFORM_MANAGED。 - 定价模式:投放活动时统一使用
priceMode = floor。 - 支持的投放类型:团购
groupbuy、拼团pintuan、套餐供给package。 - 同一商品可以投放多个活动,各活动共享商品底价,但销售定价可以不同。
“平台运营”不等于“平台自营”。ownerType = PLATFORM_SELF 的平台自营商品存在商户结算额为零的特殊处理,不套用本文商户收益示例。独立酒店房型、商城 SKU、租车等其他商品体系,也不能直接套用本文全部规则。
二、价格字段与职责
金额字段以“分”为单位,界面通常显示“元”。本文数值示例均使用元,除特别说明外不含优惠、手续费和退款。
| 名称 | 主要字段 | 作用 |
|---|---|---|
| 商品统一底价 | XdProduct.supplySettlementPriceFen | 商户提交的固定供给底价,也是平台统一调整底价的主数据 |
| 活动结算底价 | XdProductActivity.settlementPriceFen | 从商品底价同步,订单计算时使用 |
| 活动默认售价 | XdProductActivity.activityPriceFen | 平台为团购、拼团分别设置的基础销售价 |
| 划线价 | supplyOriginalPriceFen、originalPriceFen | 展示参考,不参与商户结算计算 |
| 日期售价调整额 | XdProductPriceCalendar.activityExtraFeeFen | 相对于活动默认售价的日期差额,不等于平台全部利润 |
| 日期底价加价 | XdProductPriceCalendar.settlementExtraFeeFen | 共用日历模型的字段;平台运营商品不再开放单独修改,历史记录见第九节 |
| 订单商户结算基础 | XdOrderItem.settlementAmountFen | 下单时确定并保存的商户结算金额,尚未扣除商户优惠承担和手续费 |
| 订单平台差价 | XdOrderItem.platformMarginFen | 订单创建时记录的差价;不应直接当作最终净利润 |
划线价不是成本,也不决定平台利润;不能通过修改划线价改变结算结果。
三、商户提交与平台投放
1. 商户提交
商户填写商品信息、划线价和一个固定底价。平台运营模式下:
- 划线价和结算底价必须大于零。
- 商户提交后进入平台审核,不直接创建商户自行选择的活动。
- 不保存商户提交的底价日历;商户日历接口也不允许操作平台运营商品。
- 商品创建后不允许切换运营模式。
- 已有上线活动时,商户需先下架商品,才能编辑并重新提交审核。
2. 平台审核、投放
平台选择团购、拼团或套餐供给,可以同时选择多种类型。每个活动的结算底价由商品统一底价复制:
text
活动结算底价 = 商品统一底价团购、拼团必须配置大于零的活动售价,且:
text
活动默认售价 >= 商品统一底价允许售价等于底价,此时优惠和手续费前的平台毛差价为零。此模式不是在底价基础上再固定抽取 20% 佣金。
套餐活动代表供给子项,最终面向用户的售价由套餐体系确定;不能把套餐供给活动的空售价或零售价当成商品免费销售。
四、团购和拼团的价格计算
1. 不涉及日期调整
text
订单销售额 = 活动默认售价 × 数量
商户结算基础 = 商品统一底价 × 数量
平台毛差价 = 订单销售额 − 商户结算基础例如同一商品底价 300 元:
| 投放活动 | 单份售价 | 单份商户结算基础 | 单份平台毛差价 |
|---|---|---|---|
| 团购 | 360 | 300 | 60 |
| 拼团 | 340 | 300 | 40 |
销售渠道不同可以导致售价不同,但不应导致同一商品的默认结算底价不同。
2. 酒店活动的日期售价
在商户详情的“修改售价”中,酒店类活动支持默认售价和日期售价;普通非酒店活动在该界面只提供默认售价。
对于符合统一底价规则、没有历史日期底价加价的商品:
text
当天售价 = 活动默认售价 + 当天售价调整额
当天结算单价 = 商品统一底价
当天平台毛差价 = 当天售价 − 商品统一底价日期售价可高于或低于默认售价,但不能低于结算底价。这里比较的是最终售价,不是要求所有日期调整额都为正数。
例如底价 300 元、默认售价 360 元:
| 日期销售策略 | 日期调整额 | 最终售价 | 商户结算单价 | 平台毛差价 |
|---|---|---|---|---|
| 普通日期 | 0 | 360 | 300 | 60 |
| 旺季日期 | 50 | 410 | 300 | 110 |
| 淡季日期 | -40 | 320 | 300 | 20 |
| 平价销售 | -60 | 300 | 300 | 0 |
| 低于底价 | -70 | 290 | 300 | 不允许保存 |
选定入住日期的酒店订单逐日累计,退房日不计费。例如一间房住两晚,售价分别为 360 元、410 元,则销售额 770 元,商户结算基础 600 元,平台毛差价 170 元。
没有日历记录的日期按默认售价计算;这不代表库存为零,能否购买还要通过房型、可售状态及库存等校验。
五、商户详情中的改价规则
入口:平台后台 → 商户管理 → 商户详情 → 结算底价。
| 操作 | 平台运营商品的规则 |
|---|---|
| 修改商品默认底价 | 允许,统一同步该商品所有未删除的底价模式活动,包括套餐供给活动 |
| 修改某个活动的默认底价 | 不允许,后端拒绝绕过商品级入口的请求 |
| 查询或修改活动日期底价 | 不开放,页面入口已移除,后端也拒绝 |
| 修改团购或拼团默认售价 | 允许,各活动独立设置,不改变底价 |
| 修改酒店活动日期售价 | 允许,不改变统一底价 |
| 修改套餐最终售价 | 不在此入口操作,进入套餐管理 |
| 单独修改库存 | 使用库存权限及相应入口;仅改价格时不应改变库存 |
出车底价的取值上限来自平台车型库的车型日租售价 xd_car_model.daily_price_fen,同一车型的所有商户共用;该价格在「车型管理」维护,不能在商户详情页修改。
1. 修改统一底价
平台修改商品底价时:
- 提交当前底价、新底价和修改原因,新底价须为大于零的整数分。
- 校验团购、拼团等非套餐底价活动的默认售价能覆盖新底价。
- 校验今天及未来已有日期价格能覆盖调整后的结算金额。
- 更新商品底价,并同步所有未删除的底价模式活动。
- 保持默认售价、日期售价不变;底价变化相应改变平台毛差价。
- 保存变更记录,向商户发送底价变更通知。
如果当前团购售价 360 元、拼团售价 340 元,底价不能直接从 300 元改到 350 元。应先提高拼团售价,并确认相关日期售价也满足要求。
当前实现会检查关联活动,不只检查正在销售的活动;遇到已下架活动的旧售价阻挡改价,也要核对该活动配置。
商户详情弹窗的「底价约束」会列出可能阻挡改价的约束(各非套餐活动售价、各未来日期售价),按金额从低到高排列,最多展示 10 条;只有一条约束时以单行「最高可设底价」展示。这样无需逐个活动试错即可判断该先调哪一处。
1.1 房型默认底价的影响面
酒店房型改默认结算底价时,系统会同步改写所有「跟随默认底价」的未来房态日期底价,同时保持这些日期的平台售价不变。因此:
- 商户详情弹窗在保存前提示本次将同步改写的日期数量并列出日期(超过 20 个折叠为「等 N 个」);
- 变更记录仍只有一条默认价明细,被连带改写的日期作为该记录的附带日期清单,商户通知同样带该清单。
房型日期底价与商品活动日期底价是两套机制:前者跟随房型默认底价,后者是相对活动默认底价的加价。
2. 修改售价
商户详情售价入口只允许修改审核通过的平台运营商品中,已经启用、配置了价格的底价模式团购和拼团活动。
- 新售价须为大于零的整数分,且不能低于结算底价,允许相等。
- 默认售价和日期售价分别提交,日期售价不能修改过去日期。
- 保存时携带旧底价、旧售价;数据已被其他操作修改时,需要刷新后重新确认。
- 售价变更记录来源为
PLATFORM_SALE,与底价变更记录区分。 - 只改售价不改变底价;如同时改库存,还需库存权限,并校验已售数量和库存是否发生变化。
3. 酒店默认售价与已有日期售价
通过商户详情修改酒店活动默认售价时,已有日历记录的最终售价保持不变。
系统会反向调整已有日历记录的售价差额:
text
新日期调整额 = 原日期调整额 + 原默认售价 − 新默认售价例如默认售价从 360 元改到 380 元:
- 已有日历记录、最终售价为 410 元的日期,仍为 410 元,调整额由 50 元变成 30 元。
- 已有日历记录、最终售价为 360 元的日期,仍为 360 元,调整额变成 -20 元。
- 没有日历记录的日期,跟随新的默认售价,变成 380 元。
不能因为提高了默认售价,就认为所有未来日期都已涨价。需要提高某天售价时,应单独修改该日期。
本节描述的是商户详情的改价实现,不能推断所有后台入口都有相同的日历保价行为。
六、套餐定价与分摊
套餐是独立的销售定价层。商品底价决定商户结算基础,套餐销售额的分摊不决定商户底价。
1. 固定套餐
平台设置套餐总售价,再按所选商品的分摊参考价权重分配到子订单:
text
子项权重 = allocationReferencePriceFen × 数量
子项销售额 = 套餐总售价 × 子项权重 ÷ 所有子项权重之和
子项结算基础 = 商品底价 × 数量
子项平台毛差价 = 子项销售额 − 子项结算基础实际金额按分处理,使用最大余数法分配分币尾差,保证子项销售额合计等于套餐售价。不是按商品底价比例分摊,也不是简单把全部尾差给最后一单。
例如套餐售价 540 元,两个子项各一份:
| 子项 | 商户底价 | 分摊参考价 | 分摊销售额 | 平台毛差价 |
|---|---|---|---|---|
| A | 300 | 400 | 360 | 60 |
| B | 100 | 200 | 180 | 80 |
| 合计 | 400 | 600 | 540 | 140 |
2. 自选套餐
text
子项销售额 = 套餐子项 platformPriceFen × 数量若子项未配置 platformPriceFen,当前下单实现回退使用活动售价;两者都不可用时拒绝下单。
3. 套餐优惠与成本检查
套餐阶梯优惠在创建订单时记为平台承担,减少平台差价,不直接扣减商户结算底价;后续优惠券的承担规则另行计算。
团购、拼团“售价不能低于底价”的配置校验,不等于已经保证所有套餐组合盈利。统一底价调整会同步套餐供给成本,但不会自动提高套餐售价或分摊参考价;运营仍需在套餐管理中复核组合成本和优惠后的收益。
七、优惠、手续费与最终到账
结算底价是收入计算基础,不是商户最终到账净额。
text
优惠后商户结算额 = 商户结算基础 − 商户承担优惠
优惠后平台毛收入 = 优惠后用户应付金额 − 优惠后商户结算额
商户净收入 = 优惠后商户结算额 − 商户分摊支付手续费
平台净收入 = 优惠后平台毛收入 − 平台分摊支付手续费- 平台承担的优惠减少平台收益,商户承担的优惠减少商户收益。
- 配置售价不低于底价,不代表叠加优惠和费用后平台一定盈利。
- 当前相关代码使用
0.006支付费率;这是系统实现参数,不是对支付机构实际签约费率的保证。 - 优惠券结算路径按外部支付金额计算手续费,并分配商户、平台承担额;不能把余额抵扣当成商户让利。
- 不同支付处理路径存在取整和尾差处理差异,核账应以订单费用字段、优惠结算记录和钱包流水为准。
- 商户收入一般依次进入交易冻结、待结算、可用余额;完成履约不等于立刻可以提现,具体时间按结算策略处理。
八、订单快照与改价生效
下单时保存销售额、结算基础、平台差价等订单明细。上述商品改价接口不回写已创建订单的这些金额。
- 改价后的新订单使用新的价格配置。
- 已创建订单不因修改商品底价或售价而自动重新计价,包括已创建但尚未支付的订单。
- 后续退款、改期补差等属于独立业务流程,不等于直接重算原订单。
- 酒店订单已按所选日期计价的,还会保存日期计价快照,供后续预约和改期判断使用。
例如订单已按底价 300 元创建,随后商品统一底价调到 320 元,不能仅凭商品当前底价把原订单结算基础改成 320 元。
预约补差与撤销
- 已按日期计价的订单预约原日期不再补收日历加价;改约其他日期时,只收目标日期总售价超过原日期快照销售额的部分,不在预约流程自动退负差价。
- 新日期计价快照额外保存下单时的默认结算底价。改约的商户补差只计算日期结算差额,不包含下单后默认底价的涨幅,也不回写原订单结算额。
- 旧日期快照没有默认底价字段时,优先从商品级、活动级改价历史恢复;早于首条改价记录的订单使用该记录的原价。没有可用历史记录时仍回退当前默认底价,缺失的历史价格不能凭空还原。
- 未按日期计价的券单,日历中的负售价调整额可抵扣同次预约的正加价,合计低于零时补差按零处理。商户日期结算加价仍不得为负或超过应收补差;此类配置冲突需平台核对,不能静默少结算。
- 小程序先调用只读预约报价接口,报价和提交共用后端逻辑。金额尚未取得时不能提交;提交金额与重新计算结果不一致时,刷新报价并由用户重新确认,不自动按新金额扣款。发布时先上线 API,再发布小程序。
- 预约撤销时,已支付及已完成的补差单均走自动退款,退款中或已退款的订单不重复发起。预约补差退款成功后,按退款单 ID 幂等冲回商户收入;纯余额退款也执行同一退款成功处理。
- 本次代码修复不自动补退历史已撤销预约的漏退款,也不回算历史商户流水;这些存量记录需要另行核对处理。
九、历史数据及入口差异
1. 本次修复没有自动清理旧数据
1520c9be 关闭了商户详情的单活动底价、日期底价修改通道,并补齐售价下限校验;没有运行数据库清理,也没有回算历史订单。
因此,旧数据仍可能存在:
- 商品供给底价与个别活动结算底价不一致。
- 平台运营活动的
settlementExtraFeeFen非零。 - 修复前保存的售价低于结算底价。
不能仅凭新代码已合入,就认为所有存量价格已符合统一底价规则。
2. 旧日期底价仍被兼容读取
当前共用报价逻辑仍按以下公式读取已有日期底价:
text
实际日期结算单价 = 活动结算底价 + 历史日期底价加价商户详情的日期售价校验也会参考这一实际结算单价,而不是忽略历史加价。平台运营专用日历保存则仍将日期底价加价写为零,可能覆盖这些旧值。
有存量异常时,应先核对协议、未来价格和订单,再制定数据修正方案;不要通过反复保存日历来隐式清理底价。
3. 不同日期售价入口的限制不同
商户详情的酒店日期售价入口支持最终售价低于默认售价,只要不低于实际结算底价。平台运营专用“价格日历”仍以非负活动加价为输入约束。日期降价宜使用商户详情的“修改售价 → 日期售价”入口。
十、运营检查清单
- 商户提交的是否是一个明确、有效的固定底价,而不是最终到账承诺?
- 各团购、拼团活动的默认售价是否都能覆盖统一底价?
- 日期售价是否满足底价约束,是否误把默认售价修改当成所有日期涨价?
- 调高底价前,是否核对全部关联活动和今天及未来的日期售价?
- 套餐供给成本变化后,是否重新核对组合成本、套餐售价及优惠承担?
- 是否区分平台毛差价、优惠后收入与扣手续费后的净收入?
- 是否保留改价原因、核对变更记录,并在发现旧数据异常时单独处理?
十一、实现与测试索引
以下链接相对于本文件,便于直接定位仓库实现:
| 内容 | 核心实现 |
|---|---|
| 商户提交、运营模式与日历权限 | MerchantProductController |
| 平台审核与多活动投放 | PlatformManagedProductService |
| 商品统一底价修改、禁止单活动及日期底价 | MerchantSettlementPriceService |
| 默认售价及日期售价修改 | MerchantSalePriceService |
| 酒店默认售价变更时保留已有日期总价 | MerchantSalePriceMapper.xml |
| 平台运营专用日历 | AdminProductPriceCalendarService |
| 团购金额和订单快照 | GroupbuyOrderHandler |
| 酒店日期报价 | HotelActivityPriceService |
| 套餐创建与价格拆分 | XdOrderServiceImpl,createPackageOrder、splitPackageAmount |
| 固定套餐分币分摊 | FixedPackagePriceAllocator |
| 优惠与手续费 | CouponSettlementCalculator、CouponCheckoutService |
| 钱包冻结和结算 | MerchantWalletLedgerImpl |
规则回归测试:
- MerchantSettlementPriceServiceTest:统一底价同步、绕过入口拦截、自主运营日历保留。
- MerchantSalePriceServiceTest:售价下限、等于底价、日期降价、旧值校验和日期保价。
- merchant-sale-price-contract.test.mjs:页面入口和前端价格校验。