Commerce Connector Custom Processor Developer Guide

TABLE OF CONTENTS

1. Overview

Custom Processor Extensibility allows developers to execute custom business logic during Commerce Connector transmission execution.

Custom processors are developed externally in a Custom API project by referencing the Commerce Connector SDK and implementing the IBaseProcessor interface. A processor can execute custom logic before or after a transmission step, validate data, enrich execution results, modify output data, and integrate with platform services through Dependency Injection.

Once developed, the processor assembly is deployed using the CLI deploy extension command. After deployment, the processor can be configured and used within Commerce Connector transmission workflows.


2. How to Use Custom Processor Extensibility

2.1 Create a New Custom Processor Class

Custom processors should be created in a separate class library project within the Custom API solution. This keeps custom processing logic isolated from the main application code.

A suitable project name can be used based on the implementation or client requirement.

Examples

  • Custom.Libraries.DataExchange
  • Znode.Libraries.DataExchange.Custom
  • <ClientName>.DataExchange.Custom

The custom processor project must reference the Commerce Connector SDK package.

To create a new processor, add a new class and implement the IBaseProcessor interface.

Example

using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading.Tasks;
using Znode.Libraries.CommerceConnector.SDK;
using Znode.Libraries.Common.Logger;

namespace Custom.Libraries.DataExchange
{
    public class DummyMultiStepProcessor : IBaseProcessor
    {
        protected readonly IServiceProvider _serviceProvider;
        private readonly IZnodeLogging _znodeLogging;

        public DummyMultiStepProcessor(IServiceProvider serviceProvider)
        {
            _serviceProvider = serviceProvider;
            _znodeLogging = _serviceProvider.GetService<IZnodeLogging>();
        }

        public async Task BeforeStepAsync(
            List<TransmissionStepModel> context,
            TransmissionStepModel step,
            List<TransmissionStepExecutionOutput> executionOutputs)
        {
            await Task.CompletedTask;
        }

        public async Task AfterStepAsync(
            List<TransmissionStepModel> context,
            TransmissionStepModel step,
            List<TransmissionStepExecutionOutput> executionOutputs)
        {
            await Task.CompletedTask;
        }
    }
}

2.2 Add Logging in a Custom Processor

Custom processors can write logs using IZnodeLogging.

The logger can be resolved using Dependency Injection through the provided IServiceProvider.

Example

public DummyMultiStepProcessor(IServiceProvider serviceProvider)
{
    _serviceProvider = serviceProvider;
    _znodeLogging = _serviceProvider.GetService<IZnodeLogging>();
}

Writing logs

_znodeLogging.LogMessage(
    "DummyMultiStepProcessor called",
    "DummyMultiStepProcessor",
    TraceLevel.Info);

Logs can be written for:

  • Before step execution
  • After step execution
  • Validation events
  • Exception handling
  • External integrations

Example

public async Task BeforeStepAsync(
    List<TransmissionStepModel> context,
    TransmissionStepModel step,
    List<TransmissionStepExecutionOutput> executionOutputs)
{
    _znodeLogging.LogMessage(
        "Before step execution",
        "DummyMultiStepProcessor",
        TraceLevel.Info);

    await Task.CompletedTask;
}

2.3 Writing Your Processor Class

The following example demonstrates the minimum implementation required for a custom processor.

Example

public class DummyMultiStepProcessor : IBaseProcessor
{
    public async Task BeforeStepAsync(
        List<TransmissionStepModel> context,
        TransmissionStepModel step,
        List<TransmissionStepExecutionOutput> executionOutputs)
    {
        await Task.CompletedTask;
    }

    public async Task AfterStepAsync(
        List<TransmissionStepModel> context,
        TransmissionStepModel step,
        List<TransmissionStepExecutionOutput> executionOutputs)
    {
        await Task.CompletedTask;
    }
}

Rules that are non-negotiable

RuleWhy
Implement IBaseProcessorRequired for Commerce Connector to recognize the processor.
Implement BeforeStepAsync()Executed before a transmission step.
Implement AfterStepAsync()Executed after a transmission step.
Always return completed tasksEnsures the execution pipeline continues correctly.
Handle null data safelyPrevents unexpected runtime failures.
Use Dependency Injection for servicesProvides access to platform services.

2.4 Processor Lifecycle

Commerce Connector executes the custom processor as part of the transmission workflow. For every configured transmission step, the processor is invoked before and after the step execution.

