EggE Bilişim /
Biletbank Hotel Web Services
Technical Overview v1.0 /
Caner Çakmak & Erdal Sivri
04.04.2015

1OVERVIEW

This document is developed to help new clients get ready for integrating Biletbank Web Services as a remote source to their own booking engine. This document also describes the necessary steps for testing and using Biletbank Web Services and is intended to be read by architects and programmers from both service implementers and service consumers.

In order to use the web service, the following URLs must be used :

Web Service URL (Test) :

Web Service URL (PROD) : will be provided after certification

Sample XML Request & Responses :

Static Data FTP :ftp://ftp.biletbank.com/Hotel/

Static Data FTP server contains the following static data for hotel services:

  • Countries (countries.xls)
  • Destinations (destinations.xls)
  • Hotels (hotels.xls)

Together with this document, we provide a sample client in C# (.Net 4.0) that consume the BiletBank service:

  • BiletBankTestClient: This project is a simple command line application that prompts for BiletBank username and password, and executes our main shopping flow from search to finalization.This project cover almost all use cases you need to implement and it is very well-documented.

2SUPPORT

Biletbank Web Services are a mature product, being used by multiple resellers, so a new client is less likely to find a bug with the code. However, when first implementing the solution, clients typically have questions regarding the pricing or need clarification on the XML schema.

The e-mail address is monitored daily during working hours (Mon-Fri 9am-6pm CT). For coding clarification or technology questions at any time, accurately identifying cause, it is important that you include your XML request & responses. All e-mails are responded to within 48 hours or less. Depending on the difficulty of the question, a reply is typically returned within a day if received during office hours.

The types of contacts that should be directed to the XML Support:

  • Questions on how to develop code
  • Requests for help in troubleshooting failed responses
  • Questions regarding the XML flow
  • Questions regarding how an XML message should be formatted and what fields are mandatory or optional
  • Questions concerning why the system is not responding

Important Note: If you get an error from the web service, you should first check the exception message. We have fields called HasError and ServiceError in all our responses. We kindly ask you to state the SessionId in your error e-mails to our IT team. You can get the SessionId from theAuthenticationHeaderreturned to you by the Login method.

3SECURITY

Biletbank Solutions provide a world-class hosting and security model. In order to ensure your companies’ security and the security of others, for XML, we require your static globally unique address(GUA/IP address) on the internet. This address will be used to identify your company and its associated network use within our infrastructure.

Your source address will also be provisioned accordingly as your company progresses through the environments from test to production. We do not allow dynamically allocated address ranges into secure areas at this time.

4AUTHENTICATION

In order to use web service methods, it is required to authenticate first. For this, Biletbank provides theLogin method. A sample request for theLogin method is as follows:

T_LoginRequest authRequest = newT_LoginRequest()

{

Form = newT_LoginForm()

{

Username = "John", // [Required] Username provided by BiletBank

Password = "secret", // [Required] Password provider by BiletBank

ClientIP = "", // [Optional] IP address of your client

ClientName = "My B2C Client", // [Optional] Name for your client

IsTestMode = true, // [Required] Reservations/bookings/CCpayments are not live

}

};

ClientIP and ClientName fields are optional. Username,Passwordand IsTestModefields are mandatory. You have to set the first two fields with your own username and password provided by Biletbank. The last field, IsTestMode, is very important since it determines whether reservations, bookings and CC paymentswill be real or not. If you set this field to true, reservations, bookings and CC payments you will make will not be real; we will just create a random booking code and ticket numbers for your product. You can use the following card for test payments:

  • Card Holder: Test User
  • Expiry Date: 12/2022
  • Card Number: 1111-1111-1111-1111
  • Secret Code: 111

If IsTestMode is set to false, all operations will be live and real. This means, reservations and bookings you make will be real and need to be canceled as soon as possible. You are expected to cancel your test bookings after 5-10 minutes. You are also expected to do your real tests in weekdays (Monday to Friday) between 9:00 to 17:00. Failure to cancel/void your bookings will result in charges unfortunately. Do not make a reservation or booking sooner than two/three months and make sure you take extra care to check cancellation policies, which are returned from our web service methods.

The Login method returns an AuthenticationHeader so that you can use it while calling other web service methods. Simply, an AuthenticationHeader contains the ID of your session (SessionId) and a token (SessionToken). These two required to identify yourself to the web service. As mentioned above, in Section-2 (Support), you also need the SessionId to report errors to us.

