Zalando Order Tracking and Shipping
Summary of Changes: (The purpose of this table is to keep traceability and Product team to highlight the things that were changed into the scope, based on comments or discussions)
Date | Version | Created/Update | Comment |
---|---|---|---|
v1.0 | Danail | First publish | |
09/08/2023 | v1.1 | Hristiyan | Added additional validation when sending shipment |
The purpose of this document is to detail the process in Zalando for tracking updates and shipping with relevant Hemisphere mappings and internal flow to be followed. Orders that are ZFS(Zalando Fulfilled orders) needs to be skipped because we cant ship ZFS orders. It can be checked from the field Order > Type which needs to be different from Marketplace Fulfilled).
API Docs: https://developers.merchants.zalando.com/docs/orders-preparing-shipping.html
API Call:
PATCH merchants/{merchant_ID}/orders/{order_ID}
(for Tracking update)PATCH /merchants/{merchant_ID}/orders/{order_ID}/items/{order_item_ID}/lines/{order_line_ID}
(for Shipping Status update)
Note: the parameters for this call can be taken as follows:
{order_ID}
- Orders > Marketplace Order ID{order_item_ID}
- Order Item > Item Order Line ID{order_line_ID}
- Order Item Line > mp_order_item_id
As a standard interpretation of a WMS system when products are usually packed a shipping label for them is produced. At this point is generally accepted that tracking information can be shared. This is why Zalando have actually split their flow for Tracking update AND for Shipping status update on items (fully expecting that they will not go out the door the second tracking references have been acquired from a Courier)
To account for this we will have to send our “Shipment” to Zalando and once it is successful only then update the OrderLines with the following Shipping status. As per Zalando’s documentation if we fire both calls with 5 or less seconds apart there is a chance that the order of processing gets mixed which causes issues for the order and account health. Following our Hemisphere Shipment success to “Shipped” status update will provide us the relevant time to do both in the right order and will ensure we are marking the statuses only after we’ve seen a success in updating the Tracking.
Tracking Update
Example call:
{
"data":{
"type":"Order",
"id":"$YOUR_ORDER_ID",
"attributes":{
"tracking_number":"$YOUR_TRACKING_NUMBER",
"return_tracking_number":"$YOUR_RETURN_TRACKING_NUMBER"
}
}
}
Mapping:
Zalando Field | WAP Mapping | WAP Notes | ||
---|---|---|---|---|
data |
N/A | |||
type |
Order | Hardcoded | ||
id |
Orders > Marketplace Order ID | |||
attributes |
N/A | |||
tracking_number |
Order Shipment > Tracking Number | |||
return_tracking_number |
Orders > Return ID | TBD if we don’t want to move this to Shipment as well |
For both “tracking_number” and “return_tracking_number” we can send only one value to Zalando. This means that in case we have a split shipment the values will overlap on Zalando but this is a known specific on their end. We are to track our Shipment by its status and if it returns an error, store it and stop there, but if / when returns success (and we store it as “completed”) set the shipment to sent status and move to the next step.
<v1.1> We want to add an additional validation and stop sending orders which have Orders > Retrun ID empty. We have to do this because for Zalando the Return ID is absolutely mandatory and sending orders with no Retrun ID causes issues with the account and possibility of closing down the account. So the validation should look for Orders > Return ID != ''
Incase we have an empty Return ID when trying to send an order, we want to :
- Raise
Order Shipment > Status = ‘Error’
- store an internal error in the
Order Errors table with type ‘Shipping’. As a suggesttion, the error message could be “Shipping failed! Return ID is empty! Please check and re-send” </v1.1>
Shipping Status Update
Example call:
{
"data":{
"id":"$ORDER_LINE_ID",
"type":"OrderLine",
"attributes":{
"status":"shipped"
}
}
}
Mapping:
Zalando Field | WAP Mapping | WAP Notes | ||
---|---|---|---|---|
data |
N/A | |||
id |
Order Item Line > mp_order_line_id | |||
type |
OrderLine | Hardcoded | ||
attributes |
N/A | |||
status |
shipped | Hardcoded |
As already specified this is a call that should run only after we’ve successfully sent to the marketplace a Tracking update. Additionally we have to update ONLY the Order Item Lines that have participated in this Order Shipment that was processed AND that satisfy the Zalando status requirement (they have to be on an “initial” or “received” status) and of course their internal paymen status needs to be different from Partially Refunded or Fully Refunded. When successfully updated to Zalando the Order Item Line > Status field in Hemisphere should also be updated to reflect the correct “shipped”(which is shipped) status on the marketplace. In case we are unsuccessful a relevant Order Error should be stored with the correct section, “error” severity and the relevant message to the error based on the response from Zalando.
Note: Just to stress on the need of time between one and the other calls - if a decision is made for the two steps to be happening in one execution in the end we must ensure we put the right time delay forcefully in place
NEW: As per the new parts of the Shipment abstraction change - when we get to the status updates on the MP (the tracking is one for all and it doesn’t matter the lines) we want to track what we’e successfully updated for a shipment and store an internal “shipped” status on the order_item_lines. From there as per the abstraction logic we should extrapolate the status of the order_item and the order itself. In case there are lines we are unable to ship we should put the Shipment on a Warning status and store the relevant info in order_error. We should also track successfully updated lines and store the “successfully updated quantity” on the shipment row levels