Royal Mail Shipping API - Abfrage von SOAP-Verbindungen und pem / -Zertifikaten

Ich versuche, die Royal Mail Shipping API einzurichten (wenn jemand Erfahrung damit hat, wäre ich dankbar, wenn Sie mir helfen könnten).

In der Dokumentation, die sie zur Verfügung stellen, muss ich ein Zertifikat (eine .p12-Datei) herunterladen und auf meinen Windows-Computer importieren - dies ist mit dem "Zertifikatimport-Assistenten" ziemlich einfach. Sobald die "Sicherheitsstufe festlegen" erreicht ist, muss ich @ auswähleHoc & dies fordert bei jeder Verwendung eine Erlaubnis mit einem Passwort an.

Im Internet Explorer in den "Internetoptionen" auf der Registerkarte "Inhalt" kann ich die Zertifikate anzeigen und deutlich sehen, dass dieses Zertifikat importiert wurde und nicht abgelaufen ist.

Der nächste Schritt istExtrahieren Sie die Zertifikatkomponenten, hier muss ich die drei folgenden Befehle mit OpenSSL ausführen, um die PEM-Dateien zu generieren.

$ 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 

In der Dokumentation steht dasuf die Datei @ cacert.pem kann von einer Anwendung direkt über die Datei selbst verwiesen werden., von dem ich glaube, dass ich es in meinem PHP-Skript getan habe, aber es ist nicht klar, wo ich das andere @ ablegen somycert & mykey pem files.

In der Dokumentation wird dazu Folgendes angegeben: -

Wie eine Anwendung das ausgestellte Client-SSL-Zertifikat übergibt, wenn eine SSL-Netzwerkverbindung hergestellt wird, hängt von der Anwendung und der Umgebung ab, es muss jedoch im Wesentlichen auf die Dateien "mycert.pem" und "mykey.pem" zugegriffen werden, oder in einigen Fällen auf a einzelne kombinierte Datei, die sowohl cert als auch key enthält.

Nirgends steht also, wie diese beiden Dateien von der Anwendung verwendet werden. Im Moment habe ich sie im selben Verzeichnis wie die Datei cacert.pem belassen.

Wenn ich versuche, auf die URL zuzugreifenhttps: //api.royalmail.com/shipping/onboardin direkt aus dem Browser, fordert mich auf, ein Zertifikat auszuwählen. Ich wähle dieses aus und gebe dann das richtige Passwort ein, wenn ich gefragt werde, ob ich die Berechtigung zur Verwendung dieses Schlüssels erteilen oder verweigern möchte. Sobald ich das richtige Passwort eingegeben habe, wird die folgende Seite angezeigt - kann jemand bestätigen, dass das Problem an meinem Ende liegt ODER dass Royal Mail am Ende nicht richtig konfiguriert wurde.

Darüber hinaus funktioniert das aktuelle PHP-Skript, das zum Senden von SOAP-Anfragen an die Versand-API verwendet wird, nicht (möglicherweise in Bezug auf alles oben Genannte).

In meinem PHP-Skript sind die soapclient-Optionen wie folgt eingerichtet:

$soapclient_options['cache_wsdl'] = 'WSDL_CACHE_NONE'; 
$soapclient_options['local_cert'] = 'certs/cacert.pem';
$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';

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

Wenn ich das PHP-Skript ausführe (dies ist im Grunde derselbe Code, den Royal Mail selbst mit meinen persönlichen API-Anmeldedaten versieht), wird im Browser die folgende Meldung angezeigt:

Could not connect to host 
REQUEST: [email protected] rngfJ+4dt4Gt855a5pr6u38i3B4= ODcwMTE5Nzc3 2015-10-13T11:02:20Z 2015-10-13T11:02:201.00526348001DeliveryDSD12015-10-13bobSS23, Some AvenueLondonE10g1000000

Offensichtlich kann dies aus einem unbekannten Grund keine Verbindung zum Host herstellen. Letzteres ist einfach die gesendete Anforderung. Der Rest des PHP-Skripts ist genau das gleiche wie das von Royal Mail an mich gesendete Skript und hat bestätigt, dass es von anderen verwendet wird und einwandfrei funktioniert.

Ich arbeite in einer WAMP-Umgebung, obwohl der endgültige Code in einer Linux-Umgebung vorliegt.Kann jemand helfe Ich bin wirklich verblüfft und Royal Mail selbst konnte noch keinen soliden technischen Support leisten.

