NAV
curl PHP

Introduction

Ce document présente les différentes APIs deliver.ee et comment intéragir avec.

Toutes nos API sont organisées suivant le style REST et utilise des verbes et des codes de retour standards du protocole HTTP.

Toutes nos API renvoie exclusivement du JSON: demander un autre format (par extension d’url ou par header) retournera une erreur.

A ce jour, il n’existe pas de bibliothèque officielle permettant de dialoguer avec nos API. Cette documentation est la pour vous permettre d’implémenter les mécanismes nécessaires, et des exemples concrets sont présents.

API Core

Ce document présente l’API Core api.deliver.ee. Cette API permet a nos clients et partenaires de créer, éditer et suivre des missions de transport de marchandises en zone urbaine.

Il s’agit de notre API principale.

Accès à l’API

L’API est disponible sur deux environnements:

Authentication

Retrieving your auth token

POST /users/session

curl 'https://api.deliver.ee/users/session' \
    -X POST \
    -H 'Accept: application/vnd.deliveree-v1+json' \
    -d 'user[email]=john.doe@company.com' \
    -d 'user[password]=myShinySecurePassword'

JSON response:

{
  "user": {
    "id": "tac8a83a-8787-4a1e-ac67-4bdb8500525a",
    "kind": "company_admin",
    "last_name": "Doe",
    "first_name": "John",
    "email": "john.doe@company.com",
    "phone": "336123456789",
    "preferences": {
      "sms_notifications_enabled": false,
      "email_notifications_enabled": true
    },
    "auth_token": "YOUR_AUTH_TOKEN"
  }
}

A simple HTTP POST request on /users/session with your credentials allow you to retrieve your auth_token.

This token never expires unless:

  1. you explicitly close your session by submitting a DELETE request on /users/session.
  2. you’ve lost your password and you decided to reset it through PUT /users/rescue and PUT /users/reset mechanism.

Using your auth token

GET /users/tac8a83a-8787-4a1e-ac67-4bdb8500525a

curl 'https://api.deliver.ee/users/tac8a83a-8787-4a1e-ac67-4bdb8500525a' \
    -H 'Accept: application/vnd.deliveree-v1+json' \
    -H 'Authorization: Token token=YOUR_AUTH_TOKEN'

Perform all the following requests with an HTTP Authorization header

Versioning

GET /users/USER_ID

curl 'https://api.deliver.ee/users/USER_ID' \
    -H 'Accept: application/vnd.deliveree-v1+json' \
    -H 'Authorization: Token token=YOUR_AUTH_TOKEN' \
    -H 'Accept-Language: fr-FR'

You must define the HTTP Accept header in your requests to tell which specific version of the API you want to use.

Default behaviour: fallback to the latest version if header is missing.

Internationalization (I18n)

Locales

GET /users/tac8a83a-8787-4a1e-ac67-4bdb8500525a

curl 'https://api.deliver.ee/users/tac8a83a-8787-4a1e-ac67-4bdb8500525a' \
    -H 'Accept: application/vnd.deliveree-v1+json' \
    -H 'Authorization: Token token=YOUR_AUTH_TOKEN' \
    -H 'Accept-Language: fr-FR'

Default locale is english.
Your requests may contains the HTTP header Accept-Language to override english to french

Date & Time format

Inputing or outputing date and time will respect the ISO_8601 standards:

2015-12-24T23:30:00+02:00

Customizing results

Pagination

GET /resource?page=2&per_page=5
The response body will contains an extra meta block:

{
  "meta": {
    "page": 22,
    "current_page": 2,
    "total": 106,
    "order_by": "created_at",
    "direction": "asc"
  }
}

HTTP GET endpoints that returns multiple items can be paginated using URL GET page and per_page params.

"Link": "; rel=\"first\", ; rel=\"prev\", ; rel=\"last\", ; rel=\"next\""

The response header will also contains pre-generated links easily parsable for pagination.

Ordering

GET /resource?order_by=created_at&order=asc

HTTP GET endpoints that returns multiple items can be ordered using URL GET order_by and order params.

Filtering

GET /resource?filter_by[key]=value

HTTP GET endpoints that returns multiple items can be filtered using URL GET filter_by[key]=value params.

{
  "trips": {
    "filters": {
      "status": [
        "draft",
        "canceled",
        "archived",
        "delivered",
        "pending",
        "failed",
        "assigned",
        "refused",
        "retrieved",
        "active"
      ],
      "priority": [
        null,
        "regular",
        "express"
      ],
      "vehicle": [
        null,
        "bike",
        "scooter",
        "tricycle",
        "cargo_bike",
        "van",
        "car"
      ]
    }
  }
}

Filtrable keys-values can be retrieved from GET /resource/filters request with a response such as:

Mission object overview

Lifecyle

lifecycle

Priority

Values are regular, express, or urgent and match with your company custom priority delays.
If none is provided, we’ll try to guess it from your schedule.
If no schedule is provided, priority is a mandatory attribute.

Vehicle

Values are bike, scooter, tricycle, cargo_bike, car, van.
If none is provided, we’ll try to guess it from your packages list.
If no package is provided, vehicle is a mandatory attribute.

Schedule

A missions is scheduled when you provide start_at and end_at attributes.
If none is provided, we’ll try to guess it from your priority, assuming you want to ship as soon as possible.
If no priority is provided, start_at & end_at are mandatory attributes.

Places

You must declare at least 2 places for a mission.
for a trip mission, exactly 2 places are required.

Packages

You may provide a detailed packages list definition for insurance purpose or if you don’t know how to choose your vehicle.

Stages

A stage combines a Place, an action (retrieve / deliver) and eventually some packages. You must declare at least 2 stages for a mission.
for a trip mission, exactly 2 stages are required, packages are synced automatically in this case.

Prices

Mission total price, penalty, discount and services costs are available in their respectives keys.
The price key includes the services total costs.
You can compute the total cost with the following formula: price + penalty - discount

{
  "mission": {
    "id": "eba53402-43dd-423c-77c8-3aa8304ed234",
    "external_id": "ABC123",
    "status": "pending",
    "kind": "Trip",
    "priority": "regular",
    "vehicle": "car",
    "price": 37,
    "discount": 0,
    "penalty": 0,
    "services": {
      "Equipier de manutention": 25
    }
  }
}

Notifications

You can enable triggers so that your missions senders/recipients to receive the notifications you designed:
the notifications hash attributes:

Trip’s sender

activate SMS notification:
mission[notifications][sender_sms_notifications_enabled] = true

activate E-mail notification:
mission[notifications][sender_email_notifications_enabled] = true

Trip’s recipient

activate SMS notifications:
mission[notifications][recipient_sms_notifications_enabled] = true

activate E-mail notifications:
mission[notifications][recipient_email_notifications_enabled] = true

activate E-mail survey:
mission[notifications][recipient_email_survey_enabled] = true

Usage

Create a new trip

POST /trips

