Skip to main content
菜单是对顾客在某个门店可以点的所有内容的结构化描述:菜品、定价方式、如何定制,以及适用哪些税费。您以一份 JSON 文档发布菜单,Maple 以您分配的外部 ID 作为所有对象的键。本页介绍该模型,以及如何把您自己的商品目录映射到它。发布菜单指南介绍请求流程,菜单示例提供完整示例,接口参考列出所有字段。

每个门店一份菜单

每个门店只有一份菜单。一个门店不存在多份命名菜单(例如分开的“早餐菜单”和“晚餐菜单”)的概念,不同时段的差异是在这唯一的菜单_内部_通过供应时段来表达的。 发布会整体替换这份菜单(以差异方式应用,见下文)。Maple 在内部保留版本历史,并始终提供当前版本,但从您这一侧看,模型很简单:一个门店,一份菜单,由您完整发布。
如果您自己的系统为每个门店建模了多份菜单,请在发布之前把它们合并成一份 Maple 菜单,通常做法是拆成各自带有供应时段的独立分类。

树结构

菜单是由三层嵌套对象组成的树,其中引用了共享的定义:
  • 分类(Category):菜单中的一个板块(饮品、主菜)。可以设置分时段,使其只在特定时间窗口内显示。
  • 菜品(Item):一个菜品。有一个或多个规格,并可携带加料组、税和费用。
  • 规格(Variation):菜品的一种可购买形态(小杯 / 大杯,或只是“常规”)。价格在这里。 每个菜品至少有一个规格。
  • 加料组(Modifier group):一组带有选择规则的选项(牛奶、加料选项)。可以定义一次后共享,也可以内联在菜品上。选项本身还可以带有嵌套的加料组。

映射您自己的商品目录

大多数集成方已经有自己的菜单模型。下表是常见概念的映射方式,一开始就做对可以避免最常见的错误:
请避免以下常见的错误假设:价格不在菜品上(它在规格上);大小不是单独的菜品(它是规格);每个门店只有一份菜单(分时段使用的是供应时段,而不是多份菜单)。

外部 ID 归您所有

每个对象(分类、菜品、规格、加料组、选项、税率、费用)都带有一个由您分配并拥有的 externalId。Maple 绝不会更改它。这是整个模型的支柱:
  • 使用相同的 externalId 重新发布,会更新同一个对象,而不是创建重复对象。
  • 订单行项目通过这些 ID(menu_entity_id)引用菜单,因此传入的订单可以直接映射回您的商品目录。
  • Maple 也会在响应中生成自己的 ID(item_…、var_…、ctg_…)供参考,但您始终通过自己的 externalId 来寻址一切。
  • 对象之间同样通过 externalId 相互引用。 当加料组引用使用 groupId、菜品通过 taxRateIds 指向税率,或促销通过 discountId 指定折扣时,这些值都是您分配的 externalId,而不是 Maple 生成的 ID。
请使用在您自己系统中稳定的 ID(SKU、主键),而不是可能变化的显示名称。

定价

价格是对象,而不是单纯的数字,因此模型可以表达的不止一个固定金额。基本结构是以整数最小货币单位表示的金额加上币种:
价格对象还支持价格类型(fixed、variable 开放金额、用于称重商品的 per_unit、按数量分档的 bulk)、含税定价、按币种覆盖,以及划线价(compare-at)。对于常见情况,即单一币种的固定价格,您只需要 amount。请参阅金额与货币。

加料选项

加料组包含选择规则和一组选项。规则比简单的最小/最大值更丰富,这让您可以表达诸如“最多选 3 个,但同一种不超过 2 个”之类的要求: 通过 groupId 从菜品或规格中引用共享加料组,或者内联定义一个。在同一个条目中,这两种形式互斥:引用只带 groupId;定义则带 name 和 options。混用会被拒绝,而不是被悄悄截断。选项可以带有自己的嵌套加料组,用于自选组合流程。请参阅菜单示例了解完整示例。
订单资源目前会在每个行项目上展示直接选择的第一级加料选项。更深层的嵌套选择暂时不会展开到订单资源中。

税费

这些是顶层定义,您通过 ID 将它们挂接到菜品上:
  • 税类别和税率:税率可以是 percentage、flat 或基于 bracket,计税基数可配置,可含税或不含税。通过 taxCategoryId / taxRateIds 挂接。
  • 费用:附加费和押金(瓶装押金或 CRV),通过 feeIds 挂接。
  • 折扣、促销和优惠券:用于降价的可选顶层集合。
大多数菜单只需要一个税率且没有费用;当门店需要时,可以使用更丰富的结构。

供应时段与分时段菜单

供应时段是您表达分时段菜单的方式,它取代了多份菜单的想法。
  • 设置了供应时段的分类只会在该时段内显示(早餐供应到 11:00)。
  • 菜品也可以带有自己的时段。
  • 没有设置供应时段的对象始终可供应。
每个时段由星期几加本地时间范围组成:
  • dayOfWeek:0(星期日)到 6(星期六)。每个供应日添加一个时段。
  • startTime / endTime:本地 HH:MM,24 小时制。
时段按菜单的时区计算,该时区由顶层的 timezone 字段设置(IANA,例如 America/New_York)。未设置时默认为 UTC,因此请在首次发布时设置,请参阅为供应时段设置时区。 “每日特供”或早餐板块,就是一个设置了相应时段、位于唯一那份菜单中的分类(或菜品)。请参阅每日特供示例。

库存状态

库存状态为 in_stock、out_of_stock 或 low_stock。发布时,省略该字段会保留当前值;全新的对象默认为 in_stock。您可以用它给某个菜品“下架”(86),而无需重新发布整份菜单的结构。

发布会替换整份菜单

您始终需要把整份菜单作为期望状态发送。Maple 按 externalId 以差异方式应用:
  • 校验是全有或全无:400 会列出所有问题,并且不做任何更改。
  • 相同内容的重新发布不会产生任何变化,对象标识保持稳定,因此您可以在每次菜单变化时发布,而不会产生波动。
因此,最简单的集成方式是在您的数据源每次变化时重新发布完整菜单。请参阅发布菜单。