AKTUALISIERE

Dies ist die vollständige Fehlermeldung, die im Browser angezeigt wird (ich habe die E-Mail-Adresse aus Sicherheitsgründen geändert).

Invalid Request REQUEST: [email protected] dgCW98Vqw3ladYgPPpNialODhvI= MTMzMjE1NjM4 2015-10-13T13:25:30Z 2015-10-13T13:25:302.00526348001DeliveryDSD12015-10-13Jon DoeSS23, Some RoadLondonE10g1000000

Ich habe die beiden pem-Dateien zu einer einzigen Datei mit dem Namen 'bundle.pem' zusammengeführt und in der Variablen 'local_cert' für den SoapClient & BINGO, den diese Verbindung jetzt herstellt, darauf verwiesen. Dies zeigt nun länger dasKonnte keine Verbindung herstelle gibt aber stattdessen eine "Ungültige Anfrage" an, so dass dies zumindest jetzt eine Verbindung herstellt und mir einen anderen Fehler anzeigt.

Mein gesamtes PHP-Skript ist unten:

<?php

ini_set('default_socket_timeout', 120);
ini_set('soap.wsdl_cache_enabled',1);
ini_set('soap.wsdl_cache_ttl',1);

$api_password = "xxxxxxxxxxxxxx!";
$api_username = "[email protected]";
$api_application_id = "xxxxxxxxxxxx";
$api_service_type = "D";
$api_service_code = "SD1";
$api_service_format = "";
$api_certificate_passphrase = 'xxxxxxxxxx';
$api_service_enhancements = "";

$data = new ArrayObject();
$data->order_tracking_id = "";
$data->shipping_name = "Jon Doe";
$data->shipping_company = "SS";
$data->shipping_address1 = "23, Some Road"; 
$data->shipping_address2 = "";
$data->shipping_town = "London";
$data->shipping_postcode = "E1";
$data->order_tracking_boxes = "0";
$data->order_tracking_weight = "1000";    

$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'] = 'royalmail/cert/bundle.pem';
$soapclient_options['passphrase'] = $api_certificate_passphrase;
$soapclient_options['trace'] = true;
$soapclient_options['ssl_method'] = 'SOAP_SSL_METHOD_SSLv3';
$soapclient_options['exceptions'] = true;
$soapclient_options['location'] = 'https://api.royalmail.com/shipping/onboarding';

//launch soap client
$client = new SoapClient('royalmail/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 );
$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:\n" . $client->__getLastRequest() . "\n";
    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:\n" . $client->__getLastRequest() . "\n";
die;            
?>

Nur aus Gründen der Klarheit habe ich einen Speicherauszug der Variablen $ request hinzugefügt, kurz bevor sie den try / catch-Block erreicht (beachten Sie, dass dies etwas lang ist).

Array
(
    [integrationHeader] => Array
        (
        [dateTime] => 2015-10-13T13:34:44
        [version] => 1.0
        [identification] => Array
            (
                [applicationId] => 0526348001
                [transactionId] => 
            )

    )

[requestedShipment] => Array
    (
        [shipmentType] => Array
            (
                [code] => Delivery
            )

        [serviceOccurence] => 1
        [serviceType] => Array
            (
                [code] => D
            )

        [serviceOffering] => Array
            (
                [serviceOfferingCode] => Array
                    (
                        [code] => SD1
                    )

            )

        [serviceFormat] => Array
            (
                [serviceFormatCode] => Array
                    (
                        [code] => 
                    )

            )

        [shippingDate] => 2015-10-13
        [recipientContact] => Array
            (
                [name] => Jon Doe
                [complementaryName] => SS
            )

        [recipientAddress] => Array
            (
                [addressLine1] => 23, Some Road
                [addressLine2] => 
                [postTown] => London
                [postcode] => E1
            )

        [items] => Array
            (
                [item] => Array
                    (
                        [numberOfItems] => 0
                        [weight] => Array
                            (
                                [unitOfMeasure] => Array
                                    (
                                        [unitOfMeasureCode] => Array
                                            (
                                                [code] => g
                                            )

                                    )

                                [value] => 1000000
                            )

                    )

            )

    )

)

Antworten auf die Frage(4)

Ihre Antwort auf die Frage