phpsoapsoap-clienttravelport-api

Travelport uAPI using Php soapClient


Having issue with using php soapClient to access Travelport uAPI.

Able to use Curl to get data back but not able to use Air.wsdl file to hit Travelport.

Currently using the latest Air.wsdl file which were released on the 1st of July 2015.

Anyone got a working example on how this is done?

TravelportProvider:


namespace Providers;

use Providers\Clients\SoapClient;

class TravelportProvider extends SoapClient
{

    public function __construct() {
        parent::__construct(config('travelport.airWsdl'), config('travelport.endpoint'));
    }

    public function search()
    {
        return $this->service();
    }


    public function service() {

        $parameters = array(
            'BillingPointOfSaleInfo' => array(
                'OriginApplication' => 'UAPI'
            ),
            'AirPricingSolution' => array(
                'Key' => 1
            ),
            'legs' => array(
                'Key' => 1,
                'Group' => 1,
                'Origin' => 'BNE',
                'Destination' => 'SYD',
                'departureDate' => '2015-07-23',
                'cabinClass' => 'Economy',
                'validationPassed:protected' => '1',
                'validationErrors:protected' => ''
            )
        );
        $response = $this->__soapCall('service', array($parameters));
        return $response;
    }
}

SoapClient:


namespace Providers\Clients;


abstract class SoapClient extends \SoapClient
{
    /**
     * Configuration Array
     *
     * @var array
     */
    protected $config = null;

    /**
     * Options Array
     *
     * @var array
     */
    protected $options = null;

    public function __construct($wsdl, $endpoint, $options = null) {

        // Set Soap Config
        $this->setConfig($wsdl, $endpoint);

        // Set Soap Context
        $this->setContext();

        // Create Classmap Array
//        $this->setClassmap();

        // Set Soap options
        $this->setOptions($this->config, $this->context);

        // Set the WSDL endpoint
        $this->__setLocation($endpoint);

        // Create the SoapClient
        parent::__construct($wsdl, $this->options);
    }

    /**
     * Set Soap Config
     *
     * @param string $wsdl
     * @param string $endpoint
     * @return array $config
     */
    protected function setConfig($wsdl, $endpoint) {
        // Check WSDL
        if ($wsdl == null) {
            throw new \SoapException("WSDL cannot be null");
        }

        // Credentials
        $this->config = array(
            'username' => config('travelport.username'),
            'password' => config('travelport.password'),
            'credentials' => config('travelport.credentials'),
            'wsdl' => $wsdl,
            'endpoint' => $endpoint
        );

        // Setting config
        return $this->config;
    }

    /**
     * Set Soap Context
     *
     * @return array $context
     */
    protected function setContext() {
        $this->context = array(
            'http' => array(
                'header' => array(
                    'Content-Type: text / xml; charset = UTF-8',
                    'Accept-Encoding: gzip, deflate',
                    'SOAPAction: ""'
                )),
            'ssl' => array(
                'ciphers' => 'RC4-SHA'
            )
        );
        return $this->context;
    }

    /**
     * Set Soap Options
     *
     * @param array $config
     * @param array $context
     * @return array $options
     */
    protected function setOptions($config, $context)
    {
        $this->options = array(
            'soap_version' => 'SOAP_1_1',
            'encoding' => 'UTF-8',
            'exceptions' => true,
            'stream_context' => stream_context_create($context),
            'trace' => true,
            'login' => $config['username'],
            'password' => $config['password']
        );

        // Setting options
        return $this->options;
    }
}

What I found interesting is that the latest Air.wsdl file has the same operation name "service" with the same input/output names as well. How do I choose which one to target, I want to search for LowFareSearch?

I did a $this->__getfunction() and I am getting the following


