Réservations
Endpoints
| Endpoint | Usage |
|---|---|
GET /reservations | Liste des réservations |
GET /reservations/{id} | Détail d'une réservation |
GET /reservations/search | Recherche |
PUT /reservations/{id} | Modification (dates, chambres) |
POST /reservations/{id}/cancel | Annulation, corps { reason?: string } |
POST /reservations/preview | Prévisualisation du prix avant confirmation |
GET /reservations/dashboard-stats | Statistiques agrégées |
GET /public-feedback/{id} | Avis public sur une réservation (sans authentification) |
Créer une réservation multi-chambres
{
property_id: number;
checkin_date: string; // YYYY-MM-DD
checkout_date: string; // YYYY-MM-DD
guests: Array<{
first_name: string;
last_name: string;
age: number;
email?: string;
phone?: string;
}>;
rooms: Array<{
room_type_id: number;
rate_plan_id: number;
rooms_count: number;
}>;
first_name: string;
last_name: string;
email: string;
phone: string;
special_requests?: string;
code_promo?: string;
offer_id?: number;
package_ids?: number[];
service_ids?: number[];
}
Prévisualisation (POST /reservations/preview)
Requête :
{
property_id: number;
checkin_date: string;
checkout_date: string;
rooms?: Array<{ room_type_id: number; rate_plan_id: number; rooms_count: number }>;
promo_code?: string;
offer_id?: number;
package_ids?: number[];
service_ids?: number[];
}
Réponse :
{
nights: number;
currency: string;
base_price_per_night: number;
base_total: number;
rooms_total: number;
cleaning_fee: number;
service_fee_total: number;
services_total: number;
services_details?: Array<{ id: number; name: string; price: number; type: string }>;
tax_amount: number;
tax_rate: number;
promo_discount: number;
promo_applied: boolean;
long_stay_discount: number;
offer_discount: number;
offer_applied: boolean;
offer_details: { id: number; name: string; discount_value: number; discount_type: string } | null;
packages_total: number;
packages_details: Array<{ id: number; name: string; price: number; is_global?: boolean }>;
sub_total: number;
total: number;
rooms_breakdown?: Array<{
room_type_id: number; room_type_title: string; rate_plan_id: number;
rate_plan_title: string; rooms_count: number; price_per_night: number; line_total: number;
}>;
season?: { id: number; name: string; reduction_percent: number; min_stay: number; max_stay: number } | null;
stay_validation?: { valid: boolean; message: string | null; min_stay?: number; max_stay?: number };
}
Objet réservation (lecture)
{
id: number;
booking_ref_code: string;
checkin_date: string;
checkout_date: string;
guests: { adults: number; children: number };
status: string;
special_requests: string | null;
promo_code_id: number | null;
rooms_count?: number;
rooms_details?: Array<{
channex_room_type_id: number;
channex_rate_plan_id: number;
rooms_count: number;
line_total: number;
}>;
price_details: {
currency: string;
nights: number;
base_price_per_night: number;
base_total: number;
service_fee_total: number;
services_total: number;
long_stay_discount: number;
sub_total: number;
tax_rate: number;
tax_amount: number;
promo_discount: number;
total: number;
};
// Présents uniquement après une modification de réservation
needs_additional_payment?: boolean;
additional_due?: number;
pricing?: {
old_total: number;
new_total: number;
paid_amount: number;
additional_due: number;
refund_due: number;
price_difference: number;
};
refund_initiated?: boolean;
refund_amount?: number;
property: { /* voir Propriétés */ };
}
Deux variantes coexistent
Une partie des endpoints (recherche, création simple) renvoie une forme plus légère où guests et price_details sont des chaînes JSON non parsées plutôt que des objets — comme pour les propriétés, la forme exacte dépend de l'endpoint appelé, pas seulement de la ressource. Le champ total existe en plus au niveau racine, en tant que chaîne ("245.00"), distinct du nombre price_details.total.
Modification d'une réservation (PUT /reservations/{id})
Réponse :
{
id: number;
booking_ref_code: string;
checkin_date: string;
checkout_date: string;
status: string;
pricing: {
old_total: number;
new_total: number;
additional_due: number;
price_difference?: number;
};
needs_additional_payment: boolean;
refund_initiated?: boolean;
refund_amount?: number;
}
C'est ce champ needs_additional_payment / pricing.additional_due (surplus) ou refund_initiated / refund_amount (remboursement) qui alimente les badges "Supplément à payer" / "Remboursement en attente" vus côté Gestion des réservations.