Search code examples
phpcurlsabre

Sabre SOAP API using cURL


Is there any example for creating session using SOAP API (cURL)? I need an example to create session using cURL.

$input_xml = '<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:eb="http://www.ebxml.org/namespaces/messageHeader" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsd="http://www.w3.org/1999/XMLSchema">
<SOAP-ENV:Header>
    <eb:MessageHeader SOAP-ENV:mustUnderstand="1" eb:version="1.0">
        <eb:ConversationId/>
        <eb:From>
            <eb:PartyId type="urn:x12.org:IO5:01">999999</eb:PartyId>
        </eb:From>
        <eb:To>
            <eb:PartyId type="urn:x12.org:IO5:01">123123</eb:PartyId>
        </eb:To>
        <eb:CPAId>IPCC</eb:CPAId>
        <eb:Service eb:type="OTA">SessionCreateRQ</eb:Service>
        <eb:Action>SessionCreateRQ</eb:Action>
        <eb:MessageData>
            <eb:MessageId>1000</eb:MessageId>
            <eb:Timestamp>2001-02-15T11:15:12Z</eb:Timestamp>
            <eb:TimeToLive>2001-02-15T11:15:12Z</eb:TimeToLive>
        </eb:MessageData>
    </eb:MessageHeader>
    <wsse:Security xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/12/secext" xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/12/utility">
        <wsse:UsernameToken> 
            <wsse:Username>USERNAME</wsse:Username>
            <wsse:Password>PASSWORD</wsse:Password>
            <Organization>IPCC</Organization>
            <Domain>DEFAULT</Domain> 
        </wsse:UsernameToken>
    </wsse:Security>
</SOAP-ENV:Header>
<SOAP-ENV:Body><eb:Manifest SOAP-ENV:mustUnderstand="1" eb:version="1.0">
    <eb:Reference xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="cid:rootelement" xlink:type="simple"/>
    </eb:Manifest>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>';

$action = 'SessionCreateRQ';
$url = 'https://webservices.sabre.com';
$ch = curl_init(); 
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_URL, $url); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
curl_setopt($ch, CURLOPT_TIMEOUT, 60); 
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, true); 
curl_setopt($ch, CURLOPT_POSTFIELDS, $soapXML);

$data = curl_exec($ch);
if(curl_error($ch)) {
    echo "Curl error: " . curl_error($ch);
} else {
    echo $data;
}

I got this error:

soap-env:Client.InvalidEbXmlMessageUnable to create envelope from given source: Error on line 2 of document : The processing instruction target matching "[xX][mM][lL]" is not allowed. Nested exception: The processing instruction target matching "[xX][mM][lL]" is not allowed.javax.xml.soap.SOAPException: Unable to create envelope from given source: Error on line 2 of document : The processing instruction target matching "[xX][mM][lL]" is not allowed. Nested exception: The processing instruction target matching "[xX][mM][lL]" is not allowed.


