API Partenaires Transporteurs v1

Recevez, livrez, mettez à jour.

Cette API est destinée aux sociétés de livraison partenaires de Havana Express. Elle vous permet de récupérer les colis que nous vous confions, mettre à jour leur statut et remonter les preuves de livraison.

1. Clé API

Havana Express vous remet une clé privée sk_partner_….

2. Récupérer les colis

Interrogez régulièrement GET /orders.

3. Mettre à jour

Postez le statut + preuve à chaque étape clé.

Nouveau

API v1 — Authentification par token

Version recommandée : un seul compte (email + mot de passe) donne un token Bearer valable 12 h, utilisable sur tous les endpoints. Aucun besoin de gérer des clés statiques.

https://www.havanaexpress.ma/api/public/v1

JSON UTF-8. Codes : 200 succès · 207 aucun colis mis à jour · 400 validation · 401 token invalide/expiré · 403 compte désactivé · 404 colis introuvable · 429 quota dépassé (240 req/min) · 500 erreur serveur.

POST/api/public/v1/login_check
Obtenir un token

Échange email + mot de passe contre un token Bearer valable 12 heures.

Requête
curl -X POST https://www.havanaexpress.ma/api/public/v1/login_check \
  -H "Content-Type: application/json" \
  -d '{"email":"api@partenaire.ma","password":"••••••••"}'
Réponse
{
  "status": "success",
  "token": "msl_9f3c…",
  "token_type": "Bearer",
  "expires_in": 43200,
  "expires_at": "2026-08-29T02:20:11.000Z",
  "partner": { "id": "…", "name": "Partenaire SARL" },
  "user": { "id": "…", "email": "api@partenaire.ma", "name": "Intégration" }
}
GET/api/public/v1/status
Liste officielle des statuts

Codes acceptés par changeParcelStatus, avec les champs obligatoires par statut.

Requête
curl https://www.havanaexpress.ma/api/public/v1/status -H "Authorization: Bearer msl_9f3c…"
Réponse
{
  "status": "success",
  "count": 15,
  "statuses": [
    { "code": "DELIVERED", "label_fr": "Livré", "category": "final", "required_fields": ["received_by"] }
  ]
}
POST/api/public/v1/changeParcelStatus
Changer le statut d'un ou plusieurs colis

Jusqu'à 50 colis par requête. Chaque ligne est traitée indépendamment : le résultat détaille les succès et les erreurs.

Requête
curl -X POST https://www.havanaexpress.ma/api/public/v1/changeParcelStatus \
  -H "Authorization: Bearer msl_9f3c…" \
  -H "Content-Type: application/json" \
  -d '{
    "parcels": [
      { "code": "AGA-2026-00012", "status": "DELIVERED",
        "received_by": "Youssef B.", "cod_amount": 250,
        "lat": 30.4278, "lng": -9.5981, "date": "2026-08-28 14:20:00" },
      { "code": "AGA-2026-00013", "status": "NO_ANSWER",
        "status_comment": "Client injoignable 3 tentatives" }
    ]
  }'
Réponse
{
  "status": "success",
  "updated": 2,
  "failed": 0,
  "results": [
    { "code": "AGA-2026-00012", "ok": true, "status": "DELIVERED", "label": "Livré" },
    { "code": "AGA-2026-00013", "ok": true, "status": "NO_ANSWER", "label": "Pas de réponse" }
  ]
}
POST/api/public/v1/scan
Scan en masse

Applique le même statut à jusqu'à 200 codes (réception hub, départ en transit…).

Requête
curl -X POST https://www.havanaexpress.ma/api/public/v1/scan \
  -H "Authorization: Bearer msl_9f3c…" \
  -H "Content-Type: application/json" \
  -d '{"codes":["AGA-2026-00012","AGA-2026-00013"],"status":"AT_ORIGIN_HUB"}'
Réponse
{
  "status": "success",
  "applied_status": "AT_ORIGIN_HUB",
  "updated": 2,
  "failed": 0,
  "accepted": ["AGA-2026-00012", "AGA-2026-00013"],
  "rejected": []
}
GET/api/public/v1/parcels
Liste des colis confiés

