关于 salla-shipping-app
这是一套创建和配置 Salla 物流应用的引导流程,涵盖 Shipping Management/AWB 与 Order Fulfilment 两种模式。它通过 Salla Partners 工具依次处理应用设置、OAuth 与 Webhook、物流区域及函数测试。
主要功能
- 01选择 AWB 或履约模式
- 02创建并发布公开物流应用
- 03配置 OAuth 权限范围和 Webhook
- 04设置物流区域与选项
- 05实现并预览物流函数
适用场景
- 01使用 Salla AWB 构建承运商集成
- 02设置跨承运商订单履约
- 03配置商户配送范围和费率
- 04发布前测试物流函数
MCP 相关
需要连接 Salla Partners MCP 服务,并编排其工具来创建应用、配置 OAuth 和 Webhook、设置物流、订阅事件及管理 App Functions。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ sallaapp/ salla-partners-agent-kit --skill salla-shipping-app安装后在 Claude Code 中输入/salla-shipping-app确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/api-endpoints.mdfulfillment-cycle.mdshipment-cycle.md详细介绍
Salla 配送应用流程
通过 使用 Salla Partners MCP 工具执行操作来构建配送应用。 请按顺序完成步骤 — 完成每个关卡后再继续。
配送应用必须为公开应用 — 此类别不支持私有应用 (https://docs.salla.dev/422995m0.md)。
两种应用模式 — 请先选择
Salla 有两种不同的配送应用模式(https://docs.salla.dev/422988m0.md)。它们 共用创建和 OAuth 流程,但在设置、生命周期和测试方面有所不同:
| 模式 | 说明 | 生命周期由何处管理 |
|---|---|---|
| 配送管理(承运商 / AWB) | 集成一家配送公司。现代化的 Salla AWB 模式 — 在 Salla Partners 内编写应用函数(无需构建或托管后端),调用承运商 API 生成 AWB 并将其返回给 Salla。 | references/shipment-cycle.md |
| 订单履约 | 跨多个承运商运行 — 接收订单、自动分配最合适的承运商 / 网点,然后驱动所分配的配送应用。 | references/fulfillment-cycle.md |
Salla AWB 是首选的配送管理模式 — 你的配送服务会原生显示在商家的 AWB 创建界面(订单 → 创建配送标签)中, 无需维护服务器、部署或轮询。逻辑在 Salla 的应用函数运行时中执行,可直接访问 Salla Shipping API (https://docs.salla.dev/1792089m0.md)。
**显示在 AWB 承运商选项中 / Shipping Company ID:若要让配送管理(AWB)应用 显示在商家的 AWB 承运商选项中,请发送邮件至 [email protected] (https://docs.salla.dev/1792111m0.md)。**Shipping Company ID 仅由 Salla 分配 — 你无法自行设置。
工具
| 工具 | 操作 | 功能 |
|---|---|---|
salla_reference | categories | type=shipping → 从 sub_categories 中选择 sub_category_id;发布所用的 main_category_id/categories 来自同一次调用的 main_categories/categories(App Theme,不限于 shipping) |
salla_upload | — | 上传徽标 → 文件 id |
salla_apps | create / get / connect / set_status | 创建并配置 OAuth/webhooks;get 可读取应用状态,包括当前的 search_options 选择;shipping 应用是公开的,因此请使用 app_publish 发布 |
app_publish | open / set / validate | 公开应用:验证发布信息(保存为 DRAFT;合作伙伴在 Portal 中提交) |
salla_events | list / subscribe | 订阅异步发货事件 |
salla_functions | list_triggers / save / preview | 实现并测试同步发货 App Functions |
salla_shipping | get_zones / set_zones / set_policy_options / list_zone_countries / list_zone_cities / list_search_options | 配置配送费区域以及 policy-options / shipment-features 搜索选项——这是当前实时 Shipping Settings 页面管理的两项内容 |
**前提条件:**必须已连接 Salla Partners MCP 服务。请在每个步骤中传递
app_id。如果工具返回 "Salla session expired",请重新运行登录流程。
步骤 0 — 了解需求
开始前请询问:
- 要集成哪种模式?(这决定由哪个参考文档负责整个生命周期——见上表)
- Shipping Management / AWB — 集成一家承运商;你需要编写生成 AWB 的
shipment.creating/shipment.cancellingApp Functions - Order Fulfilment — 在多个 shipping 应用中自动分配最合适的承运商/网点
- Shipping Management / AWB — 集成一家承运商;你需要编写生成 AWB 的
- 要集成哪家承运商或服务提供商?
- 是否支持货到付款(COD)?
- 承运商覆盖哪些地区/配送区域?
第 1 步 — 创建应用
- 查询类别:
salla_reference action=categories type=shipping→sub_categories。sub_category_id必须从sub_categories中选择一个配送子类别,否则会被拒绝。(目前,Fulfillment / Other / Drop-shipping 对应的 ID 为45 / 46 / 54;这些 ID 仅作示例 — 请始终读取实时值,不要硬编码。)不要将同一次调用返回的main_categories/categories用作发布时的main_category_id/categories— 那是与类型无关的独立「应用主题」/「应用影响」列表,并非配送专用列表 → step-basic-information.md。 - 上传徽标:
salla_upload(正方形 1:1,≥ 250×250 像素)→ 文件id。 - 创建应用:调用
salla_apps action=create,设置type= shipping、sub_category_id、name、short_description(50–200)、app_url、email、logo。将应用设为公开(此类别仅支持此模式)。
结果会返回 app_id。(如需在 AWB 快递选项中显示,请发送邮件至 [email protected] — 参见上文的模型部分。)
手动备用方案: Portal → My Apps → Create App(Public,类别为 Shipping App)。 完整操作指南:https://docs.salla.dev/422995m0.md
关卡:「应用已创建 — 请确认 app_id(salla_apps action=get)。」
第 2 步 — OAuth、权限范围与 Webhook 连接
通过一次 salla_apps action=connect 调用配置 OAuth + Webhook(从 salla_apps action=get 读取有效的权限范围 slug — 没有权限范围目录参考端点):
scopes— 配送 + 订单访问权限(slug → "read" | "read_write")。仅申请应用所需的最低限度权限范围;除非确实需要写入权限,否则选择read而非read_write,不要申请不会使用的宽泛权限。redirect_urls、webhook_url、webhook_security_strategy: "signature"
签名 Webhook 的密钥不会由 connect 生成 — 请在 Partner Portal
(https://portal.salla.partners/apps/{app_id})中创建或轮换密钥,并在部署前通过 salla_apps action=get(webhook_secret 字段)读取当前值;妥善保存该密钥以供 HMAC 验证使用。
OAuth、令牌存储/刷新以及针对每个商家的刷新锁 → salla-app-auth。
Webhook 签名验证(根据原始请求体验证 X-Salla-Signature,拒绝无效签名,绝不记录密钥)和幂等性 → salla-webhooks。将这些事项交由对应模块处理 — 不要在此处重新实现。
关卡:「连接已应用,且没有 _partial。Webhook URL 是否已上线并返回 200?」
第 3 步 — 配置配送区域与设置
**配送应用没有商家设置表单。**不要调用
salla_settings define_form— 该表单适用于公开/私有/通信应用,而 Portal 会拒绝配送应用的POST /settings。配送配置是下方的salla_shipping区域和搜索选项;承运商凭据通过 Shipping Settings URL 设置。设置表单这一概念本身 → salla-app-settings。
此步骤仅涵盖当前实时 Shipping Settings 页面管理的内容 — 不多不少。 后端功能标志下还有一种更新、更丰富的配送设置模型(包含按国家划分的公司类型、启用的服务类型和结构化时长),但该功能尚未发布,也没有面向商家的页面 — 不要基于它进行开发,也不要因为
salla_shipping没有相关操作而感到意外。如果该功能标志将来发布,此步骤会增加一个子步骤;在此之前,区域 + 搜索选项就是全部可用内容。
salla_shipping 管理两项彼此独立的内容,分别通过不同的调用保存 — 区域,以及由两个选项组组成的组合。请将它们作为两个独立的子流程处理。
3a — 费率区域(必需)
某个区域是适用于一个国家及一组城市的费率规则。没有按区域创建/更新/删除的接口——set_zones 每次调用都会替换_整个_区域列表。要添加区域,请重新发送所有现有区域及新增区域。要编辑区域,请重新发送所有区域,并修改目标区域。要删除区域,请重新发送除目标区域外的所有区域。
-
获取当前状态:
salla_shipping action=get_zones、app_id。**注意:**新建的配送应用已预置默认区域(所有国家 → 所有城市,固定费用)——响应非空不代表你已经配置过该区域。 -
**写入区域前,先查找真实的国家/城市 ID。**这些不是
salla_referenceID——区域使用独立的 ID 空间:salla_shipping action=list_zone_countries、app_id→ 真实的国家 ID。salla_shipping action=list_zone_cities、app_id、country_id(可选的keyword用于搜索)→ 该国家的真实城市 ID。- 两个列表都不会返回
id: -1“所有国家”/“所有城市”哨兵值——已通过实时验证:API 只会返回真实 ID。-1是实时配送设置页面为展示而在客户端添加的约定值;如果商家指的是“所有地区”,请直接在区域的country/city中使用该值,不要在列表响应中搜索它。 - 在此处使用
salla_reference/通用国家 ID 不会报错——Portal 会静默接受写入但不执行任何操作,看起来就像出了 Bug。务必从list_zone_countries/list_zone_cities获取country/city(或使用-1哨兵值),切勿猜测。
-
**就每个区域的所有字段询问商家/合作伙伴——不要擅自做业务决策。**费率、覆盖范围、配送时长和是否支持货到付款(COD)都是只有他们才知道的信息;无法从应用或其类别推断。
- 如果
get_zones(第 1 步)只显示预置的默认区域,这就是首次设置——请进行下方的完整询问。如果已有真实区域,请总结这些区域,并具体询问有哪些变更(添加国家、修改费率、删除区域),而不是从头重新询问所有内容。 - 首次询问时,每次只询问一个国家:先询问要添加哪个国家/地区,再解析其 ID(第 2 步),然后询问该区域的费率类型(固定或按重量浮动)、金额、配送时长文本,以及是否支持货到付款(如果支持,询问其费用)。向商家确认该区域后,再询问“还要添加其他国家吗?”,并重复此过程,直到他们表示完成——不要因为对方只回答了一个国家,就认定询问已经结束。
- 在商家表示已完成添加国家之后(而不是在添加第一个国家后——只有完整了解其实际覆盖范围,才能做出下面的决定),明确询问是否保留或移除预置的“所有国家/所有城市”兜底区域——不要默默替他们做决定。保留它意味着未列出的国家仍会使用默认费率(很可能不合适);移除它意味着未列出的国家将没有费率。
- 切勿替商家填写看似合理的费率、时长或货到付款默认值。如果他们还没告诉你,就询问;不要提交猜测。
- 如果
-
提交:
salla_shipping action=set_zones、app_id、shipping(区域对象数组)。每个区域:字段 是否必填 说明 id新建区域时省略或设为 0要原地更新的现有区域 ID。 country✅ 始终必填 来自 list_zone_countries(或设为-1表示全部)。city(数组)✅ 始终必填 来自 list_zone_cities(或设为[-1]表示全部)。cities_excluded(数组)可选 在已包含的国家/城市选择范围内排除的城市。仅当 country/city 不是“全部”哨兵值时才有意义。 fees.type✅ 始终必填 "fixed"|"rate"|"automatic"。fees.amount✅ 当 type: "fixed"时必填固定费用。必须为 1–9999 — set_zones会在请求到达 Portal 之前进行校验(见下文)。fees.amount_per_unit、fees.up_to_weight、fees.per_unit✅ 当 type: "rate"时必填可变费率定价:超过阈值后按单位重量计费。三项必须同时提供; amount_per_unit/per_unit> 0,up_to_weight为 1–9999,且所有值上限均为 9999。duration✅ 始终必填 自由文本,例如 "2-3 business days"— 不是结构化值。cash_on_delivery.status✅ 始终必填(布尔值) — cash_on_delivery.fees✅ 当 cash_on_delivery.status: true时必填必须 > 0,上限为 9999。 此调用会替换完整的区域列表 — 请包含要保留的所有区域。
业务规则,严格执行 — 区域的
country/city一经创建便会锁定。 创建现有区域后,无法更改其国家或城市,只能修改费率/时长/COD。set_zones会拒绝任何id与现有区域匹配、但country/city不同的已提交区域 — 请创建新区域,而不是尝试“移动”现有区域。 Portal 不会拒绝无效的费用数据,而是会静默地将其破坏。 实测已确认:缺少amount_per_unit/up_to_weight/per_unit的"rate"类型区域仍会被创建,且这三个字段都会默认为0(结果是一个永久免运费区域,而不是报错);负数fees.amount会被静默截断为0;超出范围的费用(例如999999)会导致 Portal 静默丢弃整个提交批次,而不只是有问题的区域,同时仍报告成功。现在,set_zones会在发起任何网络调用前,根据上表中的范围验证每个费用字段,并且在每次写入后重新读取区域列表,确认其确实反映了提交内容——如果某次“成功”的写入未能完整持久化,调用就会失败并给出明确提示,而不会再静默地谎报成功。如果你看到set_zones因“post-write zone count doesn't match”消息而失败,切勿盲目重新提交同一批次——请逐个检查其中的区域。
检查关卡:“salla_shipping action=get_zones 反映了你的区域(国家/城市/费率/货到付款均正确),现有 id 的任何区域都没有更改其 country/city,并且 set_zones 返回成功——而不是 post-write mismatch 错误。”
3b — 政策选项与货运功能(必需)
这是两个语义不同的选项组,共用一个目录和一次保存调用——不要为它们构建独立流程:
- 政策选项——运单/货运详情字段(包装类型、产品类型、尺寸等),用于“帮助识别货运详情,让配送体验更轻松”。这些描述的是_货运本身_。
- 货运功能——应用商店的发现/筛选元数据(“帮助用户按类型和覆盖范围搜索货运应用”)。这些信息帮助商家在应用市场中_找到_你的应用——它们不是货运数据。
-
获取目录:
salla_shipping action=list_search_options、app_id→ 每个可用选项,格式为{id, slug, type, is_filter, is_shipping_policy, categories, name: {ar, en}, values: [{id, slug, name: {ar, en}}]}, 响应 meta 中还包含一个shipping_categoryid。自行拆分:- 政策选项 =
is_shipping_policy === true的选项。 - 货运功能 = 满足
is_filter === true、is_shipping_policy === false且categories包含响应中shipping_categoryid 的选项。 (这与实时「货运设置」页面筛选同一目录的方式完全一致——不要另行推导不同的筛选条件。)已知缺口: 实测发现,在某些环境中,meta可能为空(没有shipping_categoryid)。如果发生这种情况,不要猜测类别 id——检查每个选项的categories数组是否都包含同一个 id(实际情况确实如此;该共享 id 就是货运类别),并将结果有歧义视为需要上报的阻塞问题,而不是悄悄变通。你会看到不符合任一规则的目录条目(实测确认:类似included_destination_cities、destination_countries的地理覆盖范围型 slug,以及其他类似条目——is_filter: false且is_shipping_policy: false)。这些属于较新的、尚未发布的货运设置流程(由shipping_settings_page后端功能标志控制,不在本技能范围内——参见本步骤顶部的说明)。实时「货运设置」页面也采用同样的拆分规则忽略这些条目——不要向商家询问它们;这是有意为之,并非拆分逻辑有缺陷。
已确认的实时目录(仅供参考——始终读取实际响应;Salla 可能会添加/移除选项;不要将这些 slug 硬编码为完整清单):
分组 slug阿拉伯语标签 含义 政策选项 shipment_content_type运输类型 货件内的产品/内容类型(例如,电子产品)。 政策选项 packaging_type包装类型 货件的包装方式。 政策选项 support_dimensions货件尺寸 商家是否必须提供包裹尺寸。 政策选项 support_number_of_box箱子数量 商家是否必须提供箱子数量。 货件功能 delivery_service_type取件和配送方式 承运商提供的取件/配送方式。 货件功能 shipping_cover_type配送覆盖范围 地理覆盖范围(例如,国内/国际)。 货件功能 company_type公司类型 承运商公司的类型/分类。 货件功能 services服务 承运商提供的服务。 货件功能 support_change_name公司显示名称 不是发现元数据——这是一个实际面向商家的开关:商家能否在店面结账时覆盖所显示的承运商名称。即使它位于「货件功能」组中,也应像对待任何其他运营设置一样谨慎对待。 - 政策选项 =
-
构建选择前,先了解每个选项的
type:"multi_select"/"select"— 按id从该选项的values[]中选择一个或多个条目。"boolean"— 不是直接填写 true/false:请选择slug为"true"或"false"的单个值对象(每个布尔选项的values[]中都实际包含这两个值)。两者都不选表示“未回答”。is_required仅适用于政策选项——在线的配送设置页面只会为政策选项显示每个选项对应的“必填”复选框;配送功能在 UI 中没有此控件。API 理论上允许为任何选项设置is_required,但为配送功能设置此项,在商家实际使用中没有对应效果——除非有特殊原因,否则不要为其设置此项。
-
使用真实目录采访商家/合作伙伴——不要猜测哪些值适用于他们的承运商。 每个选项的正确值都是只有他们才知道的业务事实(他们的包装、配送范围、公司类型);目录只会告诉你_可以_回答什么,而不是答案本身。
- 先检查
salla_apps action=get的search_options字段。字段为空或不存在表示是首次设置——请进行下方的完整采访。如果已有选择,请先概述这些选择,并具体询问哪些内容有变化,而不是重新询问所有内容。 - 首次采访,按分组批量提问:在一条消息中列出全部 4 个政策选项,使用每个选项真实的
name.ar/name.en标签,以及第 1 步中该选项真实的values[]选项(绝不可编造选项)——询问每个选项的取值,并明确询问该选项是否应设为必填。然后在第二条消息中列出全部 5 个配送功能,采用相同的真实标签/真实取值方式,不询问是否必填(参见上述差异)。如果在线目录中某个分组没有任何选项,则完全跳过该分组的消息。 - 对
support_change_name(配送功能),应以通俗语言提问,而不是使用术语——它的实际含义是“商家能否在店铺结账页面更改承运商的显示名称?”;请这样提问,不要直接念出 slug。
- 先检查
-
一次调用提交两个分组: 调用
salla_shipping action=set_policy_options,传入app_id和search_options(由{id, is_required?, values}组成的数组——id是搜索选项 ID,values是第 3 步收集的所选values[].id,is_required是可选的逐选项开关)。在同一个数组中混合政策选项和配送功能条目——这种分组仅用于说明,并非结构上的区分。此调用会替换当前选择——请包含你要保留的所有选项(来自两个分组)。 -
验证实际保存的内容。
salla_shipping没有读取应用_当前_选择项的操作——action=list_search_options始终只返回静态目录(所有可能的选项/取值),不受已保存内容影响。要确认实际选中了哪些选项,请调用salla_apps action=get并读取其search_options字段(当前应用的一组{id, values})——这是当前选择项的唯一真实来源。不要在不同轮次中自行跟踪;请重新读取。
检查点:“salla_shipping action=set_policy_options 调用成功,并且 salla_apps action=get 的 search_options 字段显示了所有你打算保留的选项——没有任何选项因遗漏而丢失。”
红旗——区域与政策选项
| 看似诱人的想法 | 错在哪里 |
|---|---|
| “我会用一个看起来合理的费率/时长,这样就不用问了。” | 商家的费率由商家自行决定,无法推断出来——看似合理但实际错误的数字,会导致真实客户遇到实际定价错误(3a)。 |
| “他们提到了一个国家——这大概就是他们覆盖的全部范围。” | 商家通常不会主动列出完整名单——结束区域访谈前,务必明确询问是否还有其他国家/地区(3a)。 |
| “我会跳过‘必填’问题,设为可选。” | 必填还是可选,会实实在在影响商家的结账流程,而不是走个形式——务必针对每个政策选项明确询问(3b)。 |
| “slug 名称一看就懂——没必要向商家解释。” | support_change_name 等名称,光看 slug 并不能看出其实际含义(例如,它指的是覆盖结账时显示的名称)——要用通俗语言提问,不要使用行话(3b)。 |
你仍需在 Portal 中设置 Shipping Settings URL——这是 Salla 在商家后台加载的页面,用于收集承运商凭据(API key、账号)。这与上文的区域/搜索选项是不同的概念——该 URL 页面收集的是商家每个店铺的承运商凭据,而不是你应用自身的配置。显示或保存任何凭据之前,先验证商家/会话身份,并对凭据加密存储,绝不要记录它们。(嵌入式页面会话身份验证 → salla-embedded-app。)
设置指南:https://docs.salla.dev/422996m0.md
第 4 步——核心应用功能(Shipping Management / AWB)
Shipping Management(AWB)应用会实现 两个同步 App Functions
(salla_functions action=list_triggers 类别 merchant_actions),并可订阅
三个异步事件(merchant_events)。App Functions 在 Salla 运行时中执行,
通过其返回值塑造操作,并通过 App Function MCP 预览进行测试——而不是通过 webhook 端点。
| 触发器 | 类别(MCP 已确认) | 返回类型 | 触发时机 | 处理程序的操作 |
|---|---|---|---|---|
shipment.creating | merchant_actions(同步) | Promise<Shipment> | 创建货件或退货时(订单 → completed,或创建发货标签/创建退货标签) | 调用承运商 API → 生成 AWB;返回一个 Shipment(运单号 + PDF 标签 + 状态) |
shipment.cancelling | merchant_actions(同步) | Promise<Resp> | 取消货件/退货之前 | 调用承运商 API 作废/取消;返回 Resp.success()(或返回错误以拒绝) |
shipment.created | merchant_events(异步) | — | 创建货件之后 | 同步下游状态(后台处理) |
shipment.cancelled | merchant_events(异步) | — | 取消货件之后 | 对账/通知(后台处理) |
shipment.updated | merchant_events(异步) | — | 货件详情变更之后 | 同步跟踪/状态(后台处理) |
要用于
save的名称: 同步取消函数是shipment.cancelling(merchant_actions,返回Resp),尽管 AWB 文档将其页面标为“货件已取消” (https://docs.salla.dev/1797616m0.md)。`shipment.cancelled` 是单独的 异步事件。使用salla_functions action=list_triggers核对名称(详情 →references/shipment-cycle.md)。
shipment.creating 同时处理新货件和退货——使用一个函数,根据载荷的
type 字段("shipment" 与 "return")进行分支处理(https://docs.salla.dev/1792119m0.md)。
这些同步触发器是 App Functions,而不是 Webhook。 使用
salla_functions action=save 实现每个触发器(每个触发器一个函数),并使用
salla_functions action=get 获取锁定的封装模板。处理程序签名(每个签名的首行均已锁定):
// shipment.creating — generate the AWB and return a Shipment
export default async (context: Shipments): Promise<Shipment> => {
const { payload, settings, merchant } = context;
const { data: shipment } = payload; // type: "shipment" | "return"
const result = await callCarrierAwbApi(shipment); // your third-party API
// setShipmentNumber() is REQUIRED; setPdfLabel/setStatus shape the AWB.
// Return Shipment.error("…") on carrier failure.
return Shipment.success()
.setShipmentNumber(result.awb_number)
.setPdfLabel(result.label_url)
.setStatus(ShipmentStatusEnum.IN_TRANSIT);
};
// shipment.cancelling — void with the carrier, return Resp (NOT a Shipment)
export default async (context: Shipments): Promise<Resp> => {
await voidWithCarrier(context.payload.data.shipping_number);
return Resp.success().setData({});
};
App Function 的机制归
salla-app-functions系列文档介绍——包括 V8 沙箱 限制、锁定模板/首行规则、保存/验证、5 秒同步预算 (每次内部异步调用 < 2 秒)、预先通过身份验证的 Admin API(无需Authorization标头), 以及Resp/Shipment构建器运行时:设计 →salla-app-functions-design, 处理程序正文 →salla-app-functions-handler,保存/验证 →salla-app-functions-validate,测试/预览 →salla-app-functions-test。 发货相关的具体内容——完整的Shipment构建器方法列表、ShipmentStatusEnum、Shipments上下文载荷,以及三种 AWB 处理流程——见references/shipment-cycle.md。 保存之前:请先根据获取到的类型确认载荷字段名称。 在获取模板(salla_functions action=get)与salla_functions action=save之间,将处理程序主体交给salla-app-functions-handler编写——它负责写入主体,包括以下规则:获取action=get返回的types数组中的每个 URL,并根据这些.d.ts定义,从context.payload.data中读取shipment.creating/shipment.cancelling的确切载荷字段名称(地址、包裹、重量、type: "shipment" | "return")。不要猜测sender_address/receiver_address/weight这类载运商 API 风格的名称。
关卡:“处理程序主体已通过 salla-app-functions-handler 编写,且每个 context.payload.data 字段都已根据触发器获取的 types .d.ts 确认——没有猜测任何字段——之后才执行 salla_functions action=save?”
通过 App Function MCP 预览进行测试(由 salla-app-functions-test 负责):保存函数,轮询 salla_functions action=deploy_status,直到状态为 COMPLETED,然后使用 app_id、trigger、演示用 store_id 以及触发器的表单字段(例如真实的 shipment_id)运行 salla_functions action=preview。
异步事件(shipment.created / shipment.cancelled / shipment.updated)是普通的店铺事件——使用 salla_events action=subscribe 订阅(它会替换完整列表,因此请包含所有要启用的事件)。使用 salla_events action=list 验证。传输(签名、快速返回 200、幂等性)→ salla-webhooks。
App Function 会同步返回 AWB。对于承运商确认后的带外更新(实际运费、跟踪信息、状态变更),请使用由合作伙伴发起的 Update Shipment Details REST 调用(PUT /shipments/{id},存储商家的 access_token——令牌存储/刷新 → salla-app-auth;端点结构、必填字段和状态枚举 → references/api-endpoints.md)。请根据端点的 docs.salla.dev/<id>.md 页面中记录的 OpenAPI 架构验证 PUT /shipments/{id} 请求体(通过 salla-docs 查找该页面),并在依赖它之前修正问题;使用 salla-api-core 中的读取架构 → 构建 → 验证 → 修正 → 重试循环。
关卡:“在演示店铺上,salla_functions action=preview 对 shipment.creating(type: shipment 和 type: return 两种情况)均返回有效的 Shipment,对 shipment.cancelling 返回 Resp.success(),且订单上显示了 AWB 编号 / 跟踪信息。”
步骤 5 — 订单履约(如果这是你的模式)
如果你在步骤 0 中选择的模式是订单履约(https://docs.salla.dev/423000m0.md),流程会有所不同:你无需编写 shipment.creating App Function——而是响应 order.created,选择承运商/网点,并分配货件,这会触发已分配的 Shipping App 的 shipment.creating 函数。请根据 https://docs.salla.dev/423002m0.md 配置权限范围(Basic Info、Orders、Webhooks、Shipping)和事件(order.created、shipment.created)。
完整的分配 + 退货/取消流程 →
references/fulfillment-cycle.md。
第 6 步 — 测试与发布
**测试:**通过 App Testing 连接演示商店,并模拟:新订单 → 费率请求 → 标签 → 物流跟踪 → 取消 → 退货。端到端演示商店验证由 salla-live-testing 负责。使用演示数据/非敏感数据:不要将生产承运商凭据、OAuth/Bearer 令牌、Webhook 签名密钥和真实客户个人身份信息(PII)提供给任何第三方捕获/检查工具;完成后恢复真实配置。
**发布:**物流应用是公开应用(见顶部说明)→ 分步执行 app_publish(open → 对每个部分执行 set → validate 保存为 DRAFT;合作伙伴随后在 Portal 的 /publish 页面中一键提交 — 由 salla-publication-consistency 负责)。针对特定商家构建的承运商应用属于 type: "private" 应用 → 请改用 salla-app-builder → 私有应用:无需 sub_category_id,且 shippings 作用域保持禁用状态(适用于常规合作伙伴,除非 Salla 将该应用加入允许列表)或不可用(适用于商家合作伙伴)。type: "shipping" 应用有两个阻碍:
sub_category_id必须是sub_categories中的物流子类别(salla_reference action=categories type=shipping)。- 若要在商家的 AWB 承运商选项中显示,你的应用必须由 Salla 启用 — 请发送邮件至 [email protected](https://docs.salla.dev/1792111m0.md)。
获批后,你的应用将列在 https://apps.salla.sa/en 的 Shipping 类别下。
测试指南:https://docs.salla.dev/422998m0.md · 发布指南:https://docs.salla.dev/422990m0.md
门槛:“已发布 — salla_apps action=get 显示预期状态。”
资源
| 主题 | 链接 |
|---|---|
| 配送概览(两种模式) | https://docs.salla.dev/422988m0.md |
| 配送 API 列表 | https://docs.salla.dev/api-5578809 |
| Salla AWB — 入门指南 | https://docs.salla.dev/1792089m0.md |
| AWB — 创建应用 | https://docs.salla.dev/1792111m0.md |
| AWB — 设置应用 | https://docs.salla.dev/1792112m0.md |
| AWB 功能 — 创建货件 | https://docs.salla.dev/1792119m0.md |
| AWB 功能 — 取消货件 | https://docs.salla.dev/1797616m0.md |
| 配送管理 — 创建 | https://docs.salla.dev/422995m0.md |
| 配送管理 — 设置 | https://docs.salla.dev/422996m0.md |
| 配送管理 — 应用周期 | https://docs.salla.dev/422994m0.md |
| 配送管理 — 测试 | https://docs.salla.dev/422998m0.md |
| 订单履行 — 创建 | https://docs.salla.dev/423001m0.md |
| 订单履行 — 设置 | https://docs.salla.dev/423002m0.md |
| 订单履行 — 应用周期 | https://docs.salla.dev/423000m0.md |
| 订单履行 — 测试 | https://docs.salla.dev/423003m0.md |
| Postman 集合 | https://www.postman.com/salla-app/workspace/salla-e-commerce-platform/collection/17687195-d700cd60-adf3-4b20-82ee-94851e88bd44 |
| 开发者社区 | https://t.me/salladev |