Ship-from-Store Orders

Orders are one of the most commonly used entities in the fulfillmenttools platform. Orders are typically used to trigger the DOMS and furthermore to start the overall fulfillment process.

Ship-from-Store (SfS) are shipped from a facility by a (logistics) carrier to the customer's address. Whether this facility is actually a store or a warehouse does not matter for this example. When placing an order with the fulfillmenttools platform, the deliveryPreferences are used to mark the order for shipping. Typically, a shipping label is needed for the parcels to be sent.

The other type of orders are Click-and-Collect (C&C) orders which are described in another use case document.

Ship-from-Store Orders

Here's an example on how to create a Ship-from-Store (SfS) order:

curl -sSL -X POST 'https://your.api.fulfillmenttools.com/api/orders' \
  --header 'Authorization: Bearer <TOKEN>' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "consumer": {
    "addresses": [
      {
        "addressType": "POSTAL_ADDRESS",
        "firstName": "Test",
        "lastName": "Customer",
        "street": "Domstr.",
        "houseNumber": "20",
        "postalCode": "50668",
        "city": "Köln",
        "country": "DE"
      }
    ],
    "email": "customer@mail.com"
  },
  "orderDate": "2023-03-06T17:30:00Z",
  "status": "OPEN",
  "tenantOrderId": "order-111",
  "customAttributes": {
    "someInternalId": "xyz-123"
  },
  "deliveryPreferences": {
    "shipping": {
      "preferredCarriers": [ "DHL_V2" ],
      "serviceLevel": "DELIVERY",
      "desiredDeliveryTime": "2024-05-05T15:00:00.000Z"
    },
    "reservationPreferences": {
      "mode": "ASAP" (default), "ALAP", "SCHEDULED"
      "reservationTime": "2024-05-04T13:00:00.000Z" // only for SCHEDULED
    }
  },
  "orderLineItems": [
    {
      "quantity": 2,
      "article": {
        "tenantArticleId": "111222333",
        "title": "T-Shirt",
        "imageUrl": "https://loremflickr.com/320/240/shirt",
        "attributes": [
          {
            "key": "%%subtitle%%",
            "value": "Super Brand",
            "category": "descriptive",
            "priority": 100
          },
          {
            "key": "Color",
            "value": "white",
            "category": "descriptive",
            "priority": 101
          },
          {
            "key": "Size",
            "value": "M",
            "category": "descriptive",
            "priority": 102
          }
        ]
      },
      "scannableCodes": [
        "5714500878421"
      ],
      "customAttributes": {
        "someInternalId": "0815"
      }
    }
  ]
}'

Some details on the example:

  • The deliveryPreferences mark this order as a shipping order:

    • The preferredCarriers is used to select the (logistics) carrier that was chosen for delivery.

    • The serviceLevel: This could be either DELIVERY for standard shipping, or SAMEDAY for sameday delivery.

    • Note there is no targetTime attribute as this is calculated by the fulfillmenttools platform depending on the facility and carrier configuration.

    • The desiredDeliveryTime contains the selected delivery time of the customer within the checkout of the shop. This in combination with the reservation preference mode defines when we check for stock reservation.

  • The email address is forwarded to the logistics carrier when a shipping label is requested. Make sure you have the customer's consent to process this data. Otherwise, supply a generic email address.

  • The "reservationPreferences" are used in case the order should not be fulfilled and the respective stock should not be reserved directly after the routing was performed. This is the case if the consumer places an order where the delivery date is further in the future (see desiredDeliveryTime ) and the stock should not be reserved instantly (e.g. if the items do have a best before date).

Address Formats for Specific Carriers

This section explains some carrier/country specific details for the consumer address. See this list for an overview of all available carriers.

Home Delivery

For most carriers and countries, Home Delivery is requested simply by setting the addressType to POSTAL_ADDRESS. Here are some examples (carrier = DHL_V2, DHL_BENELUX, POSTNL, GLS):

"addresses": [
  {
    "addressType": "POSTAL_ADDRESS",
    "firstName": "Karl",
    "lastName": "Kunde",
    "street": "Alexanderplatz",
    "houseNumber": "3",
    "postalCode": "10178",
    "city": "Berlin",
    "country": "DE"
  }
]
"addresses": [
  {
    "addressType": "POSTAL_ADDRESS",
    "firstName": "Jan",
    "lastName": "Janssen",
    "street": "Grote Markt",
    "houseNumber": "22",
    "postalCode": "2011 RD",
    "city": "Haarlem",
    "country": "NL"
  }
]
"addresses": [
  {
    "addressType": "POSTAL_ADDRESS",
    "firstName": "Jens",
    "lastName": "Jensen",
    "street": "Banegårdspladsen",
    "houseNumber": "14",
    "postalCode": "8000",
    "city": "Aarhus",
    "country": "DK",
    "additionalAddressInfo": "ring venligst"
  }
]

