Uber direct API
1️⃣ Principe : Uber Direct pour vos petits colis
Uber Direct permet à votre appli / site d’appeler directement le réseau de coursiers Uber pour :
- Enlever un colis à une adresse A (magasin, entrepôt, cabinet, etc.)
- Le livrer à une adresse B (client final, autre site…)
- Avec livraison le jour même, express en ≤ 2 h, ou planifiée sur Paris et l’Île-de-France. Uber+1
C’est exactement le cas d’usage que vous mentionnez : petits colis à livrer d’un point à un autre dans Paris.
2️⃣ API Uber Direct – ce que vous pouvez faire
La partie développeur est sur Uber Developer – Deliveries / Uber Direct : developer.uber.com+1
Les grandes briques :
- Authentification OAuth2 (grant client_credentials) pour récupérer un token d’accès. developer.uber.com
- Create Quote : demander un devis de livraison entre A et B (prix + ETA). developer.uber.com+1
- Create Delivery : créer réellement la livraison à partir du devis (un coursier est alors dispatché). developer.uber.com+1
- Webhooks / statuts : suivre l’évolution (en cours, livré, annulé…) selon la config de votre compte. developer.uber.com+1
La FAQ Uber Direct confirme que l’API permet de livrer “la plupart des articles qu’une personne moyenne peut transporter” – donc typiquement des petits colis, documents, boîtes, petits équipements, etc. Uber
3️⃣ Activation en France / Paris
Pour l’utiliser à Paris :
- Créer un compte Uber Direct (via Uber for Business / Uber Direct “get started”). Uber+1
- Obtenir vos identifiants client (client_id, client_secret) depuis le dashboard Uber Direct. developer.uber.com
- Activer les livraisons pour vos adresses d’origine (magasins, entrepôts, cabinets, etc.). Uber+1
- Configurer l’usage de l’API dans votre backend (Node/Nest, Python, Odoo, etc.).
Uber communique explicitement sur la disponibilité d’Uber Direct en France / Paris Île-de-France, pour la livraison “dernier kilomètre” depuis vos propres canaux (site, app, téléphone). Uber+1
4️⃣ Flow typique côté votre web-app
Sans rentrer dans le code ici, le scénario standard serait :
- Votre client passe commande sur votre site (adresse, créneau, contenu du colis).
-
Votre backend :
- appelle Uber Direct – Create Quote pour A→B,
- affiche le prix / ETA dans votre interface.
-
Si le client valide :
- votre backend appelle Create Delivery,
- vous stockez l’ID de livraison Uber.
- Vous suivez le statut via API / webhooks et le reflétez dans votre interface (statut, tracking, preuve de livraison).
le pseudo-JSON de la requête typique (quote + create_delivery) et une mini-architecture ciblée Odoo Online + NestJS adaptée à
Parfait, on y va directement 👇
1️⃣ Pseudo-JSON typique – Uber Direct
⚠️ C’est du pseudo-JSON très proche de la réalité, mais à adapter à la doc officielle Uber Direct (noms de champs / endpoints peuvent légèrement varier selon la version).
a) Récupérer un token OAuth2
POST https://login.uber.com/oauth/v2/token Content-Type: application/x-www-form-urlencoded grant_type=client_credentials &client_id=VOTRE_CLIENT_ID &client_secret=VOTRE_CLIENT_SECRET &scope=delivery
Réponse (simplifiée) :
{ "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "token_type": "Bearer", "expires_in": 3600 }
b) Quote (demander un devis de livraison)
POST https://api.uber.com/v1/deliveries/quotes Authorization: Bearer ACCESS_TOKEN Content-Type: application/json
{ "pickup": { "address": { "street": "10 Rue de Rivoli", "city": "Paris", "postal_code": "75004", "country": "FR" }, "contact": { "first_name": "Jean", "last_name": "Dupont", "phone": "+33600000000", "email": "jean.dupont@example.com" }, "notes": "Sonner à l'interphone, 3e étage." }, "dropoff": { "address": { "street": "25 Avenue des Champs-Élysées", "city": "Paris", "postal_code": "75008", "country": "FR" }, "contact": { "first_name": "Marie", "last_name": "Martin", "phone": "+33611111111", "email": "marie.martin@example.com" }, "notes": "Laisser au gardien si absente." }, "manifest": { "items": [ { "name": "Petit colis médical", "quantity": 1, "weight_kg": 1.2, "value_eur": 45.0 } ], "reference": "CMD-2025-000123" }, "delivery_options": { "service_level": "same_day", // "express" | "same_day" | "scheduled" "pickup_time": "2025-11-26T18:30:00+01:00" } }
Réponse typique :
{ "quote_id": "qte_1234567890", "currency": "EUR", "price_estimate": 9.50, "eta_pickup_minutes": 15, "eta_dropoff_minutes": 40, "expires_at": "2025-11-26T18:10:00+01:00" }
c) Create Delivery (confirmer la livraison)
POST https://api.uber.com/v1/deliveries Authorization: Bearer ACCESS_TOKEN Content-Type: application/json
{ "quote_id": "qte_1234567890", "external_reference": "ODDO-SO/2025/00045", // N° de commande Odoo "pickup": { "address": { "street": "10 Rue de Rivoli", "city": "Paris", "postal_code": "75004", "country": "FR" }, "contact": { "first_name": "Jean", "last_name": "Dupont", "phone": "+33600000000", "email": "jean.dupont@example.com" } }, "dropoff": { "address": { "street": "25 Avenue des Champs-Élysées", "city": "Paris", "postal_code": "75008", "country": "FR" }, "contact": { "first_name": "Marie", "last_name": "Martin", "phone": "+33611111111", "email": "marie.martin@example.com" } }, "manifest": { "items": [ { "name": "Petit colis médical", "quantity": 1, "weight_kg": 1.2, "value_eur": 45.0 } ], "reference": "CMD-2025-000123" }, "webhook_callback_url": "https://api.votre-domaine.com/uber/webhook" }
Réponse typique :
{ "delivery_id": "del_987654321", "status": "pending", // "pending" | "pickup_in_progress" | "picked_up" | "delivered" | "failed"... "tracking_url": "https://track.uber.com/del_987654321", "price_final": 9.50, "currency": "EUR" }
Ensuite Uber appelle votre webhook_callback_url à chaque changement de statut :
{ "event": "delivery.status_changed", "delivery_id": "del_987654321", "status": "delivered", "occurred_at": "2025-11-26T19:10:00+01:00" }
2️⃣ Mini-architecture ciblée – Odoo Online + NestJS + Uber Direct
Je te fais une version simple mais robuste, que tu peux faire évoluer (et plugger plus tard sur Cocolis, Central-Courses, etc.).
A. Rôles des briques
-
Odoo Online
- Gestion des commandes (sale.order)
- Gestion des clients / adresses (res.partner)
- Stock, facturation, etc.
- Module custom “Synergia Delivery” via Odoo Studio (quelques champs en plus)
-
NestJS “Logistics Orchestrator” (hébergé chez toi)
- Expose une API interne pour Odoo (/api/logistics/create_delivery)
- Gère l’auth Uber OAuth2 (token caching)
- Appelle Uber Direct (quote + create_delivery)
- Reçoit les webhooks Uber et les renvoie à Odoo (update du statut)
-
Uber Direct
- Réseau de livreurs
- Pricing, dispatch, tracking
- Appels de webhooks vers NestJS
B. Modèle de données côté Odoo (via Studio)
Sur sale.order (ou un modèle dédié x_delivery_order si tu veux isoler) :
Champs supplémentaires à créer :
-
x_delivery_provider (Selection)
- "none", "uber_direct", "central_courses", "cocolis", etc.
- x_delivery_quote_id (Char)
- x_delivery_price_estimate (Monetary)
- x_delivery_id (Char) – ID Uber
-
x_delivery_status (Selection)
- "draft", "quoted", "requested", "in_progress", "delivered", "failed"
- x_delivery_tracking_url (Char)
- x_pickup_address_id (Many2one -> res.partner)
- x_dropoff_address_id (Many2one -> res.partner)
Option : créer un modèle x_synergia_delivery lié à sale.order si tu veux une table logique de livraisons multi-fournisseurs.
C. Flow fonctionnel
-
Dans Odoo
- L’utilisateur confirme la commande (sale.order → sale).
- Il choisit un mode de livraison : “Coursier Uber Direct”.
- Bouton custom “Obtenir un devis livraison” (action_get_delivery_quote) → Odoo appelle ton backend NestJS.
-
Odoo → NestJS
- Odoo effectue un POST :
POST https://logistics.votre-domaine.com/api/logistics/quote Content-Type: application/json
{ "order_id": 123, "provider": "uber_direct", "pickup": { "name": "Cabinet Infirmier Paris 4", "street": "10 Rue de Rivoli", "city": "Paris", "postal_code": "75004", "country": "FR", "phone": "+33123456789" }, "dropoff": { "name": "Mme Martin", "street": "25 Avenue des Champs-Élysées", "city": "Paris", "postal_code": "75008", "country": "FR", "phone": "+33611111111" }, "items": [ { "name": "Kit pansements + consommables", "quantity": 1, "weight_kg": 1.2, "value_eur": 45.0 } ] }
-
NestJS
- Vérifie provider === "uber_direct".
- Récupère / rafraîchit le token OAuth Uber.
- Appelle l’API Quote d’Uber.
- Retourne la réponse à Odoo :
{ "provider": "uber_direct", "quote_id": "qte_1234567890", "price_estimate": 9.50, "currency": "EUR", "eta_pickup_minutes": 15, "eta_dropoff_minutes": 40 }
-
Odoo
- Remplit x_delivery_quote_id, x_delivery_price_estimate.
- Affiche le prix estimé dans la vue de la commande.
- Bouton “Valider la livraison Uber”.
- Odoo → NestJS (create_delivery)
POST https://logistics.votre-domaine.com/api/logistics/create_delivery Content-Type: application/json
{ "order_id": 123, "provider": "uber_direct", "quote_id": "qte_1234567890" }
-
NestJS
- Appelle Uber Create Delivery avec le quote_id.
- Reçoit delivery_id, tracking_url, status.
- Renvoie à Odoo :
{ "provider": "uber_direct", "delivery_id": "del_987654321", "tracking_url": "https://track.uber.com/del_987654321", "status": "pending" }
-
Odoo
- Sauvegarde x_delivery_id, x_delivery_tracking_url, x_delivery_status = "requested".
-
Uber → NestJS (webhook)
- À chaque changement de statut, Uber appelle ton endpoint :
POST https://logistics.votre-domaine.com/api/logistics/webhook/uber
{ "event": "delivery.status_changed", "delivery_id": "del_987654321", "status": "delivered" }
-
NestJS → Odoo
- NestJS appelle l’API Odoo /jsonrpc pour mettre à jour x_delivery_status :
{ "jsonrpc": "2.0", "method": "call", "params": { "service": "object", "method": "execute_kw", "args": [ "VOTRE_DB", 1, "VOTRE_API_KEY", "sale.order", "write", [[123], {"x_delivery_status": "delivered"}] ] } }
3️⃣ Ce que tu peux faire tout de suite
-
Dans Odoo Online / Studio
- Créer les champs x_delivery_* sur sale.order.
-
Ajouter 2 boutons :
- “Obtenir un devis livraison”
- “Valider la livraison Uber”
-
Dans NestJS
-
Créer un module UberDirectModule avec service :
- getQuote(payload)
- createDelivery(quoteId)
- handleWebhook(event)
-
Créer un OdooService pour :
- Mise à jour des champs x_delivery_*.
-
Créer un module UberDirectModule avec service :
-
Roadmap
- Étape 1 : Uber Direct Paris uniquement.
- Étape 2 : ajout d’un second provider (ex. Central-Courses).
- Étape 3 : moteur de règles “choisir le bon provider” (prix, poids, distance, urgence).
Si tu veux, au prochain tour je peux te donner :
- le schéma JSON unifié pour tous les providers (Uber, Central, Cocolis)
- et/ou un exemple concret de DTO + controller NestJS pour /api/logistics/quote et /api/logistics/create_delivery.