curl 'https://api.deliver.ee/trips' \
    -X POST \
    -H 'Accept: application/vnd.deliveree-v1+json' \
    -H 'Authorization: Token token=YOUR_AUTH_TOKEN' \
    -d 'mission[priority]=regular' \
    -d 'mission[vehicle]=scooter' \
    -d 'mission[notifications][recipient_sms_notifications_enabled]=true' \
	-d 'mission[start_at]=2015-12-24T13:30:00+01:00' \
    -d 'mission[end_at]=2015-12-24T16:30:00+01:00' \

A HTTP POST request on /trips endpoint allow you to open a new draft trip.
See previous paragraph for params explaination.

Parameters Possible values
priority regular, express, urgent
vehicle bike, scooter, tricycle, cargo_bike, car, van
start_at A valid ISO_8601 datetime string in the future
end_at A valid ISO_8601 datetime string in the future

Create places

POST /trips/TRIP_ID/places

curl 'https://api.deliver.ee/trips/TRIP_ID/places' \
    -X POST \
    -H 'Accept: application/vnd.deliveree-v1+json' \
    -H 'Authorization: Token token=YOUR_AUTH_TOKEN' \
    -d 'place[kind]=office' \
    -d 'place[company_name]=EvilCorp' \
    -d 'place[last_name]=Doe' \
    -d 'place[first_name]=Jane' \    
    -d 'place[address]=62 rue Jean-Jacques Rousseau' \    
    -d 'place[postcode]=75001' \   
    -d 'place[city]=Paris' \        
    -d 'place[country]=France' \    
    -d 'place[email]=1337@deliver.ee' \
    -d 'place[phone]=0123456789' \  
    -d 'place[comment]=Follow the white rabbit'

A HTTP POST request on /trips/TRIP_ID/places endpoint allow you create a new place in your trip.

Parameters Possible values
kind home, office, warehouse, shop
company_name not required with ‘home’ kind
last_name whom to contact (mandatory if kind is home)
first_name whom to contact (mandatory if kind is home)
phone Mandatory
comment Any local information that can help (door code, floor, direction)

Create packages (optional)

POST /trips/TRIP_ID/packages

curl 'https://api.deliver.ee/trips/TRIP_ID/packages' \
    -X POST \
    -H 'Accept: application/vnd.deliveree-v1+json' \
    -H 'Authorization: Token token=YOUR_AUTH_TOKEN' \
    -d 'package[description]=B2XT94R - Smartphone' \
    -d 'package[length]=20' \
    -d 'package[width]=10' \
    -d 'package[height]=5' \
    -d 'package[weight]=1' \
    -d 'package[insured]=true' \
    -d 'package[insurance_value]=999'

A HTTP POST request on /trips/TRIP_ID/packages endpoint allow you to create a new packages in your trip.

Parameters Possible values
description Description or reference, anything that can help the picker to find the package
length Length (in centimeters)
width Width (in centimeters)
height Height (in centimeters)
weight Weight (in centimeters)
insured Boolean, weither you want to insure this package or not
insurance_value Float, mandatory if insured is true

Create stages

POST /trips/TRIP_ID/stages

curl 'https://api.deliver.ee/trips/TRIP_ID/stages' \
    -X POST \
    -H 'Accept: application/vnd.deliveree-v1+json' \
    -H 'Authorization: Token token=YOUR_AUTH_TOKEN' \
    -d 'stage[kind]=pick_up' \
    -d 'stage[place_id]=40d9f90b-961e-4b8e-afad-6a254e6b5352' \
    -d 'stage[security_method]=password'

A HTTP POST request on /trips/TRIP_ID/stages endpoint allow you to create a new stages in your trip.

Parameters Possible values
kind pick_up or drop
place_id a valid place UUID provided by the previous step
security_method null or password
security_data You can specify a custom password to secure the pick_up or drop, a password will be auto-generated if security_method equals password and no data is provided.

Commit your trip

PUT /trips/TRIP_ID/commit

curl 'https://api.deliver.ee/trips/TRIP_ID/commit' \
    -X PUT \
    -H 'Accept: application/vnd.deliveree-v1+json' \
    -H 'Authorization: Token token=YOUR_AUTH_TOKEN'

Once your Trip is ready, just commit by making a HTTP PUT request on /trips/TRIP_ID/commit endpoint to tell us that you’re ready to proceed.

The trip status will change to pending.

Webhooks

Every times a mission status changes, our platform can call a script on your server.

Defining a callback URL

PUT /companies/COMPANY_ID

curl 'https://api.deliver.ee/companies/COMPANY_ID' \
    -X PUT \
    -H 'Accept: application/vnd.deliveree-v1+json' \
    -d 'company[callback_url]=http://company.com/my_shiny_webhook'

A HTTP PUT request on /companies/COMPANY_ID endpoint allow you to update the callback_url property.

Handling callbacks

<?php
$json = file_get_contents('php://input');
$mission = json_decode($json);
?>

Callbacks are sent through a HTTP POST request, with the full mission object JSON serialized in its body.
The request MIME-Type header is application/json

Errors

{
  "errors": {
    "code": 400,
    "label": "Bad Request",
    "message": "field_a is missing, field_b is not an e-mail, field_c do not match confirmation",
    "validation": [
      { "field_a": "Must be set" },
      { "field_b": "Must be a valid e-mail" },
      { "field_c": "Must match field_b value" }
    ]
  }
}
Code d’erreur Label Explaination
400 Bad Request – “The request cannot be fulfilled due to bad syntax.” Used in API response if params are missing or during validation issues.
401 Unauthorized – “Similar to 403 Forbidden, but specifically for use when authentication is required and has failed or has not yet been provided.” Used in API response when auth_token is missing.
403 Forbidden – “The request was a valid request, but the server is refusing to respond to it. Unlike a 401 Unauthorized response, authenticating will make no difference.” Used in API response when auth_token is provided and valid but user is still not authorized to perform that action.
404 Not Found – “The requested resource could not be found but may be available again in the future. Subsequent requests by the client are permissible.” Used in API response when requested resource do not exists (anymore).
405 Method Not Allowed – “A request was made of a resource using a request method not supported by that resource; for example, using GET on a form which requires data to be presented via POST, or using PUT on a read-only resource.” Used in API when action is not possible (anymore) on this resource.
422 Unprocessable entities – “The request was well-formed but was unable to be followed due to semantic errors.” Used in API response during advanced validation issues.

API Stocks

Ce document présente l’API stocks.deliver.ee. Cette API permet à nos partenaires de trouver une boutique éligible à une commande (liste d’articles + adresse de livraison); de créer, suivre, et mettre à jour les-dites commandes, ainsi que de consulter le planning d’ouverture d’une boutique.

Changelog

