Fetching reservations

Read this chapter if you want to manage WuBook’s reservations via API.

Basic concepts

There are several ways to download reservations from WuBook. Before describing some strategies, let’s considere the following concepts:

  • Marking: WuBook is able to remember what you already fetched: you don’t need to specify filters (for example dates), because in that case only not-read reservations will be returned. Marking can be done automatically or on demand.
  • Push notification: instead of periodically asking our servers for new reservations, consider the idea to establish a notification layer. WuBook is able to notify you when a new reservation is ready to be fetched. This will optmize a lot your/our servers load.

Note

Once the Push Notification has been deployed, to be safer, you can eventually schedule a fetching call with a 4 hours frequence, just in case some notification will be lost. If you are a corporate user, also check the corporate_fetchable_properties() function

During your development, use the fetch_booking() call, because it easily allows to download the same reservation and focusing this way on the integration process.

Once your integration process is done, you will then begin to setup Notifications and Marking features.

Note

Enabling the Push Notification and Marking is not necessary, but seriously recommended, because it is the best (faster, elegant and reliable) approach.

Setting up the Push Notification

WuBook is able to notify your system that new reservations are waiting for you. This will be done with a simple POST. The URL used for the POST can be configured for each property with the following call:

push_activation(token, lcode, url[, test= 0])

To disable the push notification you can use, as url, an empty string.

If you use test= 1 while specifying a valid url, a POST is immediately issued (lcode= 1000, rcode= 2000). This way, you will be able to debug the push activation. Notice that if such test will fail, the call will return an error.

Once a new reservation is collected for the property identified with the lcode argument, wubook will issue a POST to the relative URL containing two parameters: rcode (the reservation code) and lcode (the property identifier, allowing to use the same URL for multiple properties).

Note

While receiving and handling a push notification, make sure to return a 200 status code and to provide a fast answer (few seconds). Otherwise you can have a couple of problems. First of all, the push notification system will retry. Moreover, if the notification system will detect too many errors on your server, it can even suspend notifications. To provide a fast response, adopt the following approach: immediately reply 200 and perform your operations after that.

Finally, to check the current Push Notification Url for one property, use:

push_url(token, lcode)

Fetching fresh reservations

To fetch new reservations for a property, use the following function:

fetch_new_bookings(token, lcode[, ancillary= 0, mark= 1])

Once called, this function will return only new reservations (not fetched yet). It’s always a good idea to use ancillary= 1, because by enabling this option you will receive more information (see the representation section).

If mark= 1, fetched reservations will be considered marked and will not be returned at the next call.

If you want more control (a sort of transaction), you can specify mark= 0. Then, if the reservations are correctly integrated on your system, you will mark them as fetched with the following call:

mark_bookings(token, lcode, reservations)

where the reservations argument is an array of reservation codes, i.e. [123, 234, …, 890]. Once marked, the next fetch_new_bookings() call will not return them again. This way, if a bug will prevent a correct integration, mark_bookings() will not be called and WuBook will continue to return the reservations until the bug is fixed: at that point, the mark_bookings() call will be launched from your side.

The following double remark underlines at the same time a Feature and a Danger :).

Warning

if you use an empty array, all the collected reservations will be marked as fetched (check the First time fetch section).

Note

if you use an empty array, all the collected reservations will be marked as fetched (check the First time fetch section).

Fetching for the first time

If you connect a property that has already collected many reservations, you have two possibilities:

  • Ignoring existing reservations
  • Fetching them all

Please, check the following sub-section to better understand the related logic.

Ignoring existing reservations

Ignoring existing reservations, starting to fetch only the new ones, is a good idea, in particular if the property has collected thousands of reservations.

To ignore the existing reservations, just issue the following call:

mark_bookings(token, lcode, emptyarray)

By passing an empty array to the mark_bookings() function, all the collected reservations will be marked as fetched. At this point, you can safely launch fetch_new_bookings() by relying on the fact that only new reservations will be retrieved (as described on the previous chapters).