Execution Flow

Transmission Execution
        │
        ▼
BeforeStepAsync()
        │
        ▼
Transmission Step Execution
        │
        ▼
AfterStepAsync()
        │
        ▼
Next Step

For every transmission step:

  1. The processor's BeforeStepAsync() method executes.
  2. The configured transmission step executes.
  3. The processor's AfterStepAsync() method executes.
  4. Execution proceeds to the next configured step.

2.5 Available Data

When a processor executes, the following information is available.

Transmission Context

The context parameter contains all transmission steps involved in the current execution.

List<TransmissionStepModel> context

Example

var totalSteps = context.Count;

Current Step

The step parameter represents the currently executing transmission step.

TransmissionStepModel step

Example

var stepCode = step.StepCode;

A common use case is to execute custom logic only for a specific transmission step.

Example

if (step.StepCode == "step13")
{
    // custom logic
}

Execution Outputs

The executionOutputs parameter contains the execution results generated during transmission processing.

List<TransmissionStepExecutionOutput> executionOutputs

Execution outputs can be:

  • Read
  • Modified
  • Extended

These outputs can be used by subsequent transmission steps during the execution workflow.


2.6 Conditional Step Processing

BeforeStepAsync and AfterStepAsync allow custom logic to be executed before and after a transmission step. Use the step.StepCode property with an if condition to apply custom processing only to the required transmission step.

Example

public async Task BeforeStepAsync(
    List<TransmissionStepModel> context,
    TransmissionStepModel step,
    List<TransmissionStepExecutionOutput> executionOutputs)
{
    try
    {
        if (step.StepCode == "step13")
        {
            // Custom logic before step13
            _znodeLogging.LogMessage(
                "Custom processing executed before step13.",
                "DummyMultiStepProcessor",
                TraceLevel.Info);
        }

        await Task.CompletedTask;
    }
    catch (Exception ex)
    {
        _znodeLogging.LogMessage(
            ex,
            "DummyMultiStepProcessor",
            TraceLevel.Error);
    }
}

public async Task AfterStepAsync(
    List<TransmissionStepModel> context,
    TransmissionStepModel step,
    List<TransmissionStepExecutionOutput> executionOutputs)
{
    try
    {
        if (step.StepCode == "step134")
        {
            executionOutputs.Add(new TransmissionStepExecutionOutput
            {
                StepCode = step.StepCode,
                OutputData = "Modified after custom processor execution",
                DataFormat = "Text"
            });
        }

        await Task.CompletedTask;
    }
    catch (Exception ex)
    {
        _znodeLogging.LogMessage(
            ex,
            "DummyMultiStepProcessor",
            TraceLevel.Error);
    }
}

Usage

  • BeforeStepAsync: Executes custom logic before the specified transmission step.
  • AfterStepAsync: Executes custom logic after the specified transmission step and can add or modify step output.
  • step.StepCode: Use the step code in an if condition to execute custom logic only for the required transmission step.

This approach allows different custom logic to be applied to specific steps within the same transmission workflow without affecting other steps.


2.7 Modifying Step Outputs

A custom processor can add or modify execution outputs after a transmission step completes. These outputs can then be consumed by subsequent transmission steps.

Example

public async Task AfterStepAsync(
    List<TransmissionStepModel> context,
    TransmissionStepModel step,
    List<TransmissionStepExecutionOutput> executionOutputs)
{
    if (step.StepCode == "step134")
    {
        executionOutputs.Add(
            new TransmissionStepExecutionOutput
            {
                StepCode = step.StepCode,
                OutputData = "Modified after execution",
                DataFormat = "Text"
            });
    }

    await Task.CompletedTask;
}

The TransmissionStepExecutionOutput object contains the following properties:

PropertyDescription
StepCodeIdentifies the transmission step that produced the output.
OutputDataStores the output generated by the processor.
DataFormatSpecifies the format of the output data.

Example

new TransmissionStepExecutionOutput
{
    StepCode = step.StepCode,
    OutputData = "Modified after execution",
    DataFormat = "Text"
}

2.8 Using Dependency Injection

Commerce Connector supports Dependency Injection, allowing custom processors to access platform services during execution.

The IServiceProvider instance is provided through the processor constructor and can be used to resolve services as required.

Example

protected readonly IServiceProvider _serviceProvider;