DHL Packstation (Germany)

In Germany, it is possible to have the parcel shipped to a DHL Packstation. The consumer address must contain the customer's DHL "Postnummer" so make sure that information is provided by the customer during the checkout process. The "Postnummer" must be set in the additionalAddressInfo field and the street must be "Packstation" (fixed value). The houseNumber must be the number of the selected Packstation. Here's an example (carrier = DHL_V2):

"addresses": [
  {
    "addressType": "POSTAL_ADDRESS",
    "firstName": "Karl",
    "lastName": "Kunde",
    "additionalAddressInfo": "<Postnummer>",
    "street": "Packstation",
    "houseNumber": "171",
    "postalCode": "50667",
    "city": "Köln",
    "country": "DE"
  }
]

DHL Service Point / Parcel Locker (Netherlands, Belgium, Luxemburg)

In the Netherlands, the customer can pick up her parcel at a DHL service point or parcel locker (pakketautomaat). For this to work, the order needs to include two consumer addresses: one of typeINVOICE_ADDRESS, the other of type PARCEL_LOCKER. The PARCEL_LOCKER address must be the customer's address and it must include the ServicePoint ID in the additionalAddressInfo field. In the INVOICE_ADDRESS you should also provide the real customer name because it is used on the label so that the customer can be identified when picking up the parcel at the service point. Check the DHL BeNeLux API documentation for details. Here's an example for delivery to a DHL service point (carrier = DHL_BENELUX):

"addresses": [
  {
    "addressType": "INVOICE_ADDRESS",
    "firstName": "Mieke",
    "lastName": "Janssen",
    "street": "Kudelstaartseweg",
    "houseNumber": "22",
    "postalCode": "1431 GA",
    "city": "Aalsmeer",
    "country": "NL"
  },
  {
    "addressType": "PARCEL_LOCKER",
    "additionalAddressInfo": "8004-NL-201117",
    "firstName": "Mieke",
    "lastName": "Janssen",
    "street": "Kudelstaartseweg",
    "houseNumber": "22",
    "postalCode": "1431 GA",
    "city": "Aalsmeer",
    "country": "NL"
  }
]

The next example is for delivery to a DHL parcel locker. The PARCEL_LOCKER address must include the ServicePoint ID (including prefix) of the locker in the additionalAddressInfo field.

"addresses": [
  {
    "addressType": "INVOICE_ADDRESS",
    "firstName": "Mieke",
    "lastName": "Janssen",
    "street": "Kudelstaartseweg",
    "houseNumber": "22",
    "postalCode": "1431 GA",
    "city": "Aalsmeer",
    "country": "NL"
  },
  {
    "addressType": "PARCEL_LOCKER",
    "additionalAddressInfo": "8004-NL-201585",
    "firstName": "Mieke",
    "lastName": "Janssen",
    "street": "Kudelstaartseweg",
    "houseNumber": "22",
    "postalCode": "1431 GA",
    "city": "Aalsmeer",
    "country": "NL"
  }
]

PostNL Service Point / Parcel Locker (Netherlands)

In the Netherlands, the customer can pick up her parcel at a PostNL service point (PostNL-punt) or parcel locker (pakketautomaat). For this to work, the order needs to have two consumer addresses: one of typeINVOICE_ADDRESS, the other of type PARCEL_LOCKER. The PARCEL_LOCKER address should be the address of the pickup point and it must include a companyName. In the INVOICE_ADDRESS you should also provide the real customer name because it is used on the label so that the customer can be identified when picking up the parcel at the service point. Check the PostNL API documentation for details. Here's an example for delivery to a service point (carrier = POSTNL):

"addresses": [
  {
    "addressType": "INVOICE_ADDRESS",
    "firstName": "Mieke",
    "lastName": "Janssen",
    "street": "Kudelstaartseweg",
    "houseNumber": "22",
    "postalCode": "1431 GA",
    "city": "Aalsmeer",
    "country": "NL"
  },
  {
    "addressType": "PARCEL_LOCKER",
    "companyName": "ACME",
    "firstName": "Mieke",
    "lastName": "Janssen",
    "street": "Zijdstraat",
    "houseNumber": "38",
    "postalCode": "1431 ED",
    "city": "Aalsmeer",
    "country": "NL"
  }
]

The next example is for delivery to a parcel locker. The PARCEL_LOCKER address should be the address of the parcel locker and it must include a companyName. The additionalAddressInfo must contain the customer's PostNL ID number. Example (carrier = POSTNL):