5FLOWCHART

Below is the flowchart diagram of Biletbank web services. It helps you to understand the Biletbank’s basic booking mechanism. You have to call web service methods according to the order shown in the flowchart diagram.

It is the common flowchart for all product types, Flight, Hotel, and Car. You should follow the flow as shown below because it shows the order of methods. Basically, there are 6 steps to book a product and these steps are Search (Air, Hotel and Car Search), Allocate, UpdatePassengers, MakePrebooking, Payment Methods (MakePayment_FromRunningAccount, MakePayment_FromCreditCard, MakePayment_Init3DPayment) and FinalizeShopping respectively. We strongly recommend you to check the flowchart of Biletbank web services and make your integration according to this flowchart.

6METHODS

We have grouped Biletbank’s web service methods to provide a better understanding. In this section, we have explained search methods, common methods and shopping file methods. Search methods contain Air, Hotel and Car queries; Shopping methods contain the required methods to book a product or make a reservation.

6.1SEARCH

In Biletbank hotel search method, we query our providers to fetch their data and then integrate and harmonize all the data at our back end and then give the results back to you immediately.

Biletbankenables you to search hotels from several. Biletbank brings such providers’ data together and shows all search results within Biletbank’s own entities. This way, you will have access to a wide range of data from several providers within the same interface.

In order to search hotels with Biletbank Web Services, you must use HotelSearch web service method. To call HotelSearch method, it should be beneficial to know the following information:

  • Biletbank supports for searching passengers with different types.

PaxItems
Name / Code (string)
Adult (between ages 12 - 65) / ADT
Child (between ages 2 - 12) / CHD
  • Two-letter nationality codes are required. You can determine usernationalityusing the IP address of the client.

Here is an example Hotel Search Request that searches for all available hotels in Istanbul/Turkey 60 days from now. It searches for two rooms, one with 2 adults, the other with 2 adult and 1 child aged 8.

IO_HotelSearchRequest searchRequest = newIO_HotelSearchRequest()

{

AuthenticationHeader = authenticationHeader,

CreateNewShoppingFile = false,

Form = newIO_HotelSearchForm()

{

searchRequest = newHotelSearchRequest()

{

// Set this to true if you want to retrive hotel results divided into

// chunks/pages.

// Set to false if you want all results in a single query.

IfResultPerPageSpecified = false,

// How many hotel results do you want in a single page?

// If IfResultPerPageSpecified to false, this has no effect.

ResultsPerPage = 5000,

// Which page do you want?

// If IfResultPerPageSpecified to false, this has no effect.

ActivePageIndex = 1,

CheckInDate = DateTime.Now.AddDays(60).Date,

CheckOutDate = DateTime.Now.AddDays(65).Date,

// Which destinations you want to search for?

// You need to specify the Id's of destinations, which are provided as

// static data.1639 is the Id of Istanbul/Turkey.

DestinationIdList = newstring[] { "1639" },

// Set if desired to search a specific hotel. You can find the Id's of hotels

// in the static data provided.

HotelId = null,

// Always set to TR

Language = "TR",

// This is important because some hotels require guests' nationality.

// This can also affect prices.

// You can determine the nationality of a customer using its IP address,

// which you can translate to country using a GeoIP database.

Nationality = "TR",

// Set true if you want the summary texts of hotels.

// If you already have summary texts for hotels, set this to false to

// avoid extra traffic.

ifSummaryTextSpecified = false,

// Set true if you want short descriptions of hotels.

// If you already have descriptions for hotels, set this to false to avoid

// extra traffic.

IfShortDescriptionSpecified = false,

// Set this to true if you want to restrict the number of rooms returned

// per hotel.

ifMaxHotelOptionGroupSpecified = true,

// You can specify a limit of rooms for each hotel by using the

// MaxHotelOptionGroupCount field.

// If you limit the number of rooms, cheapest ones will be returned.

// Setting ifMaxHotelOptionGroupSpecified to true and

// MaxHotelOptionGroupCount to 1 will reduce the size of the response to the

// minimum. You can always call GetHotelDetail method to retrieve

// all rooms of a hotel.

MaxHotelOptionGroupCount = 1,

// Fill in your room options.

RoomList = newHotelRoom[]

{

// We are searching for two rooms one with 2 adults,

// the other with 2 adult and 1 child aged 8.

newHotelRoom()

{

AdultCount = 2,

},

newHotelRoom()

{

AdultCount = 2,

ChildCount = 1,

ChildAgeList = newint[] { 8 },

},

},

},

}

};