Date Section Changements
2016-08-23 Stocks Planning: prise en compte d’un pas
2016-07-18 Stocks Planning: prise en compte d’un id de boutique
2015-12-11 Stocks Planning: inclut la configuration du commerçant
2015-12-08 Stocks Planning: prise en compte de l’éligibilité
2015-11-19 Stocks Création de commande: start_at optionnel
2015-11-19 Stocks Section configuration
2015-11-19 Stocks Nouvelle recherche de boutique “immédiate”
2015-11-16 Core Correction des exemples PHP pour l’authentification
2015-11-13 Stocks Status des commandes & évènements
2015-11-12 Stocks Section évènements
2015-11-12 Stocks Précisions sur le code de retour de la recherche de boutique
2015-11-12 Stocks Ajout du paramètre store pour les créations de commande
2015-11-10 Stocks Ajout de la clé “delay” dans l’endpoint de planning
2015-11-09 Stocks Modification du format de retour pour le planning afin de gérer le créneau “immédiat”
2015-11-03 Stocks Ajout du champ shipping_status pour les commandes
2015-11-03 Stocks Ajout des paramètres de poids dans les requêtes d’éligibilité et de création de commandes
2015-11-03 Stocks Ajout de vehicle dans les réponses d’éligibilité
2015-10-30 Stocks Documentation sur les endpoints /ping et /session/; exemples pour l’authentification.
2015-10-27 Stocks Les commandes ont une date de début, de fin, et un délai de priorité.
2015-10-27 Stocks L’authentification utilisation le schema APIAuth et non plus deliveree.
2015-10-27 Stocks La recherche de boutique a été revue pour inclure la référence de la boutique.

Utilisation

Format de données

Les réponses de l’API ne se font qu’en JSON. Il faudra préciser ce type à chaque requête:

Accès à l’API

L’API est disponible sur deux environnements:

L’API nécessite de signer chaque requête à l’aide d’une clé d’accès et d’une clé privée. Deux jeux de ces clés vous seront fournies, un pour la production, un pour la pré-production

Versioning de l’API

L’API est actuellement en v1. Cette version sera utilisée par défaut sans que vous n’ayez à fournir un paramèter particulier. Ceci dit, il est possible que dans l’avenir une version 2 de l’API soit développée et devienne la version par défaut.

Pour cette raison, nous recommandons fortement de préciser la version de l’API dans vos requêtes, en utilisant le header Accept: application/vnd.deliveree-stock+json;version=1.

Statut de l’API

Format JSON
GET /ping

curl 'http://staging.stocks.deliver.ee/ping' \
     -X GET
{
  "code":200,
  "status":"ok",
  "reason":"OK"
}

Format texte
GET /ping

curl 'http://staging.stocks.deliver.ee/ping' \
     -X GET \
     -H 'Accept: text/plain'
OK

GET /ping

Cet endpoint est disponible pour tester la disponibilité de l’API.

Authentification

Généralités

L’authentification à l’API se fait lors de chaque requête. L’API utilise un schema d’authentification spécifique, basé sur la méthode HMAC-SHA1. Cette méthode est similaire dans le fonctionnement à celle utilisée par Amazon Web Services.

Pour utiliser l’API, il vous faut une clé d’accès et une clé privée. Ensuite, pour authentifier une requête:

  1. il vous faut joindre/concaténer certaines éléments de la requête: vous obtenez alors une chaine de caractères;
  2. ensuite, vous utilisez la clé secrète pour calculer le HMAC de cette chaine. Cette étape est appelée “signer la requête”, et le resultat “la signature”;
  3. enfin, vous ajoutez cette signature en en-tête de la requête.

Il est possible qu’une librairie automatise ce processus pour votre language: par exemple, en ruby, la gem APIAuth s’en occupe. Dans tous les cas, nous vous recommandons de lire le fonctionnement détaillé ci-dessous.

Sauf mention contraire, les requêtes données en exemple dans cette documentation n’incluent pas les informations d’authentification, et donc ne sont pas utilisables directement.

Signature des requêtes

  1. Une chaine de caractère de référence est crée en utilisant le contenu des headers
    HTTP de la requête Content-Type, Content-MD5, et Date, ainsi que l’URI de la requête.
    Vous devez vous assurer de la présence et de la validité de ces valeurs:
    Content-MD5 doit bien correspondre au MD5 du corps de la requête,
    et le header Date doit être au bon format et ne pas être dans le futur.
    Ensuite, la chaine est obtenue de cette façon:

    canonical_string = 'content-type,content-MD5,request URI,timestamp'

  2. Cette chaine est alors utilisée pour créer la signature, qui est une représentation en base64
    du SHA1-HMAC de la chaine, utilisant la clé secrête:

signature = Base64Encode(SHA1HMAC(canonical_string, secret_key))

  1. Cette signature est alors ajoutée au header HTTP Authorization de la façon suivante:

    Authorization = APIAuth access_key:signature

  2. Du côté serveur, l’API recalcule la signature de la même façon avec les headers de la requête.
    La clé d’accès fournie dans le header Authorization permet de retrouver la clé secrête.
    Les deux signatures (celle calculée et celle passée via le header) sont ensuite comparées:
    si elles sont identiques, alors la requête est considérée authentique.

  3. En protection supplémentaire, les requêtes sont considérées invalides au bout de 15 minutes, le timestamp de la requête faisant foi.

Tester l’authentification

Format JSON
GET /session

curl 'http://staging.stocks.deliver.ee/session' \
     -X GET
{
  "code":200,
  "status":"ok",
  "reason":"You are authentified"
}

GET /session
POST /session

Cet endpoint est disponible pour vous aider à tester l’authentification à l’API

Exemple 1: GET sans paramètre

access_id  = "426f891b-c457-4c18-84a4-386cc391a7ef"
secret_key = "test-secret-key"

content_type = ''
content_md5  = ''
uri          = '/session'
timestamp    = "Fri, 30 Oct 2015 14:10:00 GMT"

# canonical_string = [content_type,content_md5,uri,timestamp].join(,)
canonical_string = ',,/session,Fri, 30 Oct 2015 14:10:00 GMT'

# hmac_signature = base64encode(HMAC-SHA1(canonical_string, secret_key))
hmac_signature = "TPum5WrjKEHlDJq2+oiiA0RD7UY="

# auth_header = "APIAuth access_id:hmac_signature
auth_header = "APIAuth 426f891b-c457-4c18-84a4-386cc391a7ef:TPum5WrjKEHlDJq2+oiiA0RD7UY="
curl 'https://stocks.deliver.ee/session' \
     -X GET \
     -H 'Accept: application/json' \
     -H 'Date: Fri, 30 Oct 2015 14:10:00 GMT' \
     -H "Authorization: APIAuth 426f891b-c457-4c18-84a4-386cc391a7ef:TPum5WrjKEHlDJq2+oiiA0RD7UY="
<?php
// Required variables
$access_id = '426f891b-c457-4c18-84a4-386cc391a7ef';
$secret_key = 'test-secret-key';
$domain = 'https://stocks.deliver.ee';
$uri = '/session';
$date = gmdate('D, d M Y H:i:s T');
$content_type = 'application/json';
$md5 = '';

// Computing canonical string
$canonical_params = array(
    'content-type' => $content_type,
    'content-MD5'  => $md5,
    'request_uri' => $uri,
    'timestamp' => $date
);
$canonical_string = implode(',', $canonical_params);

