Create Booking

## Content - [Postman collection](#postman-collection) - [API Description](#api-description) - [API Parameters](#api-parameters) - [Input Parameters](#input-parameters) - [Output Parameters](#output-parameters) - [Error Codes](#error-codes) - [JSON Samples](#json-samples) - [Request 1](#request-1) - [Response 1](#response-1) - [Response 2](#response-2) ## Postman collection Please download the postman collection, environment and request for API Key to get started. Flight Booking API Collection - Local playground with examples of request/response pairs for each endpoint. Additionally it assist the developers to understand the logical flow for the endpoints. Flight Booking API Environment - Holds the credential information that allows invocation of the endpoints. You can request for the credentials for this specific API [here](/apps/myapps). Request for API key ## API Description | | | | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | API Name | booking/create | | API Type | Update | | API Source | Eretail | | Description | Second call in the aggregated booking flow. Creates a temporary PNR to reserve the inventory. Also starts the first step of 3DS payment by executing the 3DSCheck service (checks whether card has 3DS, and if yes generates the hyperlink html to the bank) | ## API Parameters ### HTTP Headers | Headers | Value | Description | | ------------------ | --------- | ---------------------------------------------------------------------------- | |Content-Type|application/json|| |apikey|*|An active SQ API Key for the FlightBooking Package| ### Input Parameters | Input Parameters | Data Type | Optional | Description | | -------------------------------------------------------- | ------------ | -------- | --------------------------------------------------------------------- | | clientUUID | String | No | Any unique transaction identifier from the consumer’s end | | sessionID | String | No | Value returned by the last call to the booking flow | | pageTicket | String | No | Value returned by the last call to the booking flow | | bookingDetails | JSONObject | No | | | itineraryDetails | JSONObject | No | | | tripType | String | No | (O)neway, (R)eturn, (M)ulti-city | | gbTaxPresent | Boolean | \* | Required if `gbTaxPresent` is true in faresummary response | | firstDepartureDate | String | \* | Required if `gbTaxPresent` is true in the faresummary response | | travellerDetails | JSONObject | No | | | type | String | No | “ADT”, “INF”, “CHD”, “B15” | | title | String | No | | | firstName | String | No | | | lastName | String | No | | | gender | String | No | “M”, “F” | | dateOfBirth | Date | \* | Mandatory for Child and Infant. Format: yyyy-MM-dd | | emailAddress | String | Yes | Mandatory for lead pax | | isLeadPax | Boolean | No | true for exactly one of the adults in the booking | | contactDetails | JSONArray | Yes | Mandatory for lead pax | | type | String | No | “MOBILE”, or “PHONE” | | areaCode | String | Yes | | | countryCode | String | Yes | | | number | String | No | | | infantDetails | JSONObject | Yes | | | title | String | No | | | firstName | String | No | | | lastName | String | No | | | gender | String | Yes | | | dateOfBirth | Date | No | Date Format: yyyy-MM-dd | | additionalRequest | JSONObject | Yes | | | mealCode | String | Yes | | | isRail | String | Yes | | | frequentFlyerDetails | JSONArray | Yes | | | ffpCode | String | No | | | ffpNumber | String | No | | | flightSelectionDetails | JSONObject | \* | Taken from fareSummary response if available | | recommendationId | String | No | | | flightIds | String Array | No | | | paymentDetails | JSONObject | No | | | cardNumber | String | No | Numeric value without text decorators | | cardExpiry | String | No | Date Format: yyyy-MM | | amount | String | No | `totalAmount` in the `fareDetails` of previous response | | bookingFlowType | String | Yes | Defaults to “CIB” for booking | | returnURL | String | No | URL for the bank to redirect after the 3DS exercise | | pointOfSales | String | No | First Board Point value. | | resumeDetails | JSONObject | Yes | Used when we jumpstart to an intermediate call within the aggregator. | | Is usually copied over from a partially failed response | ### Output Parameters | Output Parameters | Data Type | Description | | ----------------------------------------------------------------------------------------------- | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------- | | status | String | “SUCCESS” / “FAILED” | | code | Number | 200 if status is “SUCCESS”. Refer to Section 5 for possible error codes | | message | String | Populated and displayed only if status is “FAILED” | | clientUUID | String | Reflected from request | | response | JSON Object | | | sessionID | String | | | pageTicket | String | | | bookingDetails | JSONObject | | | pnrDetails | JSONObject | | | pnr | String | RecordLocator | | officeId | String | | | fareAmountDifferent-FromPricing | String | True if the price has changed since the `pricing`call | | repricedFareDetails | JSONObject | Returned if above is true. Use these values in subsequent call | | fareAmount | Number | Repriced fare amount for the selection. E.g. 450.00 | | taxAmount | Number | Repriced tax amount for the selection. E.g. 79.40 | | totalAmount | Number | Repriced total amount (fare plus tax) for the selection. E.g. 529.40 | | currency | String | | | insuranceDetails | JSONArray | Details will be present if the insurance is enabled for the country | | providerCode | String | | | productCode | String | | | productName | String | | | totalAmount | String | | | currencyCode | String | | | tncUrl | String | Terms & Conditions | | segmentIdList | String Array | | | travellerDetails | JSONArray | | | travellerID | String | | | type | String | “ADT”, “CHD”, “B15” | | title | String | | | firstName | String | | | lastName | String | | | leadPassenger | String | | | insuranceAmount | String | | | tattooNumber | String | | | priceDetails | JSONArray | Present if `fareAmountDifferentFromPricing` is true. Contains all the necessary info about the new price | | fareAmount | String | | | tax | String | | | totalAmount | String | | | taxList | JSONArray | | | code | String | | | description | String | | | category | String | | | amount | String | | | infantTraveller | JSONObject | Infant Details. Same structure as `travellerDetails` | | travellerID | String | | | type | String | “INF” | | title | String | | | firstName | String | | | lastName | String | | | leadPassenger | String | | | insuranceAmount | String | | | tattooNumber | String | | | priceDetails | JSONArray | Present if price has changed since the `getfare` call. Contains all the necessary info about the new price | | fareAmount | String | | | tax | String | | | totalAmount | String | | | taxList | JSONArray | | | code | String | | | description | String | | | category | String | | | amount | String | | | errorDetails | JSONObject | Present if the pnr could not be successfully created | | code | String | | | message | String | | | paymentDetails | JSONObject | | | enrollmentStatus | String | Whether the card is enrolled for 3DS. Values: CARD_NOT_ENROLLED | | | | CARD_ENROLLED | | | | | CARD_DOES_NOT_SUPPORT_3DS | | | | | AUTHENTICATION_NOT_AVAILABLE | | | orderInfo | String | | | htmlContent | String | The html content that will redirect to the financial entity’s website for 3DS exercise. This is the html content sent by MPGS for SIMPLE mode | | surchargeInfo | JSONObject | Present if the creditcard fee applies to the booking-card combination | | passengerList | JSONArray | Breakdown of the ccsf per passenger | | travellerId | String | Maps to the `travellerDetails`->`travellerID` value | | passengerType | String | “ADT”, “INF”, “CHD”, “B15” | | currencyCode | | String | 3-char currency code | | amount | String | | | totalAmount | String | Total ccsf charged for the booking | | carrierFeeType | String | | | feeCode | String | | | errorDetails | JSONObject | Present if the 3DS flow could not be initiated | | code | String | | | message | String | | | retryRequestDetails | JSONObject | If either of the above fails, this contains the request object to use for the retry | | request | JSONObject | Same structure as the request defined above | | isBookingDetailsRequired | Boolean | Specifies if booking details are to be filled in by the consumer | | isPaymentDetailsRequired | Boolean | Specifies if the payment details are to be filled in by the consumer | ## Error Codes | ErrorCodes | Message | Description | | ------------ | --------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | | BKAGCO0000 | Invalid Request | | | BKAGCO0001 | Invalid ClientID | Internal error that occurs when the caller could not be matched to a known identifier | | BKAGCO0020 | Missing or Invalid expected field: sessionID | | | BKAGCO0021 | Missing or Invalid expected field: pageTicket | | | BKAGCO0022 | Missing or Invalid expected field: travellerDetails. Must be a list with at least one element | | | BKAGCO0023 | Missing or Invalid expected field: passengerType | | | BKAGCO0024 | Missing or Invalid expected field: `title` | | | BKAGCO0025 | Missing or Invalid expected field: firstName | | | BKAGCO0026 | Missing or Invalid expected field: lastName | | | BKAGCO0027 | Missing or Invalid expected field: gender | | | BKAGCO0028 | Missing expected field: dateOfBirth. Compulsory for child and infant | | | BKAGCO0029 | Invalid field value: dateOfBith | | | BKAGCO0030 | Invalid field value: dateOfBith for adult. Must be atleast 12 years old | | | BKAGCO0031 | Invalid field value: dateOfBith for child. Must be between 2 and 11 years old | | | BKAGCO0032 | Invalid field value: dateOfBith for child. Must be between 2 and 11 years old | | | BKAGCO0033 | Missing or Invalid expected field: contactDetails. Must be a list with at least one element | | | BKAGCO0034 | Missing or Invalid expected field: emailAddress | | | BKAGCO0035 | Only Adults can be lead passengers | | | BKAGCO0036 | There must be exactly one leadPassenger | | | BKAGCO0037 | Missing or Invalid expected field: paymentDetails | | | BKAGCO0038 | Missing or Invalid expected field: cardNumber | | | BKAGCO0039 | Missing or Invalid expected field: cardExpiry. Expeted format: yyyy-MM | | | BKAGCO0040 | Missing or Invalid expected field: countryCode. Expected 2-char input | | | BKAGCO0041 | Missing or Invalid expected field: currencyCode. Expected 3-char input | | | BKAGCO0042 | Missing or Invalid expected field: returnUrl | | | BKAGCO0071 | Missing or Invalid expected field: amount | | | BKAGCO0072 | Unsupported airlineCode: ffpCode | | | BKAGCO0073 | Required field `ffpNumber` should be 10 digit numerical value | | | BKAGCO0078 | ffpCode` field is mandatory if `frequentFlyerDetails` field is provided | | | BKAGCO0150 | The sessionID that you have provided has already expired. Please restart the booking flow. | | | BKAGCO0200 | The operation could not be completed at the current moment please try again | | | BKAGCO0300 | The requested booking could not be retrieved from our system | | | BKAGCO0301 | The amount and/or ccChargeAmount in the request did not match the actual fareAmount | | | 9999/9998 | Unknown error occurs. Please contact CSL team for details. | For all errors of unknown origin | | ErrorCodes | Message | Description | | ---------- | -------------------------------------------------------------- | ----------- | | BKAGCR0000 | Exception occurred while creating pnr | | | BKAGCR0050 | Exception occurred while conducting 3dscheck on the creditcard | | | BKAGCR0100 | Exception occurred while retrieving obfees for the creditcard | | | BKAGCR0101 | Booking had GB tax, but was not declared (`gbTaxPresent`) | | | BKAGCR0102 | Booking did not GB Tax, but was wrongly declared (`gbTaxPresent`) | | | BKAGCR0103 | `departureDate` field is missing or the value given in the request does not match the one in the booking. | | | BKAGCR0104 | We are unable to proceed with the booking as we cannot guarantee unaccompanied minor service to or from other airlines' flights on singaporeair.com. Please contact your local Singapore Airlines office for assistance. | When booking has unaccompanied Minor and an OAL segment | | BKAGCR0150 | The requested booking could not be completed. One or more traveller is not a valid KrisFlyer | | | BKAGCR0160 | The requested booking could not be completed. We are not able to validate KrisFlyer at this moment. You can proceed to booking without providing KF details. | | ## JSON Samples ### Request #1 ```json { "clientUUID":"cpn9_6PTlfOtdTbzWzWxOHF0bvQXPAH0JzY5NNw0WOgwJJzLuGjH!1954788836!1528974779347", "bookingDetails":{ "itineraryDetails":{ "gbTaxPresent": "false", "firstDepartureDate": "2019-09-31", "tripType":"O" }, "travellerDetails":[ { "type":"ADT", "title":"Mr", "firstName":"HUY", "lastName":"TRAN", "gender":"M", "emailAddress":"saa_devmail@sqdev.com.sg", "isLeadPax":"true", "contactDetails":[ { "type":"MOBILE", "countryCode":"65", "number":"123456789" } ], "frequentFlyerDetails":[ { "ffpCode":"SQ", "ffpNumber":"8987011938" } ], "infantDetails": { "title":"Ms", "firstName":"THREE", "lastName":"TEST", "gender":"F", "dateOfBirth":"2018-08-03" }, "dateOfBirth":"1991-02-28" }, { "type":"CHD", "title":"Ms", "firstName":"Nguyen", "lastName":"Xuka", "gender":"F", "dateOfBirth":"2010-08-03" } ] }, "flightSelectionDetails": {"recommendationId":"0","flightIds":["0"]}, "paymentDetails":{ "cardNumber":"XXXXXXXXXX1111", "cardExpiry":"2022-01", "amount":"1200.50", "returnURL":"https://google.com?execution=e3s14&_eventId=mp3dssuccess" }, "sessionID":"JSESSIONID=SYaxJc6mpWvjPokq5CwC9wUOVPqkzI-q54yGyFqM1XAjV7v5Zlzw!2083335516!1863978015", "pageTicket":"4" } ``` ### Response #1 ```json { "status":"SUCCESS", "code":"200", "message":"SUCCESS", "clientUUID":"cpn9_6PTlfOtdTbzWzWxOHF0bvQXPAH0JzY5NNw0WOgwJJzLuGjH!1954788836!1528974779347", "response":{ "bookingDetails":{ "pnrDetails":{ "pnr":"K2NWAR", "officeId":"KULSQ08CC", "fareAmountDifferentFromPricing":false, "currency":"MYR", "insuranceDetails":[ { "providerCode":"TGC", "productCode":"STI", "productName":"Travel insurance", "totalAmount":480, "currencyCode":"MYR", "tncUrl":"http://www.google.com/" } ], "travellerDetails":[ { "travellerID":"1", "type":"ADT", "title":"Mr", "firstName":"One", "lastName":"Test", "leadPassenger":true, "insuranceAmount":160, "tattooNumber":"2", "infantTraveller":{ "travellerID":"1", "type":"INF", "title":"Mstr", "firstName":"Three", "lastName":"Test", "leadPassenger":false, "insuranceAmount":160, "tattooNumber":"2" } }, { "travellerID":"2", "type":"CHD", "title":"Miss", "firstName":"TWO", "lastName":"TEST", "leadPassenger":false, "insuranceAmount":160, "tattooNumber":"4" } ], "segmentIdList":[ "1", "2", "3", "4" ] } }, "paymentDetails":{ "enrollmentStatus":"CARD_ENROLLED", "orderInfo":"C1900105831", "htmlContent":"Process Secure Payment
\n" }, "sessionID":"JSESSIONID=SYaxJc6mpWvjPokq5CwC9wUOVPqkzI-q54yGyFqM1XAjV7v5Zlzw!2083335516!1863978015", "pageTicket":"4" } } ``` ### Response #2 ```json { "status":"FAILURE", "code":"BOOKAG0020", "message":"Exception occurred while creating pnr", "clientUUID":"cpn9_6PTlfOtdTbzWzWxOHF0bvQXPAH0JzY5NNw0WOgwJJzLuGjH!1954788836!1528974779347", "response":{ "bookingDetails":{ "errorDetails":{ "code":"BCOMIV0003", "message":"Trip type is invalid." } } } } ```