BOOKING API v1.0

4U Booking API

Documentation complète de l'API de gestion des réservations. Créer, modifier, consulter, check-in et gérer les paiements des bookings.

Base: /bookings
Payments: /booking-payments
Auth: x-api-key
Format: JSON
← Retour à la doc principale

Sommaire

🔐 Authentification

Clé API requise

Toutes les requêtes aux endpoints /bookings et /booking-payments nécessitent une clé API valide.

curl -H "x-api-key: YOUR_API_KEY" https://listings.4u-realestate.org/bookings

🔄 Cycle de vie d'un booking

Booked → Check-in → Checked → Validation →

À tout moment :
Cancelled Declined | No-show | Soft delete
Booked
Réservation confirmée
Checked
Check-in effectué
Paid
Paiements validés
Cancelled
Annulée
Declined
Refusée
Stand by
En attente
Open
Lodgify Open
Tentative
Lodgify Tentative

💰 Calcul financier

Les calculs utilisent la configuration de la collection BookingSource pour chaque plateforme.

1. taxRate = BookingSource.tax / 100
2. taxes = totalAmount × taxRate / (1 + taxRate) ← tax-included
3. subtotal = totalAmount - taxes - cleaningFees
4. platformFees = (subtotal + cleaningFees) × platformFees% / 100
Manual/OH : totalAmount × platformFees% (défaut 5%)
5. bankFees = totalAmount × bankFees% / 100 (Manual/OH: défaut 4%)
6. rentalIncome = totalAmount - cleaningFees - guestInsurance - taxes - platformFees - bankFees
7. managementFees = max(rentalIncome, 0) × 25%
8. netIncome = max(rentalIncome, 0) - managementFees
Note : Si totalAmount = 0 (owner booking), guestInsurance = 0. Le guestInsurance par défaut est 28.99 USD.

📡 Endpoints Bookings

GET /bookings Lister les bookings avec filtres

Liste paginée des bookings avec filtres, tri et résumé des paiements.

QUERY PARAMETERS

ParamTypeDescription
pagenumberPage (défaut: 1)
limitnumberRésultats/page (défaut: 20, max: 100)
lotIdObjectIdFiltrer par lot
lotIdsstringIDs séparés par virgules
statusstringEx: "Booked,Checked" (séparés par virgules)
bookingSourcestringEx: "AirbnbIntegration"
bookingNonumberRecherche exacte
tenantNamestringRecherche regex insensible casse
startDateISO datearrival ≥ startDate
endDateISO datearrival ≤ endDate
sortstringarrival_asc, arrival_desc, newest, oldest

Réponse

{
  "success": true,
  "bookings": [{
    "_id": "...", "bookingNo": 1234567,
    "lotId": { "_id": "...", "name": "Villa Ocean", "lotNo": "A-101" },
    "status": "Booked", "arrival": "2025-06-01", "departure": "2025-06-07",
    "totalAmount": 1500, "cleaningFees": 100, "taxes": 71.43,
    "tenantInformations": { "name": "John Doe", "email": "john@example.com" },
    "paymentsSummary": { "totalPaid": 750, "count": 1, "remaining": 750, "isFullyPaid": false }
  }],
  "total": 42, "page": 1, "limit": 20, "totalPages": 3
}
GET /bookings/upcoming Bookings à venir

Bookings dont le départ est ≥ maintenant. Exclut Cancelled, Declined, Open, Tentative.

ParamTypeDescription
lotIdsstringIDs séparés par virgules
pagenumberDéfaut: 1
limitnumberDéfaut: 20
sortBystringChamp de tri (défaut: arrival)
sortOrderstringasc ou desc
GET /bookings/accounting Vue comptable avec totaux

Vue comptable avec agrégation des totaux financiers et liste des sources.

ParamTypeDescription
lotIdsstringIDs séparés par virgules
statusstringFiltrer par statut(s)
bookingSourcestringRegex insensible casse
bookingNonumberNuméro exact
startDateISO datearrival ≥
endDateISO datearrival ≤
page, limitnumberPagination (limit défaut: 50)
sortBy, sortOrderstringTri (défaut: arrival desc)

Réponse

{
  "success": true,
  "bookings": [...],
  "totalCount": 150, "totalPages": 3, "currentPage": 1,
  "totals": {
    "totalAmount": 125000, "totalSubtotal": 110000,
    "totalPrepaidAmount": 100000, "totalCleaningFees": 8000,
    "totalTaxes": 5952, "totalPlatformFees": 3750,
    "totalBankFees": 5000, "totalRentalIncome": 95000,
    "bookingCount": 150
  },
  "bookingSources": ["AirbnbIntegration", "BookingCom", "Manual"]
}
GET /bookings/services Services add-on disponibles

