doubi9615 2015-09-15 09:47
浏览 72
已采纳

PHP SOAP - 无法连接到主机错误消息(Royal Mail Shipping API集成)

I am setting up the initial Royal Mail Shipping API integration and have the following PHP code (p.s i'm still waiting for some credentials from Royal Mail but this code should still at least connect & give me some form of authentication error instead.

I have run PHPINFO() locally and can confirm both CURL & OpenSSL are enabled. Not quite sure what else could be causing this...any ideas?

I have turned off my Windows firewall and have the URL http://localhost/royalmail/index.php

When I run this in the browser I get the error - this happens within the try block that is around half way down in the block of code.

Could not connect to host

my code below

<?php
//phpinfo();    
// AWAITING FROM ROYAL MAIL..
$api_password = "xxxx";
$api_username = "dispatch@company.com";
$api_application_id = "xxxxxx";
$api_service_type = "D";
$api_service_code = "SD1";
$api_service_format = "";
$api_certificate_passphrase = 'xxxxxxxxxxxx';
$api_service_enhancements = "";

// setting up the $data object
$data = new ArrayObject();
$data->order_tracking_id = "";
$data->shipping_name = "John";
$data->shipping_company = "AA";
$data->shipping_address1 = "23, Hurst Avenue"; 
$data->shipping_address2 = "";
$data->shipping_town = "London";
$data->shipping_postcode = "E1";
$data->order_tracking_boxes = "0";
$data->order_tracking_weight = "1500";    

$time = gmdate('Y-m-d\TH:i:s');
$created = gmdate('Y-m-d\TH:i:s\Z');
$nonce = mt_rand();
$nonce_date_pwd = pack("A*",$nonce) . pack("A*",$created) . pack("H*", sha1($api_password));
$passwordDigest = base64_encode(pack('H*',sha1($nonce_date_pwd)));
$ENCODEDNONCE = base64_encode($nonce);


$soapclient_options = array(); 
$soapclient_options['cache_wsdl'] = 'WSDL_CACHE_NONE'; 
$soapclient_options['local_cert'] = 'certs/CA2+Company+John-Bloggs+RM10001790+usr.p12';
$soapclient_options['passphrase'] = $api_certificate_passphrase;
$soapclient_options['trace'] = true;
$soapclient_options['ssl_method'] = 'SOAP_SSL_METHOD_SSLv3';
$soapclient_options['location'] = 'https://api.royalmail.com/shipping/onboarding';

//launch soap client
$client = new SoapClient('SAPI/ShippingAPI_V2_0_8.wsdl', $soapclient_options);
$client->__setLocation($soapclient_options['location']);

//headers needed for royal mail
$HeaderObjectXML  = '<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
                      xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
           <wsse:UsernameToken wsu:Id="UsernameToken-000">
              <wsse:Username>'.$api_username.'</wsse:Username>
              <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">'.$passwordDigest.'</wsse:Password>
              <wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">'.$ENCODEDNONCE.'</wsse:Nonce>
              <wsu:Created>'.$created.'</wsu:Created>
           </wsse:UsernameToken>
       </wsse:Security>';

//push the header into soap
$HeaderObject = new SoapVar( $HeaderObjectXML, XSD_ANYXML );

//push soap header
$header = new SoapHeader( 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd', 'Security', $HeaderObject );
//$header = new SoapHeader( 'SAPI/oasis-200401-wss-wssecurity-utility-1.0.xsd', 'Security', $HeaderObject );
$client->__setSoapHeaders($header);

//build the request
$request = array(
    'integrationHeader' => array(
        'dateTime' => $time,
        'version' => '1.0',
        'identification' => array(
            'applicationId' => $api_application_id,
            'transactionId' => $data->order_tracking_id
        )
    ),
    'requestedShipment' => array(
                                'shipmentType' => array('code' => 'Delivery'),
                                'serviceOccurence' => '1',
                                'serviceType' => array('code' => $api_service_type),
                                'serviceOffering' => array('serviceOfferingCode' => array('code' => $api_service_code)),
                                'serviceFormat' => array('serviceFormatCode' => array('code' => $api_service_format)),
                                'shippingDate' => date('Y-m-d'),
                                'recipientContact' => array('name' => $data->shipping_name, 'complementaryName' => $data->shipping_company),
                                'recipientAddress' => array('addressLine1' => $data->shipping_address1,  'addressLine2' => $data->shipping_address2, 'postTown' => $data->shipping_town, 'postcode' => $data->shipping_postcode),
                                'items' => array('item' => array(
                                            'numberOfItems' => $data->order_tracking_boxes,
                                            'weight' => array( 'unitOfMeasure' => array('unitOfMeasureCode' => array('code' => 'g')), 'value' => ($data->order_tracking_weight*1000) //weight of each individual item
                                                             )
                                                                )
                                                )
                                )               
);


//if any enhancements, add it into the array
if($api_service_enhancements != "") {
    $request['requestedShipment']['serviceEnhancements'] = array('enhancementType' => array('serviceEnhancementCode' => array('code' => $api_service_enhancements)));
}

//try make the call
try { 
    $response = $client->__soapCall( 'createShipment', array($request), array('soapaction' => 'https://api.royalmail.com/shipping/onboarding') );
} catch (Exception $e) {
    //catch the error message and echo the last request for debug
    echo $e->getMessage(); 
    echo "REQUEST:
" . $client->__getLastRequest() . "
";
    die;
}

//check for any errors
if(isset($response->integrationFooter->errors)) { 
    $build = "";

    //check it wasn't a single error message
    if(isset($response->integrationFooter->errors->error->errorCode)) { 
        $build .= $output_error->errorCode.": ".$output_error->errorDescription."<br/>"; 
    } else {
        //loop out each error message, throw exception will be added ehre
        foreach($response->integrationFooter->errors->error as $output_error) { 
            $build .= $output_error->errorCode.": ".$output_error->errorDescription."<br/>";
        }
    }

    echo $build; die;

}

print_r($response);

echo "REQUEST:
" . $client->__getLastRequest() . "
";
die;

?>

Where the error occurs..

try { 
    $response = $client->__soapCall( 'createShipment', array($request), array('soapaction' => 'https://api.royalmail.com/shipping/onboarding') );
} catch (Exception $e) {
    //catch the error message and echo the last request for debug
    echo $e->getMessage(); 
    echo "REQUEST:
" . $client->__getLastRequest() . "
";
    die;
}

update

I haven't created the *.pem files for this - I read this in the guide. I have created the three *.pem files (cacert.pem, mycert.pem & mykey.pem) but i'm not sure what to do with them now?

The PKCS#12 [http://en.wikipedia.org/wiki/PKCS_12] is the original industry standard from 1996 for the secure transfer of certificates and private keys (similar to an encrypted zip archive) and is directly supported by a variety of applications and Operating Systems. This provides a standardized 'single file' way to securely pass a certificate, its private key and a copy of the CA's public signing certificate.

The standard web server on Linux and BSD is Apache and that expects that all certificates and keys to be in a Base64 encoded version of the CER/DER x509v3 binary certificate format and RSA/DSA keys.

Extracting the constituent parts from a PKCS#12 file (mycert.p12) is easy on Linux using the following OpenSSL toolset commands ..

% openssl pkcs12 -in mycert.p12 -cacerts -nokeys -out cacert.pem

% openssl pkcs12 -in mycert.p12 -clcerts -nokeys -out mycert.pem

% openssl pkcs12 -in mycert.p12 -nocerts -nodes -out mykey.pem

The "cacert.pem" file contains CA's public signing. Typically it is added to a system-wide "Trusted CA" file (e.g. /etc/ssl/certs/ca-certificates.crt etc) or can be directly referenced by an application using the file itself. This certificate is needed to formally validate any certificates issued by the same CA.

Typically the "mycert.pem" file contains the PEM encoded x509v3 format "Client SSL" certificate. This is used to authenticate the client to a server when establishing an SSL/TLS connection.

The "mykey.pem" file contains the (now) unencrypted PEM encoded RSA 2048-bit private key linked to the client certificate.

How an application passes the issued client SSL certificate when establishing an SSL network connection to is application and environment dependent but it would essentially need to access both the "mycert.pem" and "mykey.pem" file, or in some cases, a single combined file containing both cert and key.

  • 写回答

1条回答 默认 最新

  • dongye6377 2015-09-15 16:09
    关注

    SOAP connection with Royal Mail, Could not connect to host I'm using the code in my answer and it works, if you keep having problem with that code call royal mail and ask to test in the live server, some timer they have problems with the onboarding.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 做个有关计算的小程序
  • ¥15 MPI读取tif文件无法正常给各进程分配路径
  • ¥15 如何用MATLAB实现以下三个公式(有相互嵌套)
  • ¥30 关于#算法#的问题:运用EViews第九版本进行一系列计量经济学的时间数列数据回归分析预测问题 求各位帮我解答一下
  • ¥15 setInterval 页面闪烁,怎么解决
  • ¥15 如何让企业微信机器人实现消息汇总整合
  • ¥50 关于#ui#的问题:做yolov8的ui界面出现的问题
  • ¥15 如何用Python爬取各高校教师公开的教育和工作经历
  • ¥15 TLE9879QXA40 电机驱动
  • ¥20 对于工程问题的非线性数学模型进行线性化