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:

Note

WuBook will return, at maximum, 120 reservations for each 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) :noindex:

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]) :noindex:

Note

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)

tboard

Information about total amount of all boards (see below: tboard)

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

origin_company_name

The origin parameter that can be sent in the new_reservation function

customer_city

customer_country

customer_mail

customer_name

customer_surname

customer_notes

customer_phone

customer_address

customer_language

customer_language_iso

A string following the ISO 639-1 Standard for languages (https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes)

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)

city_tax

City tax value calculated following the rule set on WuBook (only for wubook rsrvs)

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 tboard field contains the total amount of all boards for the whole reservation period.

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

The 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 the following keys:

  • split_reservation, which has 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).

  • paymodel, which has two possible string values:

    Value

    Description

    merchant

    The guest pays the OTA who pays the hotel in turn

    agency

    The hotel pays the OTA after receiving full payment from the guest

  • vat_included, which has a boolean value that define if the VAT is included or not in the amount.

  • addons_embedded, which has a boolean value that define if the addons are included or not in the amount.

  • vcc_additional_info, which contains information about virtual cards. It has as value a KV structure with these keys:

    Key

    Description

    vcc_valid_from

    The card validity start date

    vcc_valid_til

    The card validity end date

    vcc_balance

    The avaiable amount

    vcc_currency_code

    The currency code. Three digits (EUR, USD, ..)

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.

Note

WuBook will return, at maximum, 120 reservations for each call.

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