Fetching all existing reservations

To fetch all reservations, you have to cycle a call to:

fetch_new_bookings(token, lcode[, ancillary= 0, mark= 1])

That’s because WuBook will return, at maximum, 120 reservations for each call.

Make sure to mark them once retrieved with the mark_bookings() call (if you use mark= 0 during the call).

Reservation representations

Now that you know how to fetch reservations, it’s time to understand how to manage the return values of the fetching functions. The representation of a reservation is a KV structure, having the following keys:

Key Description
reservation_code The reservation ID (and at the same time creation timestamp= reservation date)
status Reservation Status (see below: status)
channel_reservation_code If originated by an OTA, it contains the OTA ID of this reservation (0 otherwise)
id_channel If originated by an OTA, that’s the channel type (booking, expedia, …, check get_channels_info())
id_woodoo If originated by an OTA, that’s the ID of the connected WuBook Channel
fount If originated by a Fount Site, it contains the Fount site ID (trivago, tripadv and so on, see fountfield)
modified_reservations If the reservation is modified, this field is not null (see below: modified_reservations)
was_modified If was_modified= 1, then status= 5 and you have a modification (see below: modified_reservations)
amount The reservation amount
booked_rate Deprecated (see booked_rooms): booked pricing plan: -1= Unknown, 0= Wb Parity or id of the plan
orig_amount Original Reservation Amount (amount can be modified from the extranet)
amount_reason If Amount is modified, this field contains the related comment
date_received Deprecated (see date_received_time)
date_received_time Reservation Date
date_arrival Arrival
date_departure Departure
arrival_hour  
boards Information about boards: only for wubook reservations (see below: boards)
status_reason Eventually, this field contains a reason for the current reservation status
men Number of adults (when not defined, equal to -1)
children Number of children
sessionSeed The eventual sessionSeed tag assigned during the opening of the Online Reception
customer_city  
customer_country  
customer_mail  
customer_name  
customer_surname  
customer_notes  
customer_phone  
customer_address  
customer_language  
customer_zip  
rooms A string contatining booked rooms IDs, comma separated
roomnight Roomnights (almost useless)
room_opportunities Optonal room addons (only wubook reservations)
opportunities Optonal generic addons(only wubook reservations)
dayprices Per day, per room prices
special_offer Info about an eventual special offer: name and discount (only wubook)
addons_list Info about addons (only for OTA reservations and WuBook add-ons)
rooms_occupancies Info about the occupancy of each booked room (it can be empty, see below : rooms_occupancies)
discount Information about an eventual discount (see below: discount)
mandatory_costs An optional array of Mandatory Costs (only for direct reservations)
payment_gateway_fee The amount paid by the customer online (as deposit, only for wubook rsrvs)
forced_price If true (1), dayprices should be ignored (used for youbook and aliens reservations for example)
booked_rooms Optional and detailed info about each room/rate with a day granularity (see below: booked_rooms)
ancillary If you fetch with ancillary= 1 (see below: ancillary)
device Device used to books (see below: device)
deleted_at Deprecated (see deleted_at_time)
deleted_at_time Info about eventual reservation deletion (see below: deleted)
deleted_advance  
deleted_from  
channel_data Standarized info for all channels, like split reservations (see below: channel_data)

The status of a reservation is an integer and can assume the following values:

  • 1: confirmed
  • 2: waiting for approval (only wubook reservations)
  • 3: refused (only wubook reservations)
  • 4: accepted (only wubook reservations)
  • 5: cancelled
  • 6: (probably not used anymore): cancelled with penalty

The ancillary field contains information collected by the channel manager which are out of standard (for example, textual remarks and so on). It is a KV structure. Of course, its keys are strings, while its values are arbitrary. They can be everythign (for example strings, arrays or even structs). Different channels (booking.com, expedia and so on) provide very different information and this is the best way to organize them.

