POST /v1/actions/store/update-store
本端点不管理 Webhook 配置。请求体中如出现
webhookSettings 字段会被静默忽略,响应顶层附 warnings 数组;其它字段照常更新并返回 200。Webhook 配置请使用 add-webhook、update-webhook 和 remove-webhook,列表查询走 GraphQL Store.storeWebhooks。请求体
| 字段 | 类型 | 必需 | 说明 |
|---|---|---|---|
id | string | 是 | Store ID(Short ID 格式 STO_xxx) |
name | string | 否 | 更新后的门店名称(1-48 字符) |
status | string | 否 | active、inactive 或 suspended |
logo | string | null | 否 | 门店 logo URL(设为 null 可移除) |
notificationSettings | object | null | 否 | 通知偏好设置(设为 null 可移除) |
checkoutSettings | object | null | 否 | 收银台主题配置(设为 null 可移除) |
通知设置
分两类,写入权限不同: 商户可写(✅ 通过本端点接受):| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
notifyNewOrders | boolean | true | 新订单时通知商户 |
notifyNewSubscriptions | boolean | true | 新订阅时通知商户 |
notifySubscriptionCanceled | boolean | true | 订阅取消(用户取消,仍在 access 期内)时通知商户 |
notifySubscriptionEnded | boolean | true | 订阅终止时通知商户 |
notifySubscriptionPastDue | boolean | true | 订阅扣款失败(past_due)时通知商户 |
notifySubscriptionRenewed | boolean | true | 订阅续费成功时通知商户 |
notifySubscriptionUncanceled | boolean | true | 订阅取消后恢复时通知商户 |
notifySubscriptionUpdated | boolean | true | 订阅 plan 变更时通知商户(forward-compat) |
notifyChargeback | boolean | true | 拒付(chargeback)时通知商户(forward-compat) |
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
emailOrderConfirmation | boolean | true | 订单确认时发送邮件 |
emailSubscriptionConfirmation | boolean | true | 订阅创建时发送邮件 |
emailSubscriptionCycled | boolean | true | 订阅续费时发送邮件 |
emailSubscriptionCanceled | boolean | true | 订阅取消时发送邮件 |
emailSubscriptionRevoked | boolean | true | 订阅撤销时发送邮件 |
emailSubscriptionPastDue | boolean | true | 订阅逾期时发送邮件 |
emailTrialStarted | boolean | true | 试用启动时发送邮件 |
emailTrialEnding | boolean | true | 试用即将结束时发送提醒邮件 |
emailUpcomingCharge | boolean | true | 订阅续费扣款前发送提醒邮件 |
若
notificationSettings 入参中包含任何平台管理字段(email*,或历史遗留的 notifyPayoutCompleted / notifyPayoutFailed——提现结果邮件必达,无开关键),服务端会静默丢弃这些字段,并在 200 响应的 warnings[] 中列出被丢弃的 key。如需修改 customer 邮件 toggle,请联系 PANCAKE 平台。收银台设置
| 字段 | 类型 | 说明 |
|---|---|---|
defaultDarkMode | boolean | 是否默认使用暗色模式 |
light | object | 亮色主题设置(见下方) |
dark | object | 暗色主题设置(见下方) |
light 和 dark):
| 字段 | 类型 | 说明 |
|---|---|---|
checkoutLogo | string | null | 收银台页面 logo URL |
checkoutColorPrimary | string | 主色(hex) |
checkoutColorBackground | string | 背景色(hex) |
checkoutColorCard | string | 卡片/面板颜色(hex) |
checkoutColorText | string | 文字颜色(hex) |
checkoutBorderRadius | string | 圆角半径(CSS 值) |
部分更新语义
两个 settings 对象均支持部分更新,每个子字段有三种传值语义:| 传值 | 行为 | 示例 |
|---|---|---|
| 不传(JSON 中省略) | 保留现有值 | 只传 notifyNewOrders,其它通知开关保持不变 |
null | 清除该字段 | "checkoutLogo": null 移除收银台页面 logo |
| 具体值 | 新增/更新 | "checkoutColorPrimary": "#FF6600" 设置新主色 |
null(如 "notificationSettings": null)会清除该设置组的所有字段。
请求示例
import { WaffoPancake, EntityStatus } from "@waffo/pancake-ts";
const client = new WaffoPancake({
merchantId: process.env.WAFFO_MERCHANT_ID!,
privateKey: process.env.WAFFO_PRIVATE_KEY!,
});
const { store } = await client.stores.update({
id: "STO_2aUyqjCzEIiEcYMKj7TZtw",
name: "Updated Store Name",
// 只允许写商户可见的通知 toggle(B 类);
// customer 邮件 toggle(emailOrderConfirmation 等 A 类)由 PANCAKE 平台管理,
// 请勿在此处传入(传了会被静默丢弃 + 200 warning)。
notificationSettings: {
notifyNewOrders: true,
notifyNewSubscriptions: false,
},
});
// Uses callApi() helper from authentication.mdx
const result = await callApi("POST", "/v1/actions/store/update-store", {
id: "STO_2aUyqjCzEIiEcYMKj7TZtw",
name: "Updated Store Name",
notificationSettings: {
notifyNewSubscriptions: false,
},
});
console.log(result.data.store.name); // => "Updated Store Name"
// Uses callApi() helper from authentication.mdx
String body = """
{
"id": "STO_2aUyqjCzEIiEcYMKj7TZtw",
"name": "Updated Store Name",
"notificationSettings": {
"notifyNewSubscriptions": false
}
}""";
String response = callApi("POST", "/v1/actions/store/update-store", body);
System.out.println(response);
# Uses call_api() helper from authentication.mdx
result = call_api("POST", "/v1/actions/store/update-store", {
"id": "STO_2aUyqjCzEIiEcYMKj7TZtw",
"name": "Updated Store Name",
"notificationSettings": {
"notifyNewSubscriptions": False,
},
})
store = result["data"]["store"]
print(store["name"]) # => "Updated Store Name"
// Uses callAPI() helper from authentication.mdx
body := map[string]interface{}{
"id": "STO_2aUyqjCzEIiEcYMKj7TZtw",
"name": "Updated Store Name",
"notificationSettings": map[string]interface{}{
"notifyNewSubscriptions": false,
},
}
result, err := callAPI("POST", "/v1/actions/store/update-store", body)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(result))
// Uses call_api() helper from authentication.mdx
let body = serde_json::json!({
"id": "STO_2aUyqjCzEIiEcYMKj7TZtw",
"name": "Updated Store Name",
"notificationSettings": {
"notifyNewSubscriptions": false
}
});
let result = call_api("POST", "/v1/actions/store/update-store", &body).await?;
println!("{}", result);
/* Uses call_api() helper from authentication.mdx */
const char *body =
"{\"id\":\"STO_2aUyqjCzEIiEcYMKj7TZtw\","
"\"name\":\"Updated Store Name\","
"\"notificationSettings\":{\"notifyNewSubscriptions\":false}}";
char *response = call_api("POST", "/v1/actions/store/update-store", body);
printf("%s\n", response);
free(response);
// Uses callApi() helper from authentication.mdx
std::string body = R"({
"id": "STO_2aUyqjCzEIiEcYMKj7TZtw",
"name": "Updated Store Name",
"notificationSettings": {
"notifyNewSubscriptions": false
}
})";
std::string response = callApi("POST", "/v1/actions/store/update-store", body);
std::cout << response << std::endl;
MERCHANT_ID="MER_2aUyqjCzEIiEcYMKj7TZtw"
TIMESTAMP=$(date +%s)
BODY='{"id":"STO_2aUyqjCzEIiEcYMKj7TZtw","name":"Updated Store Name","notificationSettings":{"notifyNewSubscriptions":false}}'
BODY_HASH=$(echo -n "$BODY" | openssl dgst -sha256 -binary | base64 | tr -d '\n')
CANONICAL_REQUEST="POST
/v1/actions/store/update-store
$TIMESTAMP
$BODY_HASH"
SIGNATURE=$(echo -n "$CANONICAL_REQUEST" | openssl dgst -sha256 -sign private_key.pem | base64 | tr -d '\n')
curl -X POST "https://api.waffo.ai/v1/actions/store/update-store" \
-H "Content-Type: application/json" \
-H "X-Merchant-Id: $MERCHANT_ID" \
-H "X-Timestamp: $TIMESTAMP" \
-H "X-Signature: $SIGNATURE" \
-d "$BODY"
MERCHANT_ID="MER_2aUyqjCzEIiEcYMKj7TZtw"
TIMESTAMP=$(date +%s)
BODY='{"id":"STO_2aUyqjCzEIiEcYMKj7TZtw","name":"Updated Store Name","notificationSettings":{"notifyNewSubscriptions":false}}'
BODY_HASH=$(echo -n "$BODY" | openssl dgst -sha256 -binary | base64 | tr -d '\n')
CANONICAL_REQUEST="POST
/v1/actions/store/update-store
$TIMESTAMP
$BODY_HASH"
SIGNATURE=$(echo -n "$CANONICAL_REQUEST" | openssl dgst -sha256 -sign private_key.pem | base64 | tr -d '\n')
wget -qO- "https://api.waffo.ai/v1/actions/store/update-store" \
--header="Content-Type: application/json" \
--header="X-Merchant-Id: $MERCHANT_ID" \
--header="X-Timestamp: $TIMESTAMP" \
--header="X-Signature: $SIGNATURE" \
--post-data="$BODY"
成功响应 (200)
{
"data": {
"store": {
"id": "STO_2aUyqjCzEIiEcYMKj7TZtw",
"name": "Updated Store Name",
"status": "active",
"logo": null,
"supportEmail": null,
"website": null,
"slug": "my-digital-store-a1b2c3",
"prodEnabled": false,
"notificationSettings": {
"emailOrderConfirmation": true,
"emailSubscriptionConfirmation": true,
"emailSubscriptionCycled": true,
"emailSubscriptionCanceled": true,
"emailSubscriptionRevoked": true,
"emailSubscriptionPastDue": true,
"emailTrialStarted": true,
"emailTrialEnding": true,
"emailUpcomingCharge": true,
"notifyNewOrders": true,
"notifyNewSubscriptions": false,
"notifySubscriptionCanceled": true,
"notifySubscriptionEnded": true,
"notifySubscriptionPastDue": true,
"notifySubscriptionRenewed": true,
"notifySubscriptionUncanceled": true,
"notifySubscriptionUpdated": true,
"notifyChargeback": true
},
"checkoutSettings": {
"defaultDarkMode": false,
"light": {
"checkoutLogo": null,
"checkoutColorPrimary": "#000000",
"checkoutColorBackground": "#FFFFFF",
"checkoutColorCard": "#F5F5F5",
"checkoutColorText": "#1A1A1A",
"checkoutBorderRadius": "8px"
},
"dark": {
"checkoutLogo": null,
"checkoutColorPrimary": "#FFFFFF",
"checkoutColorBackground": "#1A1A1A",
"checkoutColorCard": "#2A2A2A",
"checkoutColorText": "#F5F5F5",
"checkoutBorderRadius": "8px"
}
},
"deletedAt": null,
"createdAt": "2026-01-15T10:30:00.000Z",
"updatedAt": "2026-01-15T11:00:00.000Z"
}
}
}
响应字段
与 创建门店响应字段 相同。 验证流程管理(🔒 本端点只读;仅在响应中回显):| 字段 | 类型 | 说明 |
|---|---|---|
supportEmail | string | null | 门店客服邮箱,由客服邮箱验证流程写入 |
website | string | null | 门店产品网站 URL,由产品域名验证流程写入 |
supportEmail 与 website 无法通过本端点设置。它们分别在商户完成客服邮箱验证、产品域名验证后,由验证流程自动写入(仅对已开启生产的门店生效,即 prodEnabled: true)。请求体中携带这两个字段时返回 200,门店数据不变,且不会附带 warnings 条目 —— 字段被静默丢弃。webhookSettings 兼容性警告
请求体中如出现webhookSettings 字段,该字段会被静默忽略,响应顶层会包含一个 warnings 数组。data.store 对象不受影响。
{
"data": { "store": { "...": "..." } },
"warnings": [
{
"message": "webhookSettings is no longer accepted on update-store; the field was ignored.",
"layer": "store",
"aiHint": "AI assistant: 'webhookSettings' is permanently removed (BREAKING 2026-05). Do not retry with this field. SDK users: upgrade to @waffo/pancake-ts >= 0.6.0 and call client.webhooks.add / update / remove instead of client.stores.update({ webhookSettings }). Direct API users: POST /api/actions/store/add-webhook to create a webhook, /update-webhook to modify, /remove-webhook to delete. Query the webhook list via GraphQL Store.storeWebhooks field, not via this endpoint."
}
]
}
错误响应
重试策略:4xx 一律不要重试 — 修正请求后重发。5xx 指数退避重试(起步 5s,最多 3 次)。
| 状态码 | errors[0].message | 含义 | 推荐处理 |
|---|---|---|---|
| 400 | Missing merchantId in request context | API Key 未解析出商户上下文 | 不要重试。检查 API Key 配置。 |
| 400 | Missing required field: id | 请求体未传 id | 修正输入后重新提交。 |
| 400 | Expected format: STO_xxx, got "<value>" | id 不是有效的 Store Short ID | 修正 id 后重新提交。 |
| 400 | Store name cannot be empty or contain only whitespace | trim() 后 name 为空 | 修正 name 后重新提交。 |
| 400 | Store name cannot exceed 48 characters | name 超过 48 字符 | 缩短 name 后重新提交。 |
| 400 | Store name cannot contain control characters | name 含控制字符 | 移除控制字符后重新提交。 |
| 400 | Invalid status, must be active, inactive or suspended | status 不在枚举内 | 改用 active、inactive 或 suspended。 |
| 400 | Invalid logo: must be a string or null | logo 既不是字符串也不是 null | 传字符串 URL 或 null 以清空。 |
| 403 | Not authorized to update this store | 调用方在该门店上的角色不是 owner/admin | 不要重试。改用具备权限的商户。 |
| 404 | Store not found | 该商户下不存在该门店 ID | 不要重试。校验 id。 |