Aller au contenu principal

Réservations

Endpoints

EndpointUsage
GET /reservationsListe des réservations
GET /reservations/{id}Détail d'une réservation
GET /reservations/searchRecherche
PUT /reservations/{id}Modification (dates, chambres)
POST /reservations/{id}/cancelAnnulation, corps { reason?: string }
POST /reservations/previewPrévisualisation du prix avant confirmation
GET /reservations/dashboard-statsStatistiques 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.