commerce-app-eventing

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Configure Commerce App Eventing

配置Commerce应用事件处理

Adds or modifies event sources — Commerce-native events or external events — in an existing
app.commerce.config.ts
. Extensibility domains other than eventing (webhooks, business config) are added separately via their own skills.
在现有的
app.commerce.config.ts
中添加或修改事件源——Commerce原生事件或外部事件。事件处理之外的扩展领域(如webhooks、业务配置)需通过各自的技能单独添加。

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.
  • Actions can be authored in TypeScript only once the project has the TypeScript build setup (
    webpack-config.cjs
    + root
    tsconfig.json
    ) that
    init
    scaffolds for a TypeScript Commerce config — see
    commerce-app-init
    . Otherwise, author actions in JavaScript.
  • Ensure
    CloudIntegrationSDK
    (I/O Events) and
    commerceeventing
    (Adobe I/O Events for Adobe Commerce) are subscribed in the Developer Console workspace:
    1. List currently subscribed services:
      sh
      aio console workspace api list --projectName <project> --workspaceName <workspace> --json
    2. If either service is missing, re-subscribe with the full merged set of service codes (existing + missing).
      aio console workspace api add
      replaces the subscription list — omitting a currently-subscribed service will remove it.
      sh
      aio console workspace api add \
        --projectName <project> \
        --workspaceName <workspace> \
        --service-code <existing-codes>,CloudIntegrationSDK,commerceeventing \
        --json
      If the command fails with "product profile required" for
      commerceeventing
      , ask the user for the profile name and retry with
      --license-config commerceeventing=<profile>
      .
  • 验证应用已搭建并初始化,而非仅存在配置文件。需同时满足:
    • 项目根目录下存在
      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
    再继续。初始化操作是幂等的——它会找到现有配置,跳过交互式提示,安装依赖并生成项目文件。
  • 只有当项目具备
    init
    为TypeScript Commerce配置搭建的TypeScript构建环境(
    webpack-config.cjs
    + 根目录
    tsconfig.json
    )时,才能用TypeScript编写Action,详情见
    commerce-app-init
    。否则请用JavaScript编写Action。
  • 确保Developer Console工作区已订阅
    CloudIntegrationSDK
    (I/O Events)和
    commerceeventing
    (Adobe I/O Events for Adobe Commerce):
    1. 列出当前已订阅的服务:
      sh
      aio console workspace api list --projectName <project> --workspaceName <workspace> --json
    2. 如果任一服务缺失,使用完整的合并服务代码集(现有代码+缺失代码)重新订阅。
      aio console workspace api add
      会替换订阅列表——遗漏当前已订阅的服务会导致其被移除。
      sh
      aio console workspace api add \
        --projectName <project> \
        --workspaceName <workspace> \
        --service-code <existing-codes>,CloudIntegrationSDK,commerceeventing \
        --json
      如果命令因
      commerceeventing
      的“product profile required”失败,请向用户索要配置文件名称并添加
      --license-config commerceeventing=<profile>
      参数后重试。

Step 1 — Understand intent

步骤1 — 明确需求

Ask whether the user wants to configure Commerce events, external events, or both:
  • Commerce events (
    eventing.commerce
    ): native Commerce events. Names follow
    plugin.<segments>
    or
    observer.<segments>
    .
  • External events (
    eventing.external
    ): events from third-party systems (e.g., ERP, CRM). Names are free-form (
    [\w\-_.]+
    ).
For each event source, gather:
  • Provider label, description, and optional key
  • For each event: name, label, description, and which runtime action(s) should handle it (format:
    <package>/<action>
    )
  • For Commerce events only: fields to extract from the event payload (empty array captures the full payload), and any optional filter rules
  • Optionally, which Commerce environments the event applies to (
    env
    )
询问用户是否要配置Commerce事件、外部事件,或两者都配置:
  • Commerce事件
    eventing.commerce
    ):Commerce原生事件。名称遵循
    plugin.<segments>
    observer.<segments>
    格式。
  • 外部事件
    eventing.external
    ):来自第三方系统(如ERP、CRM)的事件。名称为自由格式(
    [\w\-_.]+
    )。
