Skip to content

Adobe's integration starter kit uses Adobe Developer App Builder to improve real-time connection reliability and reduce the time-to-market for integrations between Adobe Commerce and other back-office systems, such as ERPs, CRMs, and PIMs.

License

Notifications You must be signed in to change notification settings

adobe/commerce-integration-starter-kit

Commerce Integration Starter Kit

Node.js CI

Welcome to Adobe Commerce Integration Starter Kit.

Integrating an e-commerce platform with your ERP, OMS, or CRM is a mission-critical requirement. Companies can spend tens of thousands of dollars building these integrations. To reduce the cost of integrating with Enterprise Resource Planning (ERP) solutions and to improve the reliability of real-time connections, Adobe is introducing an integration starter kit for back-office integrations using Adobe Developer App Builder. The kit includes reference integrations for commonly used commerce data like orders, products, and customers. It also includes onboarding scripts and a standardized architecture for developers to build on following best practices.

The public documentation can be found at Adobe Developer Starter Kit docs…

Alt text

Prerequisites

Create App Builder project

Go to the Adobe developer console portal

  • Click on Create a new project from template
  • Select App Builder
  • Chose a name and title
  • Select stage workspace or create a new one
  • Add the following API services (select default Oauth server to server)
    • I/0 events
    • Adobe I/O Events for Adobe Commerce
    • I/O management API
  • Download the workspace configuration JSON file and save it as workspace.json in the ./scripts/onboarding/config starter kit folder because you will use it to configure Adobe IO Events in commerce afterward.

Configure a new Integration in commerce

Configure a new Integration to secure the calls to Commerce from App Builder using OAuth by following these steps:

  • In the Commerce Admin, navigate to System > Extensions > Integrations.
  • Click the Add New Integration button. The following screen displays Alt text
  • Give the integration a name. The rest of the fields can be left blank.
  • Select API on the left and grant access to all the resources. Alt text
  • Click Save.
  • In the list of integrations, activate your integration.
  • To configure the starter kit, you will need the integration details (consumer key, consumer secret, access token, and access token secret).

Install Commerce Eventing module (only required when running Adobe Commerce versions 2.4.4 or 2.4.5)

Install Adobe I/O Events for Adobe Commerce module in your commerce instance following this documentation

Note

By upgrading the Adobe I/O Events for Adobe Commerce module to version 1.6.0 or greater, you will benefit from some additional automated steps during onboarding.

Starter Kit first deploy & onboarding

Following the next steps, you will deploy and onboard the starter kit for the first time. The onboarding process sets up event providers and registrations based on your selection.

Download the project

  • Download and unzip the project
  • Copy the env file cp env.dist .env
  • Fill in the values following the comments on the env file.

Configure the project

Install the npm dependencies using the command:

npm install

This step will connect your starter kit project to the App builder project you created earlier. Ensure to select the proper Organization > Project > Workspace with the following commands:

aio login
aio console org select
aio console project select
aio console workspace select

Sync your local application with the App Builder project using the following command:

aio app use
# Choose the option 'm' (merge) 

Edit the file app.config.yaml if you want to deploy specific entities by commenting on the entities you don't need (e.g., product-backoffice if you don't need to sync products from an external back-office application):

application:
  runtimeManifest:
    packages:
      product-commerce:
        license: Apache-2.0
        actions:
          $include: ./actions/product/commerce/actions.config.yaml
    #  product-backoffice:
    #    license: Apache-2.0
    #    actions:
    #      $include: ./actions/product/external/actions.config.yaml
      customer-commerce:
        license: Apache-2.0
        actions:
          $include: ./actions/customer/commerce/actions.config.yaml
      customer-backoffice:
        license: Apache-2.0
        actions:
          $include: ./actions/customer/external/actions.config.yaml
    #  ...

Deploy

Run the following command to deploy the project; this will deploy the runtime actions needed for the onboarding step:

aio app deploy

You can confirm the success of the deployment in the Adobe Developer Console by navigating to the Runtime section on your workspace: Alt text

Onboarding

Configure the event registrations

By default, the registrations' config file creates all the registrations for all entities. You can edit the ./onboarding/custom/starter-kit-registrations.json file if you don't need a registration. If you don't want to receive events from commerce, remove commerce from the entity array; for backoffice updates, remove backoffice. e.g., In the previous onboarding step (Configure the project), we commented on the product-backoffice package. In this case, we have to remove backoffice from the product entity:

