commerce-app-business-config

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Configure Commerce App Business Config

配置Adobe Commerce应用业务配置

Adds or modifies the
businessConfig.schema
array in an existing
app.commerce.config.ts
. Each entry in the schema defines one merchant-configurable setting that Commerce Admin will render as a UI field. Other extensibility domains (webhooks, events) are added separately via their own skills.
在现有的
app.commerce.config.ts
中添加或修改
businessConfig.schema
数组。 schema中的每个条目定义一个商家可配置的设置,Commerce Admin会将其渲染为UI字段。 其他扩展领域(webhooks、events)需通过各自的skill单独添加。

Prerequisites

前提条件

  • Verify the app is scaffolded and initialized, not merely that the config exists. Require both:
    • app.commerce.config.ts
      present in the project root, and
    • the project initialized — signalled by the generated
      src/commerce-extensibility-1/
      directory and installed
      node_modules
      (the
      @adobe/aio-commerce-lib-app
      dependency).
  • If
    app.commerce.config.ts
    is missing, stop and invoke
    commerce-app-init
    first (it writes the config, then runs init).
  • If the config is present but the project is not initialized (no
    src/commerce-extensibility-1/
    or
    node_modules
    ), run
    npx @adobe/aio-commerce-lib-app init
    before continuing. Init is idempotent — it finds the existing config, skips the interactive prompts, installs dependencies, and generates the project files.
  • 验证应用已搭建并初始化,而非仅存在配置文件。需同时满足:
    • 项目根目录下存在
      app.commerce.config.ts
    • 项目已完成初始化——标志为生成了
      src/commerce-extensibility-1/
      目录并安装了
      node_modules
      (包含
      @adobe/aio-commerce-lib-app
      依赖)。
  • 如果缺少
    app.commerce.config.ts
    ,请先停止并调用
    commerce-app-init
    (它会写入配置文件,然后执行初始化)。
  • 如果配置文件存在但项目未初始化(无
    src/commerce-extensibility-1/
    node_modules
    ),请先运行
    npx @adobe/aio-commerce-lib-app init
    再继续。初始化是幂等操作——它会找到现有配置,跳过交互式提示,安装依赖并生成项目文件。

Step 1 — Understand intent

步骤1 — 明确需求

For each setting the user wants to expose, gather:
  • Name — machine identifier for the field (used as the config key read by the app at runtime)
  • Type — one of:
    list
    ,
    text
    ,
    password
    ,
    email
    ,
    url
    ,
    tel
    ,
    boolean
  • Label (optional) — human-readable label shown in Admin
  • Description (optional) — help text shown alongside the field in Admin
  • Default value (optional, type-dependent — see constraints in Step 2)
  • For
    list
    fields additionally:
    selectionMode
    (
    "single"
    or
    "multiple"
    ) and
    options
    (each with a
    label
    and
    value
    string)
针对用户希望展示的每个设置,收集以下信息:
  • 名称——字段的机器标识符(用作应用运行时读取的配置键)
  • 类型——可选值:
    list
    text
    password
    email
    url
    tel
    boolean
  • 标签(可选)——在Admin中显示的可读标签
  • 描述(可选)——在Admin中显示在字段旁的帮助文本
  • 默认值(可选,取决于类型——见步骤2中的约束)
  • 对于
    list
    字段,额外需要:
    selectionMode
    "single"
    "multiple"
    )和**
    options
    **(每个选项包含
    label
    value
    字符串)

Step 2 — Derive config values

步骤2 — 生成配置值

