Wired‎ > ‎

Wired! Stay connected

THIS DOCUMENTATION IS OUT OF DATE!!!! PLEASE, USE THE OFFICIAL ONE (HERE)



Index

Chapter 7: Restriction Plans       
Chapter 8: WooDoo: Channels Updates
Chapter 9: Corporate Handling
Chapter 10: Channels Handling
Examples: Examples

Last revision: 26/12/2013 

Chapter 0: Introduction

WuBook provides a Web Services Framework for third party software integration. This framework is OS and Language independent: it uses Xml
Also evaluate the idea to connect to our IRC server (irc.wubook.net, port 6667, SSL On -self signed certificate-, channel #wubook).

To use Wired and to become an official WuBook Provider, you need a Provider Key. Please, contact us to obtain your personal key.
We will register your position: at least an email is required: this email will be used to send -only important- notifications about the Wired interface,
as new features or backwards compatibility issues.

Data is sent and received with the XmlRpc Protocol (Xml Remote Procedure Call). Wikipedia has good informations about it:


Xmlrpc Procedures are published at this address:
You can access them by using common xmlrpc libraries or making simple posts (and building your own xml messages). Good libraries allow an easy job. 
A simple python example (notice that you don't need to deal with xml strings):

 >>> import xmlrpclib
 >>> server= xmlrpclib.Server(url, verbose= 1)
 >>> result, token= server.acquire_token(user, pass, pkey)
 >>> print result, token

Php is very similar and you have several interesting libraries to use. This is an example:

  include("xmlrpc.inc");
  $server = new xmlrpc_client($wubookurl);
  $args= array(new xmlrpcval($user, 'string'), new xmlrpcval($pass, 'string'), new xmlrpcval($pkey, 'string'));
  $message = new xmlrpcmsg('acquire_token', $args);
  $struct = $server->send($message)->value();
  $res= $struct->arraymem(0);
  $token= $struct->arraymem(1);

The following example is a Java client, developed with the Xmlrpc Library provided by the Apache foundation:
public String getToken(String username, String password, String pkey) throws Exception {
    Vector<String> params = new Vector<String>();
    params.addElement(username);
    params.addElement(password); params.addElement(pkey);
    Object[] objects = (Object[]) xmlRpcClient.execute(config, "acquire_token", params);
    return (String) objects[1];
}

There is a Ruby library developed by Stefan Eilers (Intelligent Mobile). The library is hosted on Github, here.
A Gem file is also available here.

This guide contains several chapters. Each chapter contains some examples: these examples have to be 
considered pseudo code: real examples are published here

You will have to deal with Simple Data (integers, strings and floats for example), Arrays and Structs. If you don't use an
high level library and you want to post XML by writing it as a string, make sure to develop propedeutic functions to represent
these data types. A good resource is available here.

The great part of the Wired callable procedures has limits. Limits are here for a simple reasons: it often happened that,
for a bug or for a poor implementation, a partner started to call with incredible frequences some methods, wasting the
resources for all Wired users. The result is we have deployed a set of limitations. Make sure to read our AntiFlood Policies!

Chapter 1: Return Values and Error Handling

Return values are shared between all procedures and have always the same format: 

 (ReturnCode [Integer], Info[structure]).

For succesfull operations, and only for them, ReturnCode is zero. The second element, Info, changes depending by the called procedure.

When the code is less then zero, something wrong occurred. In this case, info contains a Human Readable string. Note that you can catch the error type with the ReturnCode value. The following list is probably out of date. If you want a complete list, you have the following procedure:
  • werrors(token)
This function, if called with a valid token, will return a simple structure displaying all possible errors, like this:

0 Ok
-1 Authentication Failed
-2 Invalid Token
-3 Server is busy: releasing tokens is now blocked. Please, retry again later
-4 Token Request: requesting frequence too high
-5 Token Expired
-6 Lodging is not active
-7 Internal Error
-8 Token used too many times: please, create a new token
-9 Invalid Rooms for the selected facility
-10 Invalid lcode
-11 Shortname has to be unique. This shortname is already used
-12 Room Not Deleted: Special Offer Involved
-13 Wrong call: pass the correct arguments, please
-14 Please, pass the same number of days for each room
-15 This plan is actually in use
-100 Invalid Input
-101 Malformed dates or restrictions unrespected
-1000 Invalid Lodging/Portal code
-1001 Invalid Dates
-1002 Booking not Initialized: use facility_request()
-1003 Objects not Available
-1004 Invalid Customer Data
-1005 Invalid Credit Card Data or Credit Card Rejected
-1006 Invalid Iata
-1007 No room was requested: use rooms_request()

Chapter 2: Authentication

Available procedures:
  • acquire_token(account_code, pwd, pkey)
  • is_token_valid(token)
  • release_token(token)
  • provider_info(token)

acquire_token(account_code, pwd, pkey) 
Python example: result, token= server.acquire_token('user', 'pass', 'plkey')     

To call the Wired! procedures you need a token. To get a token you have to provide Authentication Credentials.
acquire_token() is used to obtain a token. You have to pass valid WuBook Credentials (Properties Credentials).  You
also need to specify your Provider Key. This key is released by our team to our partners. If you want to connect Wired,
please, file an email to devel _at_ wubook _dot_ net (the right email address to get support, too) and require your
own Provider Key.


is_token_valid(token)
Python example: res, valid= server.is_token_valid(token)

Checks the status of the token that you passed as a parameter.


release_token(token)

Closes an active token. This should always be called when a token will not be used again. First of all, you will help our servers. 
Moreover, tokens have dedicated Antiflood policies.

provider_info(token) 

To check the information WuBook holds about your Provider registration (email and so on).

Chapter 3: Rooms Handling

Available procedures:
  • fetch_rooms(token, lcode)
  • new_room(token, lcode, woodoo, name, beds, defprice, avail, shortname, defboard [, names, descriptions, boards, rtype])
  • new_virtual_room(token, lcode, rid, woodoo, name, beds, children, defprice, shortname, defboard[, names, descriptions, boards])
  • mod_room(token, lcode, rid, name, beds, defprice, avail, shortname, defboard[, names, descriptions, boards])
  • mod_virtual_room(token, lcode, rid,  name, beds, children, defprice, short, defboard[, names, descriptions, boards])
  • del_room(token, lcode, rid)
  • room_images(token. lcode, rid)
  • add_room(token, lcode, name, occupancy, defprice, defavail, short[, descrs])      DEPRECATED (use new_room)
  • add_sub_room(token, lcode, rid, name, occupancy, defprice, short[, children])   DEPRECATED (use new_virtual_room)

fetch_rooms(token, lcode)

Returns the rooms for the property identified by lcode. For each room, Wired! returns the following parameters:
  • id: the room id, used to identify the room
  • name: the room name
  • shortname: the room shortname: unique
  • occupancy: the room occupancy
  • men: adults (note: adults + children = occupancy)
  • children: children (note: adults + children = occupancy)
  • subroom: mother room
  • anchorate: mother room
  • price: the default room price (used when daily values are missing)
  • availability: the default room availability (used when daily values are missing)
  • board: the default board used on room
  • boards: all boards available on room
When subroom or anchorate is 0 (zero), the returned room is a true and independent room.
When subroom or anchorate is not 0, this value is a room id.
For subroom, it means that this room is sharing the availability with the room identified by the subroom value. Only availability is shared. You can update the other values (price, restrictions and so on). If you try to update a subroom availability, nothing happens.
Instead in case of anchorate, it means that this room is sharing the price (increased/decreased with a percentage/static value) with the room identified by the anchorate value. Only price is shared. If you try to update an anchorate price, nothing happens.

new_room(token, lcode, woodoo, name, beds, defprice, avail, shortname, defboard [, names, descriptions, boards, rtype])) 

Use this API to add a new room. WuBook will return its ID once inserted.
  • woodoo: WooDoo Ony Flag. If true (1), this room will not be sold on the WuBook Online Reception (booking engine)
  • name: the name of the room
  • beds: the default occupancy of the room (number of adults)
  • defprice: the default price of the room. This is the price used when no specific informations have been saved for a day
  • avail: the default availability of the room. This is the availability used when no specific informations have been saved for a day
  • shortname: the room shortname: unique
  • defboard: default board for the room. It can be nb (no board, room only), bb (breakfast), hb (half board), fb (full board)
  • names: Optional. The name of the room depending on the languages
  • descriptions: Optional: the description of the room depending on the languages
  • boards: Optional. Additional offered boards 
  • rtype: type of the product (room= 1, apartment= 2, unit= 3, beds= 4)
Almost all parameters are probably trivial enough and they don't require too many explanation. The parameters names, descriptions and boards are complex XMLRPC types. Names are a simple struct: {'it': 'Italian name', 'en': 'English Name'}. The same applies for the descriptions parameter: {'it': 'Italian description', 'en': 'English Description'}. The boards parameter is more complex. For each additional board, you must specify a price variation (which is a variation type and a variation value). The boards parameter is a nested struct. We provide 4 types of price variation: Static increase (dtype= 2), Static decrease (dtype= -2), Percentage increase (dtype= 1), Percentage decrease (dtype= -1). 

   {'bb': {'dtype': 1, 'value': 10}, 'hb': {'dtype': -1, 'value': 20}}

This is a simple but complete implementation in Python:

 >>> s= xmlrpclib.Server(server)
 >>> res, token= s.acquire_token(user, pwd, pkey)
 >>> names= {'it': 'Italian Name', 'en': 'English name'}
 >>> descrs= {'it': 'Italian description', 'en': 'English description'}
 >>> # Notice HalfBoard is a percentage variation +10%. While Full board is static increase of 20 
 >>> boards= {'hb': {'dtype': 1, 'value': 10}, 'fb': {'dtype': 2, 'value': 20}}
 >>> s.new_room(token, 123456, 0, 'TheName', 2, 1000.00, 20, 'DBL', 'bb', names, descrs, boards)


new_virtual_room(token, lcode, rid, woodoo, name, beds, children, defprice, shortname, defboard[, names, descriptions, boards])

One uses this function to add a new Virtual Room. This function is very similar to new_room(). Unique modifications are just the
following parameters:
  • rid: The parent of the room. The availability of this room will be shared by the parent one
  • children: the number of children
Notice that to have a Virtual Room for 2 Adults and 1 Child you must specify beds= 3 and children= 1 (it sounds like: "this room is sold with 3 beds, 1 for children).

mod_room(token, lcode, rid, name, beds, defprice, avail, shortname, defboard[, names, descriptions, boards])
mod_virtual_room(token, lcode, rid,  name, beds, children, defprice, short, defboard[, names, descriptions, boards])

Both functions allow you to update rooms values and accept the same parameters of new_room and new_virtual_room.
You must obviously specify (rid parameter) the room you want to modify!


add_room(token, lcode, name, occupancy, defprice, defavail, short[, descrs])  DEPRECATED (use new_room)

Adding a new room will return the assigned ID. See the following parameters description:
  • name: Name of the Room
  • occupancy: Room Occupancy
  • defprice: Default price of the room
  • defavail: Default availability
  • short: A string not longer than 4 chars. It has to be unique for the lodging

add_sub_room(token, lcode, rid, name, occupancy, defprice, short[, children])  DEPRECATED (use new_virtual_room)

Assign a new Virtual Room to the room identified by rid.
  • rid: Room Identifier. Virtual room is associated to this room
  • name: Name of the Virtual Room
  • occupancy: Virtual Room Occupancy
  • defprice: default price
  • short: a string not longer than 4 chars. It has to be unique for the lodging


del_room(token, lcode, rid)

Delete the Room identified by rid


room_images(token, lcode, rid) 

Returns a list of images for the Room identified by rid. Each image has its URL image_link and a flag main_image (0 or 1).

Chapter 4: Prices, Availabilities, Restrictions

Available procedures:
  • update_rooms_values(token, lcode, dfrom, rooms) 
  • update_sparse_rooms_values(token, lcode, rooms)  
  • fetch_rooms_values(token, lcode, dfrom, dto[, rooms])
  • push_update_activation(token, lcode, url)
  • push_update_url(token, lcode)

update_rooms_values(token, lcode, dfrom, rooms)

Very important: make sure to check and to understand Anti Flood Policies. To prevent floods and to grant reliability and fastness, this call has some (in fact, very high) limits.

This call is really powerful and can be used to modify each room values, for each day. It modifies the rooms values for the facility identified by lcode. It returns standard output: (code, human readable string).

dfrom is the starting date. Days will be passed as ordered lists. rooms is a structure containing a list of rooms. Each room contains a list of days. When you send an update impacting multiple rooms, these lists must have the same lenght. In the following (pseudo) example we are updating two days for two rooms. In this case, the updated days are the start date (dfrom) and start date + 1.

Notice the following code is pseudo-code, just to explain the logic. For a full example, check the Examples Section
<room>
  <id>1</id>
  <days>
    <item>
      <price>123.12</price>
    </item>
    <item>
      <price>431.12</price>
    </item>
  </days>
</room>
<room>
  <id>2</id>
  <days>
    <item>
      <price>2.12</price>
    </item>
    <item>
      <price>4.12</price>
    </item>
  </days>
</room>


Each day item can contain the following, optional values: price, avail, min_stay, min_stay_arrival, max_stay, closed, closed_departure, no_ota

closed can be 0, 1 or 2. If 0, room is open. If 1, room is closed. If 2, room is closed to check-in (close to arrival). no_ota can be 0 or 1. If 1, connected channels are closed.

All values are optional: passing a void item, nothing is updated. Only specified values are updated. The possiility to send empty dates makes possible to use update_rooms_values() also for isolated days. However, you can also check update_sparse_rooms_values(): it allows to send single and isolated days. 

update_sparse_rooms_values(token, lcode,  rooms) 

This call is the update_rooms_values()'s syster. Differently by update_rooms_values(), it allows to specify isolated days. The rooms parameter has the same structure of the rooms parameter used on update_rooms_values(), but each day must contain a dates, for example:

<room>
 <id>1</id>
 <days>
   <item>
     <price>123.12</price>
     <date>21/01/2021</date>
    </item>
    <item>
      <avail>12</price>
      <date>21/12/2021</date>
    </item>
  </days>
</room>

Notice you can send mltiple rooms, each of them having a different set of dates. In fact, update_sparse_rooms_values() wraps update_rooms_values(): it builds a compatible structure, filling missing dates with empty items.

fetch_rooms_values(token, lcode, dfrom, dto[, rooms])

You can fetch daily room values with this call. The rooms param is optional. If not specified, you will have daily values for each room. Otherwise, you can specify a list of room you're interested in.

push_update_activation(token, lcode, url)

WuBook is able to send a notification when rooms values change. This happens for example when a WuBook users modifies the availability of his rooms by using the WuBook Extranet. The push_update_activation() call can be used to setup an URL where notifications will be sent. A notification is very simple, it's just a POST with three parameters: lcode, dfrom, dto. By default, the URL configured for Update Notifications is empty and this means no notification must be sent. By setting up a right URL, notifications will be sent. To disable the Update Notification System, just user url= "" (empty string). This way, the configured URL will be resetted and no more notifications sent.

This function is very very important if you use Wired to develop your own Booking Engine. It allows to establish a reliable cache system on your side. The logic is: you periodically (let's say daily) download rooms values by using Wired functions (like fetch_rooms_values() and plans functions) and then, when you receive a PushUpdate notification, you know that your data must be refreshed for the specified range of dates.

push_update_url(token, lcode)

The previous call push_update_activation is used to configure the URL where Update Notification will be sent. This one allows instead to read the current specified URL.

Chapter 5: Reservations Handling

Available procedures:
  • fetch_bookings(token, lcode [, dfrom= None, dto= None, oncreated= True, ancillary= False])
  • fetch_bookings_codes(token, lcode, dfrom, dto [, oncreated= True])
  • fetch_booking(token, lcode, rcode [, ancillary= False])
  • fetch_new_bookings(token, lcode, ancillary, mark)
  • mark_bookings(token, lcode, reservations)
  • push_activation(token, lcode, url)
  • push_url(token, lcode)
  • cancel_reservation(token, lcode, rcode [, reason])
  • new_reservation(token, lcode,  dfrom, dto, room, customer, amount [, origin, ccard, ancillary])

You can download reservations on demand by calling the fetch_bookings() function. However, we encourage to use the Push Machinery: by calling push_activation(), you can specify an url where WuBook will notify new reservations. Once you receive such notification, then you will call fetch_bookings(). This way, there is no need to overload nodes bandwidth, periodically polling for new reservations.

push_activation(token, lcode url)

By calling this function, WuBook will notify new reservations actively. Once received a new reservation for the property identified by lcode, a POST is made to the url url. The post contains two values: rcode and lcode (reservation code and property code).


push_url(token, lcode)

Returns the current url where PUSH notifications are sent (or an empty string if push is not enabled)


fetch_bookings(token, lcode [, dfrom, dto, oncreated, ancillary])

Do you want to fetch reservations? Use this call. When you specify the params dfrom and dto, all reservations made between these dates are returned. Nothing more happens. If oncreated is False, dates are applied against the arrival date.

When ancillary is True, an additional tag is returned: <ancillary>. You will find inside this tag a struct (key= value). This tag contains channel information (for each OTA, we send different informations).

When you don't provide a dates filter (dfrom and dto), you're making a free call. In this case, only Unfetched bookings are retrieved. Moreover, these bookings are marked as Fetched: next free calls will not retrieve them. 

Note that, when a reservation is modified (cancelled, or amount change), the reservation is marked as Unfetched. At the next free call, the reservation will be returned with the same id. It's your task to handle modified and deleted reservations.

The answer contains, for each reservation, the following fields (please, don't rely on their order):

field description
reservation_code
channel_reservation_code
Reservation code
Channel reservation code (0 if reservation origin is wubok)
fountFount code (TripAdvisor, Google, Trivago....)
modified_reservations Eventual list of deleted reservation for modification (empty means no modification has been done)
amount Reservation Amount
booked_rate (beta) The booked Pricing Plan: -1= Unknown, 0= WuBook Parity (aka standard rate), N>0= the id of the booked pricing plan
orig_amount Original Reservation Amount (amount can be modified)
amount_reason If Amount is modified, this field contains the reason why
id_channel Ids Channel
date_received Reservation Date
date_arrival Arrival
date_departure Departure
arrival_hour Departure
boards  Information about boards: this information is valid only if reservation does not arrive from a channel 
status Reservation Status
status_reason Eventually, this field contains a reason for the actual reservation status
men Number of adults (when not defined, equal to -1)
children Number of children
sessionSeed the eventual sessionSeed tag used during the (online reception only) reservation process
customer_city
customer_country
customer_mail
customer_name
customer_surname
customer_notes
customer_phone
customer_address
customer_language
customer_zip
rooms this is a string containing the rooms IDs, comma separated
roomnight roomnights
room_opportunities How many room addons have been bought
opportunities How many generic addons have been bought
dayprices Per day, per room prices
special_offer Info about special offer: name and discount
addons_list Info about bought addons
rooms_occupancies Info about the occupancy of each booked room (it can be empty)
discount Information about discount 
mandatory_costs An optional array of Mandatory Costs (only for direct reservations)
payment_gateway_fee
forced_price
The amount paid by the customer online (as fee).
a boolean value, that indicates if total amount is forced or not,
(generally forced_price is 1 just for reservation created by new_reservation, alien_plugin and youbook),
in case of forced price is true, dayprices reports a wrong value and should be ignored, the true amount is on amount field.
booked_rooms A list containing one struct for every booked room. For every "room struct" another list is present,
containing one struct for every booked day. The room-level struct contains room ID.
The day-level struct contains:
- day (fmt: dd/mm/YYYY)
- 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 can contain not always present informations (mostly from OTAs).
For OTA reservations, it is possible we do not receive daily precise informations. In such cases this field is
generated automatically, the room-level "ancillary" field contains the information "auto_generated: True"; this automatic
generation consists in splitting and adapting values from fields: "dayprices" and "booked_rate".



Reservation status can assume the following values:

1: Confirmed
2: Waiting for approval
3: Refused
4: Accepted
5: Deleted
6: Deleted with penalty

The modified_reservations member contains a list (maybe empty) of reservation codes. When empty, you have a new reservation
or a cancellation. In the case WuBook will receive a modification from a channel, it will make two things: it will delete the previous 
reservation and it will add a new reservation. So, it will produce a cancellation and a new reservation. Both events are returned by 
the fetch_bookings() calls and in this case the modified_reservations array is filled to let you know what reservations have been deleted.
Please, notice the following example:

Example of the usage of modified_reservation:
  1. You have a new reservation with code 1234. This reservation is entered via booking.com. It's new. When you fetch it, you have modified_reservations= [];
  2. The reservation is modified. When you fetch_bookings(), you get 2 reservations: the 1234 reservation, with status= cancelled, and a new one, with status= new and rcode= 5678
  3. The cancelled reservation (rcode= 1234) has modified_reservations= [1234]; This way you understand that this cancellation is in fact a modification.
  4. Also the new reservation (rcode= 5678) has modified_reservations= [1234]; This way you understand what reservation is replaced by the new one.
  5. Now, the reservation is cancelled. You receive the reservation 5678, status= cancelled, modified_reservations= [];

The discount structure eventually contains information about the used discount code. It's a simple structure, providing two fields:
type and value. Type is one of Percentage= 1, Daily Amount= 2, Fixed Amount= 3, No discount= 4, Pricing Plan= 5, Hidden fixed amount= 6. The field
value, in the case of a Pricing Plan discount, is the ID of the applied pricing plan.

id_channel indicates ids provenience (0 -zero- means WuBook):

1 Expedia
2 Booking.com
3 Hotel.de
4 Itwg
5 InItalia
6 Hotels.com (Expedia)
7 Reserver.it
8 Accomodationz.com
9 HotelBeds
10 Venere.com
11 Hrs.com
12 TravelEurope
13 Atrapalo
14 MBeTravel
15 Escapio
17 BBPlanet
18 Splendia
19 Agoda
20 HostelsClub
21 Lastminute (Sabre)
22 Travelocity (Sabre)
23 Sabre
24 Budgetplaces
25 Orbitz
26 LateRooms
27
28
InToscana
Hostelworld

This list is probably out of date (new channels have been connected). To have an up to date list, use the following procedure: get_channel_symbols(token).

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

It's an easy function. You choose a property (lcode). You choose a range of dates (dfrom, dto). The result is a list of reservations containing only 3 fields: reservation_code, id_channel and status. This function is very useful. By calling it, you can find (fast procedure) a list of reservations you're intersted in. Then, you can call fetch_booking (without the final "s" -not fetch_bookings()) to retrieve details. The optional parameter oncreated (default: true) is used to filter against the creation date (when the reservation has been inserted). By passing a False value, your query is filtered against the arrival date.

fetch_new_bookings(token, lcode, ancillary, mark)

This function retrieves only fresh bookings (reservations not "marked" as fetched). The param mark is used to automatically tag fetched reservations, so that the next call to this function won't return them. If you want this behaviour, use mark= 1. Otherwise, use mark= 0. In this case, reservations are not tagged as fetched. You can tag them later by using the mark_bookings function. Notice that fetch_new_bookings() will never return more than 120 reservations

mark_bookings(token, lcode, reservations)

Tag the reservations identified by the `reservations` param as fetched. Next calls to fetch_new_bookings() won't return them. The `reservations`param is an array of reservation codes.

cancel_reservation(token, lcode, rcode[, reason])

Used to cancel reservations The reservation identified by `rcode`of the property identified by `lcode` will be canceled. Notice it's not possible to cancel OTA reservations. The optional parameter `reason` is used to add a remark -intended as a motivation- for the cancellation.

new_reservation(token, lcode,  dfrom, dto, room, customer, amount [, origin, ccard, ancillary])

Used to insert new reservations. You can see below here the fields details:
  • lcode: property code (ask property to give you its code)
  • dfrom: Arrival date
  • dto: Departure date
  • rooms: a structure composed by {room_id: [room_quantity, board]}, (board can be nb (no board, room only), bb (breakfast), hb (half board), fb (full board), "" (no board) )
  • customer: structure with customer information: lname (last name), fname (first name), email, city, phone, street, country, arrival_hour and notes. The country parameter is the 2-digit country symbol, for example: IT,UK,FR,US,RU and so on.
  • amount: total amount of the reservation
  • origin: your signature: property will see that way that this reservation has been inserted by you. (optional)
  • ancillary:  a data structure with optional info that you want to communicate. (optional)
  • ccard: credit card information fields are cc_exp_year, cc_exp_month, cc_type, cc_cvv, cc_owner and cc_number. See the Credit Card Type section to know how possible values for the cc_type field. The Credit Card CVC code can be optional depending on the settings of the property. The same applies to the credit card itself. (optional)

Chapter 6: Plans Handling

Obviously, WuBook supports multiple pricing plans. In particular, there are two types of Pricing Plans: Intensive and Daily. Probably, from a programming point of view, Daily Pricing Plans are seriously preferrable, because it's easier to manage them. In few words: Intensive Plans allow to specify prices for a range of dates, taking into consideration the day of the week. Daily Plans, instead, allow to manage prices day by day. Our advice is to always use Daily Plans in Wired. It's very easier. 


WuBook supports also Virtual Pricing Plans: they're a percentage/static variations of a specific pricing plan. These plans are (at least currently) always Intenive

Available Generic Procedures: 
  • add_pricing_plan(token, lcode, name[, daily= 1])   
  • del_plan(token, lcode, pid)
  • update_plan_name(token, lcode, pid, name)
  • get_pricing_plans(token, lcode)                             
  • add_vplan(token, lcode, name, pid, dtype, value)       
  • update_plan_rack(token, lcode, pid, rack)  
  • convert_to_daily_plan(token, lcode, pid)
  • add_virtual_plan(token, lcode, name, pid, variation)   DEPRECATED (use add_vplan)
  • mod_virtual_plan(token, lcode, planspercs)               DEPRECATED (use mod_vplans)
  • add_plan(token, lcode, name)                                    DEPRECATED (use add_pricing_plan())
  • get_plans(token, lcode, pid)                                      DEPRECATED (use get_pricing_plans())
Available Procedures for Daily Plans:
  • update_plan_prices(token, lcode, pid, dfrom, prices)               
  • fetch_plan_prices(token, lcode, pid, dfrom, dto[, rooms= []])  
Available Procedures for Intensive Plans (NOT RECOMMENDED FOR WIRED CONNECTORS):
  • mod_vplans(token, lcode, plans)
  • update_plan_periods(token, lcode, pid, periods)
  • delete_periods(token, lcode, pid, delperiods)

add_pricing_plan(token, lcode, name[, daily= 1])

Use this procedure if you want to add a new pricing plan. By default (daily= 1), new pricing plans are daily. This is seriously 
recommended. Daily pricing plans can then be managed with update_plan_prices().

del_plan(token, lcode, pid)

Function that deletes an existing plan.
  • pid: A valid plan ID (integer) as returned by add_pricing_plan() and get_pricing_plans().

update_plan_name(token, lcode, pid, name)

Function that changes the name of an existing plan.
  • pid: A valid plan ID (int)
  • name: Name of the plan (string)

get_pricing_plans(token, lcode, pid, name)

This function returns the list of pricing plans defined for the properties identified by lcode. Each pricing plan is a simple struct 
with, at least, the following fields: id, name, daily (daily= 1 means the plan is a daily pricing plan). If a pricing plan is virtual,
you have 3 additional fields: vpid, variation, variation_type. Vpid is the ID of the linked pricing plan. Variation is a float, the
value of the derivation. Variation_type can be -2, -1, 1, 2 (check add_vplan()).

add_vplan(token, lcode, name, pid, dtype, value)

You can use this function to add a new virtual plan.
  • name: Name of the virtual plan (string)
  • pid: A valid id plan (int, if zero, the virtual plan refers to the WuBook Parity)
  • dtype: The type of variation
  • value: Variation value
The dtype param is used to specify the type of your virtual plan:
  • -2: This plan is a discount. Value is a fixed amount
  • -1: This plan is a discount. Value is a percentage
  • 1: This plan increases prices. Value is a percentage
  • 2: This plan increases prices. Value is a fixed amount

update_plan_prices(token, lcode, pid, dfrom, prices)

Use this function to update the prices of the Daily Pricing Plan identified by pid. Prices is a struct like this:

      prices= {"1": [100, 101, 102], "2": [200, 201, 202]}

By assuming that dfrom= 21/12/2012, by sending this structure you will have price= 100 for day 21/12 and room id= 1. Price= 202 for day 23/12 and room id= 2.
Arrays used for multiple rooms must have the same lenght.

By specifying pid= 0 (zero), you will update the WuBook Parity Rate (Standard WuBook Rate). This happens also in the case this rate has been linked to a pricing plan (in this case, the linked pricing plan will be automatically detected and updated).

The correct xml representation of the previous example is:

  <struct>
    <member>
      <name>1</name>
      <value>
        <array><data>
          <value><int>100</int></value>
          <value><int>101</int></value>
          <value><int>102</int></value>
        </data></array>
      </value>
    </member>
    <member>
      <name>2</name>
      <value>
        ....
      </value>
    </member>
  </struct>

fetch_plan_prices(token, lcode, pid, dfrom, dto[, rooms= []])

Given a pricing plan identified by pid (0 -zero- means WuBook Parity) this function returns the prices of the rooms of the property identified 
by lcode for days included between dfrom and dto dates. If the optional parameter (which is an array) rooms is passed, this function returns
the prices for these rooms only. Notice that pid can identify a virtual pricing plan and it can be 0 (fetching that way the WuBook Parity prices,
which are the default one for the booking engine for example). So, this function allows you to fetch each price defined on wubook for your
property!

mod_vplans(token, lcode, plans)

By calling this function you can change name and/or variation of one or many virtual plans.
  • plans: an array of structs, each one containing the Pland ID, the dtype value and the value of your variation (to understand these parameters, check the add_vplan() function).


update_plan_rack(token, lcode, pid, rack)
Python example: s.update_plan_rack(tok, lcode, planid, {'2': [1,2,3,4,5,6,7]})

This function allows to modify prizes of an existing plan.
  • pid: A valid id plan (int)
  • rack: a struct that contains id rooms and prizes (struct)

convert_to_daily_plan(token, lcode, pid)
Python example: s.convert_to_daily_plan(tok, lcode, planid)

Use this function to convert the Plan identify by pid from the Intensive model to the Daily one

update_plan_periods(token, lcode, pid, periods)
Python example: s.update_plan_periods(token, lcode, planid, [{'dfrom': '21/12/2013', 'dto': '23/12/2013', 'values': {'1234': [1,2,3,4,5,6,7]}}])

By calling this function you can create/modify one or more plan periods.
  • pid: A valid id plan (int)
  • periods: an array of structs, each struct is composed by (date from start, date to end) and prizes (array)


delete_periods(token, lcode, pid, periods)

This function deletes one or more plan's periods.
  • pid: A valid id plan (int)
  • periods: an array of structs: [{'dfrom': '10/12/2020', 'dto': '20/12/2014}]

add_plan(token, lcode, name) DEPRECATED (use add_pricing_plan())

This function creates a new data plan.
  • name: Name of the plan (string)
get_plans(token, lcode, pid) DEPRECATED (use get_pricing_plans())

Function that returns all details of data plans (id, name, rank). If you insert pid, returns only details of relevant plan
  • pid: (Default None), a valid id plan
add_virtual_plan(token, lcode, name, pid, variation) DEPRECATED (use add_vplan)

You can use this function to add a new virtual plan.
  • name: Name of the virtual plan (string)
  • pid: A valid id plan (int)
  • variation: Indicates a percentual variation of the plan (a float number, min -99.9 max 99.9)

mod_virtual_plans(token, lcode, planspercs) DEPRECATED (use mod_vplans)

By calling this function you can change name and/or percentual variation of one or many virtual plans.
  • planspercs: an array of structs, each containing pid and percentual variation of virtual plans(array)

Chapter 7: Restriction Plans

Available Procedures: 
  • rplan_add_rplan(token, lcode, name, compact)
  • rplan_rplans(token, lcode)
  • rplan_del_rplan(token, lcode, rpid)
  • rplan_rename_rplan(token, lcode, rpid, name)
  • rplan_update_rplan_rules(token, lcode, pid, rules)
  • rplan_update_rplan_values(token, lcode, pid, dfrom, values)
  • rplan_get_rplan_values(token, lcode, pid, dfrom, dto, rpids)

rplan_add_rplan(token, lcode, name, compact)

This function creates a new restriction plan. With compact (use 0 or 1) you choose if the rplan has to be compact or granular. This
function returns the ID of the new restriction plan.

rplan_rplans(token, lcode)

This function returns the restriction plans of the given property

rplan_del_rplan(token, lcode, rpid)

To delete a restriction plan

rplan_rename_rplan(token, lcode, name, rpid, name)

To rename a restriction plan.

rplan_update_rplan_rules(token, lcode, rpid, rules)

To update a compact restriction plans, specifying the values of its -static- restrictions. Possible and mandatory values contatined on rules (which is a simple struct)
are min_stay, min_stay_arrival, max_stay, closed, closed_departure. 

With "closed" == 1, you close the room while using closed = "2" you set up the closed_arrival restriction.

rplan_update_rplan_values(token, lcode, rpid, dfrom, values)

This function allows to update granular values for a not-compact restriction plan (daily values). The argument values is a 
complex struct. This is a pseudo code example:

    id_room_1: dayList
    id_room_2: dayList

As you can guess, this function allows to update multiple rooms and multiple days with a unique message. Moreover, it's very powerful,
because it allows to skip some days and to specify different values for each day. Let's make an example for a unique room (the same applies for multiple rooms):

    id_room_1: [ {'min_stay': 3}, {}, {'max_stay': 4}]

In this example, the second day is not updated. Notice that the first one and the third one contains different values. The dfrom argument is obviously
used to identify the beginning of the updates. By using rpid= 0, you will update the WuBook Standard Restrictions

rplan_get_rplan_values(token, lcode, pid, dfrom, dto, rpids)

This function return a daily map of restriction plans. The argument rpids can be one or more restriction plan id, if rpids is not specified, function return all restriction plans.


Chapter 8: WooDoo: Channels Updates

Available Procedures:
  • woodoo_commands_queue(token, lcode)
  • woodoo_suspended_commands(token, lcode)
  • woodoo_executed_commands(token, lcode, date [, id_channel= False])
  • woodoo_cancel_suspended(token, lcode, trackings)
  • woodoo_relaunch_suspended(token, lcode, trackings)
These functions allow you to retrieve and manage updates list, divided by those not yet processed, suspended, or already done.


woodoo_commands_queue(token, lcode)

This function returns the list of updates not yet started. For each update the answer contains the following fields:

Field Description
tracking
Update identification number
node
WooDoo node from which the update will be launched
id_channel
Ids channel
dfrom
Initial date
dto
End date
required
Timestamp from which update has been requested
programmed
Timestamp for next scheduled update launch
attempts
Retries performed until now
last_error
Last error returned by updates attempts


woodoo_suspended_commands(token, lcode)

This function returns the list of suspended updates. For each update the answer contains the following fields:

 Fields Description
 tracking  Update identification number
 node  WooDoo node from which the update has been launched
 id_channel  Ids channel
 dfrom  Initial date
 dto  End date
 required  Timestamp from which update has been requested
 attempts  Retries performed until suspension
 last_error_date  Timestamp for last error
 last_error_txt  Error returned during last update launch


woodoo_executed_commands(token, lcode, day [, id_channel= False])

This function let's you list successfully processed updates commands. the day parameter stands to filter
results by launch date. The optional parameter id_channel filters results to retrieve updates for the given id_channel.
Each update in the returned list contains the following fields:

 Fields Description
 tracking Update identification number
 node WooDoo node from which the update has been launched
 id_chanel Ids channel
 dfrom Initial date
 dto End date
 required Timestamp from which update has been requested
 executed Timestamp of update launch
 time Duration of the update
 last_error Last error returned by updates attempts


woodoo_cancel_suspended(token, lcode, trackings)
woodoo_relaunch_suspended(token, lcode, trackings)

These two functions can be used to manage suspended update commands:
you can respectively cancel or relaunch updates.

  • trackings: Array containing Update identification numbers (this array should contain IDs in string format)

Chapter 9: Corporate handling

Corporate functions allow to list your existing accounts, properties and channels. You can also renew services
by using API.

Corporate functions must be consumed with a "corporate-token", which is a normal token, obtained with corporate credentials.

Available Procedures:
  • corporate_fetch_accounts(token [, acode])
  • corporate_fetch_channels(token, lcode)
  • corporate_get_channels(token [, lcodes= [], dfrom, dto] )
  • corporate_new_property(lodg, woodoo_only, acode)
  • corporate_new_account_and_property(lodg, woodoo_only, account)
  • corporate_renew_booking(token, lcode, months [, pretend= 1])
  • corporate_renew_channels(token, lcode, channels [, pretend= 1])
  • corporate_set_autorenew_wb(token, lcode, v)
  • corporate_set_autorenew_wo(token, lcode, lchans, v)
corporate_fetch_accounts(token [acode])

This function allows you to fetch the list of your accounts and, for each account, the list of his properties, the current number of Coins and the current prepaid balance. 
The optional parameter acode can be used to limit the results to an unique account. This parameter is the Account Code, for example AB001.

corporate_fetch_channels(token, lcode)

Given a property identified by lcode, fetch its channels.

corporate_get_channels(token [, lcodes=[], dfrom, dto])

It's similar to corporate_fetch_channels, but you can specify a date span (dfrom, dto), if a channel expires inside this range, it will be returned, you can also specify a list of lcodes.
If you do not insert lcodes, will be returned all channels of all properties.

corporate_new_property
(token, lodg, woodoo_only, acode)

This function is used to create a new property, assigning it to the (already existing) account identified by the acode parameter (example: AB001).
The woodoo_only model is a boolean value (you can use an integer, 0 or 1). If True, the new property will have a WooDoo Only Model.
The lodg parameter is a struct and the following fields are required: 'name', 'url', 'address', 'zip', 'city', 'phone', 'email', 'country'. In particular,
the country field is the 2-letters identifier of the country (as "ES", "FR", "IT", "US").

The function returns a simple structure containing two parameters: lcode (property code) and acode (which is the same acode you have specified).

corporate_new_account_and_property(token, lodg, woodoo_only, account)

This function is very similar to the previous one, but it's used to create a new property and, at the same time, its owner-account.
Differently by the previous function, you must send account information with a simple struct. Required fields are 'first_name', 'last_name', 
'phone', 'lang', 'email' and 'currency'. For currency, specify the iso code (like EUR or USD or RUB).

The return value of this function is the same of the previous one. In particular, the returned acode is the Account Code assigned by
WuBook to the new account.

corporate_renew_booking(token, lcode, n [, pretend= 1])

This function allows to renew the WuBook service of one property, identified by the `lcode` parameter, for your preferred number
of `months= n`. The renew of the service has a cost in Coins. If you use pretend= 1, the necessary number of coins is returned and
no renewal operation is done. Notice that pretend= 1 is the default value, so, to renew a service, remember to pass pretend= 0.

Important notice: as N, you can use also the following syntax: "10d" (10 days), "1y" (1 year), "3m" (3 months). 
If you specify no unit after the integer, 'm' is assumed.

corporate_renew_channels(token, lcode, channels [, pretend= 1])

Given a property identified by `lcode`, you can programmatically renew its channels. If you use pretend= 1, the necessary number 
of coins is returned and no renewal operation is done. Notice that pretend= 1 is the default value, so, to renew a service, remember 
to pass pretend= 0. The `channels` parameter is a simple struct: {id_channel: n}, where id_channel can be retrieved via
corporate_fetch_channels().

N is a number of months, but you can use also the following syntax: "10d" (10 days), "1y" (1 year), "3m" (3 months). 
If you specify no unit after the integer, 'm' is assumed.

corporate_set_autorenew_wb(token, lcode, autorenew)

Given a property identified by `lcode` you can enable the auto-renew feature for the WuBook service of this property.
If auto-renew is 1, auto-renew will be enabled. If 0, it will be disabled. 

corporate_set_autorenew_wo(token, lcode, channels, autorenew)

Given a property identified by `lcode` and a list of channels (a list of IDs), you can enable the auto-renew feature.
If auto-renew is 1, auto-renew will be enabled. If 0, it will be disabled. Notice that the information about the current
status of the auto-renew parameter is provided by fetch_channels().

Chapter 10: Channels handling (BETA)

If you want to configure Channels (Online Travel Agencies) via Wired, this chapter is for you.
Instead to configure the Rooms/Rates mapping of Booking.com or Expedia inside the WuBook Control Panel, you can specify your settings
with remote calls, programmatically. Some methods are shared between all channels, while other ones are dedicated and channel related.

Before to begin the development of these functions, please, take into consideration the following points:
  • Shared functions can be considered stable and reliable. Eventual changes should be rare.
  • Specific functions for specific channels must be persisntently considered beta. That's because channels specifications change and the relative functions will be changed in a NOT-BACK-COMPATIBLE way. Moreover, they're generally complex (from both technical/logical points of view).
  • Do not require examples!!! If you're not skilled enough with XMLRPC so that you can't guess how messages should be made, altough the provided explanations, and by considering the previous points, please, give up: these functions are probably not for you.
  • Do not require Test Channels. Unfortunately channels do not release persistent test environments and so we cannot provide them. You will have to test these functions with a production environment.
Notice also that for several calls you will need the ctype parameter. The ctype parameter allows to identify the channel type (for example, booking.com= 2). 
Remember you can have the ctype mapping by calling get_channel_symbols(token).

Available Shared Procedures:
  • fetch_otas(token, lcode)
  • tag_ota(token, lcode, chid, tag)
  • new_ota(token, lcode, ctype [,tag])
  • ota_running(token, lcode, chid)
fetch_otas(token, lcode)

This call returns the list of channels inserted for the property identified by lcode. For each channel, you will have the following fields: id, ctype, running, tag.

tag_ota(token, lcode, chid)

Given the property identified by lcode and the channel identified by chid, add a tag (description) for that channel. Description < 256 bytes.

new_ota(token, lcode, ctype [,tag])

Insert a new channel for the property identified by lcode.

ota_running(token, lcode, chid)

Use this function to check if the channel identified by chid is currently and completely configured. And running.

Booking.com Functions

The following functions are booking.com related. You can use them to manage a Booking.com channel. 
Available Procedures:
  • bcom_start_procedure(token, lcode, chid, bhid)
  • bcom_confirm_activation(token, lcode, chid)
  • bcom_init_channel(token, lcode, chid, currency)
  • bcom_rooms_rates(token, lcode, chid)
  • bcom_set_room_mapping(token, lcode, chid, rmap [, singlemap])
  • bcom_set_rate_mapping(token, lcode, chid, rmap)
  • bcom_read_allotments(token, lcode, chid, dfrom, days)
Let's describe these functions. Let's assume you have inserted a booking.com channel. You want now to start the connectivity request. This can be done by calling:

bcom_start_procedure(token, lcode, chid, bhid)

where the bhid parameter is the Booking.com hotel ID. Now, you should contact your account manager to proceed with the activation and when you selects WuBook
as official XML provider, and you confirm it on the Booking.com Extranet, you can call:

bcom_confirm_activation(token, lcode, chid, bhid)

At this point, the channel is ready to be configured. The following call is necessary (but you must launch it only once -and each time your rooms/rates on booking.com will change):

bcom_init_channel(token, lcode, chid, currency)

You can use the 3 letters standard to specify the currency (EUR, USD...). Now, initialization procedures are done. Just wait our confirmation and then you can use:

bcom_rooms_rates(token, lcode, chid, currency)

to understand which rooms/rates are currently present on Booking.com. These rooms and these rates must be mapped to WuBook rooms/rates. To map rooms, you use:

bcom_set_room_mapping(token, lcode, chid, rmap [, singlemap])

rmap is a struct {BookingRoomId: WuBookRoomId, ....}. Singlemap has the same structure and allows to identify the SingleUse mapping (check the WuBook Control Panel to fully understand its meaning). Now that all rooms are mapped, you must call:

bcom_set_rate_mapping(token, lcode, chid, rmap)

Also in this case, rmap is a struct {BookingRateId: WuBookRateId}. Use WuBookRateId= 0 to use the WuBook Parity.

That's all. Now that you have mapped all rooms and all rates, you can check if channel is running with ota_running(token, lcode, chid).

bcom_read_allotments(token, lcode, chid, dfrom, days)

Retrieve allotment information from b.com. days should be less than 31. Retrieved information contains, for each roomId, a list of days. Each day containing the following fields: date, minimumContractedRooms, minimumContractedRoomsUntil, BookedRooms.

Expedia Functions

The following functions are Expedia related. You can use them to manage an Expedia channel. 
Available Procedures:
  • exp_start_procedure(token, lcode, chid, ehid)
  • exp_init_channel(token, lcode, chid, currency, fee, vat_taxes)
  • exp_rooms_rates(token, lcode, chid)
  • exp_set_room_mapping(token, lcode, chid, rmap [, allots])
  • exp_set_rate_mapping(token, lcode, chid, rmap)
As for booking.com, once you have inserted an Expedia channel on WuBook, you need to startup the connectivity request. Do that by calling:

exp_start_procedure(token, lcode, chid, ehid)

where ehid is the Expedia Hotel ID. Now you must send an agreeement to Expedia (you can download it inside the WuBook Control Panel). 
Once the channel will be ready, we will send you and email and you can begin to initialize the channel by calling:

exp_init_channel(token, lcode, chid, currency, fee, vat_taxes)

Currency can be specified with the 3 letters code (EUR, USD...). Fee is the commission percentage required by Expedia. Vat_taxes are the Vat Taxed applied by 
the country of the property for hotel rooms (Italy and France for example apply 10%, in that case specify 10).

Now that the channel has been initialized, you can call:

exp_rooms_rates(token, lcode, chid, currency, fee, vat_taxes)

to discover which rooms/rates are currently present on Expedia. These rooms and these rates must be mapped with WuBook rates and WuBook Rooms.
For rooms, you can use:

exp_set_room_mapping(token, lcode, chid, rmap [,allots])

As for booking.com exp_set_room_mapping(), rmap is a struct having as keys the Expedia Room IDs (as strings) and as values the WuBook Room IDs. The
optional parameter allots is a struct having the same keys of rmap, but, as values, the allotment of each room (check the WuBook Control Panel to better
understand that).

Now that all of the Expedia Rooms are mapped, you have to map the Expedia Rates:

exp_set_rate_mapping(token, lcode, chid, rmap)

also in this case the rmap parameter is a struct having as keys the Expedia Rate IDs and as values the WuBook Rate IDs. Use WuBook Rate Id= 0 for the WuBook Parity.
That's all. Once completely configured, check the channel status by calling ota_running().