Reservas de hoteles: API directa y pago SSO
Una vez que haya confirmado el precio y haya recibido un token de precio, hay dos formas de completar una reserva de hotel a través de la API de Xeni. Este artículo cubre ambos enfoques.
Opciones de reserva de un vistazo
| Método | Cómo funciona | Mejor Para |
|---|---|---|
| API directa Booking | Llame al punto final de reserva mediante programación. Procese pagos a través de su propia cuenta de comerciante o mediante el procesamiento de pagos de Xeni. | Integraciones empresariales, plataformas de marca blanca, pago personalizado flows. |
| SSO Pago | Redirecciona al invitado a la página de pago alojada de Xeni donde ingresan los detalles de pago y completan la reserva. | Integraciones rápidas en las que no desea manejar el procesamiento de pagos. |
*
Opción 1: Reserva API directa
El enfoque API directo le brinda control total sobre la experiencia de reserva. Usted recopila los detalles del huésped, procesa el pago a través de su propia cuenta de comerciante (o la de Xeni) y llama al punto final de reservas de Xeni para crear la reserva.
Punto final
POST /hotels/api/v2/bookings?pricingtoken={pricingtoken}
Parámetros de consulta
| Parámetro | Tipo XENIKBPH56| Requerido | Descripción | XENIKBPH 61 |
|---|---|---|---|
preciotokenXENIKBPH6 7__ | string | Sí | El pricing_token de la respuesta de confirmación de precio. No el token de disponibilidad. |
Cuerpo de solicitud
| Campo | TipoXE NIKBPH88 | Requerido | Descripción | XENIKBPH93
|---|---|---|---|
bookingid XENIKBPH100string | Sí | A identificador de reserva único generado por su sistema. | |
habitaciones | array | Sí | Array de objetos invitados, uno por habitación. |
habitaciones[].títuloXENIKBPH123 | string | Sí | Invitado título (por ejemplo, "Señor", "Señora", "Señora"). |
habitaciones[].firs tname | string | Sí | Invitado primero nombre. |
habitaciones[].apellidoXENIKBPH1 53 | string | Sí | Invitado último nombre. |
correo electrónico XENIKBPH166string | Sí | Invitado dirección de correo electrónico para reservar confirmación. | |
teléfonoXENIKBPH177 | objeto | Sí | Invitado telefono número. |
teléfono.códigopaísXENIKBPH 189 | string | Sí | Teléfono código de país (por ejemplo, "1" para EE. UU.). |
número.de.teléfonoXENIKBPH203 | string | Sí | Teléfono número (solo dígitos). |
Solicitud de ejemplo
POST /hotels/api/v2/bookings?pricingtoken=eyJhbGciOiJIUzI1NiJ9.pricingfinal...Authorization: {signature}x-correlation-id: {correlation_id}Content-Type: application/json
{ "bookingid": "XENI-1700000000-ABC123DEF", "rooms": [ { "title": "Mr", "firstname": "John", "lastname": "Smith" } ], "email": "john.smith@example.com", "phone": { "countrycode": "1", "number": "5551234567" }}
Ejemplo de respuesta
{
"data": {
"booking_id": "XENI-1700000000-ABC123DEF",
"confirmation_number": "HTL-98765",
"booking_status": "confirmed"
}
}Procesamiento de pagos
Al utilizar el enfoque API directo, tiene dos opciones para gestionar los pagos:
- Su propia cuenta de comerciante: procese el pago a través de su procesador de pagos existente (Stripe, Braintree, Adyen, etc.) antes o después de llamar al punto final de reservas de Xeni. Esto le brinda control total sobre la experiencia de pago, las tarifas y la conciliación.
- Procesamiento de pagos de Xeni: utilice el comerciante de Xeni para gestionar el cobro de pagos. Comuníquese con su representante de cuenta Xeni para obtener detalles sobre cómo habilitar esta opción y los métodos de pago disponibles.
Recomendado para empresas: La mayoría de los clientes empresariales utilizan la reserva API directa con su propio procesador de pagos. Esto le brinda control total sobre la experiencia de usuario del pago, los métodos de pago y la conciliación financiera.
*
Opción 2: Pago SSO (página alojada)
Si prefiere no encargarse del procesamiento de pagos, Xeni proporciona una página de pago alojada. Generas una URL con los parámetros de la reserva y rediriges al huésped a ella. Xeni gestiona el cobro de pagos y la confirmación de la reserva en la página alojada.
Beneficio: El pago mediante SSO elimina la necesidad de que su aplicación maneje datos de pago confidenciales. Todo el procesamiento de pagos es manejado por la infraestructura de pago compatible con PCI de Xeni.
Entornos de pago
| Medio ambiente | Base de pago URL |
|---|---|
| UAT (Caja de arena) | https://lifestyle2.uat.booking.clu bxeni.com |
https://lifestyle2.booking.club xeni.com |
Estructura de URL de pago
La URL de pago sigue este patrón:
{checkoutbaseurl}/booknow/hotels/v2/checkout?{parameters}
Parámetros requeridos
Todos los parámetros se pasan como valores de cadena de consulta de URL. Los objetos y matrices deben estar codificados en cadenas JSON y codificados en URL.
| Parámetro | XENIKBPH251TipoDescripción | XENIKBPH255|
|---|---|---|
correlación nId | string | El ID de correlación de la búsqueda actual sesión. |
startDa te | string | Registro fecha en AAAA-MM-DD formato. |
endDate | string | Pagar fecha en AAAA-MM-DD formato. |
ubicación | JSON string | Objeto de ubicación (ver formato a continuación). |
ocupación | JSON string | Matriz de ocupación (ver formato a continuación). |
precios Token | cadena | El pricingtoken de la respuesta de confirmación de precio. No la disponibilidad token. |
properto tyId | string | El hotel propertyid. |
| XENIKBPH340roomId | string | El habitación id de la disponibilidad respuesta. |
stayPeriod | JSON string | Objeto de período de estadía con start y end fechas. |
nacionalidad | JSON string | Nacionalidad del huésped objeto. |
force Obtener | string | Set a "verdadero". |
| X ENIKBPH388isOTA | string | Set a "true" para OTA integraciones. |
paging | JSON cadena | Configuración de paginación objeto. |
preferencia | JSON string | Establecido en "[]" (JSON vacío matriz). |
*
Formatos de parámetros
Objeto de ubicación
{
"id": "12345",
"name": "Miami",
"full_name": "Miami, Florida, United States",
"country": "United States",
"type": "City",
"location": {
"lat": 25.7617,
"long": -80.1918
}
}Utilice los datos de ubicación devueltos por el punto final de autocompletar. El id debe ser una cadena.
Matriz de ocupación
[
{
"id": "room11700000000",
"numOfRoom": 1,
"adults": 2,
"childs": 0,
"childages": []
}
]Cada elemento representa una habitación. El campo id debe ser un identificador único (cualquier cadena).
Objeto del período de permanencia
{
"start": "2025-06-01",
"end": "2025-06-05"
}Objeto de nacionalidad
{
"name": "United States",
"alpha2Code": "US"
}Objeto de paginación
{
"pageNo": 1,
"pageSize": 50
}*
Ejemplo completo: creación de la URL de pago
JavaScript
function generateCheckoutUrl(params) { const baseUrl = 'https://lifestyle2.uat.booking.clubxeni.com';
const location = { id: String(params.location.id), name: params.location.name, fullname: params.location.fullname, country: params.location.country, type: params.location.type || 'City', location: { lat: params.location.lat, long: params.location.long } };
const occupancy = params.occupancy.map((occ, index) => ({ id: room${index + 1}${Date.now()}, numOfRoom: 1, adults: occ.adults, childs: occ.childs || 0, childages: occ.childages || [] }));
const urlParams = new URLSearchParams({ correlationId: params.correlationId, startDate: params.startDate, endDate: params.endDate, forceGet: 'true', isOTA: 'true', location: JSON.stringify(location), nationality: JSON.stringify({ name: 'United States', alpha2Code: 'US' }), occupancy: JSON.stringify(occupancy), paging: JSON.stringify({ pageNo: 1, pageSize: 50 }), preference: JSON.stringify([]), pricingToken: params.pricingToken, propertyId: params.propertyId, roomId: String(params.roomId), stayPeriod: JSON.stringify({ start: params.startDate, end: params.endDate }) });
return ${baseUrl}/booknow/hotels/v2/checkout?${urlParams.toString()};}
Pitón
import jsonfrom urllib.parse import urlencode
def generatecheckouturl(params): base_url = "https://lifestyle2.uat.booking.clubxeni.com"
location = { "id": str(params["location"]["id"]), "name": params["location"]["name"], "fullname": params["location"]["fullname"], "country": params["location"]["country"], "type": params["location"].get("type", "City"), "location": { "lat": params["location"]["lat"], "long": params["location"]["long"] } }
occupancy = [{ "id": f"room{i+1}{int(time.time())}", "numOfRoom": 1, "adults": occ["adults"], "childs": occ.get("childs", 0), "childages": occ.get("childages", []) } for i, occ in enumerate(params["occupancy"])]
query = urlencode({ "correlationId": params["correlationid"], "startDate": params["startdate"], "endDate": params["enddate"], "forceGet": "true", "isOTA": "true", "location": json.dumps(location), "nationality": json.dumps({"name": "United States", "alpha2Code": "US"}), "occupancy": json.dumps(occupancy), "paging": json.dumps({"pageNo": 1, "pageSize": 50}), "preference": json.dumps([]), "pricingToken": params["pricingtoken"], "propertyId": params["propertyid"], "roomId": str(params["roomid"]), "stayPeriod": json.dumps({"start": params["startdate"], "end": params["enddate"]}) })
return f"{base_url}/booknow/hotels/v2/checkout?{query}"
*
Presentando el enlace de pago
Una vez que haya creado la URL, preséntela al invitado. Enfoques comunes:
- Redireccionamiento del botón: muestra un botón "Completar reserva" que abre la URL de pago en una nueva pestaña.
- Redireccionamiento automático: lleva al usuario directamente a la página de pago.
- Iframe integrado: inserte la página de pago dentro de su aplicación (consulte con su representante de Xeni la compatibilidad con iframe).
Ejemplo: botón HTML
<a href="{checkouturl}" target="blank" rel="noopener noreferrer" style="display: inline-block; padding: 12px 24px; background-color: #2196F3; color: white; text-decoration: none; border-radius: 6px;"> Complete Booking</a>
*
Consideraciones importantes
- Caducidad del token de precio: El token de precio es válido por 10 minutos. Genere la URL de pago inmediatamente después de la confirmación del precio. Si el huésped se retrasa, es posible que tengas que volver a confirmar el precio.
- Uso único: Cada token de precio se puede utilizar para una única reserva. Una vez completado el pago (o que el token caduque), se debe obtener un nuevo token para cualquier reserva posterior.
- Formato de ID de correlación: El ID de correlación se debe pasar tal cual desde los encabezados de respuesta de la API. No lo modifiques.
- Codificación de URL: los objetos JSON en los parámetros de consulta deben estar codificados en URL correctamente. Utilice
URLSearchParams(JavaScript) ourllib.parse.urlencode(Python) para manejar la codificación automáticamente.
_Artículo siguiente: Gestión de reservas: estado, recuperación y cancelación
_