// Generating signature
$signature = base64_encode(hash_hmac('sha1', $canonical_string, $secret_key, true));

// Performing the query
$ch = curl_init($domain.$uri);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        "Accept: application/vnd.deliveree-stock+json;version=1",
        "Content-Type: $content_type",
        "Content-MD5: $md5",
        "Authorization: APIAuth $access_id:$signature",
        "Date: $date"
    )
);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$curl_response = curl_exec($ch);
curl_close($ch);

// Handling response
$api_response = json_decode($curl_response, false);
?>

Tous les exemples vont utiliser cette clé d’accès et cette clé secrète.

Dans cet exemple, aucune donnée n’est envoyée ni en paramètres d’url, ni en corps de requête. Il n’y a donc pas besoin de préciser de Content-Type ou de Content-MD5. En revanche, il faut préciser une date. S’il y a plus de 15mn d’écart entre la date envoyée et la date actuelle, la requête ne sera pas authentifié.

Une fois la chaine canonique crée, la signature s’obtient en deux étapes: premièrement, on calcule le HMAC-SHA1 de la chaine canonique. Puis, on encode le résultat en base 64. Le header se construit ensuite à partir de l’ID d’accès et de la signature

Exemple 2: GET avec paramètre(s)

access_id  = "426f891b-c457-4c18-84a4-386cc391a7ef"
secret_key = "test-secret-key"

content_type = ''
content_md5  = ''
uri          = '/session?count=2&somethingelse=somevalue'
timestamp    = "Fri, 30 Oct 2015 14:10:00 GMT"

# canonical_string = [content_type,content_md5,uri,timestamp].join(,)
canonical_string = ',,/session?count=2&somethingelse=somevalue,Fri, 30 Oct 2015 14:10:00 GMT'

# hmac_signature = Base64Encode(HMAC-SHA1(canonical_string, secret_key))
hmac_signature = "XeMyHcYCjUOdnqv42Jyqc6G81hE="

# auth_header = "APIAuth access_id:hmac_signature
auth_header = "APIAuth 426f891b-c457-4c18-84a4-386cc391a7ef:XeMyHcYCjUOdnqv42Jyqc6G81hE="
curl 'https://stocks.deliver.ee/session?count=2&somethingelse=somevalue' \
     -X GET \
     -H 'Accept: application/json' \
     -H 'Date: Fri, 30 Oct 2015 14:10:00 GMT' \
     -H "Authorization: APIAuth 426f891b-c457-4c18-84a4-386cc391a7ef:XeMyHcYCjUOdnqv42Jyqc6G81hE="
<?php
// Required variables
$access_id = '426f891b-c457-4c18-84a4-386cc391a7ef';
$secret_key = 'test-secret-key';
$domain = 'https://stocks.deliver.ee';
$uri = '/session';
$params = array(
  'foo' => 'bar',
  'hello' => 'world'
);
$query_string = http_build_query($params);
$uri .= '?'.$query_string;
$date = gmdate('D, d M Y H:i:s T');
$content_type = 'application/json';

// Preparing MD5 sum for content
$md5 = base64_encode(md5($query_string, true));

// Computing canonical string
$canonical_params = array(
    'content-type' => $content_type,
    'content-MD5'  => $md5,
    'request_uri' => $uri,
    'timestamp' => $date
);
$canonical_string = implode(',', $canonical_params);

// Generating signature
$signature = base64_encode(hash_hmac('sha1', $canonical_string, $secret_key, true));

// Performing a GET query
$ch = curl_init($domain.$uri);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        "Accept: application/vnd.deliveree-stock+json;version=1",
        "Content-Type: $content_type",
        "Content-MD5: $md5",
        "Authorization: APIAuth $access_id:$signature",
        "Date: $date"
    )
);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$curl_response = curl_exec($ch);
curl_close($ch);

// Handling response
$api_response = json_decode($curl_response, false);
?>

Cet exemple est très similaire au précédent. La seule différent est l’addition de paramètres dans l’url, qui influent donc sur la chaine canonique et la signature.

Exemple 3: Autres requêtes

access_id  = "426f891b-c457-4c18-84a4-386cc391a7ef"
secret_key = "test-secret-key"

body = 'somethingelse=somevalue&count=2'

# content_md5 = Base64Encode(md5('somethingelse=somevalue&count=2'))

content_type = 'application/x-www-form-urlencoded' # set by curl when using -d
content_md5  = 'VDBQ7G7oxo8nw3WHE7NUSA=='
uri          = '/session'
timestamp    = "Fri, 30 Oct 2015 14:10:00 GMT"

# canonical_string = [content_type,content_md5,uri,timestamp].join(,)
canonical_string = 'application/x-www-form-urlencoded,VDBQ7G7oxo8nw3WHE7NUSA==,/session,Fri, 30 Oct 2015 14:10:00 GMT'

# hmac_signature = Base64Encode(HMAC-SHA1(canonical_string, secret_key))
hmac_signature = "ObXP38lZtbchbG6wls8eRLKyRGs="

# auth_header = "APIAuth access_id:hmac_signature
auth_header = "APIAuth 426f891b-c457-4c18-84a4-386cc391a7ef:ObXP38lZtbchbG6wls8eRLKyRGs="
curl 'https://stocks.deliver.ee/session' \
     -X POST \
     -H 'Accept: application/json' \
     -H 'Date: Fri, 30 Oct 2015 14:10:00 GMT' \
     -H 'Content-MD5: VDBQ7G7oxo8nw3WHE7NUSA==' \
     -H "Authorization: APIAuth 426f891b-c457-4c18-84a4-386cc391a7ef:ObXP38lZtbchbG6wls8eRLKyRGs=" \
     -d somethingelse=somevalue \
     -d count=2
<?php
// Required variables
$access_id = '426f891b-c457-4c18-84a4-386cc391a7ef';
$secret_key = 'test-secret-key';
$domain = 'https://stocks.deliver.ee';
$uri = '/session';
$params = array(
  'foo' => 'bar',
  'hello' => 'world'
);
$query_string = json_encode($params);
$date = gmdate('D, d M Y H:i:s T');
$content_type = 'application/json';

// Preparing MD5 sum for content
$md5 = base64_encode(md5($query_string, true));

// Computing canonical string
$canonical_params = array(
    'content-type' => $content_type,
    'content-MD5'  => $md5,
    'request_uri' => $uri,
    'timestamp' => $date
);
$canonical_string = implode(',', $canonical_params);

// Generating signature
$signature = base64_encode(hash_hmac('sha1', $canonical_string, $secret_key, true));

// Performing a POST query
$ch = curl_init($domain.$uri);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        "Accept: application/vnd.deliveree-stock+json;version=1",
        "Content-Type: $content_type"
        "Content-MD5: $md5",
        "Authorization: APIAuth $access_id:$signature",
        "Date: $date"
    )
);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $query_string);
$curl_response = curl_exec($ch);
curl_close($ch);

// Handling response
$api_response = json_decode($curl_response, false);
?>