针对每个事件源,收集以下信息:
  • 提供商标签、描述及可选的键值
  • 每个事件的名称、标签、描述,以及应处理该事件的运行时Action(格式:
    <package>/<action>
  • 仅针对Commerce事件:从事件负载中提取的字段(空数组表示捕获完整负载),以及可选的过滤规则
  • 可选:事件适用的Commerce环境(
    env

Step 2 — Derive config values

步骤2 — 推导配置值

Apply the following validation rules before writing the config. Surface any issues to the user before proceeding.
FieldConstraint
Commerce event nameStarts with
plugin.
or
observer.
; each segment matches
[a-z_]+
; max 180 chars
External event name
[\w\-_.]+
; max 180 chars
Provider labelMax 100 chars
Provider descriptionMax 255 chars
Provider keyOptional; alphanumeric + hyphens only; max 50 chars
Event labelMax 100 chars
Event descriptionMax 255 chars
Field name
[a-zA-Z0-9_\-.[\]]+
or
*
Rule operator
greaterThan
,
lessThan
,
equal
,
regex
,
in
, or
onChange
Runtime action
<package>/<action>
(e.g.,
my-package/handle-order-placed
)
Event env (optional)Non-empty array of
"paas"
/
"saas"
; omitted = all environments
在写入配置前应用以下验证规则。在继续操作前向用户说明任何问题。
字段约束条件
Commerce事件名称
plugin.
observer.
开头;每个分段匹配
[a-z_]+
;最大长度180字符
外部事件名称
[\w\-_.]+
;最大长度180字符
提供商标签最大长度100字符
提供商描述最大长度255字符
提供商键值可选;仅包含字母数字和连字符;最大长度50字符
事件标签最大长度100字符
事件描述最大长度255字符
字段名称
[a-zA-Z0-9_\-.[\]]+
*
规则运算符
greaterThan
,
lessThan
,
equal
,
regex
,
in
, 或
onChange
运行时Action
<package>/<action>
(例如
my-package/handle-order-placed
事件环境(可选)非空数组,元素为
"paas"
/
"saas"
;省略则表示适用于所有环境

Step 3 — Update
app.commerce.config.ts

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

Add or merge
eventing.commerce
and/or
eventing.external
into the existing config, preserving all other domains. If the config already has an
eventing
key, extend it rather than replacing it.
Minimal example (Commerce event):
ts
eventing: {
  commerce: [{
    provider: { label: "Commerce Events Provider", description: "..." },
    events: [{
      name: "plugin.order_placed",          // plugin.<segments> or observer.<segments>
      label: "Order Placed",
      description: "Triggered when a customer places an order.",
      fields: [{ name: "order_id" }],       // empty array = full payload; Commerce events only
      runtimeActions: ["my-package/handle-order-placed"], // <package>/<action>
    }],
  }],
}
See assets/eventing-config.ts for the full reference including external event sources.
eventing.commerce
和/或
eventing.external
添加或合并到现有配置中,保留所有其他配置域。如果配置中已有
eventing
键,请扩展它而非替换。
最简示例(Commerce事件):
ts
eventing: {
  commerce: [{
    provider: { label: "Commerce Events Provider", description: "..." },
    events: [{
      name: "plugin.order_placed",          // plugin.<segments> or observer.<segments>
      label: "Order Placed",
      description: "Triggered when a customer places an order.",
      fields: [{ name: "order_id" }],       // empty array = full payload; Commerce events only
      runtimeActions: ["my-package/handle-order-placed"], // <package>/<action>
    }],
  }],
}
完整参考示例(包含外部事件源)请见assets/eventing-config.ts

Creating the handler action

创建处理程序Action

For events that reference runtime actions via
runtimeActions
, create the action file under
src/actions/
and register it in
app.config.yaml
.
对于通过
runtimeActions
引用运行时Action的事件,需在
src/actions/
下创建Action文件并在
app.config.yaml
中注册。

Register the action

注册Action

Add a user-defined package to
src/commerce-extensibility-1/ext.config.yaml
alongside the existing
app-management
package. Use any name except
app-management
(reserved by the framework):
yaml
undefined
src/commerce-extensibility-1/ext.config.yaml
中添加用户自定义包,与现有
app-management
包并列。包名不能为
app-management
(框架保留名):
yaml
undefined

src/commerce-extensibility-1/ext.config.yaml

src/commerce-extensibility-1/ext.config.yaml

(add below the auto-generated app-management package)

(添加到自动生成的app-management包下方)

runtimeManifest: packages: app-management: # ... auto-generated — do not edit my-app: # your package name — any name except "app-management" actions: handle-order-placed: function: actions/handle-order-placed/index.js # relative to src/commerce-extensibility-1/ web: "no" runtime: nodejs:24 annotations: require-adobe-auth: false

The `<package>/<action>` format in `runtimeActions` maps directly: `my-app/handle-order-placed` → package `my-app`, action `handle-order-placed`.
runtimeManifest: packages: app-management: # ... 自动生成内容 — 请勿编辑 my-app: # 你的包名 — 除"app-management"外的任意名称 actions: handle-order-placed: function: actions/handle-order-placed/index.js # 相对于src/commerce-extensibility-1/的路径 web: "no" runtime: nodejs:24 annotations: require-adobe-auth: false

`runtimeActions`中的`<package>/<action>`格式直接对应:`my-app/handle-order-placed` → 包`my-app`,Action`handle-order-placed`。

Handler skeleton

处理程序骨架

Event handlers receive a CloudEvents-shaped payload. The event data lives in
params.data
.
typescript
// src/commerce-extensibility-1/actions/handle-order-placed/index.ts
export async function main(params: Record<string, unknown>) {
  const data = params.data as Record<string, unknown>;
  // data contains the fields declared in the event's `fields` array
  // (or the full payload if fields is empty)

  const orderId = data["order_id"];

  // process the event ...

  return { statusCode: 200, body: { processed: true } };
}
事件处理程序接收CloudEvents格式的负载。事件数据位于
params.data
中。
typescript
// src/commerce-extensibility-1/actions/handle-order-placed/index.ts
export async function main(params: Record<string, unknown>) {
  const data = params.data as Record<string, unknown>;
  // data包含事件`fields`数组中声明的字段
  // (如果fields为空则包含完整负载)

  const orderId = data["order_id"];

  // 处理事件...

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

Step 4 — Validate

步骤4 — 验证

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 config field.
构建项目以确认更新后的配置有效:
sh
aio app build
构建失败时的验证错误会直接指向有问题的配置字段。

Common Issues

常见问题

  • External event has
    fields
    : The
    fields
    property is only valid on Commerce events; external events don't support it.
  • runtimeActions
    format error
    : Must be
    <package>/<action>
    . Both parts are lowercase alphanumeric + hyphens only.
  • app-management
    package name conflict
    : The framework generates this package in
    ext.config.yaml
    on every build. Use any other name for your own actions.
  • Function path is relative to
    src/commerce-extensibility-1/
    : Do not use
    src/...
    or project-root-relative paths.
    actions/handle-order-placed/index.js
    resolves correctly;
    src/commerce-extensibility-1/actions/handle-order-placed/index.js
    does not.
  • defineConfig
    not found
    : Ensure
    @adobe/aio-commerce-lib-app
    is installed and
    defineConfig
    is imported from
    @adobe/aio-commerce-lib-app/config
    .
  • Build fails on missing action: A runtime action referenced in
    runtimeActions
    must exist in the project. Check the action files under
    src/commerce-extensibility-1/actions/
    and create any missing stubs.
  • 外部事件包含
    fields
    属性
    fields
    属性仅对Commerce事件有效;外部事件不支持该属性。
  • runtimeActions
    格式错误
    :必须为
    <package>/<action>
    格式。两部分均只能包含小写字母数字和连字符。
  • app-management
    包名冲突
    :框架会在每次构建时在
    ext.config.yaml
    中生成该包。请使用其他名称命名你的自定义Action。
  • 函数路径需相对于
    src/commerce-extensibility-1/
    :请勿使用
    src/...
    或项目根目录相对路径。
    actions/handle-order-placed/index.js
    路径有效;
    src/commerce-extensibility-1/actions/handle-order-placed/index.js
    路径无效。
  • 找不到
    defineConfig
    :确保已安装
    @adobe/aio-commerce-lib-app
    并从
    @adobe/aio-commerce-lib-app/config
    导入
    defineConfig
  • 构建因缺失Action失败
    runtimeActions
    中引用的运行时Action必须存在于项目中。检查
    src/commerce-extensibility-1/actions/
    下的Action文件,创建任何缺失的存根文件。

Quality Bar

质量标准

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

Chaining

后续操作

After
aio app build
passes:
  • Add webhook interception — invoke
    commerce-app-webhooks
    to intercept Commerce operations
  • Add merchant settings — invoke
    commerce-app-business-config
    to expose configurable settings in Commerce Admin
  • Extend the Admin UI — invoke
    commerce-app-admin-ui
    to add custom columns, mass actions, or menu entries in Commerce Admin
  • Add persistent storage — invoke
    commerce-app-storage
    to back event handlers with queryable DB storage
aio app build
通过后:
  • 添加webhook拦截 — 调用
    commerce-app-webhooks
    拦截Commerce操作
  • 添加商家设置 — 调用
    commerce-app-business-config
    在Commerce Admin中暴露可配置的设置
  • 扩展Admin UI — 调用
    commerce-app-admin-ui
    在Commerce Admin中添加自定义列、批量操作或菜单项
  • 添加持久化存储 — 调用
    commerce-app-storage
    为事件处理程序提供可查询的数据库存储支持

References

参考资料

  • assets/eventing-config.ts — Reference config showing both Commerce and external event source shapes
  • assets/eventing-config.ts — 展示Commerce和外部事件源结构的参考配置