HomeDev guideAPI ReferenceGraphQL
Dev guideUser GuideGitHubNuGetDev CommunitySubmit a ticketLog In
GitHubNuGetDev CommunitySubmit a ticket

Customized Commerce 14 + ODP

Export data from Customized Commerce 14 and import it into Optimizely Data Platform (ODP) (for Commerce 14.13.0).

📘

Note

This integration exports data from Customized Commerce 14 and imports it into Optimizely Data Platform (ODP).

To integrate Customized Commerce 13 with ODP, use one of the following:

Customized Commerce version 14.13.0 contains a scheduled job called Export data to ODP to integrate Optimizely Customized Commerce with Optimizely Data Platform (ODP). This job transfers Customized Commerce data (including orders, customers, and products) to the configured ODP account.

Breaking change

Commerce 14.18.0

Optimizely changed MarketKey class to support import data to Amazon S3, which is required. You must configure all settings for Amazon S3 credentials.

  1. (Required) Added TrackingId property to MarketKey.
  2. Added S3Options property to MarketKey, which contains the required properties:
    1. BucketName – Amazon S3 bucket name.
    2. AccessKeyId – AWS Access Key ID.
    3. SecretAccessKey – AWS Secret Access Key.
    4. Region – The system name of a region like "us-east-1". Default value is us-east-1 if Region setting is empty or null.

Commerce 14.17.0

Optimizely changed MarketKey class to support multi-site and reduce the number of settings.

  1. Renamed MarketId to MarketIds to allow multiple Market IDs with one ODP account with fewer settings.
  2. Added a property called SiteId to support multi-site. SiteId value can be null or empty. When a SiteId is present:
    1. The job filters the orders by SiteId.
    2. The job filters products by catalogs which are available to SiteId.
    3. The job sends customers to every Endpoint/Access Key because customers are not related to SiteId.

ODPJobOptions

This contains settings for the ODP integration job.

NameDescriptionDefault
ExportCatalogExport products and variants to ODPtrue
ExportCustomersExport customers to ODPtrue
ExportOrdersExport orders to ODPtrue
IncludeProductsExport products to ODPtrue
ProductBatchSizeBatch size when sending products to ODP50
OrderBatchSizeBatch size when sending orders to ODP50
CustomerBatchSizeBatch size when sending customers to ODP50
MarketKeysCollection of MarketKey. These hold API URL and access key to make API calls to ODP

Configure through code

Use the following code sample to configure the integration through code.

Before 14.18.0

services.Configure < ODPJobOptions > (o => {
  o.MarketKeys = new List < MarketKey > {
    new() {
      MarketId = "US",
        AccessKey = "key",
        EndpointUrl = "<https://api.zaius.com/>"
    }
  };
});

After 14.18.0

services.Configure<ODPJobOptions>(o =>
{
    o.MarketKeys = new List<MarketKey>
    {
        new()
        {
            SiteId = "siteId",
            MarketIds = new List<string> { "US" },
            AccessKey = "key",
            EndpointUrl = "https://api.zaius.com/",
            TrackingId = "tracking id",
            S3Options = new S3Options
            {
                BucketName = "",
                AccessKeyId = "",
                SecretAccessKey = "",
                Region = ""
            }
        }
    };
});

Configure through the configuration file

Use the following code sample to configure the integration through the configuration file.

Before 14.18.0

{  
  "EPiServer" : {  
    "Commerce" : {  
       "ODPJob": {  
        "MarketKeys": [  
          {  
            "MarketId": "US",  
            "AccessKey": "key",  
            "EndpointUrl": "https://api.zaius.com/"  
          }  
        ]  
      }  
    }  
  }  
}

After 14.18.0

{
  "EPiServer": {
    "Commerce": {
      "ODPJob": {
        "MarketKeys": [
          {
            "SiteId": "siteId",
            "MarketIds": ["US", "SWE"],
            "AccessKey": "key",
            "EndpointUrl": "https://api.zaius.com/",
            "TrackingId": "",
            "S3Options": {
              "BucketName": "",
              "AccessKeyId": "",
              "SecretAccessKey": "",
              "Region": ""
            }
          }
        ]
      }
    }
  }
}

Custom fields for customers

To create and populate custom fields into the ODP customers object, create an implementation of ICustomerCustomFieldsHandler.

