企业 网站订阅

Odoo 企业版网站电商:订阅商品为什么不能和不同周期混加购物车

website_sale_subscription 真正难的不是前台显示月付价,而是购物车怎样保持同一 recurring 语义:plan 怎么选、不同周期为什么不能混装、支付页又怎么知道这是订阅单。

企业 网站
进阶 开发者 1 分钟阅读
0 评论 0 点赞 0 收藏 5 阅读

网站卖订阅产品时,很多人只盯着“月付价格能不能显示出来”。但真正常把项目做坏的,往往是购物车规则:客户选了年付,再加一个月付;或者订阅商品和一次性商品乱混,最后后台根本解释不清订单语义。

这篇文章主要参考了以下企业版源码入口:

  • enterprise/website_sale_subscription/models/sale_order.py
  • enterprise/website_sale_subscription/controllers/variant.py
  • enterprise/website_sale_subscription/views/templates.xml

一、这篇功能真正解决什么问题

website_sale_subscription 的核心不是“电商也能卖 recurring product”,而是让网站购物车在前台阶段就守住订阅语义。一旦这里失守,后面的订阅合同、开票节奏、税务地址和支付页判断都会被拖乱。

二、核心链路怎么走

1. 加车时先确定订单到底挂哪个 plan

sale.order._cart_add(..., plan_id=None) 会先看当前商品是不是 recurring product。如果是,就尝试从产品模板的 recurring pricing 里找到适配的 plan_id,并把它写到订单上。这里的关键点是:计划不是前台展示字段,而是订单语义核心。

2. 不同订阅周期不能在同一订单里混放

当购物车已经有 plan_id 时,再加另一个周期的订阅商品,源码会直接抛 UserError。这不是官方“太保守”,而是因为一张订阅订单必须有一个明确 recurring cadence;混不同周期,后续 next_invoice_date 根本没有统一基准。

3. 支付页也要知道自己在处理订阅单

controllers/variant.py 里扩展了组合信息和支付值,_get_shop_payment_values() 会明确传出 is_subscription。这样支付模板和后续流程才知道当前订单不是普通一次性销售,而是带订阅含义的电商单。

三、新手最容易踩的坑

  • 以为前台 plan 只是 UI 选项,后台无所谓。其实订单级 plan_id 才是后续订阅链路的锚点。
  • 以为 one-time sale 和 recurring 商品想混就混。源码里已经用 allow_one_time_sale_has_one_time_sale() 等逻辑精细区分。
  • 以为支付页识别不到订阅也没关系。实际上支付页不知道自己在处理 subscription,很多提醒和模板逻辑都会偏掉。

四、实战落地时最该盯的点

  • 先检查产品模板上的 recurring pricing 是否完整,否则前台选了计划也可能找不到适配 price。
  • 再检查是否真有业务需要允许 one-time 附加项;有的话,要把规则讲清楚,不要让运营误以为任何组合都能混卖。
  • 最后验证支付页上下文里 is_subscription 是否稳定出现,尤其是自定义模板或第三方支付接管页面时。

五、结论

网站订阅的难点从来不只是前台展示价格,而是让计划、购物车、支付页在同一条 recurring 语义线上同步。Odoo 企业版把这条线守在 _cart_add() 这一层,恰恰说明它知道最容易出事故的地方在哪里。

DISCUSSION

评论区

想参与讨论?先 登录 再发表评论。
还没有评论,你可以成为第一个留言的人。