用途
本技能用于为某个发货地点批量创建 Shopify 履约记录并写入物流单号,将原本需要逐个处理的发货操作合并为一个工作流完成。它不需要第三方应用,处理的是履约创建这一层;承运商面单的生成需要单独的工具或承运商集成。
前置条件
- 已认证的 Shopify CLI 会话:
shopify store auth --store <domain> --scopes read_orders,write_fulfillments
- API 授权范围:read_orders、write_fulfillments
参数
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| store | string | 是 | — | 店铺域名(如 mystore.myshopify.com) |
| location_id | string | 是 | — | 发货地点的 GID(如 gid://shopify/Location/123) |
| tracking_numbers | array | 否 | [] | 由 {fulfillment_order_id, tracking_number, tracking_url, carrier} 对象组成的列表 |
| notify_customer | bool | 否 | true | 是否向客户发送发货确认邮件 |
| dry_run | bool | 否 | true | 仅预览履约结果,不执行变更 |
| format | string | 否 | human | 输出格式:human 或 json |
安全提示
fulfillmentCreate 不可逆——已履约的订单无法通过 API 取消履约。建议先以 dry_run: true 运行,确认待履约订单列表后再正式提交。每次变更会为每个履约订单创建一条履约记录。
工作流步骤
-
OPERATION: fulfillmentOrders — 查询
- 输入:assignedLocationId: <location_id>、status: OPEN、first: 250、分页游标
- 预期输出:包含 id、order { name }、lineItems 的开放履约订单列表;分页直到 hasNextPage: false
-
OPERATION: fulfillmentCreate — 变更
- 输入:对每个履约订单:fulfillmentOrderId、trackingInfo { company, number, url }、notifyCustomer
- 预期输出:fulfillment { id, status, trackingInfo }、userErrors
GraphQL 操作
# fulfillmentOrders:query — validated against api_version 2025-01
query OpenFulfillmentOrders($locationId: ID!, $after: String) {
fulfillmentOrders(
assignedLocationId: $locationId
first: 250
after: $after
query: "status:open"
) {
edges {
node {
id
status
order {
id
name
}
lineItems(first: 10) {
edges {
node {
id
remainingQuantity
variant {
sku
title
}
}
}
}
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
# fulfillmentCreate:mutation — validated against api_version 2025-01
mutation FulfillmentCreate($fulfillment: FulfillmentInput!) {
fulfillmentCreate(fulfillment: $fulfillment) {
fulfillment {
id
status
trackingInfo {
company
number
url
}
}
userErrors {
field
message
}
}
}
会话跟踪
在每个阶段必须输出相应内容:
开始时输出:
╔══════════════════════════════════════════════╗
║ SKILL: Bulk Fulfillment Creation ║
║ Store: <store domain> ║
║ Started: <YYYY-MM-DD HH:MM UTC> ║
╚══════════════════════════════════════════════╝
每个步骤后输出:
[N/TOTAL] <QUERY|MUTATION> <OperationName>
→ Params: <brief summary of key inputs>
→ Result: <count or outcome>
若 dry_run: true,则在每个变更步骤前加 [DRY RUN] 前缀,且不执行该步骤。
完成时,若 format: human(默认)输出:
══════════════════════════════════════════════
OUTCOME SUMMARY
Open fulfillment orders found: <n>
Fulfillments created: <n>
Customer notifications sent: <n>
Errors: <n>
Output: fulfillment_batch_<date>.csv
══════════════════════════════════════════════
若 format: json,输出:
{
"skill": "bulk-fulfillment-creation",
"store": "<domain>",
"started_at": "<ISO8601>",
"completed_at": "<ISO8601>",
"dry_run": true,
"steps": [
{ "step": 1, "operation": "OpenFulfillmentOrders", "type": "query", "params_summary": "location <id>, status open", "result_summary": "<n> orders", "skipped": false },
{ "step": 2, "operation": "FulfillmentCreate", "type": "mutation", "params_summary": "<n> fulfillments", "result_summary": "<n> created", "skipped": false }
],
"outcome": {
"orders_found": 0,
"fulfillments_created": 0,
"notifications_sent": 0,
"errors": 0,
"output_file": "fulfillment_batch_<date>.csv"
}
}
输出格式
CSV 文件 fulfillment_batch_<YYYY-MM-DD>.csv,包含列:order_name, fulfillment_order_id, fulfillment_id, tracking_number, carrier, notify_customer, status
错误处理
| 错误 | 原因 | 恢复方式 |
|---|---|---|
| THROTTLED | 超过 API 速率限制 | 等待 2 秒,最多重试 3 次 |
| fulfillmentCreate 的 userErrors | 已履约或物流单号无效 | 记录错误,跳过该订单,继续处理 |
| FULFILLMENT_ORDER_LINE_ITEM_QUANTITY_MISMATCH | 部分履约数量不匹配 | 记录警告,尝试部分履约 |
| 该地点无开放订单 | 地点没有待处理工作 | 以摘要退出:找到 0 个订单 |
最佳实践
- 始终先以 dry_run: true 运行——履约无法通过 Admin API 撤销。
- 在批量测试时,或面向不希望收到单独发货邮件的 B2B 订单时,将 notify_customer 设为 false。
- 运行前在 tracking_numbers 参数中提供物流单号;没有物流单号的未履约订单仍会创建履约记录——请确认这是预期行为。
- 对于大批量订单(100+),变更循环会触发速率限制,技能会以 2 秒退避自动重试。