Liste des services add-on actifs proposés au check-in.

Réponse

{
  "success": true, "total": 5,
  "services": [{
    "_id": "...", "title": "Early Check-in",
    "description": "Check-in before 3 PM",
    "price": 50, "originalPrice": 75,
    "image": "...", "displayOrder": 1
  }]
}
GET /bookings/sources Sources & configuration fees

Liste des sources de booking avec leurs pourcentages de frais.

Réponse

{
  "success": true, "total": 6,
  "sources": [{
    "source": "AirbnbIntegration",
    "platformFees": 3, "bankFees": 0,
    "tax": 5, "guestInsurance": 28.99
  }]
}
GET /bookings/by-number/:bookingNo Trouver par numéro
ParamTypeDescription
bookingNonumberREQUISNuméro de réservation

Retourne le booking avec les financials calculés.

GET /bookings/:id/financials Recalculer les financials

Recalcule les données financières à partir de la source du booking.

Réponse

{
  "success": true,
  "financials": {
    "totalAmount": 1500, "cleaningFees": 100,
    "guestInsurance": 28.99, "taxes": 71.43,
    "platformFees": 45, "subtotal": 1328.57,
    "rentalIncome": 1194.58, "bankFees": 60,
    "managementFees": 298.65, "netIncome": 895.94
  }
}
GET /bookings/:id Détail complet

Détail complet d'un booking avec financials calculés et résumé des paiements (confirmedPaid, pendingPaid).

ParamTypeDescription
idObjectIdREQUISID MongoDB du booking
Sécurité : Les champs passport, signature et authId ne sont jamais retournés.
POST /bookings Créer un booking

BODY (JSON)

ChampTypeDescription
booking.bookingNonumberREQUISNuméro unique (par lot)
booking.lotIdObjectIdREQUISID du lot
booking.arrivalISO dateREQUISDate d'arrivée
booking.departureISO dateREQUISDate de départ
booking.totalAmountnumberREQUISMontant total TTC
booking.prepaidAmountnumberREQUISMontant pré-payé
booking.bedroomsnumberREQUISNombre de chambres
booking.tenantInformations.namestringREQUISNom du locataire
booking.tenantInformations.emailstringREQUISEmail du locataire
booking.statusstringDéfaut: "Booked"
booking.bookingSourcestringSource de la réservation
booking.cleaningFeesnumberFrais de ménage
booking.paymentMethodstringMéthode de paiement

Exemple

{
  "booking": {
    "bookingNo": 9999999,
    "lotId": "664f1a2b3c4d5e6f7a8b9c0d",
    "arrival": "2025-06-01",
    "departure": "2025-06-07",
    "totalAmount": 1500,
    "prepaidAmount": 1500,
    "bedrooms": 2,
    "bookingSource": "Manual",
    "tenantInformations": {
      "name": "John Doe",
      "email": "john@example.com"
    }
  }
}
409 Conflict : Si un booking avec ce numéro existe déjà pour ce lot.
PATCH /bookings/:id Modifier un booking

BODY (JSON)

ChampTypeDescription
bookingData.statusstringNouveau statut
bookingData.arrivalISO dateNouvelle date d'arrivée
bookingData.departureISO dateNouvelle date de départ
bookingData.totalAmountnumberNouveau montant
bookingData.lotIdObjectId ou {_id}Nouveau lot
bookingData.tenantInformationsobjectname, email, phone, address...
bookingData.*anycleaningFees, guestInsurance, services, noShow fields...
Sécurité : Les champs passport, signature, authId dans tenantInformations sont ignorés.
PATCH /bookings/:id/check-in Effectuer le check-in

Passe le booking en status "Checked", calcule les financials et met à jour les infos tenant.

Pré-requis : Le booking doit être en status "Booked".

BODY (JSON)

ChampTypeDescription
tenantInformationsobject{ name, email, phone, address, companyName }
bookingSourcestringSource pour le calcul financier
cleaningFeesnumberFrais de ménage
totalAmountnumberMontant total
paymentMethodstringMéthode de paiement
guestInsurancenumberOptionnel (défaut: config source)
servicesarray[{ serviceId, title, price, quantity, total }]
servicesTotalnumberTotal services add-on
isSupervisorPresentbooleanSuperviseur présent au check-in
checkInEmployeestringNom de l'employé

Réponse

