如果还没看过,请先浏览 Maple 如何运作 了解对象模型,并运行 快速入门 获取密钥并连接一个测试门店。
步骤 1:连接门店
只有当您的应用成为某个门店的已连接接收方后,订单才会路由给您:409。对同一路径使用 GET 和 DELETE 可以查看和移除您的连接。
步骤 2:订阅 webhook
注册一个 HTTPS 端点以及您需要的事件类型。完整目录见GET /v1/webhook_event_types;订单流程通常需要以下事件:
mwhsec_…)。请妥善保存,它不会再次显示。URL 必须是公开的 HTTPS 地址,私有和内部地址会被拒绝。
以上是订单相关事件。目录中还包括
order.created、order.paid、store.provisioned、
store.deprovisioned、store.status.changed 以及菜单同步事件。只订阅您会处理的事件。完整列表和负载请见
Webhooks。步骤 3:验证每一次推送
每次推送都是 Stripe 风格的信封:maple-webhook-id(事件 ID)和 maple-webhook-signature,格式为 t=<unix_seconds>,v1=<hex_hmac>。被签名的字符串是 {timestamp}.{subscription_id}.{notification_url}.{raw_body}。请对原始、未解析的请求体进行验证:
id 去重,因为推送保证至少送达一次。完整的可靠性约定,包括重试计划和事件记录,见Webhooks。
停机后补齐订单
如果您的接收端曾不可用(本地软件关闭或网络中断),请按以下步骤对账:- 使用您上一次成功的检查点调用
GET /v1/orders?since=<timestamp>&limit=100(不含该时间点,ISO 8601 UTC)。使用since时,结果按从旧到新排序,has_more表示还有下一页。 - 当
has_more为 true 时,把starting_after设为上一页最后一个订单 ID 并重复请求。直到积压处理完毕,再推进您的检查点。 - 当您需要 Maple 为某个错过 webhook 的有效订单重新发布一条
order.notification时,调用POST /v1/orders/{orderId}/resend。它需要webhooks:write权限范围,会创建一次新的、已签名且带重试的推送,并且不会改变订单状态。终态订单(REJECTED、CUSTOMER_CANCELLED或STORE_CANCELLED)无法重发或恢复,会返回400;请通过GET /v1/orders?since=...和GET /v1/orders/{orderId}对账。 - 如果需要保留原始事件身份,请使用事件记录,而不是
resend。
步骤 4:读取订单
order.notification 负载中的 data 是订单内容,包括 ID、顾客、商品明细和合计,因此您可以直接根据 webhook 开始备餐,无需再次调用。它遵循 GET /v1/orders/{orderId} 的结构,但不含实时的 status 和 payment。您可以随时获取订单资源,以得到权威的当前状态,包括 status 和 payment:
- 金额是以美分为单位的整数(USD)。
450即 $4.50。切勿将其解析为浮点数。totals和商品明细中的所有金额都遵循这一约定。 - 合计已预先计算。
totals.total是权威值,您无需重新计价。 - 商品明细通过
menu_entity_id引用您的菜单,其值是您为该菜品发布的externalId。先发布菜单,这些值就能与您自己的商品目录对应。(菜单负载使用 camelCase;订单和 webhook 负载使用 snake_case,见约定。) - 加料选项(modifier)是直接选择的第一级选项。 更深层嵌套的选项在 v1 中不会展开到订单资源里。
- 顾客数据刻意保持精简。 您会得到顾客的姓名和电话号码(
phone为 E.164 格式,另有phone_last_four用于显示)。外送订单还包含delivery_address,内有街道、单元、城市、州、邮编和配送说明;自取订单或 Maple 没有已存地址时,其值为null。只要该块有内容,六个地址键就都会存在。 - 出单前先检查
scheduled_for。 ASAP 订单该值为null。有值时(ISO 8601,UTC),表示顾客选定了取餐/送达时间;您会立即收到订单,因此应按scheduled_for安排备餐,而不是在收到订单时就开始。
步骤 5:做出决定并回报进度
随着订单推进,通过决定端点作出响应。除特别说明外,都不需要请求体:Response
POST /v1/orders/{orderId}/status 接受明确的状态转换:
ACCEPTED、READY、IN_DELIVERY、FULFILLED、REJECTED、STORE_CANCELLED。各状态的含义及合法的状态转换,请参阅订单生命周期。
决定调用可安全重放。 重复调用会返回
{ "status": "received" },不会产生重复的副作用,因此遇到网络波动时随时可以放心重试。见幂等性与重放安全。可选:预先验证订单
预先验证是可选的,通过订阅order.validation_requested 来开启:
- 如果您不订阅,就没有验证步骤。Maple 直接发送
order.notification,您的 accept/deny 是唯一的关卡。 - 如果您订阅,Maple 会在发送通知之前,请您确认每笔订单是否可履行(菜品供应、价格可行性、能否写入 POS),并等待您的答复。因此选择启用就是一项承诺:您未及时验证的订单会被拒绝(见下文)。
order.validation_requested 回复结果:
valid 结果会让订单继续进入通知阶段;invalid 会在向顾客收款之前拦下订单。您有约 5 分钟的时间答复,请求随后过期(资源中带有 expires_at,约 300 秒后)。如果过期,Maple 会再请求一次验证;若第二次请求仍无答复,订单会被拒绝且不发送通知,因此请在您的处理程序能够可靠地按时答复之后再订阅。这与您在接单时进行的可用性检查相同,只是提前了,这样顾客就不会为您做不出的东西付款。
“完成”是什么样子
一个 webhook 加上少量决定调用。支付和定价由我们负责,Maple 团队在您的整个构建过程中都会提供支持。
下一步
发布菜单
让每个商品明细上的
menu_entity_id 都对应到您自己的商品目录。深入了解 Webhooks
投递保证、重试、事件记录和重放。