Cet exemple est valable pour toutes les requêtes contenant un corps de données, quelque soit le verbe (GET, POST, PUT, etc).

La principale différence par rapport aux exemples précédents est la présence de données en corps de requête, et donc (généralement) d’un header Content-Type.

Il faut calculer le MD5 du corps de requête, puis l’encoder en Base 64. Cette valeur est utilisée pour le header Content-MD5 et la création de la chaine canonique.

Paramètres commerçant

Les comptes commerçants sont configurables. Ci dessous se trouve une liste des paramètres réglables. Nous vous invitons à nous contacter pour plus d’information.

Horaires d’ouvertures

Chaque commerçant a des horaires d’ouverture de configurées. Les commandes en dehors de ces horaires ne sont pas autorisées. Selon les partenaires, il se peut que des horaires d’ouvertures soit également renseignés au niveau de la boutique, auxquels cas ces derniers seront utilisés en priorité.

Délai de préparation

Le délai de préparation est utilisé dans le cas des livraisons immédiate. Il permet de laisser un délai à la boutique (souvent entre 15 et 30 minutes) pour préparer la commande afin d’éviter qu’un coursier ne vienne la retirer trop rapidement.

Délai de sécurité

Le délai de sécurité permet de s’assurer qu’une commande ne peut pas se dérouler juste avant (généralement 10 ou 15 minutes) la fermeture d’une boutique .

Planning commerçant

Cet endpoint permet d’obtenir les créneaux de livraisons possible pour le commerçant effectuant la requête et les différentes délais configurés.

Le nombre de jours ainsi que la date de départ sont configurables.

Object planning

{
  "schedule": {
    "regular": {},
    "express": {}
  },
  "merchant": {
    "preparation_delay": 30,
    "security_delay": 15
  }
}

Cet objet représente le planning de livraison.

Attribut Description
schedule
object
Clé “racine” de la réponse json.
schedule > regular
planning journalier
Tableau de plannings journaliers pour la priorité regular.
schedule > express
planning journalier
Tableau de plannings journaliers pour la priorité express.
Cette clé sera absente si la priorité n’est pas activée pour le commerçant.
schedule > urgent
planning journalier
Tableau de plannings journaliers pour la priorité urgent.
Cette clé sera absente si la priorité n’est pas activée pour le commerçant.
merchant
object
Objet contenant diverses informations liées à la configuration du commerçant
merchant > preparation_delay
integer
Délai de préparation des commandes, en minutes
merchant > security_delay
integer
Délai de securité des commandes, en minutes

Objet planning journalier

{
  "delay": 180,
  "immediate": {
    "start": "2015-11-09T14:17:00Z",
    "finish": "2015-11-09T17:17:00Z"
  },
  "programmed": [
    {
      "date": "2015-10-20",
      "utc_offset_seconds": 7200,
      "slots": [
        {
          "start": "09:00",
          "finish": "10:30"
        },
        {
          "start": "10:00",
          "finish": "11:30"
        }
      ]
    }
  ]
}

Cet objet représente les créneaux de livraison pour un jour donné et un délai de priorité pour le commerçant effectuant la requête.

Ces créneaux sont calculés grace aux informations fournies par le commerçant, notamment ses heures d’ouvertures et son délai de livraison.

Le créneau “immédiat”, lorsque présent, indique qu’il est possible d’effectuer la livraison immédiatement.

Les créneaux “programmés” ont tous une durée égale au délai de livraison, et commencent toutes les heures après l’heure d’ouverture.

Attribut Description
delay
integer
La durée (en minutes) du créneau de livraison.
immediate
object
Le créneau de livraison immédiat.
Peut être null.
immediate > start
string
Le début du créneau de livraison immédiat, au format ISO 8601
immediate > finish
string
La fin du créneau de livraison immédiat, au format ISO 8601
programmed
array
Un tableau de journées de planning contenant les créneaux de livraison programmées.
programmed > date
string
La date (ISO 8601) du jour concerné par l’objet
programmed > utc_offset_seconds
integer
Le nombre de secondes de décalage par rapport au temps UTC pour les horaires des objects slots
programmed > slots
object
Les créneaux d’ouvertures.
programmed > slots > start
string
L’heure (locale) de début de créneau au format “HH:mm”. Pour obtenir l’heure UTC, se fier à l’attribut utc_offset_seconds.
programmed > slots > finish
string
L’heure (locale) de fin de créneau au format “HH:mm”. Pour obtenir l’heure UTC, se fier à l’attribut utc_offset_seconds.

Obtenir le planning

GET /schedule
Exemple de requête et réponse:

curl 'https://stocks.deliver.ee/schedule' \
     -X GET \
     -H 'Accept: application/vnd.deliveree-stock+json;version=1' \
     -d count=2
{
  "schedule": {
    "regular": {
      "delay": 180,
      "immediate": null,
      "programmed": [
        {
          "date":"2015-10-20",
          "utc_offset_seconds":7200,
          "slots": [
            {
              "start": "09:00",
              "finish": "10:30"
            },
            {
              "start": "16:00",
              "finish": "17:30"
            }
          ]
        },
        {
          "date":"2015-10-21",
          "utc_offset_seconds":7200,
          "slots": [
            {
              "start": "09:00",
              "finish": "10:30"
            },
            {
              "start": "16:00",
              "finish": "17:30"
            }
          ]
        }
      ]
    }
  },
  "merchant": {
    "preparation_delay": 30,
    "security_delay": 15
  }
}

GET /schedule

Récupère le planning de livraison du marchant. Il y a un planning retourné par délai de livraison configuré.

Par défaut, les créneaux commencent toutes les heures (eg: 12-15, 13-16, 14-17). Il est possible de configurer ce pas, ainsi qu’utiliser le délai de livraison configuré en guise de pas.

Si un identifiant (valide) de recherche de boutique est donné en paramètre, les créneaux seront filtrés: ceux pour lesquels aucune des boutique (trouvées par la recherche) n’est ouverte seront exclus de la réponse.

Il est également possible de donner directement un identifiant de boutique afin de se baser sur les horaires d’ouvertures de cette boutique pour générer le planning.

Attention: les identifiants de boutique et de magasins sont tous deux optionnels, mais mutuellement exclusifs.

Paramètre Description  
start_date
string
La date de départ du planning au format ISO 8601. Si non renseigné, la date du jour sera utilisée.
Une date dans le passé ou non conforme ISO 8601 provoquera une erreur 422.
 
count
integer
Le nombre de jours à renvoyer, 3 si non renseigné.
Une valeur non comprise entre 1 et 7 provoquera une erreur 422.
 
step
integer
string</small> Le pas entre chaque créneau en minutes, optionnel (défaut: 60).
La valeur priority est aussi utilisable afin d’utiliser la durée de livraison configurée.
eligibility_id
string
Un identifiant de recherche de boutique, utilisé pour filtrer les créneaux (optionnel).
Une valeur non valide ou inexistante sera ignorée silencieusement.
 
