承运商服务运费计算
承运商服务(也称为承运商计算服务或配送服务)为 SHOPLINE 提供实时运费计算。
安装承运商服务应用后,商家可以前往 SHOPLINE 商家后台,依次点击 设置 > 发货与配送。在 运费 区域,设置 通用运费 或 自定义运费,并在相应页面的 收货地址 处点击 添加运费。在弹出的对话框中选择 使用承运商或应用来计算费率,然后找到已添加的承运商服务并选择相应的运费方案。客户结账时,将根据该方案实时计算运费。
实现原理和步骤
为 SHOPLINE 提供实时运费计算功能,可按以下步骤操作:

1. 应用开发部署
开发公共应用并发布至应用市场,或为商家开发私有化应用,详情可参考 应用开发。
2. 商家服务配置
当商家在店铺中添加承运商服务时,承运商服务应用需调用 创建承运商服务 接口完成服务的创建。
必须在请求参数中配置有效的 callback_url 回调地址。SHOPLINE 将通过该地址向你的承运商服务应用发起请求,主要用于以下场景:获取运输服务、计算运费费率。
你的承运商服务应用需要:
- 接收并处理 SHOPLINE 的请求
- 根据提供的订单信息实时计算运费
- 按照 SHOPLINE API 规定的响应格式返回计算结果
3. 在 SHOPLINE 商家后台配置运费方案
当商家在 SHOPLINE 商家后台配置运费方案,并选择 使用承运商或应用来计算费率 下的你的服务时,系统将通过 callback_url 向你发起请求,以获取可用的运输服务。详情如下:
参数
SHOPLINE 将通过 callback_url 发送请求,请求数据包含以下参数:
origin:始发地destination:目的地items:商品信息currency:货币类型locale:语言环境X-Shopline-Shop-Id:店铺 IDX-Shopline-Shop-Domain:店铺域名X-Shopline-Hmac-Sha256:数字签名
参数处理规则
系统会根据不同的 service_discovery 模式采用不 同的参数处理规则:
| 模式 | 始发地与目的地 | 商品参数 | 货币类型 |
|---|---|---|---|
service_discovery: false | 始发地和目的地均默认使用店铺预设地址。 | product_id 与 variant_id 均为空值。 | 店铺货币 |
service_discovery: true | 始发地为运费方案中设置的发货地址; 目的地为运费方案中设置的收货国家或地区(系统会使用虚拟地址触发多次请求)。 | product_id 与 variant_id 均为空值。 | 店铺货币 |
请求优化逻辑
在结账场景下,系统将会产生大量接口请求,因此需要特别注意接口的请求压力。为了减少不必要的请求,我们针对特定情况做了以下优化处理:
- 发货地处理规则
当运费方案的“发货地分组”为默认分组时,系统将自动采用店铺默认地址作为发货地,并与收货地参数destination组合生成请求。 - 收货地处理规则
当运费方案选择“其他国家和地区”选项时,收货地将固定采用以下 6 个国家:新加坡、英国、美国、澳大利亚、巴西、南非。这些预设国家会与发货地参数origin组合生成请求。 - 去重机制
- 发货地:按国家维度进行去重,并根据地址优先级顺序筛选。
- 收货地:同样按国家维度去重,并采用虚拟地址数据发起请求。
4. 客户结账时获取承运商运费方案
当客户使用承运商服务结算运费时,SHOPLINE 将通过 callback_url 向你发送运费计算请求。详情如下:
参数
核心参数包含:
origin:始发地(默认取用店铺预设地址)destination:目的地(用户结算时填写的收货地址)items:商品信息currency:货币类型locale:语言环境X-Shopline-Shop-Id:店铺 IDX-Shopline-Shop-Domain:店铺域名X-Shopline-Hmac-Sha256:数字签名customer:客户信息
货币处理规则
以下规则说明了 SHOPLINE 处理货币数据及汇率转换的方式。
- 请求货币:采用订单结算货币。
- 汇率转换:当返回的运费币种与输入的币种参数
currency不一致时,SHOPLINE 将按实时汇率转换后再参与运费计算。
在客户结账环节,SHOPLINE 结账页将向客户展示所有可用的运费方案和对应的实时运费(前提是需要在 SHOPLINE 商家后台配置好可用的承运商运费方案)。
API 接口参考
承运商服务 API
| API | 说明 |
|---|---|
| 创建承运商服务 | 创建一个新的承运商服务,为 SHOPLINE 提供实时运费计算。SHOPLINE 通过请求承运商服务的 callback_url 来获取承运商的服务及运费信息。 |
| 获取承运商服务列表 | 检索商店的所有承运商服务列表。 |
| 获取指定承运商服务 | 通过指定承运商服务 ID 来检索承运商服务信息。 |
| 更新承运商服务 | 更新指定的承运商服务。只有创建该承运商服务的应用才能更新它。 |
| 删除承运商服务 | 删除指定的承运商服务。只有创建该承运商服务的应用才能删除它。 |
调用 创建承运商服务、更新承运商服务 接口时,可通过 metafield 参数预配置 Customer 与 ProductVariant 资源的元字段,在结账页请求 callback_url 获取实时费率时将自动透传。
| 参数 | 类型 | 是 否必传 | 描述 |
|---|---|---|---|
| metafield | object[] | 否 | 元字段信息。 |
| metafield.resource | string | 否 | 元字段资源,当前只支持 Customer、ProductVariant。 |
| metafield.identifiers | object[] | 否 | 元字段定义信息。 |
| metafield.identifiers.key | string | 否 | 元字段定义 Key。 |
| metafield.identifiers.namespace | string | 否 | 元字段定义命名空间。 |
入参最多支持 50 个 Key,超出限制将被拦截并报错。
请求 callback_url 时的参数说明
请求头
| 字段 | 类型 | 是否必传 | 描述 |
|---|---|---|---|
| X-Shopline-Hmac-Sha256 | string | 是 | 签名的请求参数数据体的文本内容(使用 Jackson 转换的 JSON 字符串)。 |
| X-Shopline-Shop-Id | string | 是 | 店铺 ID。 |
| X-Shopline-Shop-Domain | string | 是 | 店铺域名。 |
请求体
| 字段 | 类型 | 是否必传 | 描述 |
|---|---|---|---|
| origin | object | 是 | 发货地对象。 |
| destination | object | 是 | 收货地对象。 |
| items | object[] | 是 | 商品列表,其中金额是分摊商品折扣和订单折扣后的金额。 |
| currency | string | 是 | 币种。格式:ISO 4217。 示例: USD |
| locale | string | 是 | 语言环境。 |
| is_express_checkout | boolean | 是 | 是否为快捷支付。
|
| customer | object | 否 | 客户信息。其中,metafield 里一个 key 可能有多个 value。只在结账页请求时传递该参数。 |
origin、destination、items、customer 参数均为对象类型,包含若干子字段。传入时需要填写相应子字段的值,具体结构见下方的示例代码。
请求 callback_url 时的参数示例:
{
"origin": {
"country":"US",
"postal_code":"02116",
"province":"Massachusetts",
"province_code":"MA",
"city":"Boston",
"name":"MAMAMAMAMA",
"address1":"110 Huntington Avenue",
"address2":"",
"phone":"+16175952242"
},
"destination": {
"country":"US",
"postal_code":"02116",
"province":"Massachusetts",
"province_code":"MA",
"city":"Boston",
"name":"MAMAMAMAMA",
"address1":"110 Huntington Avenue",
"address2":"",
"phone":"+16175952242"
},
"items": [
{
"name":"phone",
"quantity":1,
"grams":100,
"price":0,
"requires_shipping":true,
"taxable":true,
"product_id":"1607337290976137******0910",
"variant_id":"1807337290976254******0910",
"sku":"abc-123",
"activity_type":"1",
"benefit_type":"2",
"properties": [
{
"name":"color",
"value":"red",
"show":"true",
"type":"text",
"urls":"https://img-va.myshopline.com/image/store/168076****839/fgsdfgs.jpg?w=588&h=386"
}
],
"selling_price": {
"presentment_money": {
"amount":"10.00",
"currency":"USD"
},
"shop_money": {
"amount":"10.00",
"currency":"USD"
}
},
"variant_metafield": [
{
"key":"sku_long",
"value":"21"
},
{
"key":"sku_width",
"value":"22"
},
{
"key":"sku_height",
"value":"23"
}
]
}
],
"currency":"HKD",
"locale":"en",
"customer": {
"id":"460****098",
"email":"test@gmail.com",
"phone":"1321****678",
"metafield": [
{
"key":"member_level",
"value":"1"
}
]
}
}
返回参数
| 字段 | 是否必需 | 描述 |
|---|---|---|
| service_name | 是 | 结账时向客户显示的运费方案名称。 |
| description | 否 | 结账时向客户显示的运费方案描述。 限制为 300 个字符。如果超出此限制,则会被截断。 |
| service_code | 是 | 运费方案代码。 |
| currency | 是 | 币种。格式:ISO 4217。 示例: USD |
| total_price | 是 | 运费值,除以 100 后为实际金额。例如,运费金额为 5 美元,total_price 取值为 500;运费金额为 1000 美元,total_price 取值为 100000。 |
| phone_required | 否 | 指示客户是否必须在结账时提供电话号码。 当值为 true 时,结账时所选运费下方将显示一个电话号码输入字段。 |
| min_delivery_date | 否 | 显示运费方案的最早发货时间。格式:ISO 8601。 |
| max_delivery_date | 否 | 显示运费方案的最晚发货时间。格式:ISO 8601。 |
| shipping_discount | 否 | 运费折扣信息,包含 type、value 和 description 子字段。其中,description 会展示在结账页对应运费方案处(目前最多支持 100 个字符);type 的枚举值为 percentage 和 fixed。
![]() |
承运商服务返回实时运费 示例:
{
"rates": [
{
"service_name": "canadapost-overnight",
"service_code": "ON",
"total_price": "1295",
"description": "This is the fastest option by far",
"currency": "CAD",
"min_delivery_date": "2023-06-08T23:59:59+08:00",
"max_delivery_date": "2023-06-09T23:59:59+08:00",
"shipping_discount": {
"type": "fixed",
"value": "10",
"description": "This is a shipping discount"
}
},
{
"service_name": "fedex-2dayground",
"service_code": "2D",
"total_price": "2934",
"currency": "USD",
"min_delivery_date": "2023-06-08T23:59:59+08:00",
"max_delivery_date": "2023-06-09T23:59:59+08:00",
"shipping_discount": {
"type": "fixed",
"value": "10",
"description": "This is a shipping discount"
}
},
{
"service_name": "fedex-priorityovernight",
"service_code": "1D",
"total_price": "3587",
"currency": "USD",
"min_delivery_date": "2023-06-08T23:59:59+08:00",
"max_delivery_date": "2023-06-09T23:59:59+08:00",
"shipping_discount": {
"type": "fixed",
"value": "10",
"description": "This is a shipping discount"
}
}
]
}
注意事项
签名验证机制
为了保障数据安全,并确保业务来源的合法性,SHOPLINE 在将请求发送到承运商服务的 callback_url 之前会进行签名。承运商服务应用必须对请求进行签名验证。
签名采用 SHOPLINE Webhook 签名方法,并结合 HMAC-SHA256 签名算法生成。待签名内容为原始请求体。
签名算法示例(Java):
/**
* HMACSHA256
* @param source signContent
* @param secret appSecret
* @return
*/
public static String HMACSHA256(String source, String secret) {
if (StringUtils.isEmpty(secret) || StringUtils.isEmpty(source)) {
return null;
}
try {
Mac sha256_HMAC = Mac.getInstance("HMACSHA256");
SecretKeySpec secret_key = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HMACSHA256");
sha256_HMAC.init(secret_key);
byte[] bytes = sha256_HMAC.doFinal(source.getBytes(StandardCharsets.UTF_8));
return new String(Hex.encodeHex(bytes));
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
响应超时
如果承运商服务接口响应超过 1500 毫秒,则会触发响应超时。
服务端缓存请求
SHOPLINE 采用服务端缓存机制来优化请求效率,具体缓存规则如下:
- 缓存触发条件
当运费计算请求的以下属性完全匹配时,系统将命中缓存并直接返回缓存结果:- 默认运输箱重量及尺寸
- 货币类型
- 承运商服务 ID
- 始发地地址
- 目的地地址
- 商品重量数据
- 数字签名
- 客户信息
- 缓存失效机制
出现以下任一情况时将发起新请求:- 上述任一属性发生变动
- 缓存已超过有效期(自成功返回运费信息后 10 分钟自动失效)