Pagination + filtres status, from, to, search (numéro ou téléphone).

Requête
curl "https://www.havanaexpress.ma/api/public/v1/parcels?status=IN_TRANSIT&page=1&per_page=50" \
  -H "Authorization: Bearer msl_9f3c…"
Réponse
{
  "status": "success",
  "page": 1, "per_page": 50, "total": 128, "total_pages": 3,
  "parcels": [
    { "code": "AGA-2026-00012", "status": "IN_TRANSIT", "recipient_name": "Salma A.",
      "recipient_phone": "06…", "city": "Agadir", "cod_amount": 250 }
  ]
}
GET/api/public/v1/parcels/{code}
Détail + historique d'un colis

Toutes les informations du colis et la chronologie complète de ses statuts.

Requête
curl https://www.havanaexpress.ma/api/public/v1/parcels/AGA-2026-00012 -H "Authorization: Bearer msl_9f3c…"
Réponse
{
  "status": "success",
  "parcel": { "code": "AGA-2026-00012", "status": "DELIVERED", "received_by": "Youssef B." },
  "history": [
    { "status": "PICKED_UP", "at": "2026-08-26T09:12:00Z" },
    { "status": "DELIVERED", "at": "2026-08-28T14:20:00Z" }
  ]
}
POST/api/public/v1/logout
Révoquer le token

Invalide immédiatement le token courant.

Requête
curl -X POST https://www.havanaexpress.ma/api/public/v1/logout -H "Authorization: Bearer msl_9f3c…"
Réponse
{ "status": "success", "message": "Token revoked" }

Codes de statut

CodeLibelléChamps requisDescription
PICKED_UPRamassé · تم الاستلامLe colis a été récupéré chez le marchand par le partenaire.
AT_ORIGIN_HUBReçu au Hub · وصل لمركز الانطلاقColis réceptionné et scanné dans l'entrepôt de départ.
IN_TRANSITExpédié · تم الإرسالColis expédié et en cours d'acheminement entre deux villes.
AT_DESTINATION_HUBReçu au hub de destination · وصل لمركز الوصولColis arrivé dans la ville de livraison.
ASSIGNED_DRIVEREn livraison · تم إسناده للموزعUn livreur a été affecté au colis.
OUT_FOR_DELIVERYEn livraison · خارج للتوصيلLe colis est sorti en distribution.
DELIVEREDLivré · تم التوصيلreceived_byColis remis au destinataire. Le nom du réceptionnaire est obligatoire.
POSTPONEDReporté · مؤجلstatus_commentLivraison reportée à la demande du destinataire. Motif obligatoire.
NO_ANSWERPas de réponse · لا يجيبstatus_commentLe destinataire ne répond pas. Motif obligatoire.
VOICEMAILBoîte vocale · المجيب الآليstatus_commentAppel tombé sur la boîte vocale. Motif obligatoire.
OUT_OF_ZONEHors zone · خارج النطاقstatus_commentAdresse en dehors de la zone couverte. Motif obligatoire.
FAILEDÉchec de livraison · فشل التوصيلstatus_commentTentative de livraison échouée. Motif obligatoire.
RETURNEDRetourné · مرجعstatus_commentColis renvoyé vers le marchand. Motif obligatoire.
REFUSEDRefusé · مرفوضstatus_commentColis refusé par le destinataire. Motif obligatoire.
CANCELLEDAnnulé · ملغىstatus_commentCommande annulée. Motif obligatoire.

Les colis en statut DELIVERED ou CANCELLED sont définitifs et ne peuvent plus être modifiés via l'API.

Webhooks

Sur demande, Havana Express appelle votre URL à chaque changement de statut. Vérifiez la signature avant de traiter le payload.

POST https://votre-domaine.ma/webhooks/havana-express
X-Havana Express-Event: parcel.status_changed
X-Havana Express-Signature: sha256=<hmac_sha256(secret, corps_brut)>

{
  "event": "parcel.status_changed",
  "sent_at": "2026-08-28T14:20:11.000Z",
  "data": { "code": "AGA-2026-00012", "status": "DELIVERED", "received_by": "Youssef B." }
}
Legacy

