Commerce Connect 14 + ODP
Export data from Commerce Connect 14 and import it into Optimizely Data Platform (ODP) (for Commerce Connect 14.13.0)
Note
This integration exports data from Commerce Connect 14 and imports it into Optimizely Data Platform (ODP).
To integrate Commerce Connect 13 with ODP, use one of the following:
- Commerce Connect 13 + ODP (recommended)
- Commerce Connect 13 or 14 + ODP
Breaking change
Commerce Connect 14.20.0
Optimizely changed MarketKey
class to support import data to Amazon S3, which is required. You must configure all settings for Amazon S3 credentials.
-
(Required) Added
TrackingId
property toMarketKey
. -
Added
S3Options
property toMarketKey
, which contains the required properties:-
BucketName
– Amazon S3 bucket name. For example, if your Bucket URL for ODP imports iss3://zauis-incoming/W4WzcEs-ABgXorzY7h1LCQ
, enter zaius-incoming. -
AccessKeyId
– AWS Access Key ID. -
SecretAccessKey
– AWS Secret Access Key. -
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.
- Renamed
MarketId
toMarketIds
to allow multiple Market IDs with one ODP account with fewer settings. - Added a property called
SiteId
to support multi-site.SiteId
value can be null or empty. When aSiteId
is present:- The job filters the orders by SiteId.
- The job filters products by catalogs that are available on SiteId.
- 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.
Name | Description | Default |
---|---|---|
ExportCatalog | Export products and variants to ODP | true |
ExportCustomers | Export customers to ODP | true |
ExportOrders | Export orders to ODP | true |
IncludeProducts | Export products to ODP | true |
ProductBatchSize | Batch size when sending products to ODP | 50 |
OrderBatchSize | Batch size when sending orders to ODP | 50 |
CustomerBatchSize | Batch size when sending customers to ODP | 50 |
MarketKeys | Collection of MarketKey. These hold API URL and access key to make API calls to ODP | |
DisableDeltaExport | Run the ODP export job with delta export | false |
Note
Due to the potential of having multiple markets and currencies, product pricing cannot be transferred to ODP and displays as $0.
Export data to ODP job
Commerce Connect version 14.13.0 contains a scheduled job called Export data to ODP to integrate Optimizely Commerce Connect with Optimizely Data Platform (ODP). This job transfers Commerce Connect data (including orders, customers, and products) to the configured ODP account. The job saves data in CSV files and sends it to Amazon S3. ODP then processes the files.
ODP requires that the CSV contains the following required fields:
- Customer
commerce_cloud_id
first_name
last_name
name
email
city
country
state
street1
street2
zip
- Product
product_id
category
name
sku
price
quantity
parent_product_id
image_url
- Order
commerce_cloud_id email
first_name
last_name
name
phone
bill_address ship_address
order_id
total
discount
subtotal
tax
shipping
coupon_code
item_product_id
item_price
item_quantity
item_discount item_subtotal
ts
Delta exports
Commerce Connect version 14.23.0 supports delta exports for ODP, enabled by default. ODP only sends the data that has changed or has been added since the last export. Use the DisableDeltaExport option to turn off using delta exports.
Configure through code
Use the following code sample to configure the integration through code.
Before 14.20.0
services.Configure < ODPJobOptions > (o => {
o.MarketKeys = new List < MarketKey > {
new() {
MarketId = "US",
AccessKey = "key",
EndpointUrl = "<https://api.zaius.com/>"
}
};
});
After 14.20.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.20.0
{
"EPiServer" : {
"Commerce" : {
"ODPJob": {
"MarketKeys": [
{
"MarketId": "US",
"AccessKey": "key",
"EndpointUrl": "https://api.zaius.com/"
}
]
}
}
}
}
After 14.20.0
{
"EPiServer": {
"Commerce": {
"ODPJob": {
"MarketKeys": [
{
"SiteId": "siteId",
"MarketIds": ["US", "SWE"],
"AccessKey": "key",
"EndpointUrl": "https://api.zaius.com/",
"TrackingId": "",
"S3Options": {
"BucketName": "",
"AccessKeyId": "",
"SecretAccessKey": "",
"Region": "ADD_REGION, SEE THE FOLLOWING NOTE"
}
}
]
}
}
}
}
Note
You must add your
Region
value in the code snippet. If left as an empty string, its value defaults tous-east-1
.
- US –
us-east-1
- EU –
eu-west-1
- Australia –
ap-southeast-2
Custom fields
Create custom fields handlers
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;
}
}
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;
}
}
These interfaces contain two methods for creating schema and populating custom fields:
- IEnumerable CreateFields – Creates ODP custom fields.
- Dictionary<string, object> GetFieldValues – Populates values for custom fields.
However, this requires redeploying the code.
Use the Commerce Admin UI
To improve this process, you can use the Commerce Admin UI to create custom fields using the ODP API and create mapping for custom properties (MetaFields) for products, contacts, and orders to ODP custom fields.

Note
If you have multiple market keys, this feature loops through all market keys and creates the custom field.

When the job runs next time, the integration uses the mappings.
Rules to avoid issues
-
Commerce custom properties only support properties with primitive data types: DataTime, Number, Boolean, and String.
-
There are compatibility data type rules when mapping between Commerce properties and ODP custom fields.
Commerce Connect property data type ODP custom field data type DateTime TimeStamp (UNIX epoch) Number Number or String Boolean Boolean or String String String -
If there is any issue with mapping when you run the job, Commerce Connect logs it and skips error mapping.
Updated about 2 months ago