且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

UPS运输教程(PHP)

更新时间:2023-02-26 14:23:31

因此,这里是完整的脚本,它将创建您的XML结构,将其发送到XML并提供响应.

So here is the complete script that will create your XML structures, send them to XML and gives you responses.

<?php
// ACCESS: You will get these after you register on UPS Website
$AccessLicenseNumber = 'xxxxxxx';
$UserID = 'xxxxxxx';
$Password = 'xxxxxxxxx';
// REQUEST *********************************
$CustomerContext = "something";
$RequestAction = "ShipConfirm";     // These values are contained in documentation 
$RequestOption = "nonvalidate";
.........
.........
......... 
And many others ...

这是XML结构!!我把整个文档都涂成了红色,以写下有关每个元素的必要信息,这样,当您插入名称(例如,长度超过30个字符)时,您就可以轻松调试XML

And here is the XML Structure!! I have red the whole documentation to write down the necessary informations about every single element so you can easily debug your XML when you insert for example name longer then 30 characters

重要:您可能已经注意到,即使文档说它想要两个标题,我也只有一个标题,这是事实.但是我尝试只发送一个,并且它可以正常工作,因此不必拥有两个.

IMPORTANT: You may have noticed that I have only one header even though the documentation says that it wants TWO HEADERS, thats true. But I tried to send it only with one and it works so its not necessary to have two of them.

1. ShipmentConfirmRequest

$domtree = new DOMDocument('1.0');

// <AccessRequest>
$AccessRequest = $domtree->createElement("AccessRequest");
$AccessRequest->setAttribute("xml:lang", "en_US");
$domtree->appendChild($AccessRequest);
        // <AccessLicenseNumber>
    $AccessRequest->appendChild($domtree->createElement('AccessLicenseNumber', $AccessLicenseNumber));
        // <UserId>
    $AccessRequest->appendChild($domtree->createElement('UserId', $UserID));
        // <Password>
    $AccessRequest->appendChild($domtree->createElement('Password', $Password));
// </AccessRequest>