URL de base (clé statique)

https://www.havanaexpress.ma/api/public/partners

JSON UTF-8. Codes : 200/201 succès, 400 validation, 401 clé invalide, 403 compte désactivé, 404 colis non assigné, 500 erreur serveur.

Authentification

Ajoutez votre clé partenaire à chaque requête :

x-api-key: sk_partner_xxxxxxxxxxxxxxxxxxxxxxxxxxxx

Endpoints

Lister les colis assignés

Renvoie uniquement les colis que Havana Express vous a confiés. Filtres : status, limit (1-200), offset.

GET/api/public/partners/orders?status=picked_up&limit=50
Réponse
{
  "ok": true,
  "count": 12,
  "limit": 50,
  "offset": 0,
  "orders": [
    {
      "tracking_number": "FX-2026-00123",
      "status": "in_transit",
      "recipient_name": "Ali Bennani",
      "recipient_phone": "0612345678",
      "delivery_city": "Casablanca",
      "delivery_address": "Rue Mohammed V, 12",
      "cod_amount": 250,
      "weight_kg": 1.2
    }
  ]
}

Détails d'un colis

Informations complètes + historique (events).

GET/api/public/partners/orders/{tracking_number}
Réponse
{
  "ok": true,
  "order": {
    "tracking_number": "FX-2026-00123",
    "status": "in_transit",
    "sender_name": "Boutique Atlas",
    "recipient_name": "Ali Bennani",
    "recipient_phone": "0612345678",
    "delivery_city": "Casablanca",
    "delivery_address": "Rue Mohammed V, 12",
    "cod_amount": 250
  },
  "events": [ { "status": "in_transit", "message": "...", "created_at": "..." } ]
}

Mettre à jour le statut

Statuts autorisés : pending, picked_up, received_origin_hub, in_transit, received_destination_hub, assigned_driver, out_for_delivery, delivered, postponed, failed, returned, cancelled.

POST/api/public/partners/orders/{tracking_number}/status
Requête
curl -X POST https://www.havanaexpress.ma/api/public/partners/orders/FX-2026-00123/status \
  -H "x-api-key: sk_partner_..." \
  -H "Content-Type: application/json" \
  -d '{
    "status": "delivered",
    "received_by": "Ali Bennani",
    "signature_url": "https://cdn.example.com/sign/abc.png",
    "pod_photo_url": "https://cdn.example.com/pod/abc.jpg",
    "delivery_lat": 33.5731,
    "delivery_lng": -7.5898
  }'
Réponse
{ "ok": true, "tracking_number": "FX-2026-00123", "status": "delivered" }

Signaler un échec / report

Indiquez la raison dans le champ reason. Le client en sera notifié automatiquement.

POST/api/public/partners/orders/{tracking_number}/status
Requête
{
  "status": "failed",
  "reason": "Destinataire injoignable, 3 tentatives"
}
Réponse
{ "ok": true, "tracking_number": "FX-2026-00123", "status": "failed" }

Cycle de vie d'un colis

pendingCréé, en attente de ramassage
picked_upRamassé chez l'expéditeur
received_origin_hubReçu au Hub
in_transitExpédié
received_destination_hubArrivé au Hub de destination
assigned_driverAffecté à un livreur
out_for_deliveryEn cours de livraison
deliveredLivré ✅ (joindre POD)
postponedReporté
failedÉchec (joindre raison)
returnedRetourné expéditeur
cancelledAnnulé

Sécurité & bonnes pratiques

  • Ne partagez jamais votre clé sk_partner_…. Conservez-la côté serveur uniquement.
  • En cas de fuite, contactez Havana Express immédiatement — nous révoquons la clé et en émettons une nouvelle.
  • Polling recommandé : 1 requête / minute maximum sur GET /orders.
  • Pour la livraison, joignez systématiquement signature_url ou pod_photo_url.
  • Les coordonnées GPS (delivery_lat, delivery_lng) renforcent la preuve de livraison.

Support intégration

Notre équipe technique vous accompagne pour brancher votre TMS ou app mobile.

Contacter l'équipe