If originated by a Fount Site, the fount field contains the Fount site ID (trivago, tripadv and so on). A list of valid fount IDs can be obtained by the get_fount_symbols() call.

The device field is an integer, it’s detected only for reservations made from our Booking Engine, the meaning is described below here:

  • -1: Not Detectable
  • 0: Unknown device
  • 1: Mobile phone
  • 2: Tablet computer
  • 3: Personal computer
  • 4: iPhone
  • 5: iPad
  • 6: Android device
  • 7: BlackBerry
  • 8: iPod

The boards field contains information about selected boards. The WuBook’s booking engine, in fact, allows user to select their preference about them. It is a KV structure containing Room IDS as keys and Board String (‘bb’, ‘fb’, ..) as values.

The booked_rooms field contains an array containing one struct for every booked room. For each room struct another list is provided, containing one struct representing each booked day. The room-level struct contains the room ID. The day-level struct contains:

  • day: european date
  • price
  • booked rate ( <0: Unknown; 0: WuBook Parity (aka standard rate); >0: the id of the booked pricing plan).

Both room and day level structs contain an “ancillary” field. It contanis non-standard information (collected from OTAs).

For OTA reservations, it is possible we wont receive details about daily prices. In such cases, this field is automatically generated: the room-level “ancillary” field contains the information auto_generated: True; this automatic generation consists in splitting and adapting values from the reservation fields: dayprices and booked_rate.

The discount value is a KV structure having the following keys:

  • type: the discount type (Percentage= 1, Daily Amount= 2, Fixed Amount= 3, No discount= 4, Pricing Plan= 5, Hidden fixed amount= 6, Fixed amount that will appear as a percentage discount = 7, Package= 8)
  • pricing_plan: a pricing plan id (if the discount is configured with a plan)
  • value: the discount value
  • code: the used discount code
  • name: the discount name
  • id: the discount id

The rooms_occupancies value is an Array, having a KV structure as each element. Each KV structure contains two fields: id (the Room ID) and occupancy (an integer).

If the reservation was deleted: deleted_at_time is the date when it happened, and deleted_advance is the number of days respect to arrival date. deleted_from means where the deletion was made, and can be:

  • 1: by customer
  • 2: from BackOffice
  • 3: from the Distribution Channel
  • 4: by WuBook staff
  • 5: from Alien service
  • 6: from Wired service

channel_data field is a KV structure with information that can be treated in a standard way for all the channels. By the moment, it includes one Key: split_reservation, which will have as value another KV structure with two keys: n_stream and tot_stream. So, in case of a reservation is part of a split, you’ll know wich part of this split is the current reservation (n_stream) and how many parts is the original reservation split on (tot_stream).

Reservation modifications

Notice that a modified status does not exist. Why? A modification is always managed with a cancellation and a new reservation. In other words, when a reservation is modified (this happens only for reservations originated by OTAs), the old reservation is cancelled. A new reservation is then inserted on the system, reflecting the modifications. In this case, the modified_reservations and was_modified fields contain a complete information about the modification.

The modified_reservations and was_modified fields must be perfectly understood. They appear when a reservation is modified. How? Let’s make an example:

Moment 1: a new reservation is received, its reservation code is 123.

    If you fetch reservations now, you will get a reservation with the following values
    (notice that modified_reservations is null and was_modified= 0):

    Reservation 1:
      rcode=  123
      status= 1
      modified_reservations=
      was_modified= 0

Moment 2: the reservation is modified

    If you fetch reservations now, as described before, you will get 2 reservations with the following values:

    Reservation 1 (the cancellation of the old reservation):
      rcode=  123
      status= 5
      modified_reservations= 123
      was_modified= 1

    Reservation 2: (the new reservation)
      rcode=  234
      status= 1
      modified_reservations= 123
      was_modified= 0