{
  "product": ["commerce"],
  "customer": ["commerce", "backoffice"],
  "order": ["commerce", "backoffice"],
  "stock": ["commerce", "backoffice"],
  "shipment": ["commerce", "backoffice"]
}

Execute the onboarding

This step will generate the IO Events providers and the registrations for your starter kit project. If your Commerce instance Adobe I/O Events for Adobe Commerce module version 1.6.0 or greater, the module will also be automatically configured by the onboarding script.
To start the process run the command:

npm run onboard

The console will return the provider's IDs and save this information:

  • You will need the commerce instance ID and provider ID to configure your commerce instance later.
  • You will need the backoffice provider id to send the events to the App builder project. e.g., of output:
Process of On-Boarding done successfully: [
  {
    key: 'commerce',
    id: 'THIS IS THE ID OF COMMERCE PROVIDER',
    instanceId: 'THIS IS THE INSTANCE ID OF COMMERCE PROVIDER',
    label: 'Commerce Provider'
  },
  {
    key: 'backoffice',
    id: 'THIS IS THE ID OF BACKOFFICE PROVIDER',
    instanceId: 'THIS IS THE INSTANCE ID OF BACKOFFICE PROVIDER',
    label: 'Backoffice Provider'
  }
]

Check your App developer console to confirm the creation of the registrations: Alt text

Complete the Adobe Commerce eventing configuration

Note

If your Commerce instance Adobe I/O Events for Adobe Commerce module version is 1.6.0 or greater and the onboarding script completed successfully, the following steps are not required. The onboarding script will configure the Adobe Commerce instance automatically. Follow the steps in the next section to validate that the configuration is correct or skip to the next section.

You will configure your Adobe Commerce instance to send events to your App builder project using the following steps

Configure Adobe I/O Events in Adobe Commerce instance