{
  "success": true,
  "message": "Check-in successful",
  "booking": { ... },
  "calculatedFinancials": {
    "totalAmount": 1500, "taxes": 71.43,
    "platformFees": 45, "bankFees": 60,
    "rentalIncome": 1194.58, ...
  },
  "note": "PDF generation and email sending are handled by the main API only."
}
Limitation : La Public API ne gère pas le chiffrement passeport/signature, la génération de PDFs, l'envoi d'emails ni les push notifications. Ces actions sont réservées à l'API principale.
PATCH /bookings/:id/no-show Marquer no-show
ChampTypeDescription
isNoShowbooleantrue pour marquer, false pour annuler
noShowEmployeestringREQUISNom de l'employé
noShowNotestringNote optionnelle
noShowValidatedbooleanValidé par un superviseur
noShowConfirmedStepsbooleanÉtapes confirmées
PATCH /bookings/:id/validate-payments Valider → status "Paid"
Pré-requis : Le booking doit être en status "Checked".

Change le status en "Paid".

Limitation : La création de transactions comptables, la génération de PDFs et l'envoi d'emails sont gérés par l'API principale uniquement.
DELETE /bookings/:id Supprimer (soft delete)

Marque isDeleted=true. Le booking n'apparaît plus dans les listes.

PUT /bookings/:id/restore Restaurer un booking supprimé

Remet isDeleted=false.

💳 Endpoints Paiements

GET /booking-payments/booking/:bookingId Paiements d'un booking

Retourne tous les paiements non supprimés pour un booking donné.

GET /booking-payments/booking/:bookingId/summary Résumé paiements

Réponse

{
  "success": true,
  "data": {
    "booking": { "_id": "...", "bookingNo": 1234, "totalAmount": 1500, "prepaidAmount": 1500 },
    "payments": {
      "count": 2, "totalPaid": 1200,
      "confirmedPaid": 800, "pendingPaid": 400,
      "remaining": 300, "isFullyPaid": false
    }
  }
}
GET /booking-payments/all Tous les paiements (comptabilité)
ParamTypeDescription
page, limitnumberPagination
searchstringRecherche par numéro ou nom tenant
lotIdObjectIdFiltrer par lot
bookingSourcestringSource
paymentMethodstringMéthode de paiement
paymentStatusstring"pending" ou "confirmed"
paymentDateStartISO dateDate début
paymentDateEndISO dateDate fin
amountMinnumberMontant minimum
amountMaxnumberMontant maximum
GET /booking-payments/bookings Bookings avec paiements groupés
ParamTypeDescription
searchstringNuméro ou nom
lotId, status, bookingSourcestringFiltres booking
startDate, endDateISO datePériode
hasPaymentsbooleanAvec paiements
hasPendingPaymentsbooleanAvec paiements en attente
paymentStatusstring"pending" ou "confirmed"
paymentDateStart, paymentDateEndISO datePériode paiement
POST /booking-payments Créer un paiement
ChampTypeDescription
bookingIdObjectIdREQUISID du booking
amountnumberREQUISMontant
paymentMethodstringAirbnb, Expedia, Payo, VRBO, Credit Card, Cash, Bank Transfer, Check, Other
paymentDateISO dateDéfaut: maintenant
descriptionstringDescription
referencestringRéférence
PUT /booking-payments/:paymentId Modifier un paiement

Champs modifiables : amount, paymentMethod, paymentDate, description, reference.

PATCH /booking-payments/:paymentId/confirm Confirmer un paiement

Marque le paiement comme confirmé avec la date de confirmation.

PATCH /booking-payments/bulk-update-status Confirmer/infirmer en masse
ChampTypeDescription
paymentIdsstring[]REQUISListe des IDs de paiements
isConfirmedbooleantrue = confirmer, false = infirmer
DELETE /booking-payments/:paymentId Supprimer un paiement

Soft delete (isDeleted=true).

💻 Exemples de code

JavaScript
Python
cURL
const API = 'https://listings.4u-realestate.org';
const KEY = 'YOUR_API_KEY';
const headers = { 'x-api-key': KEY, 'Content-Type': 'application/json' };

// Lister les bookings
const res = await fetch(`${API}/bookings?status=Booked&limit=10`, { headers });
const data = await res.json();
console.log(`Total: ${data.total} bookings`);

// Créer un booking
const created = await fetch(`${API}/bookings`, {
  method: 'POST', headers,
  body: JSON.stringify({
    booking: {
      bookingNo: 9999999, lotId: 'LOT_ID',
      arrival: '2025-06-01', departure: '2025-06-07',
      totalAmount: 1500, prepaidAmount: 1500, bedrooms: 2,
      bookingSource: 'Manual',
      tenantInformations: { name: 'John Doe', email: 'john@ex.com' }
    }
  })
});

