commercetools Prerequisites & Project Configuration
Essential knowledge
Changed on:
30 July 2025
Overview
This page covers how to configure the appropriate settings in the commercetools the commercetools system i.e.: custom fields, channels, etc. so that syncing can be enabled between it and the Fluent Commerce system.Key points
- Custom fields are required for Orders, Order Line Items, Delivery, Channels, and Parcels, with specific field names provided.
- Project configuration files include application-connector.yml, application.yml, bootstrap.yml, and logback-spring.xml for different settings and environments.
- Route mappings are used to map incoming messages to handlers, with examples provided for configuration.
- Listeners manage different types of queues, including batch jobs, internal messages, notifications, and commercetools events.
- Detailed configuration examples and instructions are available for customizing routes, handlers, and Fluent account mappings.
Prerequisites
Custom fields will be required for the following areas:- Order
- Order Line Item
- Delivery
- Channels
Order
- Group key name: Fluent Custom Field
- Field name: Pickup Location Ref

Order Line Item
- Group key name : Fluent Fulfilment Metadata
- Field name : Fulfilment Metadata
Delivery
- Group key name : Fluent Consignment
- Field name : Fluent Consignment Ref
- Fluent Consignment Status
Order Parcel
- Group key name : Fluent Article
- Field name : Fluent Tracking Url
Channels
- Group key name: Fluent Store Details
- Fields name:
- Type
- Status
- Phone No.
- Latitude
- Longitude
- Timezone
- Opening Schedule
- Attributes
commercetools Custom field collection
1 {
2 "info": {
3 "_postman_id": "a194556c-159f-4810-80a0-84776857dbae",
4 "name": "CT Custom Fields",
5 "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
6 "_exporter_id": "21544403"
7 },
8 "item": [
9 {
10 "name": "Create Order custom field",
11 "event": [
12 {
13 "listen": "test",
14 "script": {
15 "exec": [
16 "tests[\"Status code \" + responseCode.code] = responseCode.code === 200 || responseCode.code === 201;",
17 "var data = JSON.parse(responseBody);",
18 "if(data.results && data.results[0] && data.results[0].id && data.results[0].version){",
19 " pm.environment.set(\"type-id\", data.results[0].id); ",
20 " pm.environment.set(\"type-version\", data.results[0].version);",
21 "}",
22 "if(data.results && data.results[0] && data.results[0].key){",
23 " pm.environment.set(\"type-key\", data.results[0].key); ",
24 "}",
25 "if(data.version){",
26 " pm.environment.set(\"type-version\", data.version);",
27 "}",
28 "if(data.id){",
29 " pm.environment.set(\"type-id\", data.id); ",
30 "}",
31 "if(data.key){",
32 " pm.environment.set(\"type-key\", data.key);",
33 "}",
34 ""
35 ],
36 "type": "text/javascript"
37 }
38 }
39 ],
40 "request": {
41 "auth": {
42 "type": "oauth2",
43 "oauth2": [
44 {
45 "key": "accessToken",
46 "value": "{{ctp_access_token}}",
47 "type": "string"
48 },
49 {
50 "key": "addTokenTo",
51 "value": "header",
52 "type": "string"
53 },
54 {
55 "key": "tokenType",
56 "value": "Bearer",
57 "type": "string"
58 }
59 ]
60 },
61 "method": "POST",
62 "header": [
63 {
64 "key": "Content-Type",
65 "value": "application/json"
66 }
67 ],
68 "body": {
69 "mode": "raw",
70 "raw": "{\n \"key\" : \"flOrderCustomField\",\n \"name\" : {\n \"en\" : \"Fluent Custom Field\"\n },\n \"description\" : {\n \"en\" : \"Fluent Custom Field\"\n },\n \"resourceTypeIds\" : [ \"order\" ],\n \"fieldDefinitions\" : [ {\n \"name\" : \"flPickupLocationRef\",\n \"label\" : {\n \"en\" : \"Pickup Location Ref\"\n },\n \"required\" : false,\n \"type\" : {\n \"name\" : \"String\"\n },\n \"inputHint\" : \"SingleLine\"\n } ]\n}"
71 },
72 "url": {
73 "raw": "{{host}}/{{project-key}}/types",
74 "host": [
75 "{{host}}"
76 ],
77 "path": [
78 "{{project-key}}",
79 "types"
80 ],
81 "query": [
82 {
83 "key": "expand",
84 "value": "",
85 "disabled": true
86 }
87 ]
88 }
89 },
90 "response": []
91 },
92 {
93 "name": "Create Lineitems custom fields",
94 "event": [
95 {
96 "listen": "test",
97 "script": {
98 "exec": [
99 "tests[\"Status code \" + responseCode.code] = responseCode.code === 200 || responseCode.code === 201;",
100 "var data = JSON.parse(responseBody);",
101 "if(data.results && data.results[0] && data.results[0].id && data.results[0].version){",
102 " pm.environment.set(\"type-id\", data.results[0].id); ",
103 " pm.environment.set(\"type-version\", data.results[0].version);",
104 "}",
105 "if(data.results && data.results[0] && data.results[0].key){",
106 " pm.environment.set(\"type-key\", data.results[0].key); ",
107 "}",
108 "if(data.version){",
109 " pm.environment.set(\"type-version\", data.version);",
110 "}",
111 "if(data.id){",
112 " pm.environment.set(\"type-id\", data.id); ",
113 "}",
114 "if(data.key){",
115 " pm.environment.set(\"type-key\", data.key);",
116 "}",
117 ""
118 ],
119 "type": "text/javascript"
120 }
121 }
122 ],
123 "request": {
124 "auth": {
125 "type": "oauth2",
126 "oauth2": [
127 {
128 "key": "accessToken",
129 "value": "{{ctp_access_token}}",
130 "type": "string"
131 },
132 {
133 "key": "addTokenTo",
134 "value": "header",
135 "type": "string"
136 },
137 {
138 "key": "tokenType",
139 "value": "Bearer",
140 "type": "string"
141 }
142 ]
143 },
144 "method": "POST",
145 "header": [
146 {
147 "key": "Content-Type",
148 "value": "application/json"
149 }
150 ],
151 "body": {
152 "mode": "raw",
153 "raw": "{\n \"key\" : \"flFulfilment\",\n \"name\" : {\n \"en\" : \"Fluent Fulfilment Metadata\"\n },\n \"description\" : {\n \"en\" : \"Fluent Fulfilment Metadata\"\n },\n \"resourceTypeIds\" : [ \"line-item\" ],\n \"fieldDefinitions\" : [ {\n \"name\" : \"flFulfilmentMetadata\",\n \"label\" : {\n \"en\" : \"Fulfilment Metadata\"\n },\n \"required\" : false,\n \"type\" : {\n \"name\" : \"String\"\n },\n \"inputHint\" : \"SingleLine\"\n } ]\n}"
154 },
155 "url": {
156 "raw": "{{host}}/{{project-key}}/types",
157 "host": [
158 "{{host}}"
159 ],
160 "path": [
161 "{{project-key}}",
162 "types"
163 ],
164 "query": [
165 {
166 "key": "expand",
167 "value": "",
168 "disabled": true
169 }
170 ]
171 }
172 },
173 "response": []
174 },
175 {
176 "name": "Create Delivery custom fields",
177 "event": [
178 {
179 "listen": "test",
180 "script": {
181 "exec": [
182 "tests[\"Status code \" + responseCode.code] = responseCode.code === 200 || responseCode.code === 201;",
183 "var data = JSON.parse(responseBody);",
184 "if(data.results && data.results[0] && data.results[0].id && data.results[0].version){",
185 " pm.environment.set(\"type-id\", data.results[0].id); ",
186 " pm.environment.set(\"type-version\", data.results[0].version);",
187 "}",
188 "if(data.results && data.results[0] && data.results[0].key){",
189 " pm.environment.set(\"type-key\", data.results[0].key); ",
190 "}",
191 "if(data.version){",
192 " pm.environment.set(\"type-version\", data.version);",
193 "}",
194 "if(data.id){",
195 " pm.environment.set(\"type-id\", data.id); ",
196 "}",
197 "if(data.key){",
198 " pm.environment.set(\"type-key\", data.key);",
199 "}",
200 ""
201 ],
202 "type": "text/javascript"
203 }
204 }
205 ],
206 "request": {
207 "auth": {
208 "type": "oauth2",
209 "oauth2": [
210 {
211 "key": "accessToken",
212 "value": "{{ctp_access_token}}",
213 "type": "string"
214 },
215 {
216 "key": "addTokenTo",
217 "value": "header",
218 "type": "string"
219 },
220 {
221 "key": "tokenType",
222 "value": "Bearer",
223 "type": "string"
224 }
225 ]
226 },
227 "method": "POST",
228 "header": [
229 {
230 "key": "Content-Type",
231 "value": "application/json"
232 }
233 ],
234 "body": {
235 "mode": "raw",
236 "raw": "{\n \"key\": \"flConsignment\",\n \"name\": {\n \"en\": \"Fluent Consignment\"\n },\n \"description\": {\n \"en\": \"Fluent Consignment\"\n },\n \"resourceTypeIds\": [\n \"order-delivery\"\n ],\n \"fieldDefinitions\": [\n {\n \"name\": \"flConsignmentRef\",\n \"label\": {\n \"en\": \"Fluent Consignment Ref\"\n },\n \"required\": false,\n \"type\": {\n \"name\": \"String\"\n },\n \"inputHint\": \"SingleLine\"\n },\n {\n \"name\": \"flConsignmentStatus\",\n \"label\": {\n \"en\": \"Fluent Consignment Status\"\n },\n \"required\": false,\n \"type\": {\n \"name\": \"String\"\n },\n \"inputHint\": \"SingleLine\"\n }\n ]\n }"
237 },
238 "url": {
239 "raw": "{{host}}/{{project-key}}/types",
240 "host": [
241 "{{host}}"
242 ],
243 "path": [
244 "{{project-key}}",
245 "types"
246 ],
247 "query": [
248 {
249 "key": "expand",
250 "value": "",
251 "disabled": true
252 }
253 ]
254 }
255 },
256 "response": []
257 },
258 {
259 "name": "Create Parcel custom fields",
260 "event": [
261 {
262 "listen": "test",
263 "script": {
264 "exec": [
265 "tests[\"Status code \" + responseCode.code] = responseCode.code === 200 || responseCode.code === 201;",
266 "var data = JSON.parse(responseBody);",
267 "if(data.results && data.results[0] && data.results[0].id && data.results[0].version){",
268 " pm.environment.set(\"type-id\", data.results[0].id); ",
269 " pm.environment.set(\"type-version\", data.results[0].version);",
270 "}",
271 "if(data.results && data.results[0] && data.results[0].key){",
272 " pm.environment.set(\"type-key\", data.results[0].key); ",
273 "}",
274 "if(data.version){",
275 " pm.environment.set(\"type-version\", data.version);",
276 "}",
277 "if(data.id){",
278 " pm.environment.set(\"type-id\", data.id); ",
279 "}",
280 "if(data.key){",
281 " pm.environment.set(\"type-key\", data.key);",
282 "}",
283 ""
284 ],
285 "type": "text/javascript"
286 }
287 }
288 ],
289 "request": {
290 "auth": {
291 "type": "oauth2",
292 "oauth2": [
293 {
294 "key": "accessToken",
295 "value": "{{ctp_access_token}}",
296 "type": "string"
297 },
298 {
299 "key": "addTokenTo",
300 "value": "header",
301 "type": "string"
302 },
303 {
304 "key": "tokenType",
305 "value": "Bearer",
306 "type": "string"
307 }
308 ]
309 },
310 "method": "POST",
311 "header": [
312 {
313 "key": "Content-Type",
314 "value": "application/json"
315 }
316 ],
317 "body": {
318 "mode": "raw",
319 "raw": "{\n \"key\": \"fluentarticle\",\n \"name\": {\n \"en\": \"Fluent Article\"\n },\n \"description\": {\n \"en\": \"Fluent Article\"\n },\n \"resourceTypeIds\": [\n \"order-parcel\"\n ],\n \"fieldDefinitions\": [\n {\n \"name\": \"trackingUrl\",\n \"label\": {\n \"en\": \"Fluent Tracking Url\"\n },\n \"required\": false,\n \"type\": {\n \"name\": \"String\"\n },\n \"inputHint\": \"SingleLine\"\n }\n ]\n}"
320 },
321 "url": {
322 "raw": "{{host}}/{{project-key}}/types",
323 "host": [
324 "{{host}}"
325 ],
326 "path": [
327 "{{project-key}}",
328 "types"
329 ],
330 "query": [
331 {
332 "key": "expand",
333 "value": "",
334 "disabled": true
335 }
336 ]
337 }
338 },
339 "response": []
340 },
341 {
342 "name": "Create Channel custom fields",
343 "event": [
344 {
345 "listen": "test",
346 "script": {
347 "exec": [
348 "tests[\"Status code \" + responseCode.code] = responseCode.code === 200 || responseCode.code === 201;",
349 "var data = JSON.parse(responseBody);",
350 "if(data.results && data.results[0] && data.results[0].id && data.results[0].version){",
351 " pm.environment.set(\"type-id\", data.results[0].id); ",
352 " pm.environment.set(\"type-version\", data.results[0].version);",
353 " pm.environment.set(\"fluent-channel-id\", data.results[0].id);",
354 "}",
355 "if(data.results && data.results[0] && data.results[0].key){",
356 " pm.environment.set(\"type-key\", data.results[0].key); ",
357 "}",
358 "if(data.version){",
359 " pm.environment.set(\"type-version\", data.version);",
360 "}",
361 "if(data.id){",
362 " pm.environment.set(\"type-id\", data.id); ",
363 "}",
364 "if(data.key){",
365 " pm.environment.set(\"type-key\", data.key);",
366 "}",
367 ""
368 ],
369 "type": "text/javascript"
370 }
371 }
372 ],
373 "request": {
374 "auth": {
375 "type": "oauth2",
376 "oauth2": [
377 {
378 "key": "accessToken",
379 "value": "{{ctp_access_token}}",
380 "type": "string"
381 },
382 {
383 "key": "addTokenTo",
384 "value": "header",
385 "type": "string"
386 },
387 {
388 "key": "tokenType",
389 "value": "Bearer",
390 "type": "string"
391 }
392 ]
393 },
394 "method": "POST",
395 "header": [
396 {
397 "key": "Content-Type",
398 "value": "application/json"
399 }
400 ],
401 "body": {
402 "mode": "raw",
403 "raw": "{\n \"key\" : \"flStoredetails\",\n \"name\" : {\n \"en\" : \"Fluent Store Details\"\n },\n \"description\" : {\n \"en\" : \"Fluent Store Details\"\n },\n \"resourceTypeIds\" : [ \"channel\" ],\n \"fieldDefinitions\" : [ {\n \"name\": \"flStoreType\",\n \"label\": {\n \"en\": \"Type\"\n },\n \"required\": false,\n \"type\": {\n \"name\": \"String\"\n },\n \"inputHint\": \"SingleLine\"\n },\n {\n \"name\": \"flStoreStatus\",\n \"label\": {\n \"en\": \"Status\"\n },\n \"required\": false,\n \"type\": {\n \"name\": \"String\"\n },\n \"inputHint\": \"SingleLine\"\n },\n {\n \"name\": \"flStoreEmail\",\n \"label\": {\n \"en\": \"Email\"\n },\n \"required\": false,\n \"type\": {\n \"name\": \"String\"\n },\n \"inputHint\": \"SingleLine\"\n },\n {\n \"name\": \"flStorePhoneNo\",\n \"label\": {\n \"en\": \"Phone No.\"\n },\n \"required\": false,\n \"type\": {\n \"name\": \"String\"\n },\n \"inputHint\": \"SingleLine\"\n },\n {\n \"name\": \"flStoreLatitude\",\n \"label\": {\n \"en\": \"Latitude\"\n },\n \"required\": false,\n \"type\": {\n \"name\": \"String\"\n },\n \"inputHint\": \"SingleLine\"\n },\n {\n \"name\": \"flStoreLongitude\",\n \"label\": {\n \"en\": \"Longitude\"\n },\n \"required\": false,\n \"type\": {\n \"name\": \"String\"\n },\n \"inputHint\": \"SingleLine\"\n },\n {\n \"name\": \"flStoreTimezone\",\n \"label\": {\n \"en\": \"Timezone\"\n },\n \"required\": false,\n \"type\": {\n \"name\": \"String\"\n },\n \"inputHint\": \"SingleLine\"\n },\n {\n \"name\": \"flOpeningSchedule\",\n \"label\": {\n \"en\": \"Opening Schedule \"\n },\n \"required\": false,\n \"type\": {\n \"name\": \"String\"\n },\n \"inputHint\": \"MultiLine\"\n },\n {\n \"name\": \"flStoreAttributes\",\n \"label\": {\n \"en\": \"Attributes \"\n },\n \"required\": false,\n \"type\": {\n \"name\": \"String\"\n },\n \"inputHint\": \"MultiLine\"\n } ]\n}"
404 },
405 "url": {
406 "raw": "{{host}}/{{project-key}}/types",
407 "host": [
408 "{{host}}"
409 ],
410 "path": [
411 "{{project-key}}",
412 "types"
413 ],
414 "query": [
415 {
416 "key": "expand",
417 "value": "",
418 "disabled": true
419 }
420 ]
421 }
422 },
423 "response": []
424 }
425 ]
426 } Project Configuration
The resource folder of the project contains all build time configurations for the commercetools connector.- application-connector.yml - Project and Connector specific configuration.
- application.yml - Core Connect SDK configuration. These are mostly default configurations and core settings.
- bootstrap.yml - Server/Container configuration. This file includes settings for all different environments and follows the spring profile standards.
- logback-spring.xml - Log configuration also supports different configurations based on spring profiles.
| Property | Description |
| connector-name | This is the name of the connector and this property is used to both name the connector as well as build the path of other configuration keys. Keep characters limited to 'a-z' and '-'. |
| route-mapping | Routes mappings are used to determine a route for an incoming message. |
| routes | Allows new routes to be defined or override existing route configuration. |
| listeners | All active listeners for the connector |
| credential.credential-manager | Sets the credential manager. When using AWS, keep the value as "aws-secrets-manager" |
| job-scheduler.job-scheduler-type | Sets the scheduler manager. Currently, the only possible value is "message-queue" |
Route Mappings
When different kinds of messages (e.g. orders, categories, products, etc…) are received by the connector, it needs to be told how to map each kind to a handler. A handler has a single purpose for example to process orders. The snippet below illustrates a configuration that tells the connector to react to commercetools inbound messages that have the resource type`“order”` and message type `“ResourceCreated“`, and forward these to the appropriate handler. Messages that fail to map to any entry in this route mapping will be discarded.1 - route: "commercetools.connect.order.create"
2 props:
3 name: "order"
4 inclusion-filter:
5 - "ResourceCreated"Routes
Handlers by default have a predefined route and properties set but it is possible to override them through the configuration files. The example below will show how to override an existing route. To view all available handlers and routes, check Connector Features1{
2 "route": "batch-inventory-sync",
3 "handler": "InventorySyncJob",
4 "priority": 0,
5 "rops": {
6 "page-size": "500"
7 },
8 "className": "com.fluentcommerce.connect.client.commercetools.handler.job.InventorySyncJobHandler",
9 "description": "Sync inventory details from Fluent to commerceTools"
10}1 routes:
2 job:
3 route: "batch-inventory-sync"
4 handlerName: "InventorySyncJob"
5 props:
6 page-size: "1000"1 routes:
2 #possible values: job, message or notification
3 job:
4 route: "<route-name>"
5 handlerName: "<handler-name>"
6 props:
7 #this flexible. Consider this is a map of String: String/int/double/long
8 page-size: "1000" Listeners
There are 4 listeners in this connector- batch - used to process queued jobs.
- messages - used to queue internal connector messages.
- notification - for internal connector events that require an external notification.
- commercetools_events - queue to receive all commercetools application events. This queue behaves differently from the other queues and it requires a property fluent-account with the Fluent account to be used by the connector. Without this property, this queue will fail to start.