TravelPort Universal API - Ping Request with PHP-cURL

Applies to:
  • TravelPort Universal API
  • PHP 4 or 5
  • cURL
What?
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;

?>
  1.  <?php 
  2.  /* 
  3.  *    Language:  English 
  4.  *    Author:    J. Lipman 
  5.  *    Website:   www.joellipman.com 
  6.  *    Copyright: Copyright (C) 2015 Joellipman.Com 
  7.  *    License:   GNU/GPL http://www.gnu.org/copyleft/gpl.html 
  8.  * 
  9.  *    uAPI sample communication in php language 
  10.  * 
  11.  *    This example requires the cURL library to be installed and working. 
  12.  * 
  13.  *    This code is for illustration purposes only. 
  14.  *    IMPORTANT: The SOAP envelope variables are case sensitive, be consistent! 
  15.  */ 
  16.   
  17.  // setup up access credentials 
  18.  $api_username = 'uAPI##########-########';                              // set to your given username for the API here 
  19.  $api_password = 'S.....................Z';                              // set to your given password for the API here 
  20.  $credentials = 'Universal API/'.$api_username.':'.$api_password;        // prefix with "Universal API/" and separate with a colon 
  21.  $credentials_64 = base64_encode($credentials);                          // encode for basic authentication 
  22.   
  23.  // pick a regional API - here we are using Europe/Middle East/Africa 
  24.  $api_url_emea = 'https://emea.universal-api.pp.travelport.com/B2BGateway/connect/uAPI/'
  25.  $api_url_emea_sys = $api_url_emea.'SystemService'
  26.  $api_url_emea_urs = $api_url_emea.'UniversalRecordService'
  27.   
  28.  // set to the TargetBranch provided by Travelport. 
  29.  $target_branch = 'P108131'
  30.   
  31.  // here is the basic ping request message XML 
  32.  // Note the namespace schemas used (try to use most recent) 
  33.  $this_message_xml = <<<EOM 
  34.  <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> 
  35.      <soapenv:Header/> 
  36.      <soapenv:Body> 
  37.          <sys:PingReq TraceId="test" 
  38.              xmlns:sys="http://www.travelport.com/schema/system_v9_0" 
  39.              xmlns:com="http://www.travelport.com/schema/common_v28_0"> 
  40.                  <com:BillingPointOfSaleInfo OriginApplication="UAPI"/> 
  41.                  <sys:Payload>this is a test for testing</sys:Payload> 
  42.          </sys:PingReq> 
  43.      </soapenv:Body> 
  44.  </soapenv:Envelope> 
  45.  EOM; 
  46.   
  47.  // Initialize the CURL object with the uAPI endpoint URL (in this case the SystemService) 
  48.  $soap_do = curl_init ($api_url_emea_sys)
  49.   
  50.  // This is the header of the request 
  51.  $header = array( 
  52.       'Content-Type: text/xml;charset=UTF-8', 
  53.       'Authorization: Basic '.$credentials_64, 
  54.       'Accept: gzip,deflate', 
  55.       'User-Agent: Travelport uAPI Test', 
  56.       'Cache-Control: no-cache', 
  57.       'Pragma: no-cache', 
  58.       'Connection: Keep-Alive', 
  59.       'Host: emea.universal-api.pp.travelport.com', 
  60.       'Content-length: ' . strlen($this_message_xml), 
  61.  )
  62.   
  63.  // set the cURL options 
  64.  curl_setopt($soap_do, CURLOPT_VERBOSE, 1);                              // For debugging purposes (read CURL manual for nore info) 
  65.  curl_setopt($soap_do, CURLOPT_CONNECTTIMEOUT, 30);                      // Timeout options 
  66.  curl_setopt($soap_do, CURLOPT_TIMEOUT, 30);                             // Timeout options 
  67.  curl_setopt($soap_do, CURLOPT_SSL_VERIFYPEER, 0);                       // Verify nothing about peer certificates 
  68.  curl_setopt($soap_do, CURLOPT_SSL_VERIFYHOST, 0);                       // Verify nothing about host certificates 
  69.  curl_setopt($soap_do, CURLOPT_POST, 1 );                                // Sending post variables 
  70.  curl_setopt($soap_do, CURLOPT_POSTFIELDS, $this_message_xml);           // Post variable being sent (The XML request) 
  71.  curl_setopt($soap_do, CURLOPT_HEADER, 0 );                              // Omit headers (enable these during testing - malformed XML but more info) 
  72.  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) 
  73.  curl_setopt($soap_do, CURLOPT_HTTPAUTH, CURLAUTH_ANY);                  // Authentication is BASIC but we'll put ANY just to make it work 
  74.  //    curl_setopt($soap_do, CURLOPT_USERPWD, $credentials_64);          // The credentials username:password (not used in my example) 
  75.  curl_setopt($soap_do, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);       // TLS version to use (1.0) 
  76.  curl_setopt($soap_do, CURLOPT_PORT, 443);                               // SSL port to use (443) 
  77.  curl_setopt($soap_do, CURLOPT_HTTPHEADER, $header);                     // Headers sent to the server 
  78.   
  79.  $ch_result = curl_exec($soap_do);                                       // Store the results in a cURL handle 
  80.   
  81.  // Check for errors and show them instead 
  82.  if (curl_errno($soap_do) != '') { 
  83.          $ch_result = curl_errno($soap_do) . ' - ' . curl_error($soap_do) . '<br/>'
  84.  } 
  85.  curl_close($soap_do)
  86.   
  87.  // Print cURL result (XML) 
  88.  echo $ch_result
  89.   
  90.  ?> 

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
  1.  HTTP/1.1 401 Unauthorized 
  2.  Content-Type: text/xml;charset=ISO-8859-1 
  3.  WWW-Authenticate: Basic realm="AXIS" 
  4.  Date: Fri, 24 Apr 2015 11:46:36 GMT 
  5.  Server: Datapower XI52 
  6.  X-Backside-Transport: FAIL FAIL 
  7.  Connection: close 
  8.  Vary: Accept-Encoding 
  9.   
  10.   
  11.  <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"> 
  12.  <SOAP-ENV:Body> 
  13.  <SOAP-ENV:Fault> 
  14.  <SOAP-ENV:faultcode>76</SOAP-ENV:faultcode> 
  15.  <SOAP-ENV:faultstring> 
  16.  Authentication Result Error Message Response (76): Authentication credentials are invalid. 
  17.  </SOAP-ENV:faultstring> 
  18.  <SOAP-ENV:faultactor></SOAP-ENV:faultactor> 
  19.  <SOAP-ENV:detail> 
  20.  Authentication Result Error Message Response (76): Authentication credentials are invalid. 
  21.  </SOAP-ENV:detail> 
  22.  </SOAP-ENV:Fault> 
  23.  </SOAP-ENV:Body> 
  24.  </SOAP-ENV:Envelope> 
  25.   
  26.  --> 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
  1.  HTTP/1.1 400 Bad Request 
  2.  Content-Type: text/xml;charset=ISO-8859-1 
  3.  Date: Sat, 25 Apr 2015 11:00:59 GMT 
  4.  Server: Datapower XI52 
  5.  X-Backside-Transport: FAIL FAIL 
  6.  Connection: close 
  7.  Vary: Accept-Encoding 
  8.   
  9.  <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"> 
  10.  <SOAP-ENV:Body> 
  11.  <SOAP-ENV:Fault> 
  12.  <SOAP-ENV:faultcode>400</SOAP-ENV:faultcode> 
  13.  <SOAP-ENV:faultstring>TPGateway - Request data not found - Request ignored -  service name = UniversalRecordService username = Universal API/uAPI##########-########</SOAP-ENV:faultstring> 
  14.  <SOAP-ENV:faultactor>            </SOAP-ENV:faultactor> 
  15.  <SOAP-ENV:detail>TPGateway - Request data not found - Request ignored -  service name = UniversalRecordService username = Universal API/uAPI##########-########</SOAP-ENV:detail> 
  16.  </SOAP-ENV:Fault> 
  17.  </SOAP-ENV:Body> 
  18.  </SOAP-ENV:Envelope> 
  19.   
  20.  --> 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
  1.  HTTP/1.1 200 OK 
  2.  X-Backside-Transport: OK OK 
  3.  Connection: Keep-Alive 
  4.  Transfer-Encoding: chunked 
  5.  X-Powered-By: Servlet/3.0 
  6.  SSLTerm: 216.113.131.97%3A443%2C%2FCF-COM_API%2FEMEA.UNIVERSAL-API.PP_443 
  7.  Content-Type: text/xml 
  8.  Content-Language: en-US 
  9.  Date: Fri, 24 Apr 2015 14:33:26 GMT 
  10.  X-Client-IP: 10.7.224.40 
  11.  X-Global-Transaction-ID: 145009361 
  12.  passwordEndDt: 20150803 
  13.  Vary: Accept-Encoding 
  14.   
  15.  <SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/"> 
  16.        <SOAP:Body> 
  17.           <SOAP:Fault> 
  18.              <faultcode>Server.InvalidRequestException</faultcode> 
  19.              <faultstring> Invalid API schema system_v8_0</faultstring> 
  20.  <detail> 
  21.  <ErrorInfo> 
  22.  <Code>1000</Code> 
  23.  <Service>WEBSVC</Service> 
  24.  <Type>Data</Type> 
  25.  <Description>Validation failed on request message.</Description> 
  26.  <TransactionId>FA54B21F0A07647783DB44DE48C8BB61</TransactionId> 
  27.  </ErrorInfo></detail> 
  28.  </SOAP:Fault> 
  29.        </SOAP:Body> 
  30.     </SOAP:Envelope> 
  31.   
  32.  --> 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.
uAPI WSDLschema Release v15.1.0.81 directory

Additional Info:
Category: API Miscellaneous :: Article: 607

© 2024 Joel Lipman .com. All Rights Reserved.