// Check-in
await fetch(`${API}/bookings/${bookingId}/check-in`, {
  method: 'PATCH', headers,
  body: JSON.stringify({
    tenantInformations: { name: 'John Doe', email: 'john@ex.com', phone: '+1234' },
    bookingSource: 'Manual', cleaningFees: 100,
    totalAmount: 1500, paymentMethod: 'Credit Card',
    services: [], servicesTotal: 0, checkInEmployee: 'Agent'
  })
});

// Ajouter un paiement
await fetch(`${API}/booking-payments`, {
  method: 'POST', headers,
  body: JSON.stringify({
    bookingId: 'BOOKING_ID', amount: 750,
    paymentMethod: 'Credit Card', description: 'First payment'
  })
});
import requests

API = 'https://listings.4u-realestate.org'
HEADERS = {'x-api-key': 'YOUR_KEY', 'Content-Type': 'application/json'}

# Lister
r = requests.get(f'{API}/bookings', params={'status': 'Booked', 'limit': 10}, headers=HEADERS)
print(f"Total: {r.json()['total']} bookings")

# Créer
r = requests.post(f'{API}/bookings', json={
    'booking': {
        'bookingNo': 9999999, 'lotId': 'LOT_ID',
        'arrival': '2025-06-01', 'departure': '2025-06-07',
        'totalAmount': 1500, 'prepaidAmount': 1500, 'bedrooms': 2,
        'tenantInformations': {'name': 'John Doe', 'email': 'john@ex.com'}
    }
}, headers=HEADERS)

# Check-in
r = requests.patch(f'{API}/bookings/{booking_id}/check-in', json={
    'tenantInformations': {'name': 'John Doe', 'email': 'john@ex.com'},
    'bookingSource': 'Manual', 'cleaningFees': 100,
    'totalAmount': 1500, 'paymentMethod': 'Credit Card',
    'services': [], 'servicesTotal': 0
}, headers=HEADERS)

# Paiement
r = requests.post(f'{API}/booking-payments', json={
    'bookingId': 'ID', 'amount': 750, 'paymentMethod': 'Credit Card'
}, headers=HEADERS)
# Lister les bookings
curl -H "x-api-key: KEY" "https://listings.4u-realestate.org/bookings?status=Booked&limit=10"

# Détail
curl -H "x-api-key: KEY" "https://listings.4u-realestate.org/bookings/BOOKING_ID"

# Vue comptable
curl -H "x-api-key: KEY" "https://listings.4u-realestate.org/bookings/accounting?status=Paid"

# Créer
curl -X POST -H "x-api-key: KEY" -H "Content-Type: application/json" \
  -d '{"booking":{"bookingNo":9999999,"lotId":"LOT_ID","arrival":"2025-06-01","departure":"2025-06-07","totalAmount":1500,"prepaidAmount":1500,"bedrooms":2,"tenantInformations":{"name":"John Doe","email":"john@ex.com"}}}' \
  "https://listings.4u-realestate.org/bookings"

# Check-in
curl -X PATCH -H "x-api-key: KEY" -H "Content-Type: application/json" \
  -d '{"tenantInformations":{"name":"John","email":"john@ex.com"},"bookingSource":"Manual","cleaningFees":100,"totalAmount":1500,"paymentMethod":"Credit Card","services":[],"servicesTotal":0}' \
  "https://listings.4u-realestate.org/bookings/BOOKING_ID/check-in"

# Paiement
curl -X POST -H "x-api-key: KEY" -H "Content-Type: application/json" \
  -d '{"bookingId":"BOOKING_ID","amount":750,"paymentMethod":"Credit Card"}' \
  "https://listings.4u-realestate.org/booking-payments"

# Confirmer paiement
curl -X PATCH -H "x-api-key: KEY" \
  "https://listings.4u-realestate.org/booking-payments/PAYMENT_ID/confirm"

# Valider → Paid
curl -X PATCH -H "x-api-key: KEY" \
  "https://listings.4u-realestate.org/bookings/BOOKING_ID/validate-payments"

⚠️ Codes d'erreur

CodeSignificationSolution
400Données invalides ou manquantesVérifier les champs requis
401Clé API manquante ou invalideAjouter un header x-api-key valide
403Clé API désactivéeContacter l'admin
404Booking/paiement non trouvéVérifier l'ID
409Doublon (bookingNo + lotId)Utiliser un numéro unique
429Rate limit dépasséAttendre et réessayer
500Erreur serveurContacter contact@4u-realestate.org