# Shoplazza 应用开发常见问题

## FAQ 分类

[

### API 调用

了解如何正确调用 Shoplazza API。

](#api-invocation)[

### 授权

了解如何配置 OAuth 和私有应用 token。

](#authorization)[

### 应用管理

管理和配置 Shoplazza 生态中的应用。

](#app-management)[

### 账号管理

了解用户账号和权限管理指南。

](#account-management)[

### Webhook

设置并配置用于实时通知的 Webhook。

](#webhook)[

### 应用商店

通过 Shoplazza 应用商店中的应用增强店铺功能。

](#app-store)[

### 主题扩展

使用主题扩展自定义主题区块和 POD 功能。

](#theme-extension)

## API 调用

### 问：API 调用中推荐如何实现分页？

#### 问题描述：

部分 API 同时支持基于 cursor（token）的分页和基于 page 的分页。但是，开发者有时会在高效获取元数据时遇到困难。

#### 原因：

基于 page 的分页更简单，但在大数据量场景下效率较低。基于 cursor（token）的分页在获取分页数据时性能和准确性更好，因为它会直接关联到下一批数据。

#### 解决方案：

*   **建议：** API 调用优先使用基于 cursor（token）的分页。仅在不支持 token 分页时使用基于 page 的分页。
*   **使用方式：** 请参考 [Cursor Pagination 文档](/zh-CN/docs/app/building-blocks/rest-api/pagination)了解实现细节。

* * *

### 问：图片无法正常展示时应该怎么办？

#### 问题描述：

站点部分位置的图片没有正常展示。

#### 原因：

如果图片没有在主题设置中正确配置，就可能出现该问题。

#### 解决方案：

1.  进入 **主题装修 → 全局设置 → 图片设计**。
2.  按设置要求添加或配置所需图片。

* * *

### 问：为什么必填字段传空值时，API 仍允许创建商品？

#### 问题描述：

部分客户发现，即使必填字段传入空值，创建商品仍会成功。这是因为部分 API 会在内部处理默认值。

#### 原因：

某些 API 会为必填字段设置默认值。如果必填字段传入空值，API 会使用预设默认值进行初始化，而不是返回错误。

#### 解决方案：

*   **检查参数要求：** 调用 API 前，请仔细查看 API 文档中的必填参数及其预期值。
*   **联系我们确认：** 如果必填字段的行为不清晰，或不符合你的使用场景，请联系支持团队进一步确认。

### 问：在 PHP 中，日志显示 200 状态正常时，如何获取正确响应？

#### 问题描述：

使用 PHP 调用 API 时，日志显示 200 状态码正常，但响应体为空或内容不正确。

#### 解决方案：

如果你使用兼容 PSR-7 的 HTTP 客户端（例如 Guzzle），可以使用以下代码获取响应内容：

```text
$response->getBody()->getContents();
```

* * *

### 问：订单与运单号的规则是什么？

目前，订单不能拆分或合并。多个订单可以共用同一个运单号。同时，一个订单可以包含多个包裹，每个包裹有各自的运单号。

* * *

### 问：total\_price 字段的计算逻辑是什么？

**税费：** `total_price` 表示顾客最终支付的金额，如适用则包含税费。

**额外费用：** `total_price` 包含 `additional_total`、`total_shipping`、`total_tax`、`shipping_tax_total` 等附加费用，以及小费（`total_tip_received`）。

**计算公式：**

**字段说明**

`sub_total`：商品总价。

`total_shipping`：运费总额。

`additional_total`：附加费用。

`total_tax`：商品税总额。

`shipping_tax_total`：运费税总额。

`total_tip_received`：收到的小费总额。

`total_discount`：优惠总额（例如商品优惠和优惠码优惠）。

当 `sub_total` 为**不含税**（`order.config.product_tax_included == false`）时：

```text
total_price = (sub_total + total_shipping + additional_total + total_tax + shipping_tax_total + total_tip_received) - total_discount
```

当 `sub_total` 为**含税**（`order.config.product_tax_included == true`）时：

```text
total_price = (sub_total + total_shipping + additional_total + shipping_tax_total + total_tip_received) - total_discount
```

**PayPal 支付：** `total_price` 反映顾客支付的金额，不包含任何 PayPal 交易手续费，该手续费由平台单独处理。

* * *

### 问：buyer\_accepts\_marketing 字段的用途是什么？

`buyer_accepts_marketing` 字段表示顾客是否同意接收营销推广：

*   **已同意：** 商家可以发送促销邮件或优惠信息。
*   **未同意：** 顾客不会被纳入营销活动。

该字段不会直接影响订单列表或其信息。

* * *

### 问：customer.orders\_count 字段是否包含已取消或未付款的订单？

`orders_count` 包含顾客在当前店铺创建的所有订单，无论其状态如何（例如已取消或未付款）。

* * *

### 问：同一店铺中，顾客可以使用不同币种支付吗？

可以，店铺支持多币种支付。为保持一致性，所有支付都会换算为店铺的主市场币种。

* * *

### 问：我通过 API 创建了订单，但为什么在店铺后台看不到？

这通常是因为订单缺少收货地址。后台会过滤掉因缺少地址信息而被判定为"无效"的订单，不予展示。但这些订单仍可通过 API 查询到。

* * *

### 问：为什么订单响应中 line item 的 `id` 在多次 API 调用之间会变化？

未付款（未完成）订单的 line item id 可能不是持久的。一旦订单成功付款，line item ID 就会稳定下来，并在后续 API 查询中保持不变。

* * *

### 问：为什么 create order API 返回 record not found？

当 create order API 返回该错误时，请按以下步骤排查：

*   确认 Product ID、Variant ID 及其他相关参数是否正确。
*   如果所有 ID 都确认无误但请求仍然失败，请检查店铺是否至少配置了一个支付渠道。
*   店铺必须至少启用一种支付方式，否则创建订单会失败并返回 “record not found” 错误。

* * *

### 问：通过 Product Image API 创建图片后，为什么图片显示加载中状态？

当图片不是托管在 Shoplazza 原生存储上时，会出现加载中状态。系统会对外部图片发起一个转存流程，期间会显示加载指示。这是临时状态，转存完成后会自动消失。

* * *

### 问：如何获取图片资源的 CDN 域名？

获取图片 CDN 域名的方式：

1.  查看 API 响应头中的 `IMAGE-DOMAIN` header。
2.  如果 `IMAGE-DOMAIN` header 的值不存在或为空，系统会自动回退到默认域名：`img.staticdj.com`。

注意：`IMAGE-DOMAIN` header 提供当前生效的图片资源 CDN 地址。实现时请始终加入回退逻辑，以应对该 header 可能缺失的情况。

* * *

### 问：如何只更新某个商品的单个 variant，而不影响同一商品下的其他 variant？

请使用专门的 Update Variant API。**重要：** 如果使用 "Update Product" API，它会用请求体中提供的 variant 列表**替换整个商品的 variant 列表**，请求中未包含的现有 variant 都会被删除。为避免这种情况，请使用 variant 专用接口，或确保你的 "Update Product" 请求包含所有需要保留的 variant。

## 授权

### 问：API 请求返回 403 错误，提示缺少权限。

#### 问题描述：

由于私有应用权限不足，API 请求返回 403 错误。

#### 原因：

该问题通常是因为店铺设置中没有为私有应用授予所需权限。

#### 解决方案：

1.  **检查权限：** 确认私有应用已配置必要权限：

    *   进入店铺后台首页。
    *   进入 **Manage Private App**。
    *   按需更新私有应用的权限设置。
2.  **当前限制：**

    *   目前私有应用暂不支持 **write shop** 权限。
    *   该权限将在后续版本中开放。

## 应用管理

### 问：如何提升应用评分？

#### 用户界面优化：

*   确保按钮、导航栏和表单易用且功能正常。
*   提供清晰的设置说明和交互功能。
*   为用户操作增加实时反馈。

#### 性能优化（Lighthouse 分数）：

*   关注 **FCP**、**LCP** 和 **TTI** 等指标。
*   优化大文件，使用图片懒加载，并提升服务器响应速度。

#### 应用可用性：

*   确保应用无明显缺陷，并能适配不同设备。

### 问：如何在店铺中安装未发布应用进行生产测试？

如果要测试尚未发布到应用市场的应用，可以使用以下 URL 格式：

```json
https://{{storeDomain}}/admin/oauth/redirect_from_partner_center?client_id={{app_client_id}}
```

替换以下参数：

*   `storeDomain` → 你的店铺域名
*   `app_client_id` → 需要测试的应用 Client ID

该链接允许店铺直接安装未发布应用，用于详细业务测试。

* * *

### 问：漏洞扫描常见问题

#### 问 1：漏洞扫描通常什么时候开始？

**答：** 漏洞扫描通常会在系统发生重要变更后，或常规安全审计期间启动。

#### 问 2：单次扫描是否会提供报告和修复建议？

**答：** 会。每次扫描都会提供详细报告，并针对发现的问题给出建议修复方案。

#### 问 3：如果我认为某些漏洞是误报，应该如何处理？

**答：** 如果低风险漏洞不影响服务，可以忽略。对于中高风险项目，请提交复核申请并提供相关证据。

#### 问 4：漏洞扫描如何工作，是否需要额外资源？

**答：** 扫描会使用自动化工具检测已知问题。通常不需要额外资源。

#### 问 5：如何确认漏洞已经修复？

**答：** 修复后重新运行扫描，确认问题已解决。

#### 问 6：创建或重启扫描任务失败时应该怎么办？

**答：** 请确认所有必填参数均正确。如果问题仍然存在，请联系支持团队。

#### 问 7：生成扫描报告需要多久？

**答：** 耗时取决于扫描复杂度。如果长时间未生成报告，请联系支持团队。

* * *

### 问：开发者能否在账号下切换店铺？

#### 当前状态：

目前暂不支持该功能。

#### 后续计划：

我们计划在未来版本中支持同一账号下的店铺切换。

## 账号管理

### 问：开发者如何删除开发者账号？

#### 当前状态：

目前暂不提供开发者账号删除功能。

#### 解决方案：

如果你需要删除开发者账号，请联系支持团队协助处理。

#### 后续计划：

我们正在评估未来开发开发者账号删除功能的可行性。

* * *

### 问：开发者能否在账号下切换店铺？

#### 当前状态：

目前暂不支持该功能。

#### 后续计划：

我们计划在未来版本中支持开发者在同一账号下切换店铺。请关注后续公告。

## Webhook

### 问：Shoplazza 如何处理 Webhook 投递失败？

#### 问题描述：

你的 Webhook 端点偶尔会处理失败，你想知道 Shoplazza 何时重试、一直失败会怎样。

#### 解决方案：

1.  **重试条件：** 只有返回 `5xx` 才会触发重试；`4xx`、超时和连接失败都不重试。
2.  **重试节奏：** 生产环境下，一次失败的投递会在约 24 小时内重试约 11 次，间隔递增：1m、1m、5m、10m、30m、1h、2h，之后每 4h 一次。
3.  **重试耗尽后：** 该投递被丢弃，但订阅**不会**被取消，同一 topic 的后续事件仍会正常投递。
4.  **幂等性：** 同一事件可能被投递多次，用 `X-Shoplazza-Deduplication-ID` 跳过重复。

* * *

### 问：收不到 Webhook 事件时应该怎么办？

#### 问题描述：

Webhook 事件可能因 IP 限制或 endpoint 配置错误而无法到达你的服务器。

#### 解决方案：

1.  **将 Shoplazza IP 加入白名单：** 允许来自 Shoplazza 外部 IP 的请求，例如 `34.210.253.121`。
2.  **检查 endpoint 配置：** 确保你的 endpoint 能正确处理 POST 请求。
3.  **查看日志：** 检查服务器日志，确认是否存在错误或请求被拦截。

* * *

## 应用商店

### 问：商家在同一个账单周期内卸载并重新安装 WhatsApp & Chat Buttons 应用，是否需要再次付费？

#### 当前行为：

需要。应用卸载后，订阅会被终止，重新安装时必须重新发起订阅。

#### 原因：

应用卸载后，订阅关系即结束。因此即使在同一个账单周期内重新安装，也需要创建新的订阅。

#### 建议：

商家应注意在有效账单周期内卸载应用的影响，因为重新安装会触发新的付款。如果对该策略有疑问，请联系支持团队确认。

* * *

## 主题扩展

### 问：如何使用主题扩展自定义主题区块和 POD 功能？

#### 原因：

Shoplazza 提供用于主题自定义和 POD 实现的 CLI 能力。请联系技术团队，我们会提供相关文档和高级定制功能指导。

* * *

### 问：为什么 CLI 命令返回 403 错误，应该如何解决？

#### 原因：

当你的应用 Client ID 没有加入 CLI 访问白名单时，会出现 403 错误。请通过技术支持邮箱联系我们，将应用 Client ID 加入白名单。这是使用 CLI 工具前必须完成的安全措施。

* * *