// <ShipmentConfirmRequest>
$ShipmentConfirmRequest = $domtree->createElement("ShipmentConfirmRequest");
$ShipmentConfirmRequest->setAttribute("xml:lang", "en_US");
$domtree->appendChild($ShipmentConfirmRequest);
        // <Request>
    $Request = $domtree->createElement("Request");
    $ShipmentConfirmRequest->appendChild($Request);
                // <TransactionReference>
        $TransactionReference = $domtree->createElement("TransactionReference");
        $Request->appendChild($TransactionReference);
                    // <CustomerContext>
                    $TransactionReference->appendChild($domtree->createElement('CustomerContext', $CustomerContext)); // Length: 1-512, Required: No
                // </TransactionReference>
                // <RequestAction>
                $Request->appendChild($domtree->createElement('RequestAction', $RequestAction)); // Length: 10, Required: Yes, Must be "ShipConfirm"
                // <RequestOption>
                $Request->appendChild($domtree->createElement('RequestOption', $RequestOption)); // Length: 1-256, Required: Yes, "validate" or "nonvalidate"
        // </Request>
        // <Shipment>
        $Shipment = $domtree->createElement("Shipment");
        $ShipmentConfirmRequest->appendChild($Shipment);
            // <Shipper>
            $Shipper = $domtree->createElement("Shipper");
            $Shipment->appendChild($Shipper);
                // <Name>
                $Shipper->appendChild($domtree->createElement('Name', $ShipperName)); // Length: 1-35, Required: Yes, Company Name
                // <AttentionName>
                $Shipper->appendChild($domtree->createElement('AttentionName', $ShipperAttentionName)); // Length: 1-35, Required: Cond, Required if destination is international
                // <PhoneNumber>
                $Shipper->appendChild($domtree->createElement('PhoneNumber', $ShipperPhoneNumber)); // Length: 1-15, Required: Cond
                // <ShipperNumber>
                $Shipper->appendChild($domtree->createElement('ShipperNumber', $ShipperNumber)); // Length: 6, Required: Yes
                // <Address>
                $Address = $domtree->createElement('Address');
                $Shipper->appendChild($Address);
                    // <AddressLine1>
                    $Address->appendChild($domtree->createElement('AddressLine1', $ShipperAddressLine)); // Length: 1-35, Required: Yes
                    // <City>
                    $Address->appendChild($domtree->createElement('City', $ShipperCity)); // Length: 1-30, Required: Yes
                    // <StateProvinceCode>
                    $Address->appendChild($domtree->createElement('StateProvinceCode', $ShipperStateProvinceCode)); // Length: 2-5, Required: Cond, Required if shipper is in the US or CA.
                    // <PostalCode>
                    $Address->appendChild($domtree->createElement('PostalCode', $ShipperPostalCode)); // Length: 1-10, Required: Cond, For all other countries, the postal code is optional
                    // <CountryCode>
                    $Address->appendChild($domtree->createElement('CountryCode', $ShipperCountryCode)); // Length: 2, Required: Yes
                // </Address>
            // </Shipper>
            // <ShipTo>
            $ShipTo = $domtree->createElement("ShipTo");
            $Shipment->appendChild($ShipTo);
                // <CompanyName>
                $ShipTo->appendChild($domtree->createElement('CompanyName', $ShipToCompanyName)); // Length: 1-35, Required: Yes
                // <AttentionName>
                $ShipTo->appendChild($domtree->createElement('AttentionName', $ShipToAttentionName)); // Length: 1-35, Required: Cond, for UPS Next Day Air Early service, and when ShipTo country is different than ShipFrom country.
                // <PhoneNumber>
                $ShipTo->appendChild($domtree->createElement('PhoneNumber', $ShipTo_phone_number)); // Length: 1-15, Required: Cond, Required for UPS Next Day Air Early service, and when Ship To country is different than the ShipFrom country.
                // <Address>
                $Address2 = $domtree->createElement('Address');
                $ShipTo->appendChild($Address2);
                    // <AddressLine1>
                    $Address2->appendChild($domtree->createElement('AddressLine1', $ShipToAddressLine)); // Length: 1-35, Required: Yes
                    // <City>
                    $Address2->appendChild($domtree->createElement('City', $ShipToCity)); // Length: 1-30, Required: Yes
                    // <StateProvinceCode>
                    $Address2->appendChild($domtree->createElement('StateProvinceCode', $ShipToStateProvinceCode)); // Length: 2-5, Required: Cond, Required if shipper is in the US or CA.
                    // <PostalCode>
                    $Address2->appendChild($domtree->createElement('PostalCode', $ShipToPostalCode)); // Length: 1-10, Required: Cond, For all other countries, the postal code is optional
                    // <CountryCode>
                    $Address2->appendChild($domtree->createElement('CountryCode', $ShipToCountryCode)); // Length: 2, Required: Yes
                // </Address>
            // </ShipTo>
            // <PaymentInformation>
            $PaymentInformation = $domtree->createElement("PaymentInformation");
            $Shipment->AppendChild($PaymentInformation);
                // <Prepaid>
                $Prepaid = $domtree->createElement("Prepaid");
                $PaymentInformation->appendChild($Prepaid);
                    // <BillShipper>
                    $BillShipper = $domtree->createElement("BillShipper");
                    $Prepaid->appendChild($BillShipper);
                        // <AccountNumber>
                        $BillShipper->appendChild($domtree->createElement('AccountNumber', $AccountNumber)); // Length: 6, Required: Cond, Based on PaymentInformation container, Must be the same UPS account number as the one provided in Shipper/ShipperNumber.
                    // </BillShipper>
                // </Prepaid>
            // </PaymentInformation>
            // <Service>
            $Service = $domtree->createElement("Service");
            $Shipment->appendChild($Service);
                // <Code>
                $Service->appendChild($domtree->createElement('Code', $ServiceCode)); // Length: 2, Required: Yes, 01 = Next Day Air 02 = 2nd Day Air ...
            // </Service>