The response of Hotel Search contains array of hotels, which contain room options. Each room options has a separate price, which is consisted of the following fare components:

  • TotalFare: Total fare of the room option for all guests.
  • Taxes: Total taxes of the room option for all guests.
  • ServiceFee:
  • LastSellerCommission:
  • PublishedPrice:

CASE 1:

In the results, if IfMinSellingPriceSpecified is true, the sales amount will be PublishedPrice.

In this case;

Your cost: TotalFare-LastSellerCommission

Your profit: PublishedPrice-(Totalfare-LastSellerCommission)

And this means your profil equals to (PublishedPrice – Your cost).

But there is a remerkable point in the above case. You should send your profit in allocate method like as [PublishedPrice - (TotalFare- LastSellerCommission) ] without making any modification . There is an example of allocate method in AllocateRequestResponse.zip folder.

The reason of this is due to the minimum sales amount rule of some hostels. According to this sales amount rule, you should increase your profit margin with using b2c systems. Because of this, the above case is used in the system. In normal situations, if you enter from your b2c screen (acente.biletbank.com), you should see the prices are lower as TotalFare.

CASE 2:

If IfMinSellingPriceSpecified field is false, sales amount will be TotalFare.

In this case;

Your cost: TotalFare- LastSellerCommission

Your profit: LastSellerCommission

If IfMinSellingPriceSpecified is false, you shoul modify your profit margin whatever you want includes putting zero in profit margin. If you set profit as zero in the allocate method, you should update the system while showing the price in search.

For example, In search phase if the sales amount is shown as (TotalFare-LastSellerCommission) and in allocate phase if you set the profit as zero, you will be selling as your cost price. Negative values are not set. If you do not make any modification, LastSellerCommission should be set.

6.2SHOPPING

These methods are shared by Air, Hotel and Car modules. We call these methods for each product. To proceed for booking of a Biletbank product, these methods have to be called after search methods, respectively.

6.2.1Allocate

Allocate method is called right after search methods. It should be set Ids of products that will be allocated to the request of Allocate method. A basicAllocate request is as follows.

IO_AllocateRequest allocateRequest = newIO_AllocateRequest()

{

AuthenticationHeader = authenticationHeader,

Form = newIO_AllocateForm()

{

SelectedItems = newIO_AllocationItem[1]

{

newIO_AllocationItem()

{

ProductId = roomOption.ProductId,

SelectedServiceFee = roomOption.Items.Select(

hotelRoom =>newIO_ProductItemServiceFee

{

ProductItemId = hotelRoom.ProductItemId,

Amount = hotelRoom.LastSellerCommission

}).ToArray();

}

}

}

};

To allocate HotelOption, you have to set each roomItems serviceFees.

Like it is said before, HotelOption has flexible service fee amount and you have to set service fee to the SelectedServiceFee field in the request of Allocate method.

It is strongly recommended you to check the response of Allocate method and use the ids and fares thereafter.

6.2.2UpdatePassengers

UpdatePassengers method serves the purpose of setting passenger information. Before calling of MakePrebooking method, it is necessary to set all passenger data. It should be set Ids of products and passenger basic information to the request of UpdatePassengers.

Points to take into consideration while requesting for UpdatePassengers:

  • Birth Date should be in “yyyy-MM-dd” format.
  • Each shopping file must have a contact passenger, therefore it is mandatory to set IfContact field as true for one passenger. That is, there must be only one passenger as contact.
  • Gender field can take two values. One is “M” for male passengers and the other one is “F” for female passengers.
  • Biletbank hotel supports two passenger types such as adult(ADT) and child(CHD) so Type field can take value among these two.
  • FirstName and LastName fields should contain only letters. It should not be set any number and space characters to these fields.
  • TempTag field should be set with the value of PaxReferenceId in the response of Allocate method.

6.2.3MakePrebooking

MakePrebooking method is used to make reservations or bookings."Reservation functionality"may not be available depending on several factors. However, you always have to call this method.

IO_MakePrebookingRequest preBookingRequest = newIO_MakePrebookingRequest()