public DummyMultiStepProcessor(IServiceProvider serviceProvider)
{
    _serviceProvider = serviceProvider;
}

Resolve a service using the service provider:

var logger =
    _serviceProvider.GetService<IZnodeLogging>();

Common platform services include:

  • Logging
  • Configuration access
  • Database services
  • External integrations
  • Platform services

2.9 Deploying the Extension

After developing the custom processor, deploy the extension using the Znode CLI.

Before deployment, connect to the Znode CLI using the provided authentication token.

Connect to the CLI

znode connect <token>

Deploy a specific processor project by specifying the project (.csproj) path.

Syntax

znode deploy extension "<path-to-project-csproj>"

Example

znode deploy extension
"D:\Extensions\Custom.Libraries.DataExchange\Custom.Libraries.DataExchange.csproj"

To deploy multiple extension projects, specify the parent folder that contains the projects.

Example

znode deploy extension "D:\Extensions"

The CLI automatically builds the project and uploads the generated assemblies for execution.


2.10 Registering the Processor

After deploying the custom processor, register it in the Commerce Connector configuration before using it in a transmission workflow.

Provide the following information while registering the processor:

FieldDescription
Processor NameEnter a descriptive name for the custom processor.

Example

DummyMultiStepProcessor

Note: The Class Name must exactly match the deployed processor class. If the class name does not match, Commerce Connector will not be able to locate and execute the processor.


2.11 Supported Mapping Types

The Mapping Engine supports the following mapping types.

Mapping TypeDescription
Direct MappingMaps a source field directly to a destination field.
Fixed/Static Value MappingAssigns a constant value.
Default Value MappingApplies a value when the source field is empty.
Formula MappingPerforms calculations and expressions.
Conditional MappingApplies mappings based on configured conditions.
Lookup MappingMaps values using lookup definitions.
Transformation MappingTransforms data before assignment.
Processor-Based MappingUses custom processor logic during mapping.
Object MappingMaps complete object structures.
Collection MappingMaps arrays and collections.

Any mapping behavior that is not supported by the standard Mapping Engine can be implemented using a custom processor.


2.12 Best Practices

Follow these best practices when developing custom processors.

Keep Processors Lightweight

Processors execute as part of the transmission workflow. Avoid unnecessary processing to minimize execution time.

Handle Exceptions Properly

Wrap custom logic in exception handling blocks and log any exceptions using IZnodeLogging.

Example

try
{
    // custom logic
}
catch (Exception ex)
{
    _znodeLogging.LogMessage(
        ex.Message,
        "DummyMultiStepProcessor",
        TraceLevel.Error);
}

Use Step Codes for Specific Logic

Execute custom logic only for the required transmission steps by evaluating the StepCode.

Example

if(step.StepCode == "ProductExport")
{
    // execute product export logic
}

Minimize External Calls

Avoid expensive API calls or database operations inside frequently executed processors to improve overall execution performance.

Maintain Stateless Design

Processors should not depend on static variables or shared state between executions.


2.13 Limitations

The current implementation of Custom Processor Extensibility does not support the following capabilities:

  • Extension Observability Screen (custom processor administration logs are not visible)
  • Extension Sync Functionality
  • Execution Log Viewer
  • Runtime Processor Diagnostics
  • Processor Health Dashboard
  • Dedicated Troubleshooting Screen

Logging and debugging should be performed using one or more of the following:

  • Application logs
  • Platform logs written through IZnodeLogging
  • Local debugging
  • Transmission execution results

This approach keeps the current Custom Processor implementation lightweight while still providing extensibility hooks before and after Commerce Connector transmission step execution.


3. Supported Mapping Expressions

The Mapping Engine supports functions, arithmetic operations, boolean expressions, ternary operators, constants, direct field mappings, and nested JSON mappings. These expressions can be used to dynamically transform and map data during transmission execution.


Summary

Custom Processor Extensibility enables developers to extend Commerce Connector by executing custom business logic before and after transmission step execution. By implementing the IBaseProcessor interface, developers can validate data, modify execution outputs, integrate with external systems, and leverage platform services through Dependency Injection.

The Mapping Engine complements custom processors by supporting direct mappings, transformation functions, arithmetic expressions, conditional logic, nested JSON mappings, and processor-based extensibility, enabling the implementation of complex integration scenarios with minimal customization.

Did you find it helpful? Yes No

Send feedback
Sorry we couldn't be helpful. Help us improve this article with your feedback.