To configure the provider in Commerce, do the following:

  • In the Adobe Commerce Admin, navigate to Stores > Settings > Configuration > Adobe Services > Adobe I/O Events > General configuration. The following screen displays. Alt text
  • Select OAuth (Recommended) from the Adobe I/O Authorization Type menu.
  • Copy the contents of the <workspace-name>.json (Workspace configuration JSON you downloaded in the previous step Create app builder project) into the Adobe I/O Workspace Configuration field.
  • Copy the commerce provider instance ID you saved in the previous step [Execute the onboarding](#execute-the-onboarding) into the Adobe Commerce Instance ID` field.
  • Copy the commerce provider ID you saved in the previous step Execute the onboarding into the Adobe I/O Event Provider ID field.
  • Click Save Config.
  • Enable Commerce Eventing by setting the Enabled menu to Yes. (Note: You must enable cron so that Commerce can send events to the endpoint.)
  • Enter the merchant's company name in the Merchant ID field. You must use alphanumeric and underscores only.
  • In the Environment ID field, enter a temporary name for your workspaces while in development mode. When you are ready for production, change this value to a permanent value, such as Production.
  • (Optional) By default, if an error occurs when Adobe Commerce attempts to send an event to Adobe I/O, Commerce retries a maximum of seven times. To change this value, uncheck the Use system value checkbox and set a new value in the Maximum retries to send events field.
  • (Optional) By default, Adobe Commerce runs a cron job (clean_event_data) every 24 hours that delete event data three days old. To change the number of days to retain event data, uncheck the Use system value checkbox and set a new value in the Event retention time (in days) field.
  • Click Save Config.

Subscribe to events in Adobe Commerce instance

Note

If your Commerce instance Adobe I/O Events for Adobe Commerce module version is 1.6.0 or greater, run the commerce-event-subscribe script to automatically subscribe to the Commerce events in scripts/commerce-event-subscribe/config/commerce-event-subscribe.json

npm run commerce-event-subscribe

Otherwise, follow the steps below to subscribe to the events manually.

To subscribe to events, follow this documentation. For events of type 'plugin' you can also check this documentation.

Here are the events with the minimal required fields you need to subscribe to, it includes the REST API endpoints that could trigger this events:

Entity Event Required fields REST API Ref
Product observer.catalog_product_delete_commit_after sku product delete
Product observer.catalog_product_save_commit_after sku, created_at, updated_at product create / update
Customer observer.customer_save_commit_after created_at, updated_at customer create / update
Customer observer.customer_delete_commit_after entity_id customer delete
Customer group observer.customer_group_save_commit_after customer_group_code customer group create / update
Customer group observer.customer_group_delete_commit_after customer_group_code customer group delete
Order observer.sales_order_save_commit_after created_at, updated_at order update (hold, unhold, cancel, emails)
Stock observer.cataloginventory_stock_item_save_commit_after product_id product stock update

Development

Project source code structure

The starter kit provides boilerplate code for the synchronization across systems of the following entities:

  • Product
  • Customer
  • Customer Group
  • Stock
  • Order
  • Shipment

The synchronization is bidirectional by default: changes in Commerce are propagated to the external back-office application. application and the other way around.

The source code is organized following the file structure of a typical App Builder application, where the actions folder contains the source code for all the serverless actions.

actions folder structure

The actions folder contains:

  • an ingestion folder containing the source code for an alternative events ingestion endpoint.

  • a webhook folder containing the source for synchronous webhooks that could be called from Commerce.

  • a folder named after each entity being synchronized (e.g. customer, order, product).

entity folder structure

Each `entity folder follows a similar structure, and it contains folders named after each system being integrated, namely:

  • a commerce folder.

    This folder contains the runtime actions responsible for handling incoming events from Commerce and synchronizing the data with the 3rd-party external system.

  • an external folder.

    This folder contains the runtime actions responsible for handling incoming events from the 3rd-party external system and updating the data accordingly in Commerce.

commerce and external folders structure

The commerce and external folders follow a similar structure:

  • a consumer folder.

    This folder contains the code for the runtime action that routes incoming events to the action responsible for handling each event.

  • one or more folders named after an action (e.g. created, deleted, etc.)

    Each of these folders contains the code for the runtime action responsible for handling one particular event.

  • an actions.config.yaml.

    This file declares the runtime actions responsible for handling the events for an entity originating in a particular system.

Individual action folder structure

Each individual action folder contains the following files:

  • an index.js file.

    It contains the main method that gets invoked when handling an event and is responsible for coordinating the different activities involved in that handling, such as validating the incoming payload, transforming the payload to the target API, and interacting with the target API.

  • a validator.js file.

    It implements the logic to validate the incoming event payload.

    Actions in the external folder provide a sample implementation based on a JSON schema specified in the schema.json file.

  • a transformer.js file.

    It implements the logic to transform the incoming event payload to make it suitable for the target API being called to propagate the changes.

  • a sender.js file.

    It implements the logic to interact with the target API in order to get the changes propagated.

    The target API will be the Commerce API for actions in the external folder and the 3rd-party external API for actions in the commerce folder.

  • pre.js and post.js files

    These files provide convenient extension points to introduce custom business logic before and after interacting with the target API.

Pass env params to an action

You can pass values from the environment to the actionparams object following: Add your parameter to .env file:

HERE_YOUR_PARAM=any value

Pass the required parameters to the action by configuring them in the actions/{entity}/../actions.config.yaml under {action name} -> inputs as follows:

{action name}:
  function: commerce/{action name}/index.js
  web: 'no'
  runtime: nodejs:16
  inputs:
    LOG_LEVEL: debug
    HERE_YOUR_PARAM: $HERE_YOUR_PARAM_ENV
  annotations:
    require-adobe-auth: true
    final: true

This parameter should be accessible on the params object

async function main(params) {
  params.HERE_YOUR_PARAM
}

Different types of actions included in the starter kit

consumer and event handler actions are the two main types of actions defined by the starter kit to implement the business logic needed to synchronize data between the different systems being integrated.

Additionally, boilerplate code and samples for event ingestion and synchronous webhook actions are provided.

consumer action

This action is subscribed to a subset of events (typically all of them belonging to the same entity, e.g. product, although there are examples where it receives events from various entities belonging to the same “domain", e.g. order and shipment). When the event provider it is attached to receives an event, this runtime action will be automatically activated.

The main purpose of this action is to route the event received to the event handler action. Normally, this routing is determined by the name of the event received.

The response returned by a consumer action is expected to be consistent with the response received from the activation of the subsequent event handler action. For example, if the event handler action returns an HTTP/400 status, the consumer action is expected to respond with the same status.

When it receives an event that it does not know how to route, it is expected to return HTTP/400 status. This will prevent the event handling from being retried.

By default, the response of the consumer actions is the following:

  • success

    // ./actions/responses.js#successResponse
    return {
      statusCode: 200,
      body: {
        type: 'EVENT TYPE',
        response: {
          // Response returned by the event handler action
        }
      }
    }
  • failure

    // ./actions/responses.js#errorResponse
    return {
      error: {
        statusCode: 400, // 404, 500, etc,
        body : {
          error: 'YOUR ERROR MESSAGE'
        }
      }
    }

event handler action

This action implements the business logic to manage an individual event notifying about a change in one of the systems being integrated. Typically, its business logic includes an API call to propagate the changes to the other system being integrated.

The consumer action activates these event handler actions to delegate the handling of a particular event. This activation is done in a synchronous way.

The response returned by an event handler action is expected to include a statusCode attribute. This attribute allows the consumer action to propagate the response HTTP status code upstream so it properly reflects on the event registration Debug Tracing tab on the Adobe Developer Console.

By default, the response of the event handler actions is the following:

  • success

    // ./actions/responses.js#actionSuccessResponse
    return {
      statusCode: 200,
      body: {
        success: true,
        message: 'YOUR SUCCESS MESSAGE'
      }
    }
  • failure

    // ./actions/responses.js#actionErrorResponse
    return {
      statusCode: 400, // 404, 500, etc
      body: {
        success: false,
        error: 'YOUR ERROR MESSAGE'
      }
    }

event ingestion action

The source code for this action can be found at ./actions/ingestion.

This runtime action is provided as an alternative approach to deliver events to the integration if the 3rd-party back-office application cannot fulfill the Events Publishing API requirements.

Additional details can be found at this README

To get the URL of the webhook, run the following command:

aio runtime action get ingestion/webhook --url

By default, the response of the event ingestion actions is the following:

  • success

    // ./actions/responses.js#successResponse
    return {
      statusCode: 200,
      body: {
        type: 'EVENT TYPE',
        response: {
          success: true,
          message: 'Event published successfully'
        }
      }
    }
  • failure

    // ./actions/responses.js#errorResponse
    return {
      error: {
        statusCode: 400, // 404, 500, etc,
        body : {
          error: 'YOUR ERROR MESSAGE'
        }
      }
    }

synchronous webhook actions

The source code for these actions can be found at ./actions/webhook.

These runtime actions are meant to expose a webhook that can be invoked synchronously from Commerce in order to affect the behavior of a particular business flow.

The ./actions/webhook/check-stock folder provides a sample implementation of a synchronous webhook action. Additional details can be found at this README

To get the URL of the webhook, run the following command:

aio runtime action get webhook/check-stock --url

By default, the response of the synchronous webhook actions is the following:

  • success

    // ./actions/responses.js#webhookSuccessResponse
    return {
      statusCode: 200,
      body: {
        op: 'success'
      }
    }
  • failure

    // ./actions/responses.js#webhookSuccessResponse
    return {
      error: {
        statusCode: 200,
        body : {
          op: 'exception'
        }
      }
    }

Remember, these responses are adapted to Commerce webhook module; in case you want to use a different approach, you can change the response implementation in the code as you need.

starter kit info action

Warning
Please DO NOT DELETE this action; future functionalities planned for upcoming starter kit releases may stop working.

The source code for this action can be found at ./actions/starter-kit-info.

This runtime action, when invoked, returns information about the starter-kit used to develop the project, such as

  • the starter kit version, and
  • the configured event registrations

To get the URL of the webhook, run the following command:

aio runtime action get starter-kit/info --url

By default, the response of the starter kit info action is the following:

  • success

    // ./actions/responses.js#actionSuccessResponse
    return {
      statusCode: HTTP_OK,
      body: {
        success: true,
        registrations: 'REGISTERED REGISTRATIONS',
        starter_kit_version: 'M.m.p-beta'
      }
    }
  • failure

    // ./actions/responses.js#actionErrorResponse
    return {
      error: {
        statusCode: 400, // 404, 500, etc,
        body : {
          success: false,
          error: 'ERROR MESSAGE'
        }
      }
    }

Log management and forwarding

Application logs allow developers to debug an application in development as well as monitor it in production.

By default, the starter kit uses the AIO SDK to store logs in Adobe I/O Runtime. You can find additional details on this topic in Managing Application Logs.

The application logs can alternatively be forwarded to a customer-owned log management solution (such as Splunk, Azure, or New Relic). Use the comparison in When to use Log Forwarding to decide when to store logs in Adobe I/O Runtime and when to forward them to a log management platform.

If you are running your Adobe Commerce instance in the cloud, you already have a New Relic instance provisioned for you. The Forwarding Logs to New Relic page describes the steps to set up the starter kit to forward logs to New Relic.

Prevent secrets from leaking in logs.

The stringParameters in the ./actions/utils.js file can be used to avoid secrets leaking when logging the parameters received by a runtime action. It will replace

  • the authorization header value with <hidden>, and
  • any parameters containing a term present in the hidden array with <hidden>

The default parameters to be hidden are:

const hidden = [
  'secret',
  'token'
]

Adjust these values to hide secrets passed as params to your runtime actions if needed.

Testing

The starter kit provides unit tests for most of the runtime actions it includes. These tests can be located in the ./test/actions folder.

Additionally, unit tests for the onboarding script can be found in the .test/onboarding folder.

The coverage report could be found in the .test/test-coverage folder.

You can find more details about unit testing and an example in Lesson 3: Testing a Serverless Action.

How to subscribe to a new event

The starter kit comes with predefined events for each entity. Sometimes, you may need to add a new event to an entity, e.g., a customer. To do this, follow the next steps:

  • Add the event to the ./onboarding/config/events.json file under the related entity flow; for example, if the event is related to a customer and is coming from commerce, you should add it under entity customer -> commerce. e.g.,
        "customer": {
          "commerce": [
            "com.adobe.commerce.observer.customer_save_commit_after",
            "com.adobe.commerce.observer.customer_delete_commit_after",
            "com.adobe.commerce.observer.customer_group_save_commit_after",
            "com.adobe.commerce.observer.customer_group_delete_commit_after",
            "com.adobe.commerce.THE_NEW_CUSTOMER_EVENT"
          ],
        ...
        }
  • Run the onboarding script:
    npm run onboard
  • In the actions/{entity}/{flow} directory, add the action that will handle this event, e.g., actions/customer/commerce/NEW_OPERATION/index.js
  • Configure the newly created operation action in the actions.config.yaml file inside the actions/{entity}/{flow} folder, e.g.:
    NEW_OPERATION:
      function: NEW_OPERATION/index.js
      web: 'no'
      runtime: nodejs:16
      inputs:
        LOG_LEVEL: debug
      annotations:
        require-adobe-auth: true
        final: true
  • Add a new case to the switch statement in the consumer of the entity flow actions/{entity}/{flow}/consumer/index.js:
      case 'com.adobe.commerce.observer.THE_NEW_CUSTOMER_EVENT': {
        logger.info('Invoking THE NEW OPERATION')
        const res = await openwhiskClient.invokeAction('customer-commerce/NEW_OPERATION', params.data.value)
        response = res?.response?.result?.body
        statusCode = res?.response?.result?.statusCode
        break
      }
  • Deploy the changes: aio app deploy

With these steps, you can consume the new event you added to the project. If you want to change an existing event, make the changes in the same places:

  • Edit the event in the ./onboarding/config/events.json file
  • Modify the event in the consumer of the flow where the event belongs
  • Make changes to the operation action invoked by the consumer switch case.
  • Deploy your changes

Included actions documentation

External back-office ingestion webhook

Product entity

Commerce to third party

Third party to Commerce

Customer entity

Commerce to third party

Third party to Commerce

Order entity

Commerce to third party

Third party to Commerce

Stock entity

Commerce to third party

Third party to Commerce

References

Contributing

Contributions are welcomed! Read the Contributing Guide for more information.

About

Adobe's integration starter kit uses Adobe Developer App Builder to improve real-time connection reliability and reduce the time-to-market for integrations between Adobe Commerce and other back-office systems, such as ERPs, CRMs, and PIMs.

Resources

License

Code of conduct

Security policy

Stars

Watchers

Forks

Packages

No packages published