- TravelPort Universal API
- PHP 4 or 5
- cURL
An article on how to resolve errors and setup a standard ping request using the TravelPort Universal API. This is to be achieved using PHP as the server-side programming language and cURL, a sub-component of PHP that allows you to send and receive requests as the server (as opposed to the client device).
Why?
Yes there's documentation online that TravelPort provide you with but it didn't help. The error I'm going to address has to do with getting the latest schemas but as I couldn't find anything using Google regarding these errors or how to set up a basic ping request, I thought I'd write this article.
How?
Using PHP and cURL, here is the full script for a standard ping request. Before you say it doesn't work, it has to be updated every time a new schema is introduced to the system. See my errors section for how you can resolve this.
copyraw
<?php /* * Language: English * Author: J. Lipman * Website: www.joellipman.com * Copyright: Copyright (C) 2015 Joellipman.Com * License: GNU/GPL http://www.gnu.org/copyleft/gpl.html * * uAPI sample communication in php language * * This example requires the cURL library to be installed and working. * * This code is for illustration purposes only. * IMPORTANT: The SOAP envelope variables are case sensitive, be consistent! */ // setup up access credentials $api_username = 'uAPI##########-########'; // set to your given username for the API here $api_password = 'S.....................Z'; // set to your given password for the API here $credentials = 'Universal API/'.$api_username.':'.$api_password; // prefix with "Universal API/" and separate with a colon $credentials_64 = base64_encode($credentials); // encode for basic authentication // pick a regional API - here we are using Europe/Middle East/Africa $api_url_emea = 'https://emea.universal-api.pp.travelport.com/B2BGateway/connect/uAPI/'; $api_url_emea_sys = $api_url_emea.'SystemService'; $api_url_emea_urs = $api_url_emea.'UniversalRecordService'; // set to the TargetBranch provided by Travelport. $target_branch = 'P108131'; // here is the basic ping request message XML // Note the namespace schemas used (try to use most recent) $this_message_xml = <<<EOM <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <soapenv:Header/> <soapenv:Body> <sys:PingReq TraceId="test" xmlns:sys="http://www.travelport.com/schema/system_v9_0" xmlns:com="http://www.travelport.com/schema/common_v28_0"> <com:BillingPointOfSaleInfo OriginApplication="UAPI"/> <sys:Payload>this is a test for testing</sys:Payload> </sys:PingReq> </soapenv:Body> </soapenv:Envelope> EOM; // Initialize the CURL object with the uAPI endpoint URL (in this case the SystemService) $soap_do = curl_init ($api_url_emea_sys); // This is the header of the request $header = array( 'Content-Type: text/xml;charset=UTF-8', 'Authorization: Basic '.$credentials_64, 'Accept: gzip,deflate', 'User-Agent: Travelport uAPI Test', 'Cache-Control: no-cache', 'Pragma: no-cache', 'Connection: Keep-Alive', 'Host: emea.universal-api.pp.travelport.com', 'Content-length: ' . strlen($this_message_xml), ); // set the cURL options curl_setopt($soap_do, CURLOPT_VERBOSE, 1); // For debugging purposes (read CURL manual for nore info) curl_setopt($soap_do, CURLOPT_CONNECTTIMEOUT, 30); // Timeout options curl_setopt($soap_do, CURLOPT_TIMEOUT, 30); // Timeout options curl_setopt($soap_do, CURLOPT_SSL_VERIFYPEER, 0); // Verify nothing about peer certificates curl_setopt($soap_do, CURLOPT_SSL_VERIFYHOST, 0); // Verify nothing about host certificates curl_setopt($soap_do, CURLOPT_POST, 1 ); // Sending post variables curl_setopt($soap_do, CURLOPT_POSTFIELDS, $this_message_xml); // Post variable being sent (The XML request) curl_setopt($soap_do, CURLOPT_HEADER, 0 ); // Omit headers (enable these during testing - malformed XML but more info) curl_setopt($soap_do, CURLOPT_RETURNTRANSFER, 1 ); // curl_exec function will show the response directly on the page (if set to 0 curl_exec function will return the result) curl_setopt($soap_do, CURLOPT_HTTPAUTH, CURLAUTH_ANY); // Authentication is BASIC but we'll put ANY just to make it work // curl_setopt($soap_do, CURLOPT_USERPWD, $credentials_64); // The credentials username:password (not used in my example) curl_setopt($soap_do, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1); // TLS version to use (1.0) curl_setopt($soap_do, CURLOPT_PORT, 443); // SSL port to use (443) curl_setopt($soap_do, CURLOPT_HTTPHEADER, $header); // Headers sent to the server $ch_result = curl_exec($soap_do); // Store the results in a cURL handle // Check for errors and show them instead if (curl_errno($soap_do) != '') { $ch_result = curl_errno($soap_do) . ' - ' . curl_error($soap_do) . '<br/>'; } curl_close($soap_do); // Print cURL result (XML) echo $ch_result; ?>
- <?php
- /*
- * Language: English
- * Author: J. Lipman
- * Website: www.joellipman.com
- * Copyright: Copyright (C) 2015 Joellipman.Com
- * License: GNU/GPL http://www.gnu.org/copyleft/gpl.html
- *
- * uAPI sample communication in php language
- *
- * This example requires the cURL library to be installed and working.
- *
- * This code is for illustration purposes only.
- * IMPORTANT: The SOAP envelope variables are case sensitive, be consistent!
- */
- // setup up access credentials
- $api_username = 'uAPI##########-########';  // set to your given username for the API here
- $api_password = 'S.....................Z';  // set to your given password for the API here
- $credentials = 'Universal API/'.$api_username.':'.$api_password;  // prefix with "Universal API/" and separate with a colon
- $credentials_64 = base64_encode($credentials);  // encode for basic authentication
- // pick a regional API - here we are using Europe/Middle East/Africa
- $api_url_emea = 'https://emea.universal-api.pp.travelport.com/B2BGateway/connect/uAPI/';
- $api_url_emea_sys = $api_url_emea.'SystemService';
- $api_url_emea_urs = $api_url_emea.'UniversalRecordService';
- // set to the TargetBranch provided by Travelport.
- $target_branch = 'P108131';
- // here is the basic ping request message XML
- // Note the namespace schemas used (try to use most recent)
- $this_message_xml = <<<EOM
- <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
- <soapenv:Header/>
- <soapenv:Body>
- <sys:PingReq TraceId="test"
- xmlns:sys="http://www.travelport.com/schema/system_v9_0"
- xmlns:com="http://www.travelport.com/schema/common_v28_0">
- <com:BillingPointOfSaleInfo OriginApplication="UAPI"/>
- <sys:Payload>this is a test for testing</sys:Payload>
- </sys:PingReq>
- </soapenv:Body>
- </soapenv:Envelope>
- EOM;
- // Initialize the CURL object with the uAPI endpoint URL (in this case the SystemService)
- $soap_do = curl_init ($api_url_emea_sys);
- // This is the header of the request
- $header = array(
- 'Content-Type: text/xml;charset=UTF-8',
- 'Authorization: Basic '.$credentials_64,
- 'Accept: gzip,deflate',
- 'User-Agent: Travelport uAPI Test',
- 'Cache-Control: no-cache',
- 'Pragma: no-cache',
- 'Connection: Keep-Alive',
- 'Host: emea.universal-api.pp.travelport.com',
- 'Content-length: ' . strlen($this_message_xml),
- );
- // set the cURL options
- curl_setopt($soap_do, CURLOPT_VERBOSE, 1);  // For debugging purposes (read CURL manual for nore info)
- curl_setopt($soap_do, CURLOPT_CONNECTTIMEOUT, 30);  // Timeout options
- curl_setopt($soap_do, CURLOPT_TIMEOUT, 30);  // Timeout options
- curl_setopt($soap_do, CURLOPT_SSL_VERIFYPEER, 0);  // Verify nothing about peer certificates
- curl_setopt($soap_do, CURLOPT_SSL_VERIFYHOST, 0);  // Verify nothing about host certificates
- curl_setopt($soap_do, CURLOPT_POST, 1 );  // Sending post variables
- curl_setopt($soap_do, CURLOPT_POSTFIELDS, $this_message_xml);  // Post variable being sent (The XML request)
- curl_setopt($soap_do, CURLOPT_HEADER, 0 );  // Omit headers (enable these during testing - malformed XML but more info)
- curl_setopt($soap_do, CURLOPT_RETURNTRANSFER, 1 );  // curl_exec function will show the response directly on the page (if set to 0 curl_exec function will return the result)
- curl_setopt($soap_do, CURLOPT_HTTPAUTH, CURLAUTH_ANY);  // Authentication is BASIC but we'll put ANY just to make it work
- // curl_setopt($soap_do, CURLOPT_USERPWD, $credentials_64); // The credentials username:password (not used in my example)
- curl_setopt($soap_do, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);  // TLS version to use (1.0)
- curl_setopt($soap_do, CURLOPT_PORT, 443);  // SSL port to use (443)
- curl_setopt($soap_do, CURLOPT_HTTPHEADER, $header);  // Headers sent to the server
- $ch_result = curl_exec($soap_do);  // Store the results in a cURL handle
- // Check for errors and show them instead
- if (curl_errno($soap_do) != '') {
- $ch_result = curl_errno($soap_do) . ' - ' . curl_error($soap_do) . '<br/>';
- }
- curl_close($soap_do);
- // Print cURL result (XML)
- echo $ch_result;
- ?>
Errors/Issues
Error: 401 Unauthorized: Obvious really, check your username and password are prefixed by the "Universal API/" (note the space) and that the they are encoded to base64:
copyraw
HTTP/1.1 401 Unauthorized Content-Type: text/xml;charset=ISO-8859-1 WWW-Authenticate: Basic realm="AXIS" Date: Fri, 24 Apr 2015 11:46:36 GMT Server: Datapower XI52 X-Backside-Transport: FAIL FAIL Connection: close Vary: Accept-Encoding <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <SOAP-ENV:Body> <SOAP-ENV:Fault> <SOAP-ENV:faultcode>76</SOAP-ENV:faultcode> <SOAP-ENV:faultstring> Authentication Result Error Message Response (76): Authentication credentials are invalid. </SOAP-ENV:faultstring> <SOAP-ENV:faultactor></SOAP-ENV:faultactor> <SOAP-ENV:detail> Authentication Result Error Message Response (76): Authentication credentials are invalid. </SOAP-ENV:detail> </SOAP-ENV:Fault> </SOAP-ENV:Body> </SOAP-ENV:Envelope> --> Solution: Credentials need base64_encode with prefix "Universal API/" and windows authentication header has to exist
- HTTP/1.1 401 Unauthorized
- Content-Type: text/xml;charset=ISO-8859-1
- WWW-Authenticate: Basic realm="AXIS"
- Date: Fri, 24 Apr 2015 11:46:36 GMT
- Server: Datapower XI52
- X-Backside-Transport: FAIL FAIL
- Connection: close
- Vary: Accept-Encoding
- <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <SOAP-ENV:Body>
- <SOAP-ENV:Fault>
- <SOAP-ENV:faultcode>76</SOAP-ENV:faultcode>
- <SOAP-ENV:faultstring>
- Authentication Result Error Message Response (76): Authentication credentials are invalid.
- </SOAP-ENV:faultstring>
- <SOAP-ENV:faultactor></SOAP-ENV:faultactor>
- <SOAP-ENV:detail>
- Authentication Result Error Message Response (76): Authentication credentials are invalid.
- </SOAP-ENV:detail>
- </SOAP-ENV:Fault>
- </SOAP-ENV:Body>
- </SOAP-ENV:Envelope>
- --> Solution: Credentials need base64_encode with prefix "Universal API/" and windows authentication header has to exist
Error: 400 Bad Request: Not sure on this one, but found that I can replicate the error if I create invalid namespaces in the sent XML:
copyraw
HTTP/1.1 400 Bad Request Content-Type: text/xml;charset=ISO-8859-1 Date: Sat, 25 Apr 2015 11:00:59 GMT Server: Datapower XI52 X-Backside-Transport: FAIL FAIL Connection: close Vary: Accept-Encoding <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <SOAP-ENV:Body> <SOAP-ENV:Fault> <SOAP-ENV:faultcode>400</SOAP-ENV:faultcode> <SOAP-ENV:faultstring>TPGateway - Request data not found - Request ignored - service name = UniversalRecordService username = Universal API/uAPI##########-########</SOAP-ENV:faultstring> <SOAP-ENV:faultactor> </SOAP-ENV:faultactor> <SOAP-ENV:detail>TPGateway - Request data not found - Request ignored - service name = UniversalRecordService username = Universal API/uAPI##########-########</SOAP-ENV:detail> </SOAP-ENV:Fault> </SOAP-ENV:Body> </SOAP-ENV:Envelope> --> Solution: Correct Bad Namespace in XML
- HTTP/1.1 400 Bad Request
- Content-Type: text/xml;charset=ISO-8859-1
- Date: Sat, 25 Apr 2015 11:00:59 GMT
- Server: Datapower XI52
- X-Backside-Transport: FAIL FAIL
- Connection: close
- Vary: Accept-Encoding
- <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <SOAP-ENV:Body>
- <SOAP-ENV:Fault>
- <SOAP-ENV:faultcode>400</SOAP-ENV:faultcode>
- <SOAP-ENV:faultstring>TPGateway - Request data not found - Request ignored - service name = UniversalRecordService username = Universal API/uAPI##########-########</SOAP-ENV:faultstring>
- <SOAP-ENV:faultactor> </SOAP-ENV:faultactor>
- <SOAP-ENV:detail>TPGateway - Request data not found - Request ignored - service name = UniversalRecordService username = Universal API/uAPI##########-########</SOAP-ENV:detail>
- </SOAP-ENV:Fault>
- </SOAP-ENV:Body>
- </SOAP-ENV:Envelope>
- --> Solution: Correct Bad Namespace in XML
Error: Invalid API schema ...: I spent a weekend on fixing this but if you take what it says, it's implying that you are using an obsolete schema (perhaps from code taken from the official tutorials which also happen to be out-of-date), fix this and the next time you try, your script should work:
copyraw
HTTP/1.1 200 OK X-Backside-Transport: OK OK Connection: Keep-Alive Transfer-Encoding: chunked X-Powered-By: Servlet/3.0 SSLTerm: 216.113.131.97%3A443%2C%2FCF-COM_API%2FEMEA.UNIVERSAL-API.PP_443 Content-Type: text/xml Content-Language: en-US Date: Fri, 24 Apr 2015 14:33:26 GMT X-Client-IP: 10.7.224.40 X-Global-Transaction-ID: 145009361 passwordEndDt: 20150803 Vary: Accept-Encoding <SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/"> <SOAP:Body> <SOAP:Fault> <faultcode>Server.InvalidRequestException</faultcode> <faultstring> Invalid API schema system_v8_0</faultstring> <detail> <ErrorInfo> <Code>1000</Code> <Service>WEBSVC</Service> <Type>Data</Type> <Description>Validation failed on request message.</Description> <TransactionId>FA54B21F0A07647783DB44DE48C8BB61</TransactionId> </ErrorInfo></detail> </SOAP:Fault> </SOAP:Body> </SOAP:Envelope> --> Solution: Invalid WSDL, use latest, eg. http://www.travelport.com/schema/system_v9_0
- HTTP/1.1 200 OK
- X-Backside-Transport: OK OK
- Connection: Keep-Alive
- Transfer-Encoding: chunked
- X-Powered-By: Servlet/3.0
- SSLTerm: 216.113.131.97%3A443%2C%2FCF-COM_API%2FEMEA.UNIVERSAL-API.PP_443
- Content-Type: text/xml
- Content-Language: en-US
- Date: Fri, 24 Apr 2015 14:33:26 GMT
- X-Client-IP: 10.7.224.40
- X-Global-Transaction-ID: 145009361
- passwordEndDt: 20150803
- Vary: Accept-Encoding
- <SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/">
- <SOAP:Body>
- <SOAP:Fault>
- <faultcode>Server.InvalidRequestException</faultcode>
- <faultstring> Invalid API schema system_v8_0</faultstring>
- <detail>
- <ErrorInfo>
- <Code>1000</Code>
- <Service>WEBSVC</Service>
- <Type>Data</Type>
- <Description>Validation failed on request message.</Description>
- <TransactionId>FA54B21F0A07647783DB44DE48C8BB61</TransactionId>
- </ErrorInfo></detail>
- </SOAP:Fault>
- </SOAP:Body>
- </SOAP:Envelope>
- --> Solution: Invalid WSDL, use latest, eg. http://www.travelport.com/schema/system_v9_0
The Real Fix
I solved this by downloading all the WSDL schema files from the TravelPort at https://support.travelport.com/webhelp/uapi/uAPI.htm#Getting_Started/Universal_API_Schemas_and_WSDLs.htm%3FTocPath%3DGetting%2520Started%7CGetting%2520Connected%7C_____2. I then noticed that the system schema I was using was v8_0 based on the documentation "getting started" was obsolete and the current version was in fact "system_v9_0"... changing this fixed it for me.
Additional Info:
Category: API Miscellaneous :: Article: 607