目录
Shopify 自带的订单邮件,什么时候到取决于你的邮件客户端什么时候同步,落在一个被你设了过滤规则的文件夹里,而且不管这单是 12 欧还是 1200 欧,长得一模一样。如果店是你自己在打理,这种信号的形状是不对的。
Webhook 能解决这件事。Shopify 会把每一笔订单 POST 到你指定的 URL,Echobell 再把这个 POST 变成一条由你决定响多大声的通知。
挑出值得打断你的那几个 topic
Shopify 把 webhook 的事件类型叫做 topic。对多数一人经营的店铺,下面这四个就够了:
| Topic | 含义 | 紧急级别 |
|---|---|---|
orders/create | 有人下单了。 | 普通 |
orders/paid | 付款已完成。只关心真正到账的钱就用这个。 | 普通 |
orders/cancelled | 顾客取消了订单。在你打包之前知道是有价值的。 | 时效性 |
refunds/create | 发生了退款。 | 时效性 |
orders/create 和 orders/paid 订阅其中一个就好,除非你真的希望一笔成交收到两条通知。对多数店铺来说,orders/paid 才是诚实的那个。
第一步 —— 建频道
在 Echobell 里建一个频道,名字可以叫「Shopify 订单」,复制它的 webhook URL,并打开 仅 POST。Shopify 一定是用 POST 发送的。
如果你想给取消和退款单独开一个更响的频道,现在一并建好,设成时效性通知。
第二步 —— 在 Shopify 里添加 webhook
在 Shopify 后台进入 设置 → 通知 → Webhook → 创建 Webhook,选择 topic,格式选 JSON,粘贴你的频道 URL。
保存时 Shopify 会发一条测试 payload。手机震了,说明链路通了。
第三步 —— 只把你真会读的字段做成模板
Shopify 的订单 payload 很长,一笔订单一百多个字段。你只需要其中几个:
标题
新订单 #{{order_number}} · {{total_price}} {{currency}}
正文
{{customer.first_name}} {{customer.last_name}}
{{line_items[0].title}}
line_items 是数组,所以 line_items[0] 是第一件商品。Echobell 模板支持按下标取值,但没有循环——一笔三件商品的订单只会显示第一件。如果这点要紧,就把件数放在旁边:
{{line_items[0].title}}(共 {{line_items.length}} 件)
和 Stripe 不同,Shopify 的 total_price 是小数字符串——是 "49.00" 而不是 4900——所以不用做任何换算就能正确显示。
第四步 —— 用条件按 topic 分流
如果你把多个 topic 指向同一个频道,Shopify 会在请求头里告诉你这是哪一个:
header["x-shopify-topic"] == "orders/paid"
这是不必在后台为每个频道各建一个 webhook、也能区分行为的最干净做法。
只有大单才叫醒我
多数店主真正想要的模式是:所有订单进一个安静的频道,只有超过某个金额的才进那个响的。
再建一个频道,设为时效性,另外指一个 orders/paid 的 webhook 过去,然后给它加条件:
total_price > 500
于是平常的日子只是背景里的嗡嗡声,而一笔 900 欧的订单是你能感觉到的东西。
这套方案没解决的问题
不做 HMAC 校验。 Shopify 会给每个 webhook 带上 X-Shopify-Hmac-Sha256 头,Echobell 不校验它,所以拦住陌生人的只有你的频道 URL。请保密,保持仅 POST 开启;如果一条伪造的订单通知会造成真实损失,就在前面放一个自己的接口去校验 HMAC,再由它调 Echobell。
Shopify 可能把同一个 webhook 投递两次。 失败会重试,而重试不做去重。请把通知当成「去看一眼这笔订单」的提示,而不是订单计数。以 Shopify 后台为准。
库存类 topic 很快就会变吵。 inventory_levels/update 在每一次库存变动时都会触发,包括你自己的手动修改。要做低库存提醒,就用条件严格过滤,否则中午之前你就会后悔。
常见问题
需要装一个 Shopify 应用吗?
不需要。设置 → 通知 下的 Webhook 是后台自带的,不需要应用、合作伙伴账号,也不需要写代码。
能让仓库看到订单但看不到我的 Shopify 后台吗?
可以。把频道分享给他们,他们只会收到通知,别的什么都没有——没有后台权限,也不会看到模板之外的客户信息。
通知里该不该放客户姓名?
这由你决定,但值得想清楚再定。模板里的任何内容都会出现在锁屏上。通常订单号和金额就足够让你决定要不要处理了。
拒付争议能收到电话吗?
使用 Shopify Payments 的店铺,争议会通过 disputes/create 这个 topic 发出。把它指向一个来电频道——它是订单类事件里唯一自带期限的那个。
小结
一个 webhook、一份模板,想要更响的版本再加一个条件。大概五分钟,从此不用再反复刷新订单页。
下载 iPhone 版 Echobell 或在 Google Play 获取,然后下一笔测试订单,看它比确认邮件先到。