[ServiceConfiguration(ServiceType = typeof (ICustomerCustomFieldsHandler))]
public class CustomCustomers: ICustomerCustomFieldsHandler {
  public IEnumerable < SchemaObjectCreateField > CreateFields() {
    return new [] {
      new SchemaObjectCreateField {
        Name = "mark_customers_teststring",
          DisplayName = "Mark ODP Connector string",
          PublicRead = true,
          Type = "string"
      },
      new SchemaObjectCreateField {
        Name = "mark_customers_testtimestamp",
          DisplayName = "Mark ODP Connector timestamp",
          PublicRead = true,
          Type = "timestamp"
      },
      new SchemaObjectCreateField {
        Name = "mark_customers_testinteger",
          DisplayName = "Mark ODP Connector integer",
          PublicRead = true,
          Type = "number"
      },
      new SchemaObjectCreateField {
        Name = "mark_customers_testdecimal",
          DisplayName = "Mark ODP Connector decimal",
          PublicRead = false,
          Type = "number"
      },
      new SchemaObjectCreateField {
        Name = "mark_customers_testboolean",
          DisplayName = "Mark ODP Connector boolean",
          PublicRead = false,
          Type = "boolean"
      }
    };
  }

  public Dictionary < string, object > GetFieldValues(ContactEntity contact) {
    var values = new Dictionary < string,
      object > ();
    var testString = contact.Properties.GetValue < string > ("mark_customers_teststring", null);
    if (!string.IsNullOrEmpty(testString)) {
      values.Add("mark_customers_teststring", testString);
    }

    var testTimestamp = contact.Properties.GetValue < DateTime ? > ("mark_customers_testtimestamp", null);
    if (testTimestamp != null) {
      values.Add("mark_customers_testtimestamp", testTimestamp.Value.ToString("s"));
    }

    var testInteger = contact.Properties.GetValue < int ? > ("mark_customers_testinteger", null);
    if (testInteger != null) {
      values.Add("mark_customers_testinteger", testInteger.Value);
    }

    var testDecimal = contact.Properties.GetValue < decimal ? > ("mark_customers_testdecimal", null);
    if (testDecimal != null) {
      values.Add("mark_customers_testdecimal", testDecimal.Value);
    }

    var testBoolean = contact.Properties.GetValue("mark_customers_testboolean", false);
    values.Add("mark_customers_testboolean", testBoolean);

    return values;
  }
}

Custom fields for products

To create and populate custom fields into the ODP products object. create an implementation of IProductCustomFieldsHandler.

[ServiceConfiguration(ServiceType = typeof (IProductCustomFieldsHandler))]
public class CustomProducts: IProductCustomFieldsHandler {
  public IEnumerable < SchemaObjectCreateField > CreateFields() {
    return new [] {
      new SchemaObjectCreateField {
        Name = "mark_product_teststring",
          DisplayName = "Mark ODP Connector string",
          PublicRead = true,
          Type = "string"
      },
      new SchemaObjectCreateField {
        Name = "mark_product_testtimestamp",
          DisplayName = "Mark ODP Connector timestamp",
          PublicRead = true,
          Type = "timestamp"
      },
      new SchemaObjectCreateField {
        Name = "mark_product_testinteger",
          DisplayName = "Mark ODP Connector integer",
          PublicRead = true,
          Type = "number"
      },
      new SchemaObjectCreateField {
        Name = "mark_product_testdecimal",
          DisplayName = "Mark ODP Connector decimal",
          PublicRead = false,
          Type = "number"
      },
      new SchemaObjectCreateField {
        Name = "mark_product_testboolean",
          DisplayName = "Mark ODP Connector boolean",
          PublicRead = false,
          Type = "boolean"
      }
    };
  }

  public Dictionary < string, object > GetFieldValues(EntryContentBase entry) {
    var values = new Dictionary < string,
      object > ();
    var testString = entry.GetValue("mark_product_teststring")?.ToString();
    if (!string.IsNullOrEmpty(testString)) {
      values.Add("mark_product_teststring", testString);
    }

    var testTimestamp = entry.GetValue("mark_product_testtimestamp") as DateTime ? ;
    if (testTimestamp != null) {
      values.Add("mark_product_testtimestamp", testTimestamp.Value.ToString("s"));
    }

    var testInteger = entry.GetValue("mark_product_testinteger") as int ? ;
    if (testInteger != null) {
      values.Add("mark_product_testinteger", testInteger.Value);
    }

    var testDecimal = entry.GetValue("mark_product_testdecimal") as decimal ? ;
    if (testDecimal != null) {
      values.Add("mark_product_testdecimal", testDecimal.Value);
    }

    var testBoolean = entry.GetValue("mark_product_testboolean") as bool ? ;
    if (testBoolean != null) {
      values.Add("mark_product_testboolean", testBoolean);
    }
    return values;
  }
}