commercetools connector - Order Sync
Changed on:
31 Jan 2024
Overview
The Order Sync is responsible for exporting orders from commercetools to Fluent and receiving order updates.
Detailed Technical Description
Key Features
- Triggers customer export when an order is placed
- Exports new orders to Fluent
- It opens a webhook to receive Fluent order-related updates. Other extensions like fulfilment and consignment will leverage this webhook
- Updates order status based on Fluent updates
Limitations
- Does not sync old orders created before the extension is installed
- Out-of-the-box(OOTB) connector supports order creation, and the order update/changes handler needs to be customized specifically to the implementation need
- Currently, HD and CC types are supported OOTB. The relevant order create handler can be overridden or a new one written to add for other order types and send in more order attributes
Technical Details
The CT-Queue message queue is used to export orders. Once an order is saved in commercetools, the system triggers the relevant event to the external queue (ct-queue), which the queue listener observes. The queue listener triggers message routes using the message name and handler. The message handler will push the order data to Fluent OMS.
CT Queue: Any order creation will be pushed to ct-queue using commercetools subscriptions. Out-of-the-box(OOTB) connector uses AWS Event Bridge and can be implemented with other queues/subscriptions supported by commercetools. More details on commercetools subscription.
CT Queue Listener: This class reads the message from CT-Queue and pushes it to the Event queue.
Event Queue: The event queue is responsible for holding the event message to be processed further.
Message Router: It will read the message name from the Event queue and pass it to the appropriate handler. In case of order changes, the message name will be mapped against route properties named “
`order`
`commercetools.connect.order.create`
1- route: "commercetools.connect.order.create"
2 props:
3 name: "order"
4 inclusion-filter:
5 - "ResourceCreated"
Language: json
Name: commercetools.connect.order.create
Description:
[Warning: empty required content area]Order Create Handler: This will be a class that reads message data from the internal queue and, based on the order identifier, fetches more information from commercetools-SDK ( The core commercetools SDK, which interacts with commercetools APIs ) and maps them with Fluent data model and pushes it to Fluent OMS.
The message handlers are fully extensible. Partners can make the changes as per their requirements. The commercetools-connector allows message routing with flexible message handlers to process and transform data moving from a source to a destination. Partners can change the message names and override the classes. It is fully expected the order create handler will be overridden to send in more attributes specific to the implementation.
Out-of-the-box(OOTB) commercetools-connector provides the ability to create auto-generated order numbers based on order type. Fluent supports two order types HD(Home Delivery) and CC (Click and Collect); hence the order number gets generated with a specific pattern for their types, as shown below:
CC Order: “order-” (order-CC201022133420)
HD Order: “order-” (order-HD201022122149)
1//Auto order number creation logic
2final String orderType = getOrderType(context, order.get().getShippingInfo().getShippingMethod().getKey());
3if (StringUtils.isBlank(orderType)) {
4 throw new UnprocessableMessageException("Order type is missing");
5}
6String orderNumber = order.get().getOrderNumber();
7if(StringUtils.isEmpty(orderNumber)) {
8 orderNumber = generateOrderNumber(orderType, accountReference.getRetailerId());
9 updateOrderNumber(ctApiClient, getQuery(context, "mutation"), order.get(), orderNumber);
10}
Language: json
Name: orderType example
Description:
[Warning: empty required content area]The order type will be determined based on the shipping method, which is configured on Fluent Oms app > Admin > Settings >
`fc.connect.commerce-tools.order.shipping-method-mapping`
Customers will be created with the order creation process. It checks if the customer first exists in the fluent retailer and, if not, will create a new customer by using fluent customer Graphql mutation.
1//Customer identification/creation logic
2String customerId;
3 if (null == customerQueryData.customer()) {
4 createCustomer(context, accountReference, order.get());
5 customerId = context.ofFluentContext().executeQuery(customerQuery, GetCustomerQuery.Data.class).customer().id();
6 } else {
7 customerId = customerQueryData.customer().id();
8 }
Language: json
Name: customer graphql mutation
Description:
[Warning: empty required content area]Example to extend the functionality
Partners can override existing handlers using the application-connector.yml and Handler class. To change the logic of the Order Create handler, first go to
`commercetools-modules/commercetools-connector/src/main/resources/application-connector.yml`
1fluent-connect:
2 routes:
3 - name: "commercetools.connect.order.create"
4 handler: "OrderCreateHandler"
5 props:
6 query: "ct-order.graphql"
7 mutation: "ct-updateorderNumber.graphql"
Language: json
Name: application-connector.yml
Description:
[Warning: empty required content area]New handlers can also be added directly to the above
`application-connector.yml`
Create a new Handler that extends
`MessageHandler`
`com.fluentcommerce.connect`
`com.fluentcommerce.connect.custom.commercetools.handler.message.<your-handler>.java`
1@Slf4j
2@Component
3@HandlerInfo(name = "FluentOrderCreateHandler", description = "Create a order at Fluent OMS")
4public class FluentOrderCreateHandler extends MessageHandler {
5 private static final String ORDER_ATTRIBUTE = "order";
6 // write your logic
7}
Language: json
Name: <your-handler>.java
Description:
[Warning: empty required content area]Order Queries and Mutation
Below are the queries and mutations that come as an Out-of-the-box(OOTB) feature with the commercetools-connector and are fully flexible and can be overridden by the partners.
Order mutation to create order on the Fluent OMS app
1mutation CreateOrder($input: CreateOrderInput) {
2 createOrder(input: $input) {
3 ref
4 id
5 status
6 }
7}
Language: json
Name: create order mutation
Description:
[Warning: empty required content area]Order query to fetch order from Fluent OMS app
1query GetOrder($ref: String!) {
2 order(ref: $ref) {
3 ref
4 id
5 status
6 attributes{
7 name
8 type
9 value
10 }
11 }
12}
Language: json
Name: Order query
Description:
[Warning: empty required content area]Query to fetch order from commercetools
`fc-commercetools-module/src/main/graphql/mutations/order/GetOrder.graphql`
1query Search($id: String, $orderNumber: String) {
2 search: order(id: $id, orderNumber: $orderNumber) {
3 id
4 version
5 orderNumber
6 totalPrice {
7 type
8 currencyCode
9 centAmount
10 fractionDigits
11 }
12 taxedPrice {
13 totalNet {
14 type
15 currencyCode
16 centAmount
17 fractionDigits
18 }
19 totalGross {
20 type
21 currencyCode
22 centAmount
23 fractionDigits
24 }
25 totalTax {
26 type
27 currencyCode
28 centAmount
29 fractionDigits
30 }
31 }
32 custom {
33 customFieldsRaw {
34 name
35 value
36 }
37 }
38 customer {
39 id
40 email
41 firstName
42 lastName
43 title
44 defaultShippingAddress {
45 phone
46 }
47 defaultBillingAddress {
48 phone
49 }
50 }
51 lineItems {
52 id
53 variant {
54 sku
55 }
56 quantity
57 state {
58 quantity
59 state {
60 id
61 key
62 }
63 }
64 custom {
65 customFieldsRaw {
66 name
67 value
68 }
69 }
70 taxedPrice {
71 totalNet {
72 type
73 currencyCode
74 centAmount
75 fractionDigits
76 }
77 totalGross {
78 type
79 currencyCode
80 centAmount
81 fractionDigits
82 }
83 totalTax {
84 type
85 currencyCode
86 centAmount
87 fractionDigits
88 }
89 }
90 }
91 shippingInfo {
92 deliveries {
93 id
94 custom {
95 customFieldsRaw {
96 name
97 value
98 }
99 }
100 parcels {
101 id
102 trackingData {
103 trackingId
104 carrier
105 provider
106 providerTransaction
107 isReturn
108 }
109 }
110 }
111 shippingMethodName
112 shippingMethod {
113 name
114 key
115 predicate
116 }
117 taxedPrice {
118 totalNet {
119 type
120 currencyCode
121 centAmount
122 fractionDigits
123 }
124 totalGross {
125 type
126 currencyCode
127 centAmount
128 fractionDigits
129 }
130 totalTax {
131 type
132 currencyCode
133 centAmount
134 fractionDigits
135 }
136 }
137 }
138 shippingAddress {
139 title
140 firstName
141 lastName
142 streetName
143 streetNumber
144 additionalStreetInfo
145 postalCode
146 city
147 region
148 state
149 country
150 company
151 department
152 building
153 apartment
154 pOBox
155 phone
156 mobile
157 email
158 fax
159 additionalAddressInfo
160 externalId
161 key
162 }
163 billingAddress {
164 title
165 firstName
166 lastName
167 streetName
168 streetNumber
169 additionalStreetInfo
170 postalCode
171 city
172 region
173 state
174 country
175 company
176 department
177 building
178 apartment
179 pOBox
180 phone
181 mobile
182 email
183 fax
184 additionalAddressInfo
185 externalId
186 key
187 }
188 }
189}
Language: json
Name: GetOrder.graphql
Description:
[Warning: empty required content area]Mutation to update order in commercetools
1mutation Search($id: String!, $version: Long!, $actions: [OrderUpdateAction!]!) {
2 search: updateOrder(id: $id, version: $version, actions: $actions) {
3 id
4 }
5}
Language: json
Name: update order
Description:
[Warning: empty required content area]