Here is a for loop which creates as many <Package> elements as you want (You can remove this if you want to send only one PACKAGE)
            for ($i = 0; $i < sizeof($Pack_IDs); $i++) {
            // <Package>
            $Package = $domtree->createElement('Package');
            $Shipment->appendChild($Package);
                // <PackagingType>
                $PackagingType = $domtree->createElement('PackagingType');
                $Package->appendChild($PackagingType);
                    // <Code>
                    $PackagingType->appendChild($domtree->createElement('Code', $PackageTypeCode)); // Length: 2, Required: Yes, 01 = UPS Letter 02 = Customer Supplied Package ...
                // </PackagingType>
                // <Description>
                $Package->appendChild($domtree->createElement('Description', $Description)); // Length: 1-35, Required: Cond, Required for shipment with return service.
                // </Description>
                // <Dimensions>
                $Dimensions = $domtree->createElement('Dimensions'); // Required: Cond, Length + 2*(Width + Height) must be less than or equal to 130 IN or 330 CM.
                $Package->appendChild($Dimensions);
                    // <UnitOfMeasurement>
                    $UnitOfMeasurement = $domtree->createElement('UnitOfMeasurement');
                    $Dimensions->appendChild($UnitOfMeasurement);
                        // <Code>
                        $UnitOfMeasurement->appendChild($domtree->createElement('Code', $DimensionUnitOfMeasurementCode)); // Length: 2, Required: Yes*, Codes are: IN = Inches, CM = Centimeters, 00 = Metric Units Of Measurement, 01 = English Units of Measurement.
                    // </UnitOfMeasurement>
                    // <Length>
                    $Dimensions->appendChild($domtree->createElement('Length', $PackageLength)); // Length: 9, Required: Yes*, Valid values are 0 to 108 IN and 0 to 270 CM.
                    // <Width>
                    $Dimensions->appendChild($domtree->createElement('Width', $PackageWidth)); // Length: 9, Required: Yes*
                    // <Height>
                    $Dimensions->appendChild($domtree->createElement('Height', $PackageHeight)); // Length: 9, Required: Yes*
                // </Dimensions>
                // <PackageWeight>
                $PackageWeight = $domtree->createElement('PackageWeight');
                $Package->appendChild($PackageWeight);
                    // <UnitOfMeasurement>
                    $UnitOfMeasurement2 = $domtree->createElement('UnitOfMeasurement');
                    $PackageWeight->appendChild($UnitOfMeasurement2);
                        // <Code>
                        $UnitOfMeasurement2->appendChild($domtree->createElement('Code', $WeightUnitOfMeasurementCode)); // Length: 3, Required: Cond, LBS = Pounds KGS = Kilograms OZS = Ounces ...
                    // <Weight>
                    $PackageWeight->appendChild($domtree->createElement('Weight', $Pack_weights[$i])); // Length: 1-5, Required: Yes*, Weight accepted for letters/envelopes.
                    // </UnitOfMeasurement>
                // </PackageWeight>
            // </Package>
            }
        // </Shipment>
        // <LabelSpecification>
        $LabelSpecification = $domtree->createElement('LabelSpecification');
        $ShipmentConfirmRequest->appendChild($LabelSpecification);
            // <LabelPrintMethod>
            $LabelPrintMethod = $domtree->createElement('LabelPrintMethod');
            $LabelSpecification->appendChild($LabelPrintMethod);
                // <Code>
                $LabelPrintMethod->appendChild($domtree->createElement('Code', $LabelCode)); // Length: 4, Required: Yes*
            // </LabelPrintMethod>
            // <LabelImageFormat>
            $LabelImageFormat = $domtree->createElement('LabelImageFormat');
            $LabelSpecification->appendChild($LabelImageFormat);
                // <Code>
                $LabelImageFormat->appendChild($domtree->createElement('Code', $LabelImageCode)); // Length: 3, Required: Cond, Required if ShipmentConfirmRequest/LabelSpecification/LabelPrintMethod/Code = GIF. Valid values are GIF or PNG. Only GIF is supported on the remote server.
            // </LabelImageFormat>
        // </LabelSpecification>
// </ShipmentConfimRequest>

因此,现在我们准备并填充了XML结构.我建议您打印XML结构,并仔细地将其与文档进行几次比较,以避免出现许多错误,这仅仅是因为您将某些内容附加到了错误的父项或其他内容上.

So now we have the XML Structure prepared and filled. I recommend you to print the XML structure and carefully compare it with the documentation few times to avoid many errors just because you appended something to wrong parent or whatever.

这是发送XML并接收请求所需的代码.

And here is the code you need, to send your XML and receive a request.

2. ShipmentConfirmResponse

$domtree->preserveWhiteSpace = true;
$domtree->formatOutput = true;
$xml_string = $domtree->saveXML();

// UPS Address
$url = 'https://wwwcie.ups.com/ups.app/xml/ShipConfirm'; // IMPORTANT: This is a testing URL address, dont be scared to send your request (Real URL is different -> documentation)
// SEND THE REQUEST
$stream_options = array(
    'http' => array(
       'method'  => 'POST',
       'header'  => 'Content-type: application/x-www-form-urlencoded',
       'content' => "$xml_string",
    ),
);
$context  = stream_context_create($stream_options);
$response = file_get_contents($url, null, $context); // Response XML structure 