"addresses": [
  {
    "addressType": "INVOICE_ADDRESS",
    "firstName": "Mieke",
    "lastName": "Janssen",
    "street": "Kudelstaartseweg",
    "houseNumber": "22",
    "postalCode": "1431 GA",
    "city": "Aalsmeer",
    "country": "NL"
  },
  {
    "addressType": "PARCEL_LOCKER",
    "additionalAddressInfo":"<PostNL ID>",
    "companyName": "PostNL",
    "firstName": "Mieke",
    "lastName": "Janssen",
    "street": "Werf",
    "houseNumber": "15",
    "postalCode": "1435 KP",
    "city": "Rijsenhout",
    "country": "NL"
  }
]

bpost Pick-up Point (Belgium)

In Belgium, bpost offers the customer to pick up the parcel at a Pick-up point or a Parcel locker. The order must contain an address of type PARCEL_LOCKER and the additionalAddressInfo must contain the service point id as determined by the bpost GeoLocator API. At the moment, we support bpost service points of type 1 (PostOffice), 2 (Post Point & Parcel Point), 4 (Pack Station/Parcel Locker), and 16 (Kariboo/Parcel Point).

Here's an example for delivery to a bpost Pick-up Point (carrier = BPOST):

"addresses": [
  {
    "addressType": "PARCEL_LOCKER",
    "additionalAddressInfo": "100472",
    "firstName": "Jean",
    "lastName": "Peeters",
    "street": "Carrefour de l'Europe",
    "houseNumber": "2",
    "postalCode": "1000",
    "city": "Bruxelles",
    "country": "BE"
  }
]

Another option is to specify an address of type PARCEL_LOCKER with the actual customer address but without an additionalAddressInfo field. In this case, when the shipping label is requested the point of delivery is chosen automatically by determining the nearest service point. This address will then be printed on the shipping label instead of the customer's address.

"addresses": [
  {
    "addressType": "PARCEL_LOCKER",
    "firstName": "Jean",
    "lastName": "Peeters",
    "street": "Rue de l'Etuve",
    "houseNumber": "44",
    "postalCode": "1000",
    "city": "Bruxelles",
    "country": "BE"
  }
]

As always, you can provide an optional INVOICE_ADDRESS. Check the bpost integration helpdesk for details.

postnord Service Point / Parcel Locker

In the Nordics, e.g. Denmark, Finland, Sweden, the customer can choose to pick up the parcel at a postnord Service Point or Parcel locker (Pakkeboks/Nærboks). For this to work, the PARCEL_LOCKER address must include the Service Point ID (e.g. 105926) in the additionalAddressInfo field. Optionally, you can provide an INVOICE_ADDRESS. Check the postnord API documentation for more information. Here's an example for delivery to a postnord Service Point (carrier = POST_NORD):

"addresses": [
  {
    "addressType": "PARCEL_LOCKER",
    "additionalAddressInfo": "105926",
    "firstName": "Peter",
    "lastName": "Nielsen",
    "street": "Gymnasievej",
    "houseNumber": "29",
    "postalCode": "4600",
    "city": "Køge",
    "country": "DK"
  }
]

GLS ParcelShop Delivery

In Denmark and many other countries, the customer can pick up the parcel at a GLS depot or ParcelShop (PakkeShop). For this to work, the PARCEL_LOCKER address must be the address of the parcel shop and it must include the ParcelShopID (e.g. 2080099016, 0560013596) in the additionalAddressInfo field. First name and last name must be of the customer so he can be identified when picking up the parcel. Optionally, you can provide an INVOICE_ADDRESS. Check the GLS ShipIT documentation for more information on parcel shops. Here's an example for delivery to a GLS parcel shop (carrier = GLS):

"addresses": [
  {
    "addressType": "PARCEL_LOCKER",
    "additionalAddressInfo": "2080095282",
    "firstName": "Jens",
    "lastName": "Jensen",
    "street": "Gymnasievej",
    "houseNumber": "29",
    "postalCode": "4600",
    "city": "Køge",
    "country": "DK"
  }
]

Service Options

Some carriers offer additional service options to be requested with the shipping labels, e.g. "signature required", "insurance", "cash on delivery", etc. You can specify these services in the preferredCarriersWithProduct element of the deliveryPreferences within the order.

Here's an example how to request the "signature" option for Belgian carrier bpost:

 "deliveryPreferences": {
    "shipping": {
        "preferredCarriersWithProduct": [
            {
                "carrierKey": "BPOST",
                "carrierServices": [
                    "SIGNATURE"
                ]
            }
        ],
        "serviceLevel": "DELIVERY"
    }
}

The list of supported options/services depends on the chosen carrier. Please contact us if you find an option missing that you would like to use for your labels.

Reference

Last updated