UPS配送教程(PHP)

dgsult0t  于 2023-01-12  发布在  PHP
关注(0)|答案(1)|浏览(203)

我终于设法建立了一个UPS托运XML请求,我想与其他人分享它挣扎.所以这里是一个完整的PHP面向对象的有效XML根据最新的文档从2017.
我这样做是因为互联网上没有太多有用的信息,我想改变这一点。
这段代码还解决了许多常见的错误,你可以在StackOverflow上找到问题,但大多数没有答案。这不是一个问题,它是为那些谁将在未来做UPS发货的教程。
我已经设法解决这些常见的UPS错误与我的代码:

XML文档格式不正确-〉这个错误有点棘手,因为我已经检查了我的XML结构上千次,我有它100%相同的文档说,但我有一个旧的文档,所以很少的东西得到了改变,所以当我重新创建的结构,以最新的一个问题得到了解决。
XML文档格式良好,但文档无效-〉我真的不知道是什么原因导致了这个错误,但稍微改变一下“发送逻辑”就解决了这个问题(您可以看看XML结构的结尾是如何完成的)。

在我解决了这两个“最大的”错误后,UPS请求开始工作,正确的错误消息出现了,说明了更多关于错误的细节...例如“AccessLicenseNumber invalid”等
因此,您应该做的第一件事是在UPS网站上注册并从那里下载最新的文档。
注:此代码发送第一个请求“ConfirmRequest”,它将得到响应“ConfirmResponse”,第二个请求“AcceptRequest”,它将得到“AcceptResponse”,如下图所示!

gcmastyq

gcmastyq1#

这是一个完整的脚本,它将创建XML结构,将它们发送到XML并给出响应。

<?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

重要提示:你可能已经注意到我只有一个头文件,即使文档说它需要两个头文件,这是真的。但我试图只发送一个,它的工作,所以它没有必要有两个。
1.发货确认请求

$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结构,并仔细地将其与文档进行几次比较,以避免仅仅因为您将某些内容附加到错误的父对象或其他内容而出现许多错误。
这里是您需要的代码,用于发送XML和接收请求。

2.发货确认响应

$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变量中,因此可以访问任何想要的数据

// 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结构不同。

3.发货接受请求

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和运费,并做任何你想做的事情。
重要提示:您还将获得Base64编码的标签图像

4.发货接受响应

$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;
    }
}

相关问题