{

AuthenticationHeader = authenticationHeader,

Form = newIO_MakePrebookingForm()

{

ProductIds = allocateResponse.LastAllocatedProductIds

}

}

“allocateResponse” is the result of the Allocate method, which should be called before the MakePrebooking method.

The basic thing to request for MakePrebooking is to set IDs of products allocated to the field ProductIds.You should check BookingCode field in the response of MakePrebooking, if BookingCode field is empty, then you must continue to instant booking.

6.2.4Payment Methods

Biletbank has three options for payments. Two of them are related to payments via credit card and the other one is related to running account. These methods are explained in detail below.

6.2.4.1MakePayment_FromRunningAccount

Biletbank creates running account for each client and this method is used to pay total amount of products from client's running account created at our end.To request for MakePayment_FromRunningAccount method, the following fields are needed to be set: ShoppingFileId, Amountand Currency. A basic request is as follows.

IO_MakeRunningAccountPaymentRequest runningAccountPaymentRequest = newIO_MakeRunningAccountPaymentRequest()

{

AuthenticationHeader = authenticationHeader,

PaymentForm = newIO_MakeRunningAccountPaymentForm()

{

ShoppingFileId = shoppingFile.Id,

Amount = shoppingFile.RemainingSum,

Currency = shoppingFile.Currency,

PaymentType = MakeRunningAccountPaymentType.PERIOD_BALANCE_PAYMENT

},

// This field is used to deduct your commission earning from the total amount.

// If you do not deduct your commission, the money will be transfered to your

// invoice pool, which you can use to buy tickets later using the

// MakeRunningAccountPaymentType.INVBALANCE_PAYMENT flag for PaymentType above.

// If you do deduct your commission, the total amount of the product will be

// less than the original: (Original - YourCommissionEarning)

DeductLastSellerCommission = false,

};

Depending on your agrement with BiletBank, you need to choose among the following options for the PaymentType field. Note that you may not have permission to use some or none of them.

  1. RA_BALANCE_PAYMENT: Obsolete as of January 1st 2014.
  2. CCBALANCE_PAYMENT: You can transfer money to your CC pool using the BiletBank web interface and then you can use the money in this pool to pay for your products.
  3. MTBALANCE_PAYMENT: You can do a money transfer to BiletBank, which you can use to buy products.
  4. INVBALANCE_PAYMENT: When you purchase products in BiletBank system, you will earn commissions (unless the DeductLastSellerCommission is set to true), which you can use to buy products.
  5. PERIOD_BALANCE_PAYMENT: If you agreed with BiletBank on a buy-now-pay-later schema, you can use this flag. Your account will be billed with the amount of the product, which you will pay in periods of week or month
  6. VIRTUAL_PAYMENT: If you have your own providers integrated to the BiletBank system, you have to use this payment type to purchase your products. Since the product belongs to you, we will not charge you for the base fare and taxes(most likely, we will charge a transaction fee). This payment type is also referred to as provider payment: PROVIDER_PAYMENT.
  7. UP_LIMIT_POOL: This field is not used for now. You will get an error if you try to make the payment with this option.

You can get the total amount of products by RemainingSum field in ShoppingFile.

6.2.4.2MakePayment_FromCreditCard, MakePayment_Init3DPayment

Payments via credit card can be done by two methods, MakePayment_FromCreditCard and MakePayment_Init3DPayment. Before calling of these methods, you should set credit card info correctly and please be sure that all informationis true.

Requests are same for both methods, the only difference is that you have to set a "return url" for 3D Payment. We should know the url of your client after calling of MakePayment_Init3DPayment.Basic request for MakePayment_FromCreditCard is as follows.

IO_MakeCreditCardPaymenRequest creditCardPaymentRequest = newIO_MakeCreditCardPaymenRequest()

{

AuthenticationHeader = authenticationHeader,

PreAuthForm = newIO_MakeCreditCardPayment_PreauthForm()

{

BillingName = "JONATHAN MYER",

CardHolder = "JONATHAN MYER",

CardNumber = "1111111111111111",

CardType = "Visa",

CV2 = "111",

ExpirationYear = 18,

ExpirationMonth = 2,

ShoppingFileId = shoppingFile.Id,

OriginalAmount = shoppingFile.RemainingSum,

Amount = shoppingFile.RemainingSum, // Without Installment

Currency = shoppingFile.Currency