So, the first concept is: when a reservation is modified, its status becomes 5 (cancelled). The modified_reservations field becomes equal to rcode and was_modified becomes 1. Surely, the next resevation is the replacement of this one. This new reservation has the modified_reservations field equal to the rcode of the previous reservation (this way, you can understand that it replaces it) and status = 1.

Now, let’s add another element of complexity. What happens if the reservation is modified again? Always considering the previous example, let’s check this possibility:

Moment 3: the reservation is modified again

    If you fetch reservations now, you will get 2 reservations with the following values:

    Reservation 1 (the cancellation of the old reservation):
      rcode=  234
      status= 5
      modified_reservations= 123
      was_modified= 1

    Reservation 2: (the new reservation)
      rcode=  345
      status= 1
      modified_reservations= 234
      was_modified= 0

As you can see, the logic is the same. Just notice that the modified_reservations field of the Reservation 1, differently by the previous case (where it was equal to rcode), continue to report 123: this way, you will know that this reservation was originally the replacement of 123.

Warning

Important notice: for reservations received before 15/06/2015, the behaviour is different:

  • The was_modified field is not consistent and you must ignore it
  • The modified_reservations is not sticky: when a reservation is modified, its status becomes 5 and modified_reservations becomes equal to its rcode.

Example:

Moment 1: a new reservation is received
  Reservation 1:
    rcode= 1
    status= 1
    modified_reservations=

Moment 2: the reservation is modified
  Reservation 1:
    rcode= 1
    status= 5
    modified_reservations= 1  ### <-- mod= rcode
  Reservation 2:
    rcode= 2
    status= 1
    modified_reservations= 1

Moment 3: the reservation is modified again
  Reservation 1:
    rcode= 2
    status= 5
    modified_reservations= 2  ### <-- mod= rcode
  Reservation 2:
    rcode= 3
    status= 1
    modified_reservations= 2

That’s because we have improved in a not backward compatible way the modification system during June 2015.

Other functions

Altough the previous chapters can be considered a complete reference to fetch reservations form wubook, we list on this last section the full list of available functions you can use to improve things or to better manage particular cases.

fetch_bookings(token, lcode[, dfrom= None, dto= None, oncreated= 1, ancillary= 0])

This function is used to fetch reservations eventually using a range of dates as filter. Notice that retrieved reservations returned when you specify a date are not marked as fetched. The dfrom and dto arguments are european dates (as string: “21/12/2021”). When oncreated is 1, the filter is applied against the reservation date. When oncreated is 0, the filter is applied against the arrival date.

If not filter (dfrom and dto) is specified, this call will be equal to a fetch_new_bookings() call, with mark parameter = 1.

fetch_bookings_codes(token, lcode, dfrom, dto[, oncreated= 1])

Similar to fetch_bookings(), but instead of returning the list of reservations, this functions returns just an array of reservation codes.

fetch_booking(token, lcode, rcode[, ancillary= False])

To retrieve a unique reservation identified by rcode.

get_fount_symbols(token)

To retrieve a list of valid fount IDs and relative names.

XML Examples

Here, you’ll find some examples of reservations creation, modification and deletion in XML format.

1- Creation: below, there is an example of a brand-new creation.

+ show/hide code
2 - Modification - Case 1: in this case, we are modifying the dates of both of the rooms present in the previous example.

Note

the modified dates are the same for every room.

+ show/hide code
3- Modification - Case 2: in this case, we are modifying the dates for only one room among the rooms present in the Example 1.

Note

this implies a splitting of the XML call, which is a better choice because it gets rid of reduntant useless data sending.

+ show/hide code
4 - Modification - Case 3: in this case, we are deleting the reservation of one of the rooms.

Note

in this case, there’s no need to split the call; the XML sent is just one.

+ show/hide code

5 - Deletion - Case 1: in this case, we are deleting the modification made before in Example n. 3.

+ show/hide code

6 - Deletion - Case 2: in this case, we are deleting the modification made before in Example n. 4.

+ show/hide code