Array
(
    [0] => AirRepriceRsp service(AirRepriceReq $parameters)
    [1] => ScheduleSearchRsp service(ScheduleSearchReq $parameters)
    [2] => LowFareSearchRsp service(LowFareSearchReq $parameters)
    [3] => LowFareSearchAsynchRsp service(LowFareSearchAsynchReq $parameters)
    [4] => RetrieveLowFareSearchRsp service(RetrieveLowFareSearchReq $parameters)
    [5] => AirPriceRsp service(AirPriceReq $parameters)
    [6] => AirFareRulesRsp service(AirFareRulesReq $parameters)
    [7] => AvailabilitySearchRsp service(AvailabilitySearchReq $parameters)
    [8] => AirFareDisplayRsp service(AirFareDisplayReq $parameters)
    [9] => SeatMapRsp service(SeatMapReq $parameters)
    [10] => AirRefundQuoteRsp service(AirRefundQuoteReq $parameters)
    [11] => AirRefundRsp service(AirRefundReq $parameters)
    [12] => AirTicketingRsp service(AirTicketingReq $parameters)
    [13] => AirVoidDocumentRsp service(AirVoidDocumentReq $parameters)
    [14] => AirRetrieveDocumentRsp service(AirRetrieveDocumentReq $parameters)
    [15] => AirExchangeRsp service(AirExchangeReq $parameters)
    [16] => AirExchangeQuoteRsp service(AirExchangeQuoteReq $parameters)
    [17] => AirExchangeTicketingRsp service(AirExchangeTicketingReq $parameters)
    [18] => AirMerchandisingOfferAvailabilityRsp service(AirMerchandisingOfferAvailabilityReq $parameters)
    [19] => AirUpsellSearchRsp service(AirUpsellSearchReq $parameters)
    [20] => FlightTimeTableRsp service(FlightTimeTableReq $parameters)
    [21] => AirPrePayRsp service(AirPrePayReq $parameters)
    [22] => EMDRetrieveRsp service(EMDRetrieveReq $parameters)
    [23] => EMDIssuanceRsp service(EMDIssuanceReq $parameters)
    [24] => AirMerchandisingDetailsRsp service(AirMerchandisingDetailsReq $parameters)
    [25] => FlightInformationRsp service(FlightInformationReq $parameters)
    [26] => FlightDetailsRsp service(FlightDetailsReq $parameters)
)

Solution

  • If you want to use WSDL, you must copy original WSDL file and put in it the description of one service. Do this for each of the desired service. So if you need two of Air.wsdl service, you will have two separate WSDL files. Example for AirMerchandisingOfferAvailabilityRsp:

    <?xml version="1.0" encoding="UTF-8"?>
    <definitions name="AirService"
                 xmlns="http://schemas.xmlsoap.org/wsdl/"
                 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                 xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
                 xmlns:tns="http://www.travelport.com/service/air_v32_0"
                 xmlns:ns1="http://www.travelport.com/schema/air_v32_0"
                 targetNamespace="http://www.travelport.com/service/air_v32_0">
    
        <import namespace="http://www.travelport.com/service/air_v32_0"
              location="AirAbstract.wsdl" />
        <binding name="AirMerchandisingOfferAvailabilityBinding" type="tns:AirMerchandisingOfferAvailabilityPortType">
            <soap:binding style="document"
                          transport="http://schemas.xmlsoap.org/soap/http" />
            <operation name="service">
                <soap:operation soapAction="http://localhost:8080/kestrel/AirService"/>
                <input>
                    <soap:body use="literal" />
                </input>
                <output>
                    <soap:body use="literal" />
                </output>
                <fault name="ErrorInfoMsg">
                    <soap:fault name="ErrorInfoMsg" use="literal" />
                </fault>
            </operation>
        </binding>
        <!-- Service -->
        <service name="AirService">
            <port name="AirMerchandisingOfferAvailabilityPort"
                  binding="tns:AirMerchandisingOfferAvailabilityBinding">
                <soap:address
                     location="http://localhost:8080/kestrel/AirService" />
            </port>
        </service>
    </definitions>
    

    I did so.