Nykaa: Order Sync Flow
Step 1: At first, we will fetch all the connections with their respective channels on the basis of the integration type of the Nykaa app. To fetch the connections based on the automation step’s stepId, we will be using the following query:
SELECT ie_app_automation_steps_config.connectionId,
ie_app_automation_steps_config.latestSyncTimeStamp, ie_appinstall_connection.accessToken
FROM ie_app_automation_steps_config
LEFT JOIN ie_appinstall_connection ON ie_app_automation_steps_config.connectionId=ie_appinstall_connection.id
WHERE ie_app_automation_steps_config.appAutomationStepId=?
AND ie_app_automation_steps_config.isActive='1'
AND ie_appinstall_connection.accessToken IS NOT NULL
AND ie_appinstall_connection.isActive = 'active'
Step 2: Secondly, we will iterate over the connection id and fetch all the channel related data corresponding to the connection id using the following query:
SELECT channels.connectionId,channels.externalChannelId ,external_wms_channels.locationId,
warehouses.externalWarehouseId,accounts.account_slug,channels.integration_model_id ,
channels.integrationType AS integrationType
FROM channels
LEFT JOIN external_wms_channels ON channels.id= external_wms_channels.channel_id
LEFT JOIN warehouses ON warehouses.id = external_wms_channels.warehouse_id
LEFT JOIN accounts ON channels.account_id = accounts.id
WHERE channels.connectionId IN (?)
Now, we will prepare an object as shown below from the data received by executing the above query and send it further in the task queue.
Channel connection map object:
{
"channelData": {
"integrationType": "17",
"externalChannelId": " ",
"accountSlug": " ",
"connectionId": " ",
"location": {
"Test": "Warehouse"
},
"latestSyncTimeStamp": " ",
"isActive": "active",
"refreshToken": " ",
"inputFields": {
"username": "ajay@eshopbox.com",
"password": "eshop@123"
}
}
}
The access token is generated needs to be stored in Cache Memory in the specified format given below:
{
"connectionAccessToken_{{connectionId}}":"{{ACCESS TOKEN}}"
}
Step 3: We will then hit the get order list API of Nykaa to fetch order’s list. While hitting the API, we also require to send a request body consisting of these following filters: updateDate, filterStatusList, sellerId, pageNumber and limit.
Sample API:
https://xxxxx/RestWS/api/sellerPanel/v3/orderList
Sample Request Body:
{
"updateDate": "30/07/2020 17:55:09",
"filterStatusList": "1,5",
"sellerId": "mwhc2",
"pageNumber": "1",
"limit": "200"
}
Sample Headers:
Authorization : {{API Key}}
facility : {{Seller ID}}
Step 4: We receive the following response from Nykaa as shown below :
{
"responseCode": 0,
"responseMessage": "Success",
"orderList": [
{
"orderNo": "59878966-1",
"orderStatus": "15",
"orderDate": "14/06/2019 16:53:44",
"orderLastUpdateDate": "03/06/2020 17:47:07",
"onHold": "0",
"sellerId": "TEST4"
},
{
"orderNo": "53210664-1",
"orderStatus": "15",
"orderDate": "14/06/2019 16:53:44",
"orderLastUpdateDate": "04/06/2020 16:16:50",
"onHold": "0",
"sellerId": "TEST4"
},
{
"orderNo": "34033344-1",
"orderStatus": "15",
"orderDate": "14/06/2019 16:53:44",
"orderLastUpdateDate": "09/06/2020 13:29:29",
"onHold": "0",
"sellerId": "TEST4"
}
]
}
Step 5: We divide the list of orders obtained above, in the response, into a pack of 20 and send them further in a task queue with the channelData map.
{
"channelData": {
"integrationType": "17",
"externalChannelId": "",
"accountSlug": "",
"connectionId": "",
"location": {
"Warehouse": "Warehouse"
},
"workspaceToken": " ",
"accessToken": "",
"isActive": "active",
"refreshToken": " ",
"inputFields": "{\"tenant\":\"eshopbox\",\"username\":ajay@eshopbox.com,\"password\":\"eshop@123\"}",
"listOfOrders": [
{
"orderNo": "59878966-1",
"orderStatus": "15",
"orderDate": "14/06/2019 16:53:44",
"orderLastUpdateDate": "03/06/2020 17:47:07",
"onHold": "0", "sellerId": "TEST4"
},
{
"orderNo": "53210664-1",
"orderStatus": "15",
"orderDate": "14/06/2019 16:53:44",
"orderLastUpdateDate": "04/06/2020 16:16:50",
"onHold": "0", "sellerId": "TEST4"
},
{
"orderNo": "34033344-1",
"orderStatus": "15",
"orderDate": "14/06/2019 16:53:44",
"orderLastUpdateDate": "09/06/2020 13:29:29",
"onHold": "0", "sellerId": "TEST4"
}
]
}
Step 6: Now in the task queue listener, we will be preparing request body for each order by iterating over the order number and call the order fetch API from Nykaa.
API URL:
https://xxxxx/RestWS/api/sellerPanel/v3/orderFetch
Request body:
{"orderNo" : ["83724872-1"] }
Curl:
curl --location --request POST 'https://preprod.vineretail.com/RestWS/api/sellerPanel/v3/orderFetch' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'apiKey: NTFURVNUNH43OWUxZTY3MGY2YWE0MDUxYjQ3ZTE2ZWQxNjMyY2UzZGMyOTJhZWNkYTgyOTQ0ZDFhZWU4YTU0' \
--header 'Cookie: cfduid=d686824f48d566932427e0b40a10761a21600699771' \
--data-urlencode 'RequestBody={"orderNo" : ["83724872-1"] }'
Sample Headers:
Authorization : {{API Key}}
facility : {{Seller ID}}
Step 7: We will be receiving a response which is as follows:
{
"responseCode": 0,
"responseMessage": "Success",
"orders": [
{
"orderNo": "83724872-1",
"orderStatus": "5",
"orderDate": "14/06/2019 16:53:44",
"sla": null,
"customerName": "saswati p",
"paymentMethod": "1",
"orderAmount": "1479.00",
"orderCurrency": "INR",
"orderTaxAmount": "0.00",
"onHold": "0",
"shippingCharge": "200.00",
"discountAmount": "120.00",
"discCouponCode": null,
"storeCredit": "0.00",
"gvAmount": "0.00",
"codCharge": "0.00",
"address1": "flat D - 10, jrm pearl",
"address2": null,
"address3": null,
"phone": "0085980000",
"email": "pani@gmail.com",
"countryCode": "IND",
"state": "Haryana",
"city": "Humla",
"pinCode": "786007",
"billToName": "saswati p",
"bill_Address1": "flat D - 10, jrm pearl",
"bill_Address2": null,
"bill_Address3": null,
"bill_Phone": "0085980000",
"bill_Email": "pani@gmail.com",
"bill_CountryCode": "IND",
"bill_State": "Haryana",
"bill_City": "Humla",
"bill_ZipCode": "786007",
"cancelRemark": null,
"reasonForCancellation": null,
"priority": null,
"orderLastUpdateDate": "26/06/2019 17:22:13",
"masterOrderNo": "NYKL00003378",
"gstin": null,
"sellerId": "TEST4",
"orderItems": [
{
"lineNo": "1",
"deliveryMode": "1",
"skuCode": "TEST-55829-00006",
"skuName": "Test4 vendor SKU6",
"orderQty": "1",
"rejectedQty": null,
"cancelledQty": null,
"shippedQty": null,
"returnedQty": null,
"deliveredQty": null,
"lineAmount": "698.93",
"lineTaxAmount": "0.00",
"unitPrice": "699.00",
"mrp": "699.00",
"discountAmount": "100.00",
"shippingCharge": "99.93",
"codCharge": null,
"invoiceNo": null,
"transCode": "999904",
"transName": "NykaaSelf",
"awbNo": null,
"imeiNos": null,
"confirmDate": "26/06/2019 17:22:13",
"gvAmount": null,
"storeCredit": "0.00",
"lineStatus": "5",
"cst": null,
"vat": null
},
{
"lineNo": "2",
"deliveryMode": "1",
"skuCode": "TEST-55829-00005",
"skuName": "Test4 vendor SKU5",
"orderQty": "1",
"rejectedQty": null,
"cancelledQty": null,
"shippedQty": null,
"returnedQty": null,
"deliveredQty": null,
"lineAmount": "780.07",
"lineTaxAmount": "0.00",
"unitPrice": "700.00",
"mrp": "700.00",
"discountAmount": "20.00",
"shippingCharge": "100.07",
"codCharge": null,
"invoiceNo": null,
"transCode": "999904",
"transName": "NykaaSelf",
"awbNo": null,
"imeiNos": null,
"confirmDate": "26/06/2019 17:22:13",
"gvAmount": null,
"storeCredit": "0.00",
"lineStatus": "5",
"cst": null,
"vat": null
}
]
}
]
}
Step 8: We will be adding the order details in the channelData map in the following way:
{
"channelData": {
"integrationType": "17",
"externalChannelId": "",
"accountSlug": "",
"connectionId": "",
"location": {
"Warehouse": "Warehouse"
},
"workspaceToken": " ",
"accessToken": "",
"isActive": "active",
"refreshToken": " ",
"inputFields": "{\"tenant\":\"eshopbox\",\"username\":ajay@eshopbox.com,\"password\":\"eshop@123\"}",
"listOfOrders": [
{
"orderNo": "59878966-1",
"orderStatus": "15",
"orderDate": "14/06/2019 16:53:44",
"orderLastUpdateDate": "03/06/2020 17:47:07",
"onHold": "0", "sellerId": "TEST4"
},
{
"orderNo": "53210664-1",
"orderStatus": "15",
"orderDate": "14/06/2019 16:53:44",
"orderLastUpdateDate": "04/06/2020 16:16:50",
"onHold": "0", "sellerId": "TEST4"
},
{
"orderNo": "34033344-1",
"orderStatus": "15",
"orderDate": "14/06/2019 16:53:44",
"orderLastUpdateDate": "09/06/2020 13:29:29",
"onHold": "0", "sellerId": "TEST4"
}
],
"orderDetails":{
"responseCode": 0,
"responseMessage": "Success",
"orders": [
{
"orderNo": "83724872-1",
"orderStatus": "5",
"orderDate": "14/06/2019 16:53:44",
"sla": null,
"customerName": "saswati p",
"paymentMethod": "1",
"orderAmount": "1479.00",
"orderCurrency": "INR",
"orderTaxAmount": "0.00",
"onHold": "0",
"shippingCharge": "200.00",
"discountAmount": "120.00",
"discCouponCode": null,
"storeCredit": "0.00",
"gvAmount": "0.00",
"codCharge": "0.00",
"address1": "flat D - 10, jrm pearl",
"address2": null,
"address3": null,
"phone": "0085980000",
"email": "pani@gmail.com",
"countryCode": "IND",
"state": "Haryana",
"city": "Humla",
"pinCode": "786007",
"billToName": "saswati p",
"bill_Address1": "flat D - 10, jrm pearl",
"bill_Address2": null,
"bill_Address3": null,
"bill_Phone": "0085980000",
"bill_Email": "pani@gmail.com",
"bill_CountryCode": "IND",
"bill_State": "Haryana",
"bill_City": "Humla",
"bill_ZipCode": "786007",
"cancelRemark": null,
"reasonForCancellation": null,
"priority": null,
"orderLastUpdateDate": "26/06/2019 17:22:13",
"masterOrderNo": "NYKL00003378",
"gstin": null,
"sellerId": "TEST4",
"orderItems": [
{
"lineNo": "1",
"deliveryMode": "1",
"skuCode": "TEST-55829-00006",
"skuName": "Test4 vendor SKU6",
"orderQty": "1",
"rejectedQty": null,
"cancelledQty": null,
"shippedQty": null,
"returnedQty": null,
"deliveredQty": null,
"lineAmount": "698.93",
"lineTaxAmount": "0.00",
"unitPrice": "699.00",
"mrp": "699.00",
"discountAmount": "100.00",
"shippingCharge": "99.93",
"codCharge": null,
"invoiceNo": null,
"transCode": "999904",
"transName": "NykaaSelf",
"awbNo": null,
"imeiNos": null,
"confirmDate": "26/06/2019 17:22:13",
"gvAmount": null,
"storeCredit": "0.00",
"lineStatus": "5",
"cst": null,
"vat": null
},
{
"lineNo": "2",
"deliveryMode": "1",
"skuCode": "TEST-55829-00005",
"skuName": "Test4 vendor SKU5",
"orderQty": "1",
"rejectedQty": null,
"cancelledQty": null,
"shippedQty": null,
"returnedQty": null,
"deliveredQty": null,
"lineAmount": "780.07",
"lineTaxAmount": "0.00",
"unitPrice": "700.00",
"mrp": "700.00",
"discountAmount": "20.00",
"shippingCharge": "100.07",
"codCharge": null,
"invoiceNo": null,
"transCode": "999904",
"transName": "NykaaSelf",
"awbNo": null,
"imeiNos": null,
"confirmDate": "26/06/2019 17:22:13",
"gvAmount": null,
"storeCredit": "0.00",
"lineStatus": "5",
"cst": null,
"vat": null
}
]
}
]
}
Step 9: We will push the above channel Data Map onto the pub/sub topic: nykaa_new_order_data.
Step 10: We will prepare the request body for create order API in the pub/sub topic listener.
Mapping of keys in create order API and keys in the channel data map is as follows:
No. | Keys in create order API | Keys in the channel data map or values set |
---|---|---|
1. | externalChannelID |
|
2. | customerOrderNumber |
|
3. | shipMethod |
|
4. | orderDate |
|
5. | isCOD |
|
6. | paymentType |
|
7. | taxAmount |
|
8. | shipChargeAmount |
|
9. | subtotal | Sum of lineItemTotal |
10. | orderTotal |
|
11. | balanceDue | if COD then orderTotal else if Prepaid then 0 |
12. | shippingAddress |
|
13. | shippingAddress.customerName |
|
14. | shippingAddress.addressLine1 |
|
15. | shippingAddress.addressLine2 (optional) |
|
16. | shippingAddress.city |
|
17. | shippingAddress.state |
|
18. | shippingAddress.postalCode |
|
19. | shippingAddress.countryCode |
|
20. | shippingAddress.countryName |
|
21. | shippingAddress.contactPhone |
|
22. | shippingAddress.email |
|
23. | billingAddress |
|
24. | billingAddress.customerName |
|
25. | billingAddress.addressLine1 |
|
26. | billingAddress.addressLine2 (optional) |
|
27. | billingAddress.city |
|
28. | billingAddress.state |
|
29. | billingAddress.postalCode |
|
30. | billingAddress.countryCode |
|
31. | billingAddress.countryName |
|
32. | billingAddress.contactPhone |
|
33. | billingAddress.email |
|
34. | items |
|
34. | items.lineItemSequenceNumber |
|
35. | items.itemID |
|
36. | items.orderItemID |
|
37. | items.productName |
|
38. | items.customerPrice |
|
39. | items.discount |
|
40. | items.lineItemTotal | orders.orderItems.lineAmount |
42. | items.productImageUrl |
|
43. | items.productUrl |
|
44. | items.quantity |
|
45. |
|
|
46. | items. |
|
47. | items.externalWarehouseID |
|
48. | vendorOrderNumber |
|
49. | thirdPartyShipping(optional) | ? |
50. | expectedShipDate | orders. |
51. | onHold | orders.onHold |
Step 11: WMS create API URL for creating orders in Eshopbox is as follows:
https://{{accountSlug}}.eshopbox.com/api/order
Sample request body:
{
"vendorOrderNumber": "83724872-1",
"balanceDue": " ",
"externalChannelID": " ",
"orderSiteID": " ",
"subtotal": ,
"customerOrderNumber": "83724872-1",
"orderTotal": 1479.00,
"paymentType": "1",
"isCOD": "1",
"shipMethod": " ",
"thirdPartyShipping": 1,
"shippingAddress": {
"customerName": "saswati p",
"addressLine1": "flat D - 10, jrm pearl",
"addressLine2": "",
"city": "Humla",
"state": "Haryana",
"postalCode": "786007",
"countryCode": "IND",
"countryName": " ",
"contactPhone": "0085980000",
"email": "pani@gmail.com"
},
"billingAddress": {
"customerName": "saswati p,
"addressLine1": "flat D - 10, jrm pearl",
"addressLine2": "",
"city": "Humla"",
"state": "Haryana",
"postalCode": "786007",
"countryCode": "IND",
"countryName": " ",
"contactPhone": "0085980000",
"email": "pani@gmail.com"
},
"taxAmount": 0.00,
"orderDate": "14/06/2019 16:53:44",
"items": [
{
"productImageUrl": " "
"itemID": "TEST-55829-00006",
"quantity": 1,
"lineItemSequenceNumber": "1",
"orderItemID": " ",
"discount": 100.0,
"lineItemTotal": 698.93,
"productUrl": "",
"customerPrice": ,
"externalWarehouseID": "Warehouse",
"productName": "Test4 vendor SKU6"
},
{
"productImageUrl": " "
"itemID": "TEST-55829-00005",
"quantity": 1,
"lineItemSequenceNumber": "2",
"orderItemID": " ",
"discount": 20.0,
"lineItemTotal": 780.07,
"productUrl": "",
"customerPrice": ,
"externalWarehouseID": "Warehouse",
"productName": "st4 vendor SKU5"
}
],
"shipChargeAmount": 0
}
Sample Header:
Authorization : Bearer token
Handling when order is hopped to another location :
Step 1 : Check if order is created or not on basis of channel id and custom order number
SELECT customerOrderNumber FROM orders WHERE channel_id =:channelId AND customerOrderNumber IN (:orderId)
Step 2 : If order exists, then cancel the shipment against customer order number
Get the order item details using the query :
select o.id from orders o where o.customerOrderNumber in ("a6bb1025-eb83-4b91-93be-350fc9731b0b");
select
oi.lineItemSequenceNumber as lineItemSequenceNumber,
oi.itemID as itemId ,
oi.orderItemId as orderItemId,
oi.quantity as quantity
from
order_items oi
inner join orders o on
o.id = oi.order_id
where
oi.order_id in (3)
Cancel shipment URL:
https://wms.eshopbox.com/api/cancel-order
Request body :
{
"reason": "Other",
"externalChannelID": "CH1491",
"cancellationTime": "2022-02-18 11:03:33",
"customerOrderNumber": "ESBPB06130",
"items": [
{
"itemID": "8907819297831",
"quantity": "1",
"lineItemSequenceNumber" : 3601014,
"remark": "Other"
},
{
"itemID": "8907819297831",
"quantity": "1",
"lineItemSequenceNumber" : 3601015,
"remark": "Other"
}
]
}
Step 3 : Now create a shipment and mention new location
Get the order item details using the query :
select o.id from orders o where o.customerOrderNumber in ("a6bb1025-eb83-4b91-93be-350fc9731b0b");
select
oi.lineItemSequenceNumber as lineItemSequenceNumber,
oi.itemID as itemId ,
oi.orderItemId as orderItemId,
oi.quantity as quantity
from
order_items oi
inner join orders o on
o.id = oi.order_id
where
oi.order_id in (3)
Request Body :
{
"externalChannelID": "CH1946",
"customerOrderNumber": "MCAGGN09425",
"externalShipmentID": "MCAGGN09425-1946-01",
"externalWarehouseID": "Gurgaon_FC",
"channelExpectedShipDate": "2023-01-01 10:51:51",
"items": [
{
"lineItemSequenceNumber": 18028361,
"itemID": "424ZL3GNFR8",
"quantity": 1,
"orderItemID": "MCAGGN09425-28178803",
"remark": "customer cancel"
},
{
"lineItemSequenceNumber": 18028363,
"itemID": "42BUC3GXB0I",
"quantity": 1,
"orderItemID": "MCAGGN09425-28178805",
"remark": "customer cancel"
},
{
"lineItemSequenceNumber": 18028364,
"itemID": "42CKW3GWZ60",
"quantity": 1,
"orderItemID": "MCAGGN09425-28178806",
"remark": "customer cancel"
},
{
"lineItemSequenceNumber": 18028365,
"itemID": "42H2B3GXB0U",
"quantity": 1,
"orderItemID": "MCAGGN09425-28178807",
"remark": "customer cancel"
},
{
"lineItemSequenceNumber": 18028366,
"itemID": "42T0X3H4APO",
"quantity": 1,
"orderItemID": "MCAGGN09425-28178808",
"remark": "customer cancel"
},
{
"lineItemSequenceNumber": 18028367,
"itemID": "42W4W3GWZ5C",
"quantity": 1,
"orderItemID": "MCAGGN09425-28178809",
"remark": "customer cancel"
}
]
}