关于 same-day-delivery
面向电商商家的当日本地配送规划技能,涵盖结账时段、配送区域、派单方式及常见平台和自定义商店的运营问题。
主要功能
- 01规划配送区域与时段
- 02选择自有司机或配送平台
- 03将订单接入派单平台
- 04设置时段容量与截止时间
- 05处理配送异常
适用场景
- 01上线本地当日配送
- 02提供结账预约时段
- 03为配送订单配置派单
- 04避免时段超额预约
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ finsilabs/ awesome-ecommerce-skills --skill same-day-delivery安装后在 Claude Code 中输入/same-day-delivery确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
tile.jsonevals/atomic-slot-booking-with-concurrency-con/criteria.jsontask.mdevals/driver-dispatch-eta-updates-and-failure-/criteria.jsontask.mdevals/postgis-zone-schema-and-point-in-polygon/criteria.jsontask.md详细介绍
当日送达
概述
本地当日送达需要三项服务协同工作:让客户在结账时选择配送时段、将订单派送给司机,以及向客户反馈配送状态。对于大多数商家来说,第三方末端配送服务(DoorDash Drive、Uber Direct、Onfleet)是实现当日送达最快捷的途径——它们负责司机调度,让你专注于运营。
何时使用此技能
- 在指定地理区域推出当日或下一小时送达服务时
- 允许客户在结账时选择首选配送时段时
- 构建显示待处理订单并优化路线的司机调度控制面板时
- 接入第三方末端配送公司(DoorDash Drive、Uber Direct、Onfleet)时
- 管理各时段的运力上限,避免配送资源超额承诺时
核心说明
步骤 1:确定平台和配送模式
| 平台 | 推荐工具 | 原因 |
|---|---|---|
| Shopify | Local Delivery by Zapiet + DoorDash Drive 或 Uber Direct | Zapiet 负责在结账时预订时段;DoorDash Drive / Uber Direct 自动调度司机 |
| WooCommerce | WooCommerce Local Pickup Plus + Onfleet 或自有司机 | Local Pickup Plus 负责管理区域和时段;Onfleet 提供司机调度和跟踪功能 |
| BigCommerce | Zapiet Delivery + Onfleet 或 Dispatch Science | Zapiet 等应用可添加配送安排功能;Dispatch Science 可优化路线 |
| 自定义 / 无头架构 | 构建时段预订功能 + 接入 Onfleet/DoorDash Drive API 进行调度 | 可全面控制区域管理、时段运力和司机路线规划 |
请先选择配送模式:
- **自有司机:**你可以控制服务质量和成本,但必须管理司机排班、车辆和路线规划。适用于:花店、杂货店,以及拥有稳定本地客户群的餐厅。
- **按需配送员(DoorDash Drive、Uber Direct):**可按需呼叫司机,无固定成本。适用于:偶尔需要当日送达、但不想组建司机车队的商家。
- **混合模式:**由自有司机负责预定时段;紧急订单交由按需配送员处理。
步骤 2:设置配送区域和时段预订
Shopify
使用 Zapiet — Pickup + Delivery(功能最全面的应用):
- 从 Shopify App Store 安装 Zapiet — Pickup + Delivery
- 在 Zapiet 中,前往 Delivery → Zones,通过以下方式定义配送覆盖区域:
- 邮政编码/ZIP 代码(最简单):列出所有可配送的 ZIP 代码
- 从商店地址起算的半径
- 自定义绘制多边形(需要更高级别的 Zapiet 套餐)
- 在 Delivery → Time Slots 中设置配送时段:
- 定义每日时间段(例如,上午 10 点至中午 12 点、中午 12 点至下午 2 点、下午 2 点至 4 点、下午 4 点至 6 点)
- 设置每个时段的容量(例如,每个 2 小时时段最多 20 个订单)
- 设置各时段的订单截止时间(例如,下午 2 点至 4 点时段的订单必须在中午 12 点前下单)
- 在 Delivery → Rates 中按区域设置配送费(可按距离计算,也可设为固定费用)
- 客户输入地址后,就能在 Shopify 结账时看到可选配送时段
在 Zapiet 中管理订单:
- 前往 Zapiet → Orders,查看所有按配送时段排序的配送订单
- 在此视图中导出司机的拣货清单和配送清单
- 将订单标记为“配送中”和“已送达”,以便向客户更新状态
WooCommerce
使用 WooCommerce Local Pickup Plus(WooCommerce.com 官方扩展):
- 从 WooCommerce.com 安装 Local Pickup Plus
- 前往 WooCommerce → Settings → Shipping → Local Pickup Plus
- 添加取货/配送地点 — 对于配送,请按邮政编码或半径定义服务区域
- 启用“配送日期和时间选择”,让顾客选择时段
- 在插件设置中配置时段和容量
**如需更高级的区域管理:**使用 Flexible Shipping 插件或 WooCommerce Table Rate Shipping,根据邮政编码匹配创建配送费率。
**如需调度司机:**使用 Onfleet(onfleet.com),它提供 WooCommerce webhook 集成 — 新配送订单会自动显示在 Onfleet 中,供分配司机。
BigCommerce
在 BigCommerce 上使用 Zapiet:
- 从 BigCommerce App Marketplace 安装 Zapiet
- 配置方式与上方的 Shopify 工作流相同 — 定义区域、时段和容量
使用 ShipperHQ:
- ShipperHQ 内置本地配送区域和时间段限制
- 前往 ShipperHQ → Carrier Manager → Add Local Delivery carrier 并定义区域规则
第 3 步:连接到司机调度平台
使用 DoorDash Drive(按需服务,无固定司机成本)
DoorDash Drive 会派遣 DoorDash 零工经济司机取货并配送订单。该服务覆盖美国大多数主要城市。
- 前往 developer.doordash.com/portal 注册并获取 DoorDash Drive API 密钥
- 对于 Shopify:从 Shopify App Store 安装 DoorDash Drive — 当你将订单标记为待调度时,它会自动创建 DoorDash 配送任务
- DoorDash 会通过 SMS 向顾客发送实时追踪链接
- 按次配送付费(通常为 $7–$15,具体取决于距离)
使用 Uber Direct(按需服务)
与 DoorDash Drive 类似 — Uber Direct 使用 Uber 司机进行本地配送。
- 前往 developer.uber.com/products/uber-direct 注册
- 如果你的平台有 Uber Direct 应用,请安装该应用;也可以使用 REST API
- 向 Uber Direct API 发送取货地址(你的门店)和送达地址(顾客地址),创建配送任务
使用 Onfleet(自有司机 + 路线优化)
如果你有自己的配送团队,并且需要路线优化和实时追踪,这是最佳选择。
- 前往 onfleet.com 注册(每月 $349 起,最多支持 3 名司机)
- 安装 WooCommerce webhook 集成,或使用 Zapier 将你的平台连接到 Onfleet
- 新订单会自动创建为 Onfleet 任务
- 调度员在 Onfleet Web 仪表板中将任务分配给司机
- 司机可使用移动应用进行逐向导航并拍摄送达凭证照片
- 司机开始行程时,顾客会收到包含实时追踪链接的 SMS
第 4 步:处理边缘情况
顾客查看时段后,该时段已满:
- 大多数应用(Zapiet、Onfleet scheduling)会在结账时实时检查时段是否可用
- 在应用设置中启用时段容量限制,防止超额预订
地址位于配送区域之外:
- Zapiet 会在显示时段前检查配送区域 — 如果地址位于区域之外,则隐藏配送选项,仅显示取货/标准配送
- 上线前,请使用靠近区域边界的地址进行充分测试
司机无法完成订单:
- 对于 DoorDash Drive / Uber Direct:平台会自动改派给另一名司机
- 对于自有司机(Onfleet):调度员必须在仪表板中手动改派;请为即将到达时段时间但尚未分配的任务设置 Onfleet 提醒
截止时间管理:
- 将订单截止时间设为配送时段开始前 2–3 小时,以留出拣货、打包和装车的时间
- Zapiet 会自动隐藏已过截止时间的时段
第 5 步:自定义/无头实现
对于需要完全控制区域管理和时段预订的无头商店:
// Check if a customer address is in a delivery zone
async function checkDeliveryEligibility(params: {
customerZip: string;
deliveryZones: { name: string; zipCodes: string[]; deliveryFeeCents: number }[];
}): Promise<{ eligible: boolean; zone?: string; feeCents?: number }> {
const zone = params.deliveryZones.find(z => z.zipCodes.includes(params.customerZip));
if (!zone) return { eligible: false };
return { eligible: true, zone: zone.name, feeCents: zone.deliveryFeeCents };
}
// Get available time slots for today (slots with remaining capacity)
async function getAvailableSlots(params: {
date: Date;
zone: string;
slots: { id: string; label: string; capacity: number; booked: number; cutoffTime: Date }[];
}): Promise<{ id: string; label: string; spotsRemaining: number }[]> {
const now = new Date();
return params.slots
.filter(slot => slot.cutoffTime > now && slot.booked < slot.capacity)
.map(slot => ({
id: slot.id,
label: slot.label,
spotsRemaining: slot.capacity - slot.booked,
}));
}
// Dispatch a delivery via DoorDash Drive API
async function dispatchDoorDashDelivery(params: {
externalDeliveryId: string;
pickupAddress: Address;
dropoffAddress: Address;
customerPhone: string;
pickupWindow: { startTime: string; endTime: string }; // ISO 8601
}): Promise<{ trackingUrl: string; fee: number }> {
const response = await fetch('https://openapi.doordash.com/drive/v2/deliveries', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.DOORDASH_DRIVE_JWT}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
external_delivery_id: params.externalDeliveryId,
pickup_address: `${params.pickupAddress.street1}, ${params.pickupAddress.city}, ${params.pickupAddress.state} ${params.pickupAddress.zip}`,
dropoff_address: `${params.dropoffAddress.street1}, ${params.dropoffAddress.city}, ${params.dropoffAddress.state} ${params.dropoffAddress.zip}`,
dropoff_phone_number: params.customerPhone,
pickup_time: params.pickupWindow.startTime,
}),
});
const data = await response.json();
return { trackingUrl: data.tracking_url, fee: data.fee };
}
最佳实践
- 从邮政编码区域开始,而不是半径或多边形 — 基于邮政编码的配送区域更易管理,也更容易向客户说明(“我们配送到这些邮政编码区域”),而且不需要进行地理编码
- 为时段截止时间留出充足余量 — 订单截止后,至少留出 2 小时再开始配送时段,让仓库完成拣货、打包并将订单交给司机
- 在每个时段开始前生成配送清单 — 在司机出发前 30 分钟打印清单;清单应列出每笔订单的地址、时段和特殊说明
- 在司机接近时发送预计送达时间推送通知 — 能实时查看预计送达时间的客户,提交“我的配送到哪了”之类支持请求的次数会少得多;Onfleet 和 DoorDash Drive 都能自动处理这一流程
- 监控时段的容量填充率 — 如果时段总是在开始前几小时就满额,请增加容量;如果截止时填充率低于 50%,请合并或减少时段
常见问题
| 问题 | 解决方案 |
|---|---|
| 两位客户同时预订某个时段的最后一个名额 | 使用带容量检查的原子递减 — Zapiet 会处理此问题;如果自行构建,请使用数据库级锁或原子更新 |
| 客户输入的地址位于配送区域之外,却仍能看到时段 | 在结账时于服务端验证区域资格,而不只是客户端;Zapiet 会自动执行此验证 |
| 向客户显示的截止时间使用了错误的时区 | 始终以 UTC 存储并比较时间;使用浏览器的 Intl API 按客户的本地时区显示时间 |
| 分配给司机的订单数量超出其在该时段内的配送能力 | 限制每位司机每个时段的订单数量,并在 Onfleet 中启用路线优化;安排时段时设置合理的容量上限 |
相关技能
- @order-fulfillment-workflow
- @shipment-tracking
- @order-management-system
- @international-shipping
- @dropshipping-integration