Apply the following per-type validation rules before writing. Surface any issues to the user before proceeding.
FieldConstraint
name
Required, non-empty string
type
Required; one of
list
,
text
,
password
,
email
,
url
,
tel
,
boolean
label
Optional string
description
Optional string
list.selectionMode
Required for list fields:
"single"
or
"multiple"
list.options
Required for list fields; each option needs both
label
and
value
strings
list/single
default
Required; must match one of the option
value
strings (non-empty)
list/multiple
default
Optional array of strings (defaults to
[]
); each element must match an option value
text
default
Optional string (defaults to
""
)
password
default
Must be
""
— any non-empty default is rejected to prevent secrets in config
email
default
Optional;
""
or a fully valid email address
url
default
Optional;
""
or a fully valid absolute URL
tel
default
Optional;
""
or matches
/^\+?[0-9\s\-()]+$/
(digits, spaces, hyphens, parens, optional
+
)
boolean
default
Optional boolean (defaults to
false
)
businessConfig.schema
must contain at least one field — an empty array is rejected at build time.
在写入前应用以下针对不同类型的验证规则。在继续前向用户指出所有问题。
字段约束条件
name
必填,非空字符串
type
必填;可选值为
list
text
password
email
url
tel
boolean
label
可选字符串
description
可选字符串
list.selectionMode
列表字段必填:
"single"
"multiple"
list.options
列表字段必填;每个选项需同时包含
label
value
字符串
list/single
默认值
必填;必须与某个选项的
value
字符串匹配(非空)
list/multiple
默认值
可选字符串数组(默认值为
[]
);每个元素必须与某个选项的value匹配
text
默认值
可选字符串(默认值为
""
password
默认值
必须为
""
——任何非空默认值都会被拒绝,以避免在配置中存储机密信息
email
默认值
可选;
""
或完全有效的邮箱地址
url
默认值
可选;
""
或完全有效的绝对URL
tel
默认值
可选;
""
或匹配正则表达式
/^\+?[0-9\s\-()]+$/
(数字、空格、连字符、括号,可选前缀
+
boolean
默认值
可选布尔值(默认值为
false
businessConfig.schema
必须包含至少一个字段——空数组会在构建时被拒绝。

Step 3 — Update
app.commerce.config.ts

步骤3 — 更新
app.commerce.config.ts

Add (or merge into) the top-level
businessConfig.schema
array, preserving all other domains. If the config already has a
businessConfig
key, append to
businessConfig.schema
rather than replacing it.
Minimal examples:
ts
businessConfig: {
  schema: [
    // Password (masked input — API keys, secrets)
    { name: "api_key", type: "password", label: "API Key", default: "" },

    // Single-select list
    {
      name: "region", type: "list", selectionMode: "single",
      label: "Region",
      options: [{ label: "EU", value: "eu" }, { label: "US", value: "us" }],
      default: "eu",   // required; must match an option value
    },

    // Boolean toggle
    { name: "debug_mode", type: "boolean", label: "Enable Debug Mode", default: false },

    // Dynamic list — options resolved at runtime via a factory that receives the action's params.
    // Required `default` factory for single-select; optional for multiple (falls back to []).
    {
      name: "paymentMethod", type: "dynamicList", selectionMode: "single",
      label: "Default Payment Method",
      options: async (params) => {
        const methods = await fetchPaymentMethods(params.SOME_API_KEY);
        return methods.map((m) => ({ label: m.title, value: m.code }));
      },
      default: (resolvedOptions) => resolvedOptions[0].value,
    },
  ],
}
See assets/business-config.ts for the full reference showing all field types.
添加(或合并到)顶层的
businessConfig.schema
数组,保留所有其他领域的配置。如果配置文件已存在
businessConfig
键,请追加到
businessConfig.schema
而非替换它。
最简示例:
ts
businessConfig: {
  schema: [
    // 密码(掩码输入——API密钥、机密信息)
    { name: "api_key", type: "password", label: "API Key", default: "" },

    // 单选列表
    {
      name: "region", type: "list", selectionMode: "single",
      label: "Region",
      options: [{ label: "EU", value: "eu" }, { label: "US", value: "us" }],
      default: "eu",   // 必填;必须与某个选项的value匹配
    },

    // 布尔开关
    { name: "debug_mode", type: "boolean", label: "Enable Debug Mode", default: false },

    // 动态列表——选项通过接收action参数的工厂在运行时解析。
    // 单选列表必填`default`工厂;多选列表可选(默认回退到[])。
    {
      name: "paymentMethod", type: "dynamicList", selectionMode: "single",
      label: "Default Payment Method",
      options: async (params) => {
        const methods = await fetchPaymentMethods(params.SOME_API_KEY);
        return methods.map((m) => ({ label: m.title, value: m.code }));
      },
      default: (resolvedOptions) => resolvedOptions[0].value,
    },
  ],
}
查看assets/business-config.ts获取展示所有字段类型的完整参考示例。

Step 4 — Register the extension point

步骤4 — 注册扩展点

Run init so that
commerce/configuration/1
is added to
app.config.yaml
and
install.yaml
, and the required
@adobe/aio-commerce-lib-config
dependency is installed. This is idempotent — safe to run even if the extension is already registered.
sh
npx @adobe/aio-commerce-lib-app init
运行init命令,将
commerce/configuration/1
添加到
app.config.yaml
install.yaml
中,并安装所需的
@adobe/aio-commerce-lib-config
依赖。此操作是幂等的——即使扩展已注册,运行该命令也是安全的。
sh
npx @adobe/aio-commerce-lib-app init

Step 5 — Validate

步骤5 — 验证

Build the project to confirm the updated config is valid:
sh
aio app build
A build failure with a validation error points directly to the offending field.
构建项目以确认更新后的配置有效:
sh
aio app build
如果构建失败并出现验证错误,会直接指向有问题的字段。

Reading config in runtime actions

在运行时action中读取配置

Use
@adobe/aio-commerce-lib-config
to read the values merchants set in Commerce Admin. The library must be initialized with the generated schema on every action invocation before any config call.
使用
@adobe/aio-commerce-lib-config
读取商家在Commerce Admin中设置的值。 在每次action调用时,必须先使用生成的schema初始化该库,才能调用任何配置相关方法。

Basic pattern

基础模式

typescript
import {
  initialize,
  getConfigurationByKey,
  getConfiguration,
  byCodeAndLevel,
} from "@adobe/aio-commerce-lib-config";
// Schema is generated by `aio app build` into .generated/configuration-schema.json
// under the commerce-configuration-1 extension; adjust the relative path for your action.
import schema from "../../.generated/configuration-schema.json" with { type: "json" };

export async function main(params) {
  await initialize({ schema });

  // Read a single field — config is null if the key has never been set
  const { config } = await getConfigurationByKey(
    "api_key", // the `name` from your schema
    byCodeAndLevel("global", "global"), // scope
  );
  const apiKey = config?.value ?? "";

  // Read all fields for a scope
  const { config: allConfig } = await getConfiguration(
    byCodeAndLevel("global", "global"),
  );
  // allConfig is an array of { name, value, origin } entries

  return { statusCode: 200, body: { success: true } };
}
typescript
import {
  initialize,
  getConfigurationByKey,
  getConfiguration,
  byCodeAndLevel,
} from "@adobe/aio-commerce-lib-config";
// Schema由`aio app build`生成到commerce-configuration-1扩展下的.generated/configuration-schema.json文件中;根据你的action调整相对路径。
import schema from "../../.generated/configuration-schema.json" with { type: "json" };

export async function main(params) {
  await initialize({ schema });

  // 读取单个字段——如果键从未被设置,config为null
  const { config } = await getConfigurationByKey(
    "api_key", // 你的schema中的`name`
    byCodeAndLevel("global", "global"), // 作用域
  );
  const apiKey = config?.value ?? "";

  // 读取某个作用域下的所有字段
  const { config: allConfig } = await getConfiguration(
    byCodeAndLevel("global", "global"),
  );
  // allConfig是包含{ name, value, origin }条目的数组

  return { statusCode: 200, body: { success: true } };
}

Scope selectors

作用域选择器

SelectorWhen to use
byCodeAndLevel("global", "global")
App-wide settings — applies to all stores
byCodeAndLevel(storeCode, "store_view")
Per store view (most specific)
byCode(storeCode)
Resolves using the default level for the scope
byScopeId(scopeId)
When you have the scope's numeric ID from Commerce
Values inherit from parent scopes — a field not set on
store_view
falls back to
store
,
website
, then
global
.
选择器使用场景
byCodeAndLevel("global", "global")
应用级设置——适用于所有店铺
byCodeAndLevel(storeCode, "store_view")
按店铺视图(最具体的作用域)设置
byCode(storeCode)
使用作用域的默认级别解析配置
byScopeId(scopeId)
当你拥有Commerce中作用域的数字ID时
值会从父作用域继承——未在
store_view
级别设置的字段会回退到
store
website
,最后是
global
级别。

Password fields

密码字段

aio app build
generates
AIO_COMMERCE_CONFIG_ENCRYPTION_KEY
automatically into
.env
the first time it encounters a password field (and validates it on subsequent builds). No manual setup needed.
To decrypt values at runtime, the key must be available to the action. Wire it as an input in the action's
ext.config.yaml
:
yaml
inputs:
  AIO_COMMERCE_CONFIG_ENCRYPTION_KEY: $AIO_COMMERCE_CONFIG_ENCRYPTION_KEY
With the key in place,
getConfigurationByKey
returns the plaintext value — no extra decryption code needed.
aio app build
首次遇到密码字段时,会自动在
.env
中生成
AIO_COMMERCE_CONFIG_ENCRYPTION_KEY
(并在后续构建时验证它)。无需手动设置。
要在运行时解密值,该密钥必须对action可用。在action的
ext.config.yaml
中将其作为输入配置:
yaml
inputs:
  AIO_COMMERCE_CONFIG_ENCRYPTION_KEY: $AIO_COMMERCE_CONFIG_ENCRYPTION_KEY
密钥配置完成后,
getConfigurationByKey
会返回明文值——无需额外的解密代码。

Common Issues

常见问题

  • list/single
    default missing
    : Single-select list fields require a
    default
    — it can't be omitted. It must exactly match one of the option
    value
    strings.
  • defineConfig
    not found
    : Ensure
    @adobe/aio-commerce-lib-app
    is installed and
    defineConfig
    is imported from
    @adobe/aio-commerce-lib-app/config
    .
  • list/single
    默认值缺失
    :单选列表字段必须设置
    default
    ——不能省略。它必须完全匹配某个选项的
    value
    字符串。
  • 找不到
    defineConfig
    :确保已安装
    @adobe/aio-commerce-lib-app
    ,并从
    @adobe/aio-commerce-lib-app/config
    导入
    defineConfig

Quality Bar

质量标准

  • aio app build
    completes without errors
  • aio app build
    执行完成且无错误

Chaining

后续操作

After
aio app build
passes:
  • Add webhook interceptors — invoke
    commerce-app-webhooks
    to intercept Commerce operations before or after they execute
  • Add event subscriptions — invoke
    commerce-app-eventing
    to subscribe to Commerce or external events
  • Extend the Admin UI — invoke
    commerce-app-admin-ui
    to add custom columns, mass actions, order view buttons, or menu entries in Commerce Admin
aio app build
通过后:
  • 添加webhook拦截器——调用
    commerce-app-webhooks
    以在Commerce操作执行前后拦截它们
  • 添加事件订阅——调用
    commerce-app-eventing
    以订阅Commerce或外部事件
  • 扩展Admin UI——调用
    commerce-app-admin-ui
    以在Commerce Admin中添加自定义列、批量操作、订单视图按钮或菜单项

References

参考资料

  • assets/business-config.ts — Reference config showing all field types with inline constraint comments
  • assets/business-config.ts——展示所有字段类型并附带内联约束注释的参考配置