Marketplaces / Zalando Direct connection / Zalando Orders Download / Zalando Orders Download (1)

Zalando Orders Download (1)

Version Created / Updated by Date Notes
1.0 Danail Deltchev
1.1 Danail Deltchev 22.11.2022 Change in mapping in order (SKU and ChannelItemID)
1.2 Danail Deltchev 24.11.2022 Additional mapping for Zalando ID
1.3 Danail Deltchev 07.11.2022 Change in Order Item Line Status Mapping
             [HEMISPHERE-16002](https://hemi.atlassian.net/browse/HEMISPHERE-16002)
                -
        Getting issue details...
                                STATUS |

| 1.4 | Danail Deltchev | 05.06.2023 | Addition to return download validation and mapping |

The purpose of this document is to detail the download of orders from Zalando

The flow will be focused on the Seller fulfilment model but as already mentioned there will be some specifics around Zalando Fulfilled orders - please watch out for the ZFS specifications

The steps allowed by Zalando are the following

  • Download orders
  • Update “reserved stock” (something like a “picking” status update)
  • Update order as Exported (acknowledgement)
  • Update tracking (something like a “packed” status update)
  • Update orders to “Shipped”
  • If order can’t be fulfilled push a “Cancel” status per item
  • If post Shipment there is a return we have to mark the order (per item) as Returned

As mentioned the focus of this document will be the Download of the orders and all needs to make sure that orders are prepared for any of the following steps

“Reserve stock” is most probably something we will not use. Its purpose is to lock stock within Zalando itself which we would’ve already done as even pending orders trigger a stock recalculation for us

API Docs:

API Call: GET /merchants/{merchant_id}/orders

In all cases we are to use the above call for retrieving orders. Through usage of parameters for filtering, sorting and including (see below) we are to take all needed information to be able to map and set for processing the right way

The above mentioned Orders API if not altered will return only order data for the latest created orders by 50 on page. We want to be calling for updated after orders meaning we have to include the parameter:

last_updated_after (we always want to use UTC as zone)

Example call with last_updated_after: https://api-sandbox.merchants.zalando.com/merchants/{merchant_ID}/orders last_updated_after=2017-01-01T09:11:48Z Accept:application/vnd.api+json "Authorization:Bearer $YOUR_ACCESS_TOKEN"

By this parameter we can specify orders that are modified after a certain time. On this premise we want to make our standard overlap and capture orders with a minimum of 15 minutes in the past FROM the previous successful run

Because the limit of the orders in page(50) we will need to use and page number parameter in the url(page[number]).

To be able to capture all needed information we need to use the “include” parameter. This allows us to add multiple different sections besides just the standard Order information. We want to include “order_items” and “order_lines”.

Example call with include:

https://api-sandbox.merchants.zalando.com/merchants/{merchant_ID}/orders include=order_items,order_lines Accept:application/vnd.api+json "Authorization:Bearer $YOUR_ACCESS_TOKEN"

Example detailed response to an order call:

{
  "data": {
    "type": "Order",
    "id": "",
    "attributes": {
      "merchant_id": "",
      "logistics_provider_id": "",
      "order_id": "",
      "order_number": "",
      "order_date": "2019-11-18T09:12:41.947+00:00",
      "merchant_order_id": "",
      "sales_channel_id": "",
      "locale": "de-DE",
      "customer_number": "",
      "status": "approved",
      "shipping_address": {
        "address_type": "HOME_ADDRESS",
        "address_id": "",
        "first_name": "Bob",
        "last_name": "Smith",
        "address_line_1": "123 Main Street",
        "zip_code": "90125",
        "city": "Wolkenkuckucksheim",
        "country_code": "DE"
      },
      "shipment_number": "",
      "billing_address": {
        "address_type": "HOME_ADDRESS",
        "address_id": "",
        "first_name": "Bob",
        "last_name": "Smith",
        "address_line_1": "123 Main Street",
        "zip_code": "90125",
        "city": "Wolkenkuckucksheim",
        "country_code": "DE"
      },
      "tracking_number": "",
      "return_tracking_number": "",
      "order_lines_count": 4,
      "order_lines_price_amount": 325,
      "order_lines_price_currency": "EUR",
      "delivery_end_date": "2019-11-22T09:12:32.169+00:00",
      "exported": true,
      "created_by": "",
      "created_at": "2019-11-18T13:53:50.803+00:00",
      "modified_by": "",
      "modified_at": "2019-11-26T02:01:02.777+00:00",
      "order_type": "PartnerFulfilled",
      "customer_email": "",
      "stock_location_id": ""
    },
    "links": {
      "self": "URL"
    },
    "relationships": {
      "order_items": {
        "links": {
          "related": "URL"
        },
        "data": [
          {
            "type": "OrderItem",
            "id": "001"
          },
          {
            "type": "OrderItem",
            "id": "002"
          }
        ]
      },
      "order_transitions": {
        "links": {
          "related": "URL"
        }
      }
    }
  },
  "included": [
    {
      "type": "OrderItem",
      "id": "001",
      "attributes": {
        "order_item_id": "",
        "order_id": "",
        "article_id": "SKU-456",
        "external_id": "",
        "description": "Cool Shoes",
        "quantity_initial": 0,
        "quantity_reserved": 0,
        "quantity_shipped": 3,
        "quantity_returned": 0,
        "quantity_canceled": 0,
        "created_by": "system",
        "created_at": "2019-11-18T13:53:50.803+00:00",
        "modified_by": "",
        "modified_at": "2019-11-26T02:00:36.032+00:00"
      },
      "links": {
        "self": "URL"
      },
      "relationships": {
        "order_lines": {
          "links": {
            "related": "URL"
          },
          "data": [
            {
              "type": "OrderLine",
              "id": "001"
            },
            {
              "type": "OrderLine",
              "id": "002"
            },
            {
              "type": "OrderLine",
              "id": "003"
            }
          ]
        }
      }
    },
    {
      "type": "OrderItem",
      "id": "002",
      "attributes": {
        "order_item_id": "",
        "order_id": "",
        "article_id": "SKU-987",
        "external_id": "",
        "description": "Nifty Hat",
        "quantity_initial": 0,
        "quantity_reserved": 0,
        "quantity_shipped": 1,
        "quantity_returned": 0,
        "quantity_canceled": 0,
        "created_by": "system",
        "created_at": "2019-11-18T13:53:50.803+00:00",
        "modified_by": "",
        "modified_at": "2019-11-26T02:00:36.032+00:00"
      },
      "links": {
        "self": "URL"
      },
      "relationships": {
        "order_lines": {
          "links": {
            "related": "URL"
          },
          "data": [
            {
              "type": "OrderLine",
              "id": "007"
            }
          ]
        }
      }
    },
    {
      "type": "OrderLine",
      "id": "001",
      "attributes": {
        "order_line_id": "",
        "order_item_id": "",
        "status": "shipped",
        "price": {
          "amount": 50,
          "currency": "EUR"
        },
        "discounted_price":{
           "amount":50,
           "currency":"EUR"
        },
        "created_by": "system",
        "created_at": "2019-11-18T13:53:50.803+00:00",
        "modified_by": "",
        "modified_at": "2019-11-26T02:00:36.032+00:00",
        "source_stock_location_id": "44836AD6-F22A-49A5-B7D9-98479EB95BB5",
        "refunds": [
          {
            "date": "2020-09-14T14:52:09.772Z",
            "amount": 39.99,
            "reason": "DELIVERY_IS_MISSING_WAREHOUSE",
            "trigger": "manual",
            "currency": "EUR"
          }
        ]
      },
      "links": {
        "self": "URL"
      },
      "relationships": {
        "order_line_transitions": {
          "links": {
            "related": "URL"
          }
        }
      }
    },
    {
      "type": "OrderLine",
      "id": "002",
      "attributes": {
        "order_line_id": "",
        "order_item_id": "",
        "status": "shipped",
        "price": {
          "amount": 100,
          "currency": "EUR"
        },
        "discounted_price":{
           "amount":100,
           "currency":"EUR"
        },
        "created_by": "system",
        "created_at": "2019-11-18T13:53:50.803+00:00",
        "modified_by": "",
        "modified_at": "2019-11-26T02:00:36.032+00:00",
        "source_stock_location_id": "44836AD6-F22A-49A5-B7D9-98479EB95BB5",
        "refunds": [
          {
            "date": "2020-09-14T14:52:09.772Z",
            "amount": 39.99,
            "reason": "DELIVERY_IS_MISSING_WAREHOUSE",
            "trigger": "manual",
            "currency": "EUR"
          }
        ]
      },
      "links": {
        "self": "URL"
      },
      "relationships": {
        "order_line_transitions": {
          "links": {
            "related": "URL"
          }
        }
      }
    },
    {
      "type": "OrderLine",
      "id": "003",
      "attributes": {
        "order_line_id": "",
        "order_item_id": "",
        "status": "shipped",
        "price": {
          "amount": 100,
          "currency": "EUR"
        },
        "discounted_price":{
           "amount":100,
           "currency":"EUR"
        },
        "created_by": "system",
        "created_at": "2019-11-18T13:53:50.803+00:00",
        "modified_by": "",
        "modified_at": "2019-11-26T02:00:36.032+00:00",
        "source_stock_location_id": "44836AD6-F22A-49A5-B7D9-98479EB95BB5",
        "refunds": [
          {
            "date": "2020-09-14T14:52:09.772Z",
            "amount": 39.99,
            "reason": "DELIVERY_IS_MISSING_WAREHOUSE",
            "trigger": "manual",
            "currency": "EUR"
          },
          {
            "date": "2020-09-14T14:52:09.772Z",
            "amount": -39.99,
            "reason": "DELIVERY_IS_MISSING_WAREHOUSE",
            "trigger": "manual",
            "currency": "EUR"
          }
        ]
      },
      "links": {
        "self": "URL"
      },
      "relationships": {
        "order_line_transitions": {
          "links": {
            "related": "URL"
          }
        }
      }
    },
    {
      "type": "OrderLine",
      "id": "007",
      "attributes": {
        "order_line_id": "",
        "order_item_id": "",
        "status": "shipped",
        "price": {
          "amount": 75,
          "currency": "EUR"
        },
        "discounted_price":{
           "amount":75,
           "currency":"EUR"
        },
        "created_by": "system",
        "created_at": "2019-11-18T13:53:50.803+00:00",
        "modified_by": "",
        "modified_at": "2019-11-26T02:00:36.032+00:00",
        "source_stock_location_id": "44836AD6-F22A-49A5-B7D9-98479EB95BB5",
        "refunds": [
          {
            "date": "2020-09-14T14:52:09.772Z",
            "amount": 39.99,
            "reason": "DELIVERY_IS_MISSING_WAREHOUSE",
            "trigger": "manual",
            "currency": "EUR"
          },
          {
            "date": "2020-09-14T14:52:09.772Z",
            "amount": -39.99,
            "reason": "DELIVERY_IS_MISSING_WAREHOUSE",
            "trigger": "manual",
            "currency": "EUR"
          }
        ]
      },
      "links": {
        "self": "URL"
      },
      "relationships": {
        "order_line_transitions": {
          "links": {
            "related": "URL"
          }
        }
      }
    }
  ]
}

Mapping:

Zalando Fields WAP Mapping WAP Notes
data N/A
type N/A Marking the type of the following section. As part of “data” we are expecting to receive the “orders” information, hence we are looking for “order” type so we can start our mapping process
id Order Zalando > Sales Order ID This is our general ID by which we are tracking and updating / communicating for a single order
attributes
merchant_id N/A ID of the merchant on Zalando
logistics_provider_id N/A
order_id Orders > Marketplace Order ID This is our general ID by which we are tracking and updating / communicating for a single order
For more information please see below section Additional Information > Order structure
order_number Order Zalando > Order Number

AND Orders > Selling Manager SalesRecordNumber | | | | | order_date | | | Orders > Order Created Time | | | | | merchant_order_id | | | N/A | Our own ID | | | | sales_channel_id | | | N/A | The ID of the Zalando Channel to map and ensure it is to the right account | | | | locale | | | Order Zalando > Locale | As sales_channel_id but human readable | | | | customer_number | | | Orders > Buyer user ID | | | | | status | | | Orders > Order status | | | | | shipping_address | | | N/A | There is a specific handling of Shipping addresses based on their Type For more information please see below section Additional Information > Shipping Addresses | | | | | address_type | | Orders > Type | If the order is “PartnerFulfilled” we have the following mapping: • HOME_ADDRESS - Home • PICKUP_POINT - Click and collect • PACK_STATION - Pack Station (new value) If the order is “ZalandoFulfilled” we map this field to “Marketplace fulfilled” (new value that should incorporate ZFS, FBA , eBay fulfilled and any other such options) NOTE: Any of the below fields in Shipping address are to be mapped the same way no matter if it is Seller fulfilled or ZFS. The only difference will come from the “address_type” information coming from Zalando | | | | | address_id | | Orders > Shipping Address ID | | | | | | first_name | | Orders > Shipping Buyer Name | Concat with “last_name” with a single space between them | | | | | last_name | | Orders > Shipping Buyer Name | Concat with “first_name” with a single space between them | | | | | address_line_1 | | Orders > Shipping Street 1 | | | | | | address_line_2 | | Orders > Shipping Street 2 OR Order Zalando > Service Point Name AND Order Zalando > Service Point ID AND Order Zalando > Service Point Member ID

OR Order Zalando > Membership ID | The case goes the following way IF address_type = HOME_ADRESS OR IF address_type = PICKUP_POINT (Note: might be a good idea to store the string in a separate field as a value just in case there are changes. If we can’t map both fields in this option this should be an error for insufficient Shipping address information) OR IF address_type = PACK_STATION (Note: if we can’t map this value we are to treat this as error for insufficient Shipping address information) | | | | | address_line_3 | | Orders > Shipping Street 2 | We have to make a check if this value is the same as “city”. If it is just skip it. If it is different though: In the case of address_type = HOME_ADDRESS we are to concatenate this value to Street2 with a single space between them In the other two cases we should directly place the value within our Street2 field as there is nothing to concatenate to | | | | | zip_code | | Orders > Shipping Post Code | | | | | | city | | Orders > Shipping City | | | | | | country_code | | Orders > Shipping Country Code | Because we dont have Shipping Country Name in the mapping from Zalando we will map it with the shipping country code from our lookup list. | | | | | service_point_details | | N/A | | | | | | | service_point_name | Order Zalando > Service Point Name | SAME AS ADDRESS LINE 2 IN THE CASE OF “PICKUP_POINT”. OPTION FOR ADDITIONAL CHECK FOR MISSING INFO TO HOPEFULLY FILL IN EVERYTHING NEEDED FOR THE ORDER | | | | | | service_point_id | Order Zalando > Service Point ID | | | | | | | service_point_member_id | Order Zalando > Service Point Member ID | | | | | shipment_number | | | N/A | | | | | billing_address | | | N/A | | | | | | address_type | | N/A | | | | | | address_id | | Orders > Billing Address ID | New field. | | | | | first_name | | Orders > Billing Name | Concat with “last_name” with a single space between them | | | | | last_name | | Orders > Billing Name | Concat with “first_name” with a single space between them | | | | | address_line_1 | | Orders > Billing Street 1 | | | | | | address_line_2 | | Orders > Billing Street 2 | | | | | | address_line_3 | | Orders > Billing Street 2 | Make a check if the value is the same as for “city”. If yes, skip, if not - concatenate to Street2 with a single space between them | | | | | zip_code | | Orders > Billing Post code | | | | | | city | | Orders > Billing City | | | | | | country_code | | Orders > Billing Country Code | | | | | tracking_number | | | Orders > Shipping Track Num | | | | | return_tracking_number | | | Orders > Return ID | | | | | order_lines_count | | | N/A | General count of quantity for the order | | | | order_lines_price_amount | | | Orders > Order Total Amount Orders > Order Subtotal Amount | Should be calculated be summing of all order items. (Order Item > Item Price Order Item > Order Item > Quantity) | | | | order_lines_price_currency | | | Orders > Currency | | | | | delivery_end_date | | | Orders > Deliver By date | New field | | | | exported | | | N/A | | | | | created_by | | | N/A | | | | | created_at | | | Order Zalando > Fulfilment Order Approved Date | | | | | modified_by | | | N/A | | | | | modified_at | | | N/A | | | | | order_type | | | N/A | Field is used to track Hemisphere order type as described above | | | | customer_email | | | Orders > Buyer email | | | | | stock_location_id | | | N/A | | | | links | | | | N/A | | | | | self | | | N/A | To be checked at a later stage if we want to store this | | | relationships | | | | N/A | Relationships describe the flow and connections between the different sections of an order For more information please see below section Additional Information > Relationships | | | | order_items | | | N/A | | | | | | links | | N/A | | | | | | | related | N/A | | | | | | data | | N/A | | | | | | | type | N/A | Expectation for Order is always to have “OrderItem” as type of relationship sections. Through the following IDs is made the connection to the actual order items in the “included” section following the “data” section | | | | | | id | Order Item > Item Order Line ID | ID to follow the actual ordered Item to capture more information and then follow through to the Item Lines | | | | order_transitions | | | N/A | | | | | | links | | N/A | | | | | | | related | N/A | | | included | | | | | N/A | The section that holds all additional data for an order that sits in separate “levels” (please see “Order Structure” below). In this document below you will see two “types” of “included” so we can map and detail the needs for bot “OrderItem” and “OrderLine” | | | type | | | | N/A | Below section follows the “OrderItem” level | | | id | | | | Order Item > Item Order Line ID | | | | attributes | | | | N/A | | | | | order_item_id | | | N/A | | | | | order_id | | | N/A | | | | | article_id | | | Order Item > Channel Item ID | | | | | external_id | | | Order Item > Item SKU | | | | | description | | | Order Item > Item Title | | | | | quantity_initial | | | Order Item > Item Quantity | All these combined should provide the original ordered quantity. Single quantity should not stay in two statuses it should always only move from one to the other. Summing these fields will give us the total ordered always, no matter at what status we are downloading the order | | | | quantity_reserved | | | Order Item > Item Quantity | | | | | quantity_shipped | | | Order Item > Item Quantity | | | | | quantity_returned | | | Order Item > Item Quantity | | | | | quantity_canceled | | | Order Item > Item Quantity | | | | | created_by | | | N/A | | | | | created_at | | | N/A | | | | | modified_by | | | N/A | | | | | modified_at | | | N/A | | | | links | | | | N/A | | | | | self | | | N/A | To be checked at a later stage if we want to store this | | | relationships | | | | N/A | As already mentioned this describes the relationship with following levels within the order | | | | order_lines | | | N/A | | | | | | links | | N/A | | | | | | | related | N/A | | | | | | data | | N/A | | | | | | | type | N/A | When in the OrderItem level we are always expecting to see the associated “OrderLines” | | | | | | id | N/A | | | | type | | | | N/A | Below section follows the “Orderline” level | | | id | | | | Order Item Line > mp_order_item_id | | | | attributes | | | | N/A | | | | | order_line_id | | | N/A | | | | | order_item_id | | | N/A | | | | | status | | | Order Item Line > Marketplace Status | | | | | price | | | N/A | | | | | | amount | | Order Item > Item Price AND Order Item Line > Price | IMPORTANT: In a case where we have “discounted_price” as well it should take precedence for the Item Price in Hemisphere. In any such cases we are to track the difference between “price” and “discounted_price” to calculate the Order Item > discount_amount Also as it is obvious price is on Line level meaning there is a chance we face a single product with different line prices. To capture this the right way for each “OrderItem” we have to calculate the “average” price and discounted_price to decide what to store then in the Hemisphere Order Item section Additionally the two fields should be stored against each item as well for better traceability NEW - confirm line prices should stay in Order Item Line table as new fields. TO BE ADDED - description for enrichment of the process in order download abstraction | | | | | currency | | N/A | | | | | discounted_price | | | N/A | | | | | | amount | | Order Item > Item Price* AND Order Item Line > Price | Please see price above for more info | | | | | currency | | N/A | | | | | created_by | | | N/A | | | | | created_at | | | N/A | | | | | modified_by | | | N/A | | | | | modified_at | | | N/A | | | | | source_stock_location_id | | | N/A | | | | | refunds | | | N/A | Seems on Zalando Refunds are tracked per Line and to make it more fun they can seem reversible (Note: This poses a big question that will be communicated with Zalando, so this is TBD not with the team at this point though)

Additionally there is the option to not have this section at all but still have a canceled or returned line For more information please see below section Additional Information > Refunds | | | | | date | | Order Payment > Payment Date | | | | | | amount | | Order Payment > Total Amount | | | | | | reason | | Order Payment > Reason | | | | | | trigger | | N/A | | | | | | currency | | N/A | | | | links | | | | N/A | | | | | self | | | N/A | | | | relationships | | | | N/A | | | | | order_line_transitions | | | N/A | | | | | | links | | N/A | | | | | | | related | N/A | |

Additional Information:

  • Order Structure - The Orders in Zalando have 3 levels in their structure - Order, OrderItem and OrderLine. Those are generally following the same structure we have in Hemisphere as well with the biggest difference being that Zalando holds the price on Line level opposed to us where we hold it on Item level. The way the Structure in Zalando works is in the standard call, as part of a “data” section we receive the “Order” information. If we don’t specifically request as an “include” specific to receive OrderItem and OrderLine we will not. Once requested though within the “include” response section we are getting both of those levels in the same object hierarchy where the flow is actually Order > OrderItem > OrderLine. This can be recognised and followed through the “Relationship section” (more information below) *Note:* The only question I am still not 100% sure of is if there is any additional grouping in calling multiple orders with “include”. Nothing is leading me to believe so, hence all the explanations are focused around this structure provided by Zalando themselves. At this point in MP integrations everything is possible though 🙂 What else is important to know and understand for Zalando is how they generally handle Orders in their system which will help with understanding of some IDs. What we receive as “order” in Zalando’s system is actually the so called “Fulfillment Order”. A fulfilment order is a combination of products that a seller is supposed to fulfil together for a buyer. This bundling up can be done by “merchant”, “sales_channel_id” and other. What this gives us as information is 2 things
    • There is 1 more layer overarching the fulfilment order - this is what the buyer sees as a buyer can actually purchase multiple products from different “merchants” together
    • Depending on how many merchants we are servicing and our general internal structure this means that we can see on the marketplace Order Numbers that are actually duplicated across different instances BUT we will always have a unique order_id (which is in effect the fulfilmentOrderId)
  • Statuses - The Order and OrderLine statuses work differently in Zalando - The Order level one is mostly for knowledge and has some generalisations while the Line level status gives us a detailed breakdown. We should use a combination of those two to determine how to act on our own status. Below you can see the different options for those two statuses with their explanations followed by a table on how this should affect our own tool status
    • Order Status
      • initial - this is something that we generally threat as a “pending” tool status - a placed order that is still not paid
      • approved - payment has peen confirmed by Zalando and the order can now be processed and shipped. Post this status we can actually start going into details of the Line statuses too to decide what we want but generally we are expecting that post this status we should have an order ready for processing. We want to store it as “pending” the first time around so we can “export” it which is basically an acknowledgement step. We want to keep it on “pending” until acknowledged successfully as if we don’t manage to update Zalando for whatever reason 3 hours after the order placement it will be auto canceled. Once we read back from Zalando both an “approved” and “exported: true” order we can continue and update it to RFS or Incomplete in Hemisphere
      • fulfilled - a completed order for Zalando - this can be Shipped, canceled or Returned Line statuses which are all final statuses
    • Order Line Status - this follows predominantly the status of the quantity
      • initial - default starting status - quantity needs to be picked and something done with it
      • reserved - we have specifically reserved quantity for this (within our tool this is the default behaviour, unless specifically requested and found this is helpful to send to Zalando we will NOT use this status and updates for this. We are taking care of this via our own stock calculations)
      • shipped - a line is packed and shipped - this is treated as final status for Zalando although we can update later as Returned
      • canceled - a status (and update) to be used prior to shipments - in cases where we could not fulfil the item. Final status for the line
      • returned - a status to be pushed once items have been received within the warehouse (our way of approving a refund to be made on the Marketplace). Final status for the line
Order Status Order Line Status WAP Tool status WAP Notes
initial N/A Pending When the Order status is “initial” this means no payment has been cleared = doesn’t matter if there are any specific changes to the lines statuses - this is Pending
approved N/A Pending*
Ready For Shipping (Incomplete) An Order status of “approved” means that there is at least one Line that still hasn’t reached a final status. This means for us that whatever other line statuses are there is at least one that we need to fulfil = “RFS” (or incomplete in a case of insufficient information as per our standards)
New: We have to store the approved orders initially as “pending” as well until we “export” them successfully. Once we do so we should receive the order back from Zalando as status “approved” but also “exported: true” at which point we move to the standard RFS / Incomplete logic
fulfilled Shipped Shipped If there is at least one Line status on “shipped” yet this is still a Shipped order for us (even if partially canceled / returned as well)
fulfilled Returned / canceled canceled If all Line statuses are any mixture of “returned” and / or “canceled” statuses for us this is a generally fully canceled order
  • Shipping Addresses - Just to reiterate: there are different types of addresses and we have to follow slightly different logic for address 2 and 3 fields depending on this. Address 2 and 3 are fields that might not be present at all at which point based on the type we have to take the decision if this is a problem for us or not. Also as a reminder we should be ready for the scenario where Billing address is not provided at all at which point we should map fields from the Shipping section to the Billing section
  • Relationships - Relationships as per the structure above work in providing associated IDs for OrderItems into Orders section and for OrderLines into the relevant OrderItem section. Information to take care of - Data section and Include sections are separate, meaning we will probably receive a lot of orders first and then their orderItems and Lines included - we want to store a full order (including any enrichments) at the same time. Also just to mention again - OrderItem and OrderLine sit on the same “level” under the “include” section and only the Relationship sections are pointing us to the right objects to track and connect. It can be a good validation to track general price and quantity of all Lines recorded against an order with the totals provided in the “Order” section to ensure we’ve mapped everything as expected
  • Refunds - this section provides with information directly on the Line and Item what is refunded and when. There are no specific IDs that are combining any such refunds so expectation is that we are going to treat every single Line > Refund as a separate partial refund. Each Line should be looked through by itself though as it is the total for that specific line and can be used for combination and validation against the “total”. Last but not least (with a big question) - it seems refunds can be reversed as well. If we are reading an OrderLine with multiple refunds that we haven’t stored yet (should be able to map via the date against this item’s refund) we should track both positive and negative values. If we have (as per the example) values that are cancelling each other out we don’t have anything to store. If there is more positive value though than the negative we have to store a refund. In case there is more negative than the positive we are to store a refund with an error on it and have the overspill value as part of the message NEW: Based on latest information from their test orders we need to create a separate fallback for Refunds. In case we don’t have a “refund” section to an order line BUT the line is on a “canceled” or “returned” status we are to treat the whole line as refunded for our refund processor. This means we should use the following 1) Store the time of reading the order record from Zalando as “refund date” 2) The price to be used should be captured the same way as for an order_item record - if we have discountedAmount we should use it as the “refund amount” for this specific line. If not we should default to the standard “price” provided by Zalando 3) For “reason” we should simply store the status of the line. If we are capturing multiple potential refunds in one and are not storing a partial refund for each product / line separately then we should just use the string “canceled or Returned”. If we store separate refunds though it will be good to directly store the status as reason in this case (v1.4) The way we should map refunds is by their OrderLine ID and map it by the Hemi field Order Item Line > Marketplace Order Item ID. When downloading the order as per the above description there are two ways to spot a refund on an order item line. We need to check all Completed Refunds in Hemi and map if this line has already been refunded. If yes we should skip it so we don’t duplicate a refund. If it is missing though we need to store it as per the above descriptions. The Transaction ID generation should follow a simple flow of getting the value we store in Orders > Marketplace Order ID and add the next available 2 digits numeration from the available refunds (end result should be like this hduw68a6d87wta8d7686_01, fgfggg172639739172gg31hxx_02 and so on. Everything else should be treated the same way as if we have “refunds” section - initial fields, filling in the refund rows and statuses on the order_items, etc.

Note: As a gentle reminder - we want all abstraction requirements to fit here too - create payment record when order status is different from pending, fill in Country name, debundle the order, calculate the VAT (if abstraction part is ready), etc

Is this article helpful?
0 0 0