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 随身WiFi网络灯亮但是没有网络,如何解决?
  • ¥15 gdf格式的脑电数据如何处理matlab
  • ¥20 重新写的代码替换了之后运行hbuliderx就这样了
  • ¥100 监控抖音用户作品更新可以微信公众号提醒
  • ¥15 UE5 如何可以不渲染HDRIBackdrop背景
  • ¥70 2048小游戏毕设项目
  • ¥20 mysql架构,按照姓名分表
  • ¥15 MATLAB实现区间[a,b]上的Gauss-Legendre积分
  • ¥15 delphi webbrowser组件网页下拉菜单自动选择问题
  • ¥15 linux驱动,linux应用,多线程