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
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.
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 which are available to 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 |
Note
Due to the potential of having multiple markets and currencies, product pricing cannot be transferred to ODP and displays as $0.
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": ""
}
}
]
}
}
}
}
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;
}
}
Updated 2 months ago