Solution

  • class SabreAPI {
        const SOAP_XML_FOLDER = 'soapxml';
        const SOAP_API_URL = 'https://sws-crt.cert.havail.sabre.com';
    
        protected $_userName = '<hidden>';
        protected $_password = '<hidden>';
        protected $_ipcc = '<hidden>';
    
        protected $_soapToken = '';
    
        protected function _soapSendRequest($action, $xml)
        {
            $headers = [
                'Content-Type: text/xml; charset="utf-8"',
                'Content-Length: ' . strlen($xml),
                'Accept: text/xml',
                'Keep-Alive: 300',
                'Connection: keep-alive',
                'Cache-Control: no-cache',
                'Pragma: no-cache',
                'SOAPAction: "' . $action . '"'
            ];
    
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_URL, self::SOAP_API_URL);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_TIMEOUT, 60);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
    
            $data = curl_exec($ch);
    
            if(curl_error($ch)) {
                throw new \Exception("Curl error: ".curl_error($ch));
            } else {
                return $this->_parseSoapAnswer($data, $action, $xml);
            }
        }
    
        public function soapOpenSession()
        {
    
            $action = 'SessionCreateRQ';
            $soapXML = $this->_getSoapXml($action, [
                'timestamp' => date('Y-m-d\TH:i:s\Z'),
                'userName' => $this->_userName,
                'password' => $this->_password,
                'ipcc' => $this->_ipcc,
            ]);
    
            $token = $this->_soapSendRequest($action, $soapXML);
    
            if ($token !== false) {
                $this->_soapToken = $token;
            }
    
            return $this;
        }
    
        protected function _getSoapXml($xmlName, $params = []) 
        {
            $filePath = self::SOAP_XML_FOLDER . '/' . $xmlName . '.xml';
    
            if (!file_exists($filePath)) {
                throw new \Exception("\AviaAPI\Sabre\SabreAPI::_getSoapXmlAuth(\'{$xmlName}\') XML file not found");
            }
    
            $xml = file_get_contents($filePath);
    
            foreach ($params as $paramName => $paramVal) {
                $xml = str_replace('%'.$paramName.'%', $paramVal, $xml);
            }
            return $xml;
        }
    
        /**
         * Parsing SOAP Answer
         * @param string $soapAnswer
         * @return mixed
         */
        protected function _parseSoapAnswer($soapAnswer, $soapAction, $xml)
        {
        //del soap prefix
            $soapAnswer = str_replace(['SOAP-ENV:', 'soap-env:', 'eb:', 'wsse:', 'stl:', 'tir39:'], '', $soapAnswer);
            $soapAnswer = simplexml_load_string($soapAnswer);
    
            $body = $soapAnswer->Body;
            $header = $soapAnswer->Header;
    
            //check error
            if (isset($body->Fault))
            {
                $faultCode = (string)$body->Fault->faultcode;
                $faultString = (string)$body->Fault->faultstring;
    
                trigger_error("\AviaAPI\Sabre\SabreAPI SOAP Failed. Server return error: {$faultCode}: {$faultString}", E_USER_NOTICE);
                return false;
            }
    
            if ($soapAction == "SessionCreateRQ")
            {
                $BinarySecurityToken = (string)$header->Security->BinarySecurityToken;
                return $BinarySecurityToken;
            }
    
            $answer = '';
    
            if (isset($body->CompressedResponse))
            {
                //decompress answer
                $decodedAnswer = base64_decode($body->CompressedResponse);
                $answer = simplexml_load_string(gzdecode($decodedAnswer), "SimpleXMLElement", LIBXML_NOCDATA);
            }
            else
            {
                $answer = $body;
            }
    
            if (isset($answer->Errors->Error))
            {
                $lastError = (string)$answer->Errors->Error[(count($answer->Errors->Error) - 1)]["ShortText"];
                $lastError .= "; " . (string)$answer->Errors->Error[(count($answer->Errors->Error) - 2)]["ShortText"];
    
                trigger_error("\AviaAPI\Sabre\SabreAPI Server return error: {$lastError}", E_USER_NOTICE);
                return false;
            }
    
            return $answer;
        }
    }
    

    And SessionCreateRQ.xml put into soapxml folder:

    <?xml version="1.0" encoding="utf-8"?>
    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <soap:Header>
            <MessageHeader xmlns="http://www.ebxml.org/namespaces/messageHeader">
                <From>
                    <PartyId>WebServiceClient</PartyId>
                </From>
                <To>
                    <PartyId>WebServiceSupplier</PartyId>
                </To>
                <CPAId>%ipcc%</CPAId>
                <ConversationId>SWS-Test-%ipcc%</ConversationId>
                <Service>SessionCreate</Service>
                <Action>SessionCreateRQ</Action>
                <MessageData>
                    <MessageId>9314594d-6c40-406b-9029-b887b13906b6</MessageId>
                    <Timestamp>%timestamp%</Timestamp>
                </MessageData>
            </MessageHeader>
            <Security xmlns="http://schemas.xmlsoap.org/ws/2002/12/secext">
                <UsernameToken>
                    <Username>%userName%</Username>
                    <Password>%password%</Password>
                    <Organization xmlns="">%ipcc%</Organization>
                    <Domain xmlns="">DEFAULT</Domain>
                </UsernameToken>
            </Security>
        </soap:Header>
        <soap:Body>
            <SessionCreateRQ xmlns="http://www.opentravel.org/OTA/2002/11">
                <POS>
                    <Source PseudoCityCode="%ipcc%"/>
                </POS>
            </SessionCreateRQ>
        </soap:Body>
    </soap:Envelope>