store
string
Un identifiant de boutique (optionnel).
Une valeur non valide ou inexistante sera ignorée silencieusement.
 

Recherche de boutique

Ces endpoint permettent de trouver une boutique qui couvre le code postal demandé et qui a les produits demandés en stock.

Le premier endpoint est assez générique, et permet de savoir si au moins une boutique peut traiter la commande à l’heure où la requête est effectuée. Les divers paramètres du commerçant (tel que le délai de préparation ou les horaires d’ouvertures) ou des boutiques ne sont pas pris en compte, uniquement l’inventaire des boutiques. Cet endpoint permet de déterminer s’il est pertinent de proposer le mode de livraison deliver.ee et le planning de livraison (avec livraison immédiate et planning de créneaux, obtenus via l’endpoint de planning)

Le second endpoint est adapté aux commerçants souhaitant principalement effectuer de la livraison immédiate, et n’utilisant donc pas l’endpoint de planning ni les créneaux suggérés. Cette recherche prends en compte les différents paramètres du commerçant et des magasins, notamment au niveau des horaires d’ouvertures et délai de préparation.

Dans les deux cas, si des boutiques sont aptes à traiter la commande, la référence de la boutique la plus appropriée sera renvoyée dans la réponse. Cette donnée est fournie à titre indicatif: il se peut qu’entre cette recherche et la validation (paiement) de la commande, cette boutique ne soit plus en mesure de traiter la commande.

Objet eligibilité

{
  "eligibility": {
    "id": "436963b9-02d4-4763-8a3f-8cdc54e6ad21",
    "cart_id": "ABCID789",
    "status": "success",
    "results_count": 30,
    "best_result_reference": "STOREID",
    "vehicle": "bike",
    "products": [
      {
        "sku": "someproductsku",
        "qty": 1
      }
    ]
  }
}

Cet objet représente le résultat d’une recherche de boutique.

Attribut Description
id
string
L’identifiant de la recherche
cart_id
string
L’identifiant de la commande/du panier
status
string
Le résultat de la recherche. Valeur parmi success, failed, zone_failed, products_failed.
results_count
integer
Le nombre de boutique aptes à traiter la commande
best_result_reference
string
L’identifiant de la boutique la plus apte à traiter la commande.
Peut être null si aucune boutique n’est apte à traiter la commande.
vehicle
string
L’identifiant du véhicule qui sera utilisé.
Ne sera non-null que si status est success.
Valeur parmi bike, scooter, tricycle, cargo_bike, car, van.
products
array
Un tableau récapitulant les produits demandés.
products > sku
string
La référence du produit chez le commerçant.
products > qty
integer
Le nombre de produits demandés.

Objet eligibilité immédiate

{
  "eligibility": {
    "cart_id": "ABCID789",
    "vehicle": "bike",
    "products": [
      {
        "sku": "someproductsku",
        "qty": 1
      }
    ],
    "regular": {
      "status": "out_of_schedule",
      "results_count": 0,
      "best_result_reference": null,
      "start_at": "2015-11-19T16:00:00Z",
      "duration": 180,
      "end_at": "2015-11-19T19:00:00Z"
    },
    "express": {
      "status": "success",
      "results_count": 7,
      "best_result_reference": "STOREID",
      "start_at": "2015-11-19T16:00:00Z",
      "duration": 90,
      "end_at": "2015-11-19T17:30:00Z"
    }
  }
}

Cet objet représente le résultat d’une recherche de boutique dans le cadre d’une livraison immédiate.

Attribut Description
cart_id
string
L’identifiant de la commande/du panier
vehicle
string
L’identifiant du véhicule qui sera utilisé.
Ne sera non-null que si status est success.
Valeur parmi bike, scooter, tricycle, cargo_bike, car, van.
products
array
Un tableau récapitulant les produits demandés.
products > sku
string
La référence du produit chez le commerçant.
products > qty
integer
Le nombre de produits demandés.
regular
object
Le résultat de la recherche d’éligibilité pour une livraison immédiate en délai reguliar.
Peut être null ou absent.
express
object
Le résultat de la recherche d’éligibilité pour une livraison immédiate en délai express.
Peut être null ou absent.
urgent
object
Le résultat de la recherche d’éligibilité pour une livraison immédiate en délai urgent.
Peut être null ou absent.
regular > status
string
Le résultat de la recherche. Valeur parmi success, failed, zone_failed, products_failed, out_of_schedule.
regular > results_count
integer
Le nombre de boutique aptes à traiter la commande
regular > best_result_reference
string
L’identifiant de la boutique la plus apte à traiter la commande.
Peut être null si aucune boutique n’est apte à traiter la commande.
regular > start_at
string
L’heure de début (ISO8601) de commande théorique, utilisée pour vérifier les boutiques ouvertes.
regular > end_at
string
L’heure de fin (ISO8601) de commande théorique, utilisée pour vérifier les boutiques ouvertes.
regular > duration
integer
La durée en minutes de la livraison.

Recherche générique

POST /orders/eligibility
Exemple de requête et réponse:

curl 'https://stocks.deliver.ee/orders/eligibility' \
     -X POST \
     -H 'Accept: application/vnd.deliveree-stock+json;version=1' \
     -d cart_id=abc \
     -d postal_code=75001 \
     -d "products[][sku]"=abc \
     -d "products[][qty]"=1 \
     -d "products[][sku]"=cde \
     -d "products[][qty]"=1
{
  "eligibility":{
    "id": "436963b9-02d4-4763-8a3f-8cdc54e6ad21",
    "cart_id":"abc",
    "status":"zone_failed",
    "results_count": 0,
    "best_result_reference": null,
    "vehicle": null,
    "products":[
      {
        "sku":"abc",
        "qty":"1"
      },
      {
        "sku":"cde",
        "qty":"1"
      }
    ]
  }
}

POST /orders/eligibility

Effectue une recherche de boutique pour les paramètres données. Sauf indication contraire, tous les paramètres sont requis.

L’API retourne un code 200 à partir du moment où la requête est authentique et bien formée, même s’il n’y a pas de boutiques correspondant à la recherche. Le champ eligibility > status contient le status de la recherche.

L’id de recherche retourné dans la réponse peut être transmis lors de la récupération du planning afin d’éliminer directement les créneaux où aucune boutique n’est ouverte.

Paramètre Description
cart_id
string
L’identifiant de la commande/du panier.
L’absence de cet attribut provoquera une erreur 422.
postal_code
string
Le code postal pour la livraison de la commande.
L’absence de cet attribut provoquera une erreur 422.
products
array
Un tableau récapitulant les produits demandés.
L’absence de ce tableau provoquera une erreur 422.
Un tableau vide provoquera une erreur 422.
products > sku
string
La référence du produit chez le commerçant.
L’absence de cet attribut provoquera une erreur 422.
products > qty
integer
Le nombre de produits demandés.
L’absence de cet attribut provoquera une erreur 422.
products > weight
decimal
Le poids du produit (optionnel).
products > height
decimal
La hauteur du produit (optionnel).
products > length
decimal
La longueur du produit (optionnel).
products > width
decimal
La largeur du produit (optionnel).

Recherche immédiate

POST /orders/eligibility/immediate
Exemple de requête et réponse:

curl 'https://stocks.deliver.ee/orders/eligibility/immediate' \
     -X POST \
     -H 'Accept: application/vnd.deliveree-stock+json;version=1' \
     -d cart_id=abc \
     -d postal_code=75001 \
     -d "products[][sku]"=abc \
     -d "products[][qty]"=1 \
     -d "products[][sku]"=cde \
     -d "products[][qty]"=1
{
  "eligibility": {
    "cart_id": "ABCID789",
    "vehicle": "bike",
    "products": [
      {
        "sku": "someproductsku",
        "qty": 1
      }
    ],
    "regular": {
      "status": "out_of_schedule",
      "results_count": 0,
      "best_result_reference": null,
      "start_at": "2015-11-19T16:00:00Z",
      "duration": 180,
      "end_at": "2015-11-19T19:00:00Z"
    },
    "express": {
      "status": "success",
      "results_count": 7,
      "best_result_reference": "STOREID",
      "start_at": "2015-11-19T16:00:00Z",
      "duration": 90,
      "end_at": "2015-11-19T17:30:00Z"
    }
  }
}

POST /orders/eligibility/immediate

Effectue une recherche de boutique pour une livraison immédiate avec les paramètres données.

Au niveau des paramètres et codes de retour, cet endpoint se comporte identiquement à la recherche de boutique générique mentionnée ci-dessus.

Consultation des commandes

Ces endpoints permettent de lister les commandes ou d’en consulter une en particulier. Le commerçant n’a accès qu’a ses propres commandes.

Objet commande

{
  "id": "d95f0a2b-2a88-44b3-8910-46caf759c5c0",
  "partner_id": "test",
  "cart_id": "test",
  "status": "draft",
  "shipping_status": "pending",
  "first_name": "Jane",
  "last_name": "Doe",
  "address": "30, bd Susanne Thibault",
  "postal_code": "75001",
  "city": "Paris",
  "country": "France",
  "address_comment": "",
  "phone": "0123456789",
  "email": "test@example.org",
  "start_at": "2015-10-21T00:00:00.000Z",
  "start_at": "2015-10-21T03:00:00.000Z",
  "priority": "regular",
  "products": [
    {
      "sku": "1168833661638",
      "qty": 1
    }
  ]
}

Cet objet représente une commande.

les créneaux de livraison pour un jour donné pour le commerçant effectuant la requête.

Ces créneaux sont calculés grace aux informations fournies par le commerçant, notamment ses heures d’ouvertures et son délai de livraison.

Les créneaux ont tous une durée égale au délai de livraison, et commencent toutes les heures après l’heure d’ouverture.

Attribut Description
id
string
L’identifiant (interne) de la commande
partner_id
string
L’identifiant de la commande dans l’API partenaire
cart_id
string
L’identifiant de la commande/du panier chez le commerçant
status
string
Statut de la commande. Valeur possibles:
pending, eligibility_failed, assigned, assignment_failed, accepted, closed
shipping_status
string
Statut de la livraison.
Valeur parmi pending, assigned, active, retrieved, delivered, canceled, paused, failed, refused, rescheduled, archived.
first_name
string
Le prénom du client
last_name
string
Le nom de famille du client
address
string
L’adresse de livraison
postal_code
string
Le code postal de livraison
city
string
La ville de livraison
country
string
Le pays de livraison
address_comment
string
Infos complémentaires de livraison (digicode, etc)
phone
string
Numéro de téléphone du client
email
string
Adresse email du client
start_at
string
Date + heure (ISO 8601) à laquelle la commande commence
end_at
string
Date + heure (ISO 8601) à laquelle la commande doit être livrée
priority
string
Délai de priorité de la commande
products
array
Un tableau récapitulant les produits demandés.
products > sku
string
La référence du produit chez le commerçant.
products > qty
integer
Le nombre de produits demandés.

Lister les commandes

GET /orders
Exemple de requête et réponse:

curl 'https://stocks.deliver.ee/orders' \
     -X GET \
     -H 'Accept: application/vnd.deliveree-stock+json;version=1'
{
  "orders": [
    {
      "id": "d95f0a2b-2a88-44b3-8910-46caf759c5c0",
      "partner_id": "test",
      "cart_id": "test",
      "status": "draft",
      "shipping_status": "pending",
      "products": [
        {
          "sku": "1168833661638",
          "qty": 1
        }
      ],
      "first_name": "Jane",
      "last_name": "Doe",
      "address": "30, bd Susanne Thibault",
      "postal_code": "75001",
      "city": "Paris",
      "country": "France",
      "address_comment": "",
      "phone": "0123456789",
      "email": "test@example.org",
      "start_at": "2015-10-21T00:00:00.000Z",
      "end_at": "2015-10-21T03:00:00.000Z",
      "priority": "regular"
    }
  ],
  "meta": {
    "per_page": 10,
    "current_page": 1,
    "prev_page": null,
    "next_page": null,
    "total_count": 1,
    "total_pages": 1
  }
}

GET /orders

Liste les commandes du commerçant actuel.

Paramètre Description
page
integer
La page de résultat à retourner.
Valeur par défaut: 1.
Une valeur inférieur à 1 retournera une erreur 422.
per_page
integer
Le nombre de résultat à retourner par page.
Valeur par défaut: 10.
Une valeur inférieur à 1 retournera une erreur 422.



La réponse inclut des métadonnées liées à la pagination.

Métadonnée Description
per_page
integer
Le nombre d’élément par page.
current_page
integer
Le numéro de la page retournée.
prev_page
integer
Le numéro de la page précédente.
Peut être null.
next_page
integer
Le numéro de la page suivante.
Peut être null.
total_count
integer
Le nombre total d’éléments.
total_pages
integer
Le nombre total de pages de résultats.

Récupérer une commande

GET /orders/:id
Exemple de requête et réponse:

curl 'https://stocks.deliver.ee/orders/d95f0a2b-2a88-44b3-8910-46caf759c5c0' \
     -X GET \
     -H 'Accept: application/vnd.deliveree-stock+json;version=1'
{
  "order": {
    "id": "d95f0a2b-2a88-44b3-8910-46caf759c5c0",
    "partner_id": "test",
    "cart_id": "test",
    "status": "draft",
    "shipping_status": "pending",
    "products": [
      {
        "sku": "1168833661638",
        "qty": 1
      }
    ],
    "first_name": "Jane",
    "last_name": "Doe",
    "address": "30, bd Susanne Thibault",
    "postal_code": "75001",
    "city": "Paris",
    "country": "France",
    "address_comment": "",
    "phone": "0123456789",
    "email": "test@example.org",
    "start_at": "2015-10-21T00:00:00.000Z",
    "end_at": "2015-10-21T03:00:00.000Z",
    "priority": "regular"
  }
}

GET /orders/:id

Récupère la commande correspondant à l’id passé dans l’URL.

