Le Webservice My Flying Box (MFB) fournit une interface (API) pour obtenir des offres de transports de multiples transporteurs de manière homogène et passer commande des offres qui vous intéressent.
En intégrant ce webservice à votre plateforme, vous aurez accès à des tarifs compétitifs sans avoir à implémenter séparément les webservice de chaque transporteur individuellement. Vous économisez ainsi du temps et de l'argent.
Cette documentation est destinée à un public de techniciens dont l'objectif est de mettre en oeuvre le Webservice MFB sur leur système. Elle présente de manière exhaustive les spécifications de toutes les resources exposées par le webservice et la manière de les utiliser, avec des exemples de code dans plusieurs languages.
N'hésitez pas à nous contacter à l'adresse tech@myflyingbox.com si vous avez la moindre question. Nous pouvons aussi fournir des services d'intégration si nécessaire.
Pour une intégration directe dans vos applications et pour servir d'exemples, nous fournissons également des librairies clientes pour PHP, Prestashop et WooCommerce.
Cette colonne contient des exemples de code pour la plupart des fonctionnalités du Webservice MFB.
Les languages supportés sont listés en haut de la colonne, et vous pouvez changez le language actif à la volée, selon vos besoins.
Nous avons essayé de produire des exemples pouvant être facilement copiés/collés pour faciliter vos tests. Vous n'aurez en général qu'à remplacer vos identifiants de connexions. Si vous avez des suggestions d'amélioration pour les exemples de code, n'hésitez pas à nous envoyer un message à tech@myflyingbox.com.
Avant d'entrer dans les détails techniques, voici un résumé des étapes d'un scénario classique d'utilisation du webservice. Chaque ligne faisant référence à une requête vers le webservice contient un lien vers la documentation correspondante ; les autres lignes correspondent à des étapes qui sont à effectuer de votre côté uniquement.
Lorsque votre compte est enregistré sur le webservice, un email vous sera adressé avec vos coordonnées de connexion pour le serveur de test. Vous devez utiliser le serveur de test uniquement pour la mise en place intégrale du service web. Lorsque votre implémentation est fonctionnelle, contactez nous pour obtenir vos coordonnées de connexion au serveur de production et commander à passer des commandes réelles.
Le Webservice MFB utilise des ressources REST de manière standard dans toute l'API. Toutes les déclarations de requêtes ont donc un sens:
Pour le moment nous n'utilisons pas les verbes HTTP PUT, PATCH et DELETE.
L'URL de base pour toutes les requêtes est : https://api.myflyingbox.com/v2
Toutes les URIs ci-dessous doivent être apposées à cette URL de base.
Vous ne pouvez pas utiliser le Webservice MFB sans authentification.
L'authentification n'est pas persistante ; il vous faudra donc inclure les identifiants de connexion à chaque requête.
L'authentification fonctionne selon la méthode
HTTP Basic Access Authentication
.
curl https://api.myflyingbox.com/v2/ -u identifiant:mot_de_passe
require 'net/http' # Ou 'net/https' pour ruby < 2.0.0
uri = URI('https://api.myflyingbox.com/v2/quotes')
Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
request = Net::HTTP::Get.new uri
request.basic_auth 'identifiant', 'mot_de_passe'
response = http.request request # Net::HTTPResponse object
end
{
"status":"failure",
"error":{
"type":"access_denied",
"message":"Unauthorized"
},
"self":"https://api.myflyingbox.com/v2"
}
failure
access_denied
Unauthorized
api.myflyingbox.com/v2/v2
Toutes les requêtes utilisent le protocole HTTP.
Le contenu des requêtes doit être encodé en UTF-8.
Le webservice supporte deux formats pour passer les paramètres de requêtes :
Quel que soit le format que vous décidez d'utiliser, assurez-vous de passer la bonne en-tête HTTP "content-type".
Vous pouvez consulter l'exemple de code pour les demandes de devis pour des modèles de requêtes curl utilisant chacun de ces deux formats.
Les réponses sont transmises au format JSON.
La plupart des languages de programmation proposent des bibliothèques JSON maintenues, que vous pouvez utiliser pour manipuler les réponses transmises par le webservice.
Tous les textes sont encodés en UTF-8. Si votre système n'utilise pas UTF-8, assurez-vous de convertir correctement les chaînes de caractères afin que toutes les interactions avec le webservice se fassent bien en UTF-8. Ce point est particulièrement important pour le bon rendu des adresses d'expédition/de livraison.
Les réponses sont encapsulées dans une enveloppe de base décrite ci-dessous.
Lorsque vous envoyez une requête au Webservice MFB, vous avez accès à trois sources d'information pour interpréter le succès ou l'échec de la requête :
Notez que deux autres attributs sont disponibles à fin de débug si vous rencontrez des erreurs sur vos requêtes :
Ci-dessous sont présentés les différents codes de réponse HTTP avec les codes d'erreur correspondants. Vous pouvez appuyer votre implémentation sur ces codes.
{
"status":"failure",
"error":{
"type":"resource_not_found",
"message":"Quote not found"
},
"self":"https://api.myflyingbox.com/v2/quotes/3"
}
Un devis contient une collection d'offres de transports. Lorsque vous demandez un nouveau devis, vous devez transmettre les caractéristiques de base de votre expédition (pack-liste, ville de départ et destination) dans le format attendu (voir 'paramètres de la requête' ci-dessous).
Après avoir reçu un devis, vous pouvez commander toute offre transmise dans le devis (voir section commander plus bas). Notez que lorsque vous passez commande vous ne pouvez pas modifier les caractéristiques de base (codes postaux, pays, dimension des colis) de l'expédition. Si vous devez modifier ces informations, il vous faudra alors demander un nouveau devis avec les bonnes informations.
Les paramètres doivent être encapsulés dans un élément racine 'quote' (voir exemple de code à droite).
curl https://test.myflyingbox.com/v2/quotes -i -X POST -u {identifiant}:{mot_de_passe} \
-H "Content-Type:application/json" \
-d '{"quote": {
"shipper": {
"country":"GB",
"postal_code": "SW1A 1AA",
"city": "London"
},
"recipient": {
"is_a_company": "false",
"country": "FR",
"postal_code": "31300",
"city": "Toulouse"
},
"parcels": [
{
"weight": 1,
"length": 60,
"width": 60,
"height": 40
},
{
"weight": 2.5,
"length": 30,
"width": 30,
"height": 20
}
]
}}'
curl https://test.myflyingbox.com/v2/quotes -i -X POST -u {login}:{password} \
-H "Content-Type:application/json" \
-d '{"quote": {
"shipper": {
"country":"GB",
"postal_code": "SW1A 1AA",
"city": "London"
},
"recipient": {
"is_a_company": "false",
"country": "FR",
"postal_code": "31300",
"city": "Toulouse"
},
"parcels": [
{
"weight": 1,
"length": 60,
"width": 60,
"height": 40
},
{
"weight": 2.5,
"length": 30,
"width": 30,
"height": 20
}
],
"offers_filters": {
"with_carrier_codes": ["ups"]
"without_product_codes": ["ups_access_point_standard"]
}
}}'
curl https://test.myflyingbox.com/v2/quotes -i -X POST -u {login}:{password} \
-d "quote[shipper][country]=GB" \
-d "quote[shipper][postal_code]=SW1A 1AA" \
-d "quote[shipper][city]=London" \
-d "quote[recipient][country]=FR" \
-d "quote[recipient][postal_code]=31300" \
-d "quote[recipient][city]=Toulouse" \
-d "quote[recipient][is_a_company]=false" \
-d "quote[parcels][][weight]=1" \
-d "quote[parcels][][length]=60" \
-d "quote[parcels][][width]=60" \
-d "quote[parcels][][height]=40" \
-d "quote[parcels][][weight]=2.5" \
-d "quote[parcels][][length]=30" \
-d "quote[parcels][][width]=30" \
-d "quote[parcels][][height]=20"
curl https://test.myflyingbox.com/v2/quotes -i -X POST -u {identifiant}:{mot_de_passe} \
-H "Content-Type:application/json" \
-d '{
"quote": {
"parcel_type": "document",
"parcels": [
{
"type": "document",
"weight": 0.5
}
],
"recipient": {
"city": "Toulouse",
"country": "FR",
"is_a_company": false,
"postal_code": "31300"
},
"shipper": {
"city": "Nice",
"country": "FR",
"postal_code": "06000"
}
}
}'
{
"id": "2a4a628c-e541-4571-b817-a57cc3f89a1b",
"shipper": {
"postal_code": "AB1 6CC",
"country": "GB"
},
"recipient": {
"is_a_company": "true",
"postal_code": "06800",
"country": "FR"
},
"parcels": [
{
"weight": 3,
"length": 40,
"width": 30,
"height": 10,
},
{
"weight": 1.75,
"length": 50,
"width": 10,
"height": 10,
}
],
"offers": [
{
"id":"6d37b0ed-833d-4a59-9e57-d6bd7d935c9b",
"quote_id":"270cf4a5-e99f-45a5-9dca-1bf75cd3ca64",
"product_id":"732e50b7-ed0e-424a-8631-51c5135d2b23",
"product":{
"id":"732e50b7-ed0e-424a-8631-51c5135d2b23",
"carrier_code":"dhl",
"code":"dhl_worldwide_express",
"name":"Worldwide Express",
"delay":"24",
"pick_up":true,
"drop_off":false,
"preset_delivery_location":false
},
"price":{
"formatted":"€293.68",
"currency":"EUR",
"amount":293.68,
"amount_in_cents":29368
},
"price_vat":{
"formatted":"€57.56",
"currency":"EUR",
"amount":57.56,
"amount_in_cents":5756
},
"total_price":{
"formatted":"€351.24",
"currency":"EUR",
"amount":351.24,
"amount_in_cents":35124
},
"collection_dates":[
{
"date":"2017-11-14",
"cutoff":"If you book before 1pm on Thursday, or book up to a week in advance"
},
{
"date":"2017-11-15",
"cutoff":"If you book before 1pm on Friday, or book up to a week in advance"
},
{
"date":"2017-11-18",
"cutoff":"If you book before 1pm on Monday, or book up to a week in advance"
}
]
},
{
"id":"33a60039-ea0c-4855-b9aa-616690288a4a",
"quote_id":"270cf4a5-e99f-45a5-9dca-1bf75cd3ca64",
"product_id":"46dc8970-c48a-4420-a85c-6dd31becba00",
"product":{
"id":"46dc8970-c48a-4420-a85c-6dd31becba00",
"carrier_code":"dpd",
"code":"dpd_air_express",
"name":"Air Express",
"delay":"72",
"pick_up":true,
"drop_off":false,
"preset_delivery_location":false
},
"price":{
"formatted":"€240.74",
"currency":"EUR",
"amount":240.74,
"amount_in_cents":24074
},
"price_vat":{
"formatted":"€47.19",
"currency":"EUR",
"amount":47.19,
"amount_in_cents":4719
},
"total_price":{
"formatted":"€287.93",
"currency":"EUR",
"amount":287.93,
"amount_in_cents":28793
},
"collection_dates":[
{
"date":"2017-11-14",
"cutoff":"If you book before 1pm on Thursday, or book up to a week in advance"
},
{
"date":"2017-11-15",
"cutoff":"If you book before 1pm on Friday, or book up to a week in advance"
},
{
"date":"2017-11-18",
"cutoff":"If you book before 1pm on Monday, or book up to a week in advance"
}
]
}
]
}
Une offre est proposée par un transporteur avec un prix et des conditions. Les offres sont vendues sous différents noms de produit MFB, qui disposent de logos spécifiques et différentes variantes (classique, économie, express, etc.).
Les offres retournées par le webservice ne peuvent pas être accédées séparément du devis ou de la commande à laquelle elles sont rattachées. Elles sont retournées sous forme de collection dans les devis ou comme objet unique dans les commandes.
Pour les offres avec collecte en point de dépot (par opposition à l'enlèvement à domicile), le Webservice MFB vous donne accès à une liste d'adresses disponibles pour l'offre en question.
Pour savoir si une offre est concernée ou non, testez l'attribut booléen 'drop_off' sur le produit associé à l'offre. S'il est à 'true', le dépôt peut se faire dans un dépôt.
Pour obtenir les points de dépôts les plus pertinent, vous devez passer une adresse complète dans la requête. Une liste de dépôts vous sera retournée, classée par pertinence (la plus pertinente en premier).
La requête retourne une collection de lieux. Chaque lieu comporte les attributs suivants :
Pour les offres avec livraison en point relais (par opposition à la livraison à domicile), le Webservice MFB vous donne accès à une liste d'adresses disponibles pour l'offre en question.
Pour savoir si une offre est concernée ou non, testez l'attribut booléen 'preset_delivery_location' sur le produit associé à l'offre. S'il est à 'true', la livraison se fera en point relais, sinon elle se fera à l'adresse du destinataire.
Pour obtenir les points relais les plus pertinent, vous devez passer une adresse complète dans la requête. Une liste de relais vous sera retournée, classée par pertinence (la plus pertinente en premier).
La requête retourne une collection de lieux. Chaque lieu comporte les attributs suivants :
La création d'une commande signifie que vous réservez un transport sur la base d'une offre et des attributs du devis. La création avec succès d'une commande constitue un lien contractuel ferme : vous serez facturé pour toutes les commandes créées avec succès, sur la base du coût final transmis par le transporteur après exécution de la prestation.
Les paramètres doivent être encapsulé dans un élément racine 'order'.
Notez que les données suivantes seront automatiquement récupérées depuis le devis et ne peuvent pas être modifiée au moment de la commande : codes postaux et pays de l'expéditeur et du destinataire, dimensions des colis. Si vous devez modifier ces informations, vous devrez passer par un nouveau devis et passer commande sur une offre équivalente du nouveau devis ; vous ouvez utiliser le code produit pour vous assurer dans ce cas que vous commandez bien un service identique.
curl https://test.myflyingbox.com/v2/orders -i -X POST -u {login}:{password} \
-H "Content-Type:application/json" \
-d '{
"order": {
"offer_id": "b26115b4-1852-4937-be54-a65c510744bb",
"shipper": {
"name": "Lce Test collection",
"company": "MY FLYING BOX SAS",
"street": "15 route de France",
"state": "Alpes-Maritimes",
"phone": "+33622123613",
"email": "test@test.com"
},
"recipient": {
"name": "Lce Test delivery",
"company": "MY FLYING BOX SAS",
"street": "15 route de France",
"state": "Alpes-Maritimes",
"phone": "+33622123613",
"email": "test@test.com"
},
"parcels": [
{
"value": "15",
"currency": "EUR",
"description": "Books",
"shipper_reference": "4684-0770",
"recipient_reference": "AB-3072"
}
]
}
}'
curl https://test.myflyingbox.com/v2/orders -i -X POST -u {login}:{password} \
-H "Content-Type:application/json" \
-d '{
"order": {
"declare_customs_electronically": true,
"offer_id": "625d4079-f0dd-470f-bc37-31582ad14fd8",
"shipper": {
"company": "test",
"name": "test",
"street": "test",
"phone": "0123456789",
"email": "email@test.com",
"eori_number": "FR35819137589",
"vat_number": "FR35819137589",
"collection_date": "2024-09-05"
},
"recipient": {
"name": "test",
"street": "test",
"state": "NY",
"phone": "0123456789",
"email": "email@test.com",
"ein": "EIN123456"
},
"parcels": [
{
"description": "test",
"country_of_origin": "FR",
"value": "150.0",
"currency": "EUR"
}
],
"customs_details": {
"invoice_number": "INV312312",
"reason_for_export": "commercial",
"ship_price": 49.78,
"ship_currency": "EUR"
},
"customs_items": [
{
"description": "description article",
"customs_code": "4201003000",
"quantity": 1,
"currency_code": "EUR",
"mass_unit": "kg",
"country_of_origin": "FR",
"unit_value": 150.0,
"unit_weight": 3.0,
"value_currency": "EUR"
}
]
}
}'
{
"uuid": "1471b700-1c14-4076-ade5-861798844129",
"shipper": {
"name": "Lce Test collection",
"company": "MY FLYING BOX SAS",
"street": ["15 route de France"],
"city": "Cagnes-sur-Mer",
"state": "Alpes-Maritimes",
"postal_code": "AB1 6CC",
"phone": "+33622123613",
"country": "UK"
},
"recipient": {
"name": "Lce Test delivery",
"is_a_company": "true",
"company": "MY FLYING BOX SAS",
"street": ["15 route de France"],
"city": "Cagnes-sur-Mer",
"state": "Alpes-Maritimes",
"postal_code": "06800",
"phone": "+33622123613",
"country": "FR"
},
"parcels": [
{
"weight": '3',
"length": '40',
"width": '30',
"height": '10',
"value": "15",
"currency": "EUR",
"description": "Books",
"shipper_reference": "4684-0770",
"recipient_reference": "AB-3072"
},
{
"weight": '1.75',
"length": '50',
"width": '10',
"height": '10',
"value": "15",
"currency": "EUR",
"description": "Books",
"shipper_reference": "4684-0773",
"recipient_reference": "AB-3073"
}
]
}
Après création de la commande, dans la plupart des cas, des étiquettes devront être imprimées par l'expéditeur et correctement apposées sur les colis.
Les étiquettes sont disponibles presque immédiatement après avoir passé commande, en envoyant une requête à l'URL spécifiée ci-desous. Les étiquettes sont retournées sous forme d'un unique fichier PDF. Lorsque la commande inclut plusieurs colis, ou si plusieurs étiquettes doivent être imprimées pour un même colis, tous les documents nécessaires sont inclut dans le PDF transmis.
Aucun paramètre n'est attendu pour cette requête. Seul l'UUID de la commande doit être passée dans l'URL.
Un fichier PDF brut est retourné dans la réponse à la requête si les étiquettes sont disponibles.
Si pour quelque raison que ce soit les étiquettes ne sont pas encore disponibles, vous recevrez un code d'erreur HTTP 404 avec un code d'erreur 'labels_not_ready'. Dans ce cas, prévoyez d'effectuer à nouveau la requête ultérieurement.
Après confirmation d'une commande, vous avez immédiatement accès aux informations de suivi de tous les colis concernés.
Aucun paramètre n'est attendu pour cette requête. Seul l'UUID de la commande doit être passée dans l'URL.
La réponse renvoie toutes les informations concernant les événements de suivi pour chaque colis, ordonnés de la même manière que lors de la demande de devis initiale.
Notez que les informations de suivi varient d'un transporteur à l'autre. Nous faisons suivre ces informations de manière homogène à travers cette API, avec un maximum de flexibilité : beaucoup d'attributs sont optionels et lorsque nous recevons des informations non standard nous essayons néanmoins de les faire suivre. Assurez-vous d'implémenter cette fonctionnalité avec le même niveau de flexibilité, pour ne pas générer de blocage.
Le niveau racine (noeud 'data') contient un tableau d'informations de suivi pour chaque colis. Les attributs ci-dessous correspondent à une entrée de ce tableau. Vous trouverez dans la colonne de droite un exemple de réponse complète.
curl https://test.myflyingbox.com/v2/orders/eb27ff8e-b353-4a3f-8e7e-69576e64ee1a/tracking \
-i -u {identifiant}:{mot_de_passe}
{
"status":"success",
"self":"https://test.myflyingbox.com/v2/orders/eb27ff8e-b353-4a3f-8e7e-69576e64ee1a/tracking.json",
"data":[
{
"parcel_index":0,
"events":[
{
"code":"shipment_created",
"happened_at":"2013-12-10T11:26:23+01:00",
"label":{
"fr":"Expédition créée",
"en":"Shipment created"
}
},
{
"code":"picked_up",
"happened_at":"2013-12-11T11:24:00+01:00",
"label":{
"fr":"Paquet enlevé",
"en":"Package picked up"
},
"location":{
"city":"NICE CEDEX 3",
"postal_code":"06284",
"country":"FR"
}
},
{
"code":"in_transit",
"happened_at":"2013-12-12T03:43:00+01:00",
"label":{
"fr":"En transit",
"en":"In transit"
},
"location":{
"city":"ROISSY CHARLES DE GAULLE CEDEX",
"postal_code":"95702",
"country":"FR"
}
},
{
"code":"arrived_at_facility",
"happened_at":"2013-12-12T05:11:00+01:00",
"label":{
"fr":"Arrivé à la plateforme",
"en":"Arrived at hub"
},
"location":{
"city":"STANSTED",
"state":"ES",
"postal_code":"CM24",
"country":"GB"
}
},
{
"code":"delivery_in_progress",
"happened_at":"2013-12-12T10:39:00+01:00",
"label":{
"fr":"Livraison en cours",
"en":"Delivery in progress"
},
"location":{
"city":"ENFIELD",
"state":"MI",
"postal_code":"EN3",
"country":"GB"
}
},
{
"code":"delivery_exception",
"happened_at":"2013-12-12T11:48:00+01:00",
"label":{
"fr":"Problème de livraison",
"en":"Delivery exception"
},
"location":{
"city":"ENFIELD",
"state":"MI",
"postal_code":"EN3",
"country":"GB"
},
"details":{
"code":"not_available_or_closed",
"label":{
"fr":"Client non disponible ou entreprise fermée",
"en":"Customer not available or business closed"
}
}
}
]
}
]
}
Si nécessaire, après avoir placé une commande, vous pouvez l'annuler. La commande doit toujours être dans l'état "created".
Aucun paramètre n'est nécessaire pour cette requête. Seul l'UUID de la commande doit être passé dans l'URL de la requête.
La réponse contient la commande.
curl -X PUT https://test.myflyingbox.com/v2/orders/eb27ff8e-b353-4a3f-8e7e-69576e64ee1a/cancel \
-i -u {login}:{password}
Programmer un enlèvement veut dire que vous demander au transporteur d'envoyer un camion pour récupérer vos paquets. Cette fonctionnalité est uniquement disponilbe pour les commandes créées avec enlèvement différé (delayed pickup).
Les paramètres doivent être encapsulé dans un élément racine 'pickup'.
Cette action combine et remplace la création de devis et la création de commande présentées ci-dessus. Pour cette requête, vous devez fournir les données et les informations pour trier et filtrer les offres en une unique requête. Le premier service correspondant aux attributs fournis sera sélectionné et commandé.
Les paramètres doivent être encapsulé dans un élément racine 'order'.
curl https://test.myflyingbox.com/v2/orders/automatic -i -X POST -u {login}:{password} \
-H "Content-Type:application/json" \
-d '{
"order": {
"shipper": {
"company": "test",
"name": "test",
"street" :"test",
"phone": "+33600000000",
"email": "support@myflyingbox.com",
"collection_date": "2022-10-20",
"country": "FR",
"postal_code": "31300",
"city": "Toulouse"
},
"recipient": {
"company": "test",
"name": "test",
"street": "test",
"phone": "+33600000000",
"email": "support@myflyingbox.com",
"country": "FR",
"postal_code": "06000",
"city": "Nice",
"is_a_company": "false"
},
"parcels": [
{
"description": "description",
"length": "15",
"height": "15",
"width": "15",
"weight": "1"
}
],
"offers_sort_attributes": {
"total_price": "asc"
},
"offers_filters": {
"with_preset_delivery_location": false,
"with_pick_up": true,
"with_drop_off": false,
"with_carrier_codes": ["dhl", "ups", "fedex"]
}
}
}'
Ci-dessous sont listés les derniers changement effectués sur la documentation, par ordre chronologique inversé (plus récent en premier).