Introduction
Bulk order import allows you to create numerous orders directly from the WOOP interface with just a few clicks.
This feature is accessible from the delivery page, via the "action" button located at the top right of the deliveries.
Once the feature is selected, several fields will need to be filled in:
- Retailer: Entity for which you wish to generate orders (the field will be pre-selected if you have an account set up in a retailer context)
- Order file import: File that will serve as the basis for generating the orders
- Templates: These are file templates to guide you in generating orders (If you are not familiar with the JSON format, we recommend retrieving the CSV format and opening it in Excel or Google GSheet).
Filling in the order file
General operation
The file to be imported is converted into JSON (if the received file was a CSV) and then goes through several processing stages. These processes are carried out order by order:
- Transformation of data into JSON (if the file is a CSV)
- Retrieval of each key to be recorded in the database (field in parentheses in the CSV header).
- Checking to see if the data types match what is expected.
- Checking to see if all mandatory fields of our API have a value.
- If a pick-up point/exchange place is provided as a picking or delivery address, we verify its existence and retrieve its information
During the different stages, we check for potential errors in the file and these errors are stored so they can be displayed in the import result of the file, at the end of the process.
Once these checks are completed, orders with no errors are sent to our API to be recorded.
When all orders are recorded, the interface moves to the result phase to inform you of the number of validated and erroneous orders.
Filling in the order file
| Fields (* required) | Data format | Comments | |
| Order number (externalOrderId) |
36 characters maximum String |
Unique order number. Ex: ORDER12345678 If not filled, a UUID will be generated |
|
| Reference number (referenceNumber) | String |
Order reference, can be the same as the order number Ex: REF12345678 |
|
| Store ID (storeId)* | String |
ID of the store associated with the order Ex: 5412EE |
|
| Order state code (state.code) |
Allowed values: ORDER_TO_BE_COMPLETED, ORDER_WITHOUT_SHIPMENT |
Ex: “ORDER_TO_BE_COMPLETED” | |
| Delivery ID (state.options.deliveryId) | String |
Order delivery ID Ex: delivery1 |
|
| Parcel numbers (state.options.parcelIds) | List of strings |
List of parcel IDs Ex: “parcel1,parcel14” |
|
| Collection location type (picking.location.type)* |
String Allowed values: address, exchangePlace, pickupPoint |
Type of collection location address Ex: pickupPoint Automated filling if: - picking.location.id filled -> exchangePlace - picking.location.id + picking.location.carrierCode -> pickupPoint - If nothing in picking.location.id & picking.location.carrierCode -> address |
|
| Collection location ID (picking.location.id) | String |
ID of the collection location (if the address type is exchangePlace or pickupPoint) Ex: FR00149 |
|
| Carrier code for pick-up point (picking.location.carrierCode) | String |
Carrier code (if the address type is pickupPoint) Ex: mondial-relay |
|
| Collection address line 1 (picking.location.addressLine1) | String |
Full address of the collection location Ex: 65 Rue de Luxembourg If not filled, data from the exchange place/store will be retrieved |
|
| Collection address line 2 (picking.location.addressLine2) | String | Address complement | |
| Lift? (picking.location.elevator) | Boolean |
Presence of a lift Ex: true (if yes), false (if no) |
|
| Floor number (picking.location.floor) | Number |
Floor of the collection location Ex: 4 |
|
| Door code (picking.location.doorCode) | String |
Door code of the collection location Ex: 1234A |
|
| Collection postal code (picking.location.postalCode) | String |
Postal code of the collection location Ex: 59800 If not filled, data from the exchange place/store will be retrieved |
|
| Collection city (picking.location.city) | String |
City of the collection location Ex: Lille If not filled, data from the exchange place/store will be retrieved |
|
| Collection district (picking.location.district) | String | District of the collection location | |
| Collection country (picking.location.country) | String |
Country code of the collection location Ex: FR If not filled, data from the exchange place/store will be retrieved |
|
| Comment (picking.location.comment) | String | ||
| Latitude (picking.location.coordinates.latitude) | Number | ||
| Longitude (picking.location.coordinates.longitude) | Number | ||
| Collection interval start (picking.interval.start)* | Datetime |
Ex: 2025-01-10T13:00:00 You can enter just the date 2025-01-10, the collection start time will default to 00:00 |
|
| Collection interval end (picking.interval.end)* | Datetime |
Ex: 2025-01-10T14:59:59 You can enter just the date 2025-01-10, the collection end time will default to 23:59 |
|
| Collection contact first name (picking.contact.firstName) | String |
First name of the collection contact Ex: Joe If not filled, data from the exchange place/store will be used |
|
| Collection contact last name (picking.contact.lastName) | String |
Last name of the collection contact Ex: DOE If not filled, data from the exchange place/store will be used |
|
| Collection contact phone (picking.contact.phone) | String |
Phone number of the collection contact Ex: +33601020304 If not filled, data from the exchange place/store will be used |
|
| Collection contact email (picking.contact.email) | String |
Email address of the collection contact Ex: joedoe@gmail.com If not filled, data from the exchange place/store will be used |
|
| Collection contact language (picking.contact.language) | String |
Language code of the collection contact Ex: fr If not filled, data from the exchange place/store will be used |
|
| Collection contact timezone (picking.contact.timezone) | String |
Timezone of the collection contact Ex: Europe/Paris If not filled, data from the exchange place/store will be used |
|
| Main contact? (picking.contact.main) | Boolean | Ex: true (if yes), false (if no) | |
| Collection contact title (picking.contact.title) | String | Ex: Manager | |
| Professional contact? (picking.contact.isProfessional) | Boolean | Ex: true (if yes), false (if no) | |
| Collection contact company name (picking.contact.companyName) | String | Ex: Woop | |
| Delivery location type (delivery.location.type) |
String Allowed values: address, exchangePlace, pickupPoint |
Type of delivery location address Ex: address If an address is entered in delivery.location.addressLine1 -> auto-fill with the value "address" |
|
| Delivery location ID (delivery.location.id) | String | ID of the delivery location (if the address type is exchangePlace or pickupPoint) | |
| Carrier code for pick-up point - delivery (delivery.location.carrierCode) | String | Carrier code (if the address type is pickupPoint) | |
| Delivery address line 1 (delivery.location.addressLine1)* | String |
Full address of the delivery location Ex: 65 Rue de Luxembourg |
|
| Delivery address line 2 (delivery.location.addressLine2) | String | Address complement | |
| Elevator? (delivery.location.elevator) | Boolean |
Presence of an elevator Ex: true (if yes), false (if no) |
|
| Floor number (delivery.location.floor) | Number |
Floor of the delivery location Ex: 4 |
|
| Door code (delivery.location.doorCode) | String |
Door code of the delivery location Ex: 1234A |
|
| Delivery postal code (delivery.location.postalCode)* | String |
Postal code of the delivery location Ex: 59800 |
|
| Delivery city (delivery.location.city)* | String |
City of the delivery location Ex: Lille |
|
| Delivery district (delivery.location.district) | String | District of the delivery location | |
| Delivery country (delivery.location.country) | String |
Country code of the delivery location Ex: FR If not filled in, the country specified at the Exchange Place will be automatically entered |
|
| Comment (delivery.location.comment) | String | ||
| Latitude (delivery.location.coordinates.latitude) | Number | ||
| Longitude (delivery.location.coordinates.longitude) | Number | ||
| Delivery interval start (delivery.interval.start)* | Datetime |
Ex: 2025-01-10T15:00:00 You can enter just the date 2025-01-10, the default delivery start time will be 00:00 |
|
| Delivery interval end (delivery.interval.end)* | Datetime |
Ex: 2025-01-10T16:59:59 You can enter just the date 2025-01-10, the default delivery end time will be 23:59 |
|
| Delivery contact first name (delivery.contact.firstName)* | String |
First name of the delivery contact Ex: Joe |
|
| Delivery contact last name (delivery.contact.lastName)* | String |
Last name of the delivery contact Ex: DOE |
|
| Delivery contact phone (delivery.contact.phone)* | String |
Phone number of the Collection contact Ex: +33601020304 |
|
| Delivery contact email (delivery.contact.email)* | String |
Email address of the Collection contact Ex: joedoe@gmail.com |
|
| Delivery contact language (delivery.contact.language) | String |
Language code of the delivery contact Ex: fr If not filled in, the language specified at the Exchange Place/Store will be automatically entered here |
|
| Delivery contact timezone (delivery.contact.timezone) | String |
Timezone of the delivery contact Ex: Europe/Paris If not filled in, the default timezone will be EUROPE/Paris |
|
| Satisfaction contact method (delivery.contact.optIn.survey) |
List of strings Allowed values: SMS,EMAIL |
Contact method for satisfaction surveys Ex: “SMS,EMAIL” |
|
| Delivery contact method (delivery.contact.optIn.delivery) |
List of strings Allowed values: SMS,EMAIL |
Contact method for delivery tracking Ex: “SMS” |
|
| Professional contact? (delivery.contact.isProfessional) | Boolean | Ex: true (if yes), false (if no) | |
| Delivery contact company name (delivery.contact.companyName) | String | Ex: Woop | |
| Parcel ID (packages.packageId) | String |
ID used to differentiate parcels (only for CSV files, information not recorded with the order) Ex: PACKAGE1 |
|
| Parcel reference (packages.references.reference) | String |
Parcel reference Ex: 12345B |
|
| Parcel barcode value (packages.references.barcode.value) | String |
Barcode value Ex: 54fd56g4f5gfd456sd |
|
| Parcel barcode format (packages.references.barcode.format) | String |
Barcode format Ex: 128 |
|
| Parcel barcode type (packages.references.barcode.type) | String |
Barcode display type Ex: barcode |
|
| Parcel reference state (packages.references.state.value) | String |
Parcel state Ex: ON_DOCK |
|
| Parcel reference state date (packages.references.state.date) | Datetime |
Parcel state date Ex: 2025-01-10T15:00:00 You can enter just the date 2025-01-10, the parcel state time will default to 23:59 |
|
| Trailer ID (packages.references.containerId.trailerId) | String | Ex: TRAILER1 | |
| Pallet ID (packages.references.containerId.palletId) | String | Ex: PALLET1 | |
| Parcel category (packages.category) | String |
Parcel category Ex: ALIMENTATION |
|
| Parcel length (packages.length.value) | Number |
Parcel length Ex: 20 Automatically filled if the packages.category value is entered |
|
| Parcel length unit (packages.length.unit) |
String Allowed values: mm, cm, m, in, ft-us, ft |
Parcel length unit Ex: cm Automatically filled if the packages.category value is entered |
|
| Parcel width (packages.width.value) | Number |
Parcel width Ex: 20 Automatically filled if the packages.category value is entered |
|
| Parcel width unit (packages.width.unit) |
String Allowed values: mm, cm, m, in, ft-us, ft |
Parcel width unit Ex: cm Automatically filled if the packages.category value is entered |
|
| Parcel height (packages.height.value) | Number |
Parcel height Ex: 60 Automatically filled if the packages.category value is entered |
|
| Parcel height unit (packages.height.unit) |
String Allowed values: mm, cm, m, in, ft-us, ft |
Parcel height unit Ex: cm Automatically filled if the packages.category value is entered |
|
| Parcel weight (packages.weight.value) | Number |
Parcel weight EX: 2.04 Automatically filled if the packages.category value is entered |
|
| Parcel weight unit (packages.weight.unit) |
String Allowed values: mg, g, kg, oz, lb, mt, t |
Parcel weight unit Ex: kg Automatically filled if the packages.category value is entered |
|
| Type of product in the parcel (packages.products.type) |
String Allowed values: TYPOLOGY_GENERIC, TYPOLOGY_PALLET_GENERIC, TYPOLOGY_GROCERY, TYPOLOGY_FRESH, TYPOLOGY_FROZEN, TYPOLOGY_DANGEROUS, TYPOLOGY_HOUSEHOLD, TYPOLOGY_LARGE_HOUSEHOLD, TYPOLOGY_VOLUMINOUS, TYPOLOGY_FRAGILE, TYPOLOGY_VOLUMINOUS_FRAGILE, TYPOLOGY_NON_STANDARD, TYPOLOGY_SMALL_HOUSEHOLD, TYPOLOGY_DANGEROUS_LIMITED_QUANTITY, TYPOLOGY_HIGHT_VALUE, TYPOLOGY_FURNITURE, TYPOLOGY_LIVING_ANIMALS, TYPOLOGY_MEDICAL_PRODUCTS, TYPOLOGY_FRAGILE_FURNITURE, TYPOLOGY_SMALL_FURNITURE, TYPOLOGY_LARGE_FURNITURE, TYPOLOGY_ASSEMBLED_FURNITURE |
Type of product in the parcel Ex: TYPOLOGY_FRESH See info for filling in the field
If not provided, the default value is TYPOLOGY_GENERIC |
|
| Product EAN (packages.products.ean) | String |
Product EAN code Ex: 0123456789012 |
|
| Product CUG (packages.products.cug) | String |
Product CUG code Ex: 012345678 |
|
| Product label (packages.products.label) | String |
Product label Ex: Pack of pasta packets |
|
| Quantity of products (packages.products.quantity) | Number |
Quantity of the product in the parcel Ex: 1 Automatically set to 1 if not entered |
|
| Parcel quantity (packages.quantity) | Number |
Parcel quantity Ex: 1 Automatically set to 1 if not entered |
|
| Product price (packages.products.price.value) | Field reserved for entering a product price |
||
Product price currency (packages.products.price.currency) |
Field reserved for entering the product price currency |
||
Product services (packages.products.productServices) |
Allowed values SERVICE_INSTALL, SERVICE_RECOVERY, SERVICE_UNPACKING, SERVICE_FRONT_HOME, SERVICE_REGULAR_FRONT_HOME, SERVICE_PICKUP_POINT, SERVICE_RETURN, SERVICE_SELECTED_ROOM, SERVICE_SIMPLE_INSTALL, SERVICE_COMPLEX_INSTALL, SERVICE_PAY_ON_DELIVERY, SERVICE_STANDARD_TAXI, SERVICE_XL_TAXI, SERVICE_WITH_SIGNATURE, SERVICE_GREEN, SERVICE_SHUTTLE, SERVICE_TWO_DRIVERS, SERVICE_EXHIBITION_MODEL, SERVICE_WHITE_GLOVE, SERVICE_EXCHANGE, SERVICE_DELIVERY_TO_MAILBOX, SERVICE_SCHEDULED, SERVICE_FREIGHT_ELEVATOR, SERVICE_BY_PRODUCT |
Field reserved for entering the different services for the product.
|
|
| Product families (packages.products.productFamilies) | String |
|
|
| Parcel footprint (packages.attributes.footprint.value) | Number |
Parcel carbon footprint Ex: 13 |
|
| Parcel footprint unit (packages.attributes.footprint.unit) |
String Allowed values: m2, cm2, pallet |
Parcel carbon footprint unit Ex: m2 |
|
| Parcel type (packages.type) |
String Allowed values: PACKAGE, TRAY, PALLET |
Parcel type Ex: PACKAGE |
|
| Parcel volume (packages.volume.value) | String |
Parcel volume Ex: 15 |
|
| Parcel volume unit (packages.volume.unit) |
String Allowed values: mm3, cm3, ml, l, kl, m3, km3, tsp, tbs, in3, fi-oz, cup, pnt, qt, gal, ft3, yd3 |
Parcel volume unit Ex: cm3 |
|
| Services (services) |
List of strings Allowed values: SERVICE_ASSEMBLY, SERVICE_INSTALL, SERVICE_RECOVERY, SERVICE_UNPACKING, SERVICE_FRONT_HOME, SERVICE_REGULAR_FRONT_HOME, SERVICE_PICKUP_POINT, SERVICE_RETURN, SERVICE_SELECTED_ROOM, SERVICE_SIMPLE_INSTALL, SERVICE_COMPLEX_INSTALL, SERVICE_PAY_ON_DELIVERY, SERVICE_STANDARD_TAXI, SERVICE_XL_TAXI, SERVICE_WITH_SIGNATURE, SERVICE_GREEN, SERVICE_SHUTTLE, SERVICE_TWO_DRIVERS, SERVICE_EXHIBITION_MODEL, SERVICE_WHITE_GLOVE, SERVICE_EXCHANGE, SERVICE_DELIVERY_TO_MAILBOX, SERVICE_SCHEDULED, SERVICE_FREIGHT_ELEVATOR, SERVICE_BY_PRODUCT |
List of services associated with the order Ex: SERVICE_FRONT_HOME, SERVICE_WITH_SIGNATURE See info for filling in the field
SERVICE_FRONT_HOME entered by default if not specified SERVICE_BY_PRODUCT entered by default if the field (packages.products.productServices) is filled in |
|
| Amount due (expectedPayment.value) | Number |
Remaining amount to be paid Ex: 15.20 |
|
| Currency (expectedPayment.currency) | String |
Currency of the remaining amount to be paid Ex: EUR |
|
| Payment method (expectedPayment.paymentMethod) |
String Allowed values: CASH, CREDIT_CARD, DEBIT_CARD, DIRECT_DEBIT, BANK_TRANSFER, CHECK |
Payment method for the remaining amount Ex: CASH |
|
| Tag key (tags.key) | String |
Tag key Ex: origin |
|
| Tag value (tags.value) | String |
Associated value Ex: web |
|
| Application of the tag to orchestration (tags.applyToOrchestration) | Boolean | Ex: true (if yes), false (if no) | |
| Carrier selection mode (carrierSelection.mode) |
String Allowed values: INCLUSION, EXCLUSION |
Field reserved for ‘inclusion or exclusion of a carrier in the orchestration process | |
| Codes of selected carriers (carrierSelection.carrierCodes) |
Field reserved for the carrier code. Contact a WOOP admin to get the list |
||
| Additional data key (additionalData.key) |
String free field |
Field reserved for adding additional data ex: Date_installation |
|
| Additional data value (additionalData.value) |
String free field |
Field reserved for adding additional data ex: 18/02/2025 |
Advanced
Fields state.options.parcelIds, carrierSelection.carrierCodes and delivery.contact.optIn
These fields are of the "array" type to allow for multiple entries. If you're using a CSV file, you need to enter all the data on the same line and within quotation marks “”
Examples:
- state.options.parcelIds: "PARCEL1,PARCEL2”
- carrierSelection.carrierCodes: “chronopost,mondial-relay”
- delivery.contact.optIn.survey: “SMS”
- delivery.contact.optIn.survey: “SMS, EMAIL”
Arrays of objects
This section only concerns CSV files.
Here is the list of data that are arrays of objects and will be covered in this section:
- packages
- packages.references
- packages.products
- tags
- additionalData
This data requires special attention because you need to create a line for each object of the same family. Specifically, if your order has three tags, you need to duplicate the order on three lines and change the tag on each line. If your order has three tags and four additionalData, it will therefore be on four lines.
When you duplicate a line to add data to a data array, you must not modify the other order data => ⚠️ The order number must remain the same.
Note that it is possible to add a new tag, an additionalData, a package on the same line…
Special case for packages:
As mentioned earlier, if there are two packages to be entered for the order, we need to create two CSV lines to be able to create them. On each line, you will need to change the packageId. This value doesn't matter as it is not recorded, but it is used to differentiate the packages during order processing.
If each package has two products and three references, then the order will be on six CSV lines:
- First line: package 1 product 1 reference 1
- Second line: package 1 product 2 reference 2
- Third line: package 1 product 2 reference 3
- Fourth line: package 2 product 1 reference 1
- Fifth line: package 2 product 2 reference 2
- Sixth line: package 2 product 2 reference 3
The product must always be entered as it is a mandatory field. If the product entered is already present on another CSV line of the order, it will not be added a second time to the order.
Some data is mandatory and it will be necessary to keep, for example, one package per line. No data will be duplicated if it is already present on another CSV line of the order.