现在,您已经将响应XML结构存储在$ response变量中,因此您可以从中访问所需的任何数据

Now you have the response XML structure stored in a $response variable so you can access any data you want from it

// Response handling
$ShipmentConfirmResponse = new SimpleXMLElement($response);
if ((string)$ShipmentConfirmResponse->Response->ResponseStatusCode == 1) { // If the response is "success" then continue with second request
    // If ShipmentCofirmRequest is successful, send ShipmentAcceptRequest
    $ShipmentDigest = $ShipmentConfirmResponse->ShipmentDigest;
    AcceptRequest($AccessLicenseNumber, $UserID, $Password, $CustomerContext, $ShipmentDigest, $ShipmentID, $connect); // After first successful request call a function which will send AcceptRequest

} else {
    echo $ShipmentConfirmResponse->Response->Error->ErrorDescription;
}

这是用于发送第二个请求"AcceptRequest"的功能 它的代码相同,但XML结构不同.

So here is a function for sending second request "AcceptRequest" Its the same code but with different XML structure.

3. ShipmentAcceptRequest

function AcceptRequest ($AccessLicenseNumber, $UserID, $Password, $CustomerContext, $ShipmentDigest) {
    $RequestAction = "ShipAccept";

    $domtree = new DOMDocument('1.0');

    // <AccessRequest>
    $AccessRequest = $domtree->createElement("AccessRequest");
    $domtree->appendChild($AccessRequest);
            // <AccessLicenseNumber>
        $AccessRequest->appendChild($domtree->createElement('AccessLicenseNumber', $AccessLicenseNumber));
            // <UserId>
        $AccessRequest->appendChild($domtree->createElement('UserId', $UserID));
            // <Password>
        $AccessRequest->appendChild($domtree->createElement('Password', $Password));
    // </AccessRequest>
    // <ShipmentAcceptRequest>
    $ShipmentAcceptRequest = $domtree->createElement("ShipmentAcceptRequest");
    $domtree->appendChild($ShipmentAcceptRequest);
            // <Request>
        $Request = $domtree->createElement("Request");
        $ShipmentAcceptRequest->appendChild($Request);
                    // <TransactionReference>
            $TransactionReference = $domtree->createElement("TransactionReference");
            $Request->appendChild($TransactionReference);
                        // <CustomerContext>
                        $TransactionReference->appendChild($domtree->createElement('CustomerContext', $CustomerContext));
                    // </TransactionReference>
                    // <RequestAction>
                    $Request->appendChild($domtree->createElement('RequestAction', $RequestAction));
            // </Request>
            // <ShipmentDigest>
            $ShipmentAcceptRequest->appendChild($domtree->createElement('ShipmentDigest', $ShipmentDigest));
    // </ShipmentAcceptRequest>

然后再次发送此代码.然后,您需要查看$ response变量是否成功,然后可以存储跟踪ID和运费,并使用它进行任何操作.

And again you send it with this code. Then you need to take a look inside a $response variable if it was successful or not and you can store the tracking ID and Shipping price and do whatever you want with it.

重要提示:您还将获得Base64编码的标签图像

IMPORTANT: You will also get Base64 encoded label image

4. ShipmentAcceptResponse

    $domtree->preserveWhiteSpace = true;
    $domtree->formatOutput = true;
    $xml_string = $domtree->saveXML();
    $url = 'https://wwwcie.ups.com/ups.app/xml/ShipAccept'; // Again testing URL

    $stream_options = array(
        'http' => array(
        'method'  => 'POST',
        'header'  => 'Content-type: application/x-www-form-urlencoded',
        'content' => "$xml_string",
    ),
);
    $context  = stream_context_create($stream_options);
    $response = file_get_contents($url, null, $context);

    $ShipmentAcceptResponse = new SimpleXMLElement($response);

    if ((string)$ShipmentAcceptResponse->Response->ResponseStatusCode == 1) {

        $Tracking_ID = $ShipmentAcceptResponse->ShipmentResults->PackageResults->TrackingNumber;
        $Price = $ShipmentAcceptResponse->ShipmentResults->ShipmentCharges->TransportationCharges->MonetaryValue;
        $ImageBase64 = $ShipmentAcceptResponse->ShipmentResults->PackageResults->LabelImage->GraphicImage;

    } else {
        echo $ShipmentAcceptResponse->Response->Error->ErrorDescription;
    }
}