L’API n’accepte aucun paramètre de requête.

L’API retourne une erreur 404 en cas d’ID de commande non existant pour le commerçant.

Création de commande

Cet endpoint permet de créer les commande pour le commerçant.

Créer une commande

POST /orders
Exemple de requête et réponse:

curl 'https://stocks.deliver.ee/orders' \
     -X POST \
     -H 'Accept: application/vnd.deliveree-stock+json;version=1' \
     -d cart_id="1323336" \
     -d postal_code="75001" \
     -d first_name="John" \
     -d last_name="Doe" \
     -d address="1, rue de l'elysée" \
     -d city="Paris" \
     -d country="France" \
     -d address_comment="sonner chez Johnny" \
     -d phone="0123456789" \
     -d email="ytest@example.com" \
     -d start_at="2015-10-09T11:44:07+02:00" \
     -d priority="regular"
     -d "products[][sku]"="3811688336616" \
     -d "products[][qty]"="3"
{
  "order": {
    "cart_id": "1323336",
    "status": "eligibility_failed",
    "shipping_status": "pending",
    "products": [
      {
        "sku": "3811688336616",
        "qty": "3"
      }
    ],
    "start_at": "2015-10-09T11:44:07.000Z",
    "end_at": "2015-10-09T14:44:07.000Z",
    "priority": "regular",
    "first_name": "John",
    "last_name": "Doe",
    "address": "1, rue de l'elysée",
    "postal_code": "75001",
    "city": "Paris",
    "country": "France",
    "address_comment": "sonner chez Johnny",
    "phone": "0123456789",
    "email": "test@example.com"
  }
}

POST /orders

Tente de créer une commande. A l’exception de store et start_at, tous les paramètres sont requis.

Lorsque le paramètre start_at n’est pas envoyé, la commande est considérée comme une commande immédiate, et la date de départ sera maintenant + délai de préparation + 5 minutes.

Certains commerçants choisissent en interne la boutique à utiliser. Ces derniers doivent envoyer le paramètre store.

Pour les autres commerçants, le paramètre store est ignoré, et une recherche de boutique éligible est lancée au moment de la création. En cas d’échec, la commande aura le statut eligibility_failed;

Dans tous les cas, si une commande avec un statut autre que draft, eligibility_failed, ou assignment_failed existe pour le cart_id donné, une erreur 422 sera retournée.

Cet endpoint renvoie un objet de type commande.

Paramètre Description
cart_id
string
L’identifiant de la commande/du panier.
start_at
string
Date + heure (ISO 8601) de départ commande.
Une date dans le passé ou non conforme ISO 8601 provoquera une erreur 422.
En cas d’absence, la commande sera considérée comme immédiate (cf. explications ci dessus).
priority
string
Priorité de la commande.
Une valeur autre que regular, express, ou urgent provoquera une erreur 422.
Une valeur non configurée pour le commerçant provoquera une erreur 422.
first_name
string
Le prénom du client
last_name
string
Le nom de famille du client
address
string
L’adresse de livraison
postal_code
string
Le code postal de livraison
city
string
La ville de livraison
country
string
Le pays de livraison
address_comment
string
Infos complémentaires de livraison (digicode, etc)
phone
string
Numéro de téléphone du client
email
string
Adresse email du client
store
string
La référence du magasin choisi par le commerçant en interne.
Se référer à la description générale de l’endpoint.
products
array
Un tableau récapitulant les produits demandés.
Un tableau vide provoquera une erreur 422.
products > sku
string
La référence du produit chez le commerçant.
L’absence de cet attribut provoquera une erreur 422.
products > qty
integer
Le nombre de produits demandés.
L’absence de cet attribut provoquera une erreur 422.
products > weight
decimal
Le poids du produit (optionnel).
products > height
decimal
La hauteur du produit (optionnel).
products > length
decimal
La longueur du produit (optionnel).
products > width
decimal
La largeur du produit (optionnel).

Evènements

Objet évènement

{
  "id":"b50610fa-bc2e-4c69-b20b-208f256e2e24",
  "created_at":"2015-11-12T14:14:08.266Z",
  "data":{
    "id":"a1d65297-e54a-44d6-b0d6-510162220d13",
    "status":"assigned",
    "products":[
      {
        "sku":"somesku",
        "qty":1
      }
    ],
    "end_at":"2015-11-18T13:30:28.000Z",
    "first_name":"James",
    "last_name":"Jones",
    "address":"62, rue des impasses boulevardiennes",
    "postal_code":"75001",
    "city":"Paris",
    "country":"France",
    "address_comment":"Sonner chez Jim",
    "phone":"33676767676",
    "email":"hello@example.fr",
    "cart_id":"755454",
    "created_at":"2015-11-12T10:51:25.505Z",
    "start_at":"2015-11-18T10:30:28.000Z",
    "priority":"regular",
    "vehicle":"bike",
    "shipping_status":"pending"
  },
  "event":"order.update"
}

Cet object représente un évènement.

Attribut Description
id
string
L’identifiant (interne) de l’évènement
created_at
string
La date de création de l’évènement
event
string
Le type d’évènement
data
object
Les données propres à l’évènement.
Se fier au tableau d’évènements pour plus d’infos.

Fonctionnement

L’API est capable d’envoyer des informations en mode “push” lors de certains évènements (listés ci-dessous).

Ces évènements sont envoyés en POST sur une (ou plusieurs) urls configurées sur demande.

Les requêtes envoyés sont signées avec le même mécanisme utilisé par l’API Stocks pour vérifier les requêtes.

Évènement Description
order.update Une commande a été mise à jour.
data contient l’objet commande dans son intégralité.

Erreurs

Exemple de réponse d’erreur

{
  "code": 404,
  "status": "not_found",
  "reason": "Couldn't find Order with 'id'=1"
}

Lorsqu’une erreur se produit, l’API retourne toujours un document json. Le statut HTTP de la réponse sera toujours équivalent au code inclut dans la réponse.

Paramètre Description
code
integer
Le code HTTP de l’erreur
status
string
La signification du code
reason
string
Un message d’erreur descriptif, lisible par un humain.

Les codes d’erreurs suivants sont utilisés:

Code d’erreur Signification
400 Bad Request – La requête est mal formée
401 Unauthorized – La requête n’est pas signée, la signature n’est pas correcte, ou bien expirée
403 Forbidden – La resource demandée existe, mais l’utilisateur n’est pas autorisé à y accéder
404 Not Found – La resource demandée n’existe pas
405 Method Not Allowed – Vous tentez d’accéder à une resource en utilisant une mauvaise méthode (verbe HTTP)
406 Not Acceptable – Vous demandez un format autre que json
410 Gone – La resource n’existe plus sur nos serveurs
500 Internal Server Error – Un problème est arrivé sur notre serveur. Merci de réessayer ultérieurement.
501 Not Implemented – Fonctionnalité réclamée non supportée par le serveur.
503 Service Unavailable – Service hors-ligne pour maintenance. Merci de réessayer ultérieurement.