Sunday, January 6, 2013

Getting the UPS shipping label via their API

After integrating our site with FedEx, we decided to also offer support for UPS. Some of our clients use FedEx and some use UPS. The FedEx integration was fairly quick and easy. The UPS integration is basically the same so far.

To get started, UPS provides a document and code sample for creating a shipment via the UPS Shipping Web Service API, but the code does not show how to get the actual shipping label.

Hopefully the following code helps someone else. For example, UPS returns the label in two parts when you request a GIF image of the label. The response gives you the GIF image and an HTML page. The HTML page references the image. Specifically, the page looks for a file named labelTRACKINGNUMBER.gif.

Here's the code. Enjoy!


     protected void Button1_Click(object sender, EventArgs e)  
     {  
       try  
       {  
         ShipService shipService = new ShipService();  
         ShipmentRequest shipmentRequest = new ShipmentRequest();  
   
         shipService.UPSSecurityValue = GetUpsShipSecurityValue();  
   
         UpsShipService.RequestType request = new UpsShipService.RequestType();  
         String[] requestOption = { "nonvalidate" };  
         request.RequestOption = requestOption;  
         shipmentRequest.Request = request;  
   
         UpsShipService.ShipmentType shipment = new UpsShipService.ShipmentType();  
         shipment.Description = "This is the description...";  
   
         shipment.PaymentInformation = GetUpsPaymentInfo();  
         shipment.Shipper = GetUpsShipper();  
         shipment.ShipFrom = GetUpsShipFrom();  
         shipment.ShipTo = GetUpsShipTo();  
         shipment.Service = GetUpsShipmentService();  
         shipment.Package = GetUpsPackageType();  
         shipmentRequest.LabelSpecification = GetUpsLabelSpecification();  
   
         shipmentRequest.Shipment = shipment;  
   
         ShipmentResponse shipmentReponse =
              shipService.ProcessShipment(shipmentRequest);  
   
         string graphicImage =
              shipmentReponse.ShipmentResults.PackageResults[0].ShippingLabel.GraphicImage;  
   
         byte[] byteLabel1 = Convert.FromBase64String(graphicImage);  
         string shippingLabelFileName1 = SaveShippingLabelGIF(byteLabel1, "_labels\\", shipmentReponse.ShipmentResults.ShipmentIdentificationNumber);  
   
         string htmlImage =
              shipmentReponse.ShipmentResults.PackageResults[0].ShippingLabel.HTMLImage;  
   
         byte[] htmlLabel = Convert.FromBase64String(htmlImage);  
         string shippingLabelFileNameHtml1 = 
              SaveShippingLabelHTML(htmlLabel, "_labels\\",shipmentReponse.ShipmentResults.ShipmentIdentificationNumber);    
   
         Label1.Text = string.Format("{0}: Tracking: {1}; Cost: {2}", 
              shipmentReponse.Response.ResponseStatus.Description, 
              shipmentReponse.ShipmentResults.ShipmentIdentificationNumber,
              shipmentReponse.ShipmentResults.ShipmentCharges.TotalCharges.MonetaryValue);  
   
         System.Uri uri = new System.Uri(Request.Url.AbsoluteUri);  

         HyperLink1.Text = shippingLabelFileNameHtml1;
         HyperLink1.Target = "_blank";
         HyperLink1.NavigateUrl = string.Format("http://{0}/_labels/{1}", uri.Host, shippingLabelFileNameHtml1);  
       }  
       catch (System.Web.Services.Protocols.SoapException exSoap)  
       {  
         Label1.Text = string.Format("Soap Exception: {0}", exSoap.Detail.InnerText);  
       }  
       catch (Exception ex)  
       {  
         Label1.Text = string.Format("Exception: {0}", ex.Message);  
       }  
   
     }  
   
     private UpsShipService.UPSSecurity GetUpsShipSecurityValue()  
     {  
       UpsShipService.UPSSecurity upsSecurity = new UpsShipService.UPSSecurity();  
   
       UpsShipService.UPSSecurityServiceAccessToken upsSecurityAccessToken = 
              new UpsShipService.UPSSecurityServiceAccessToken();  
       upsSecurityAccessToken.AccessLicenseNumber = "";  
       upsSecurity.ServiceAccessToken = upsSecurityAccessToken;  
   
       UpsShipService.UPSSecurityUsernameToken upsSecurityUserNameToken = 
              new UpsShipService.UPSSecurityUsernameToken();  
       upsSecurityUserNameToken.Username = "YOUR API USERNAME";  
       upsSecurityUserNameToken.Password = "YOUR API PASSWORD";  
       upsSecurity.UsernameToken = upsSecurityUserNameToken;  
   
       return upsSecurity;  
     }  
   
     private PaymentInfoType GetUpsPaymentInfo()  
     {  
       PaymentInfoType paymentInfo = new PaymentInfoType();  
       ShipmentChargeType shipmentCharge = new ShipmentChargeType();  
       BillShipperType billShipper = new BillShipperType();  
       billShipper.AccountNumber = "YOUR ACCOUNT NUMBER";  
       shipmentCharge.BillShipper = billShipper;  
       shipmentCharge.Type = "01"; // credit card type...required?  
   
       ShipmentChargeType[] shipmentChargeArray = { shipmentCharge };  
       paymentInfo.ShipmentCharge = shipmentChargeArray;  
   
       return paymentInfo;  
     }  
   
     private ShipperType GetUpsShipper()  
     {  
       ShipperType shipper = new ShipperType();  
       shipper.ShipperNumber = "YOUR ACCOUNT NUMBER";  
   
       ShipAddressType shipperAddress = new ShipAddressType();  
   
       String[] addressLine = { "3136 Kingsdale Center, #117" };  
       shipperAddress.AddressLine = addressLine;  
       shipperAddress.City = "Upper Arlington";  
       shipperAddress.PostalCode = "43221";  
       shipperAddress.StateProvinceCode = "OH";  
       shipperAddress.CountryCode = "US";  
         
       shipper.Address = shipperAddress;  
       shipper.Name = "Signature Closers";  
       shipper.AttentionName = "*** Attention Line ***";  
   
       ShipPhoneType shipperPhone = new ShipPhoneType();  
       shipperPhone.Number = "8886777462";  
       shipper.Phone = shipperPhone;  
   
       return shipper;  
     }  
   
     private ShipFromType GetUpsShipFrom()  
     {  
       ShipFromType shipFrom = new ShipFromType();  
       ShipAddressType shipFromAddress = new ShipAddressType();  
   
       String[] addressLine = { "3136 Kingsdale Center, #117" };  
       shipFromAddress.AddressLine = addressLine;  
       shipFromAddress.City = "Upper Arlington";  
       shipFromAddress.PostalCode = "43221";  
       shipFromAddress.StateProvinceCode = "OH";  
       shipFromAddress.CountryCode = "US";  
       shipFrom.Address = shipFromAddress;  
   
       shipFrom.Name = "Signature Closers";  
       shipFrom.AttentionName = "*** FROM Attention Line ***";  
   
       return shipFrom;  
     }  
   
     private ShipToType GetUpsShipTo()  
     {  
       ShipToType shipTo = new ShipToType();  
       ShipToAddressType shipToAddress = new ShipToAddressType();  
   
       String[] addressLine1 = { "5168 Birchwood Farms Dr." };  
       shipToAddress.AddressLine = addressLine1;  
       shipToAddress.City = "Mason";  
       shipToAddress.PostalCode = "45040";  
       shipToAddress.StateProvinceCode = "OH";  
       shipToAddress.CountryCode = "US";  
       shipTo.Address = shipToAddress;  
       shipTo.AttentionName = "Schap!";  
       shipTo.Name = "Schapplication";  
   
       ShipPhoneType shipToPhone = new ShipPhoneType();  
       shipToPhone.Number = "5135555555";  
       shipTo.Phone = shipToPhone;  
   
       return shipTo;  
     }  
   
     private UpsShipService.ServiceType GetUpsShipmentService()  
     {  
       //01 = Next Day Air  
       //02 = 2nd Day Air  
       //03 = Ground  
       //07 = Express  
       //08 = Expedited  
       //11 = UPS Standard  
       //12 = 3 Day Select  
       //13 = Next Day Air Saver  
       //14 = Next Day Air Early AM  
       //54 = Express Plus  
       //59 = 2nd Day Air A.M.  
       //65 = UPS Saver  
       //82 = UPS Today Standard  
       //83 = UPS Today Dedicated Courier  
       //84 = UPS Today Intercity  
       //85 = UPS Today Express  
       //86 = UPS Today Express Saver  
       //96 = UPS Worldwide Express Freight  
   
       UpsShipService.ServiceType service = 
              new UpsShipService.ServiceType();  
       service.Code = "01";  
       return service;  
     }  
   
     private UpsShipService.PackageType[] GetUpsPackageType()  
     {  
       UpsShipService.PackageType package = new UpsShipService.PackageType();  
   
       PackageWeightType packageWeight = new PackageWeightType();  
       packageWeight.Weight = "1";  
   
       ShipUnitOfMeasurementType uom = new ShipUnitOfMeasurementType();  
       uom.Code = "LBS";  
       packageWeight.UnitOfMeasurement = uom;  
       package.PackageWeight = packageWeight;  
   
       //01 = UPS Letter  
       //02 = Customer Supplied Package  
       //03 = Tube  
       //04 = PAK  
       //21 = UPS Express Bo   
       //24 = UPS 25KG Box  
       //25 = UPS 10KG Box  
       //30 = Pallet  
       //2a = Small Express Box  
       //2b = Medium Express Box   
       //2c = Large Express Box   
   
       PackagingType packType = new PackagingType();  
       packType.Code = "01";  
       package.Packaging = packType;  
       UpsShipService.PackageType[] pkgArray = { package };  
   
       return pkgArray;  
     }  
   
     private LabelSpecificationType GetUpsLabelSpecification()  
     {  
       LabelSpecificationType labelSpec = new LabelSpecificationType();
   
       LabelImageFormatType labelImageFormat = new LabelImageFormatType();  
       labelImageFormat.Code = "GIF";  
       labelSpec.LabelImageFormat = labelImageFormat;  
   
       return labelSpec;  
     }  
   
     /// <summary>  
     /// Saves the GIF part of the label as labelTRACKINGNUMBER.gif.  
     /// </summary>  
     /// <returns>The saved file name.</returns>  
     private string SaveShippingLabelGIF(byte[] labelBuffer, string folder, string trackingNumber)  
     {  
       string fileName = string.Format("label{0}.gif", trackingNumber);  
       return SaveShippingLabel(labelBuffer, folder, trackingNumber, fileName);  
     }  
   
     /// <summary>  
     /// Sets the HTML part of the label as "page_TRACKINGNUMBER.html" and saves the label.  
     /// </summary>  
     /// <returns>The saved file name.</returns>  
     private string SaveShippingLabelHTML(byte[] labelBuffer, string folder, string trackingNumber)  
     {  
       string fileName = string.Format("page_{0}.html", trackingNumber);  
       return SaveShippingLabel(labelBuffer, folder, trackingNumber, fileName);  
     }  
   
     private string SaveShippingLabel(byte[] labelBuffer, string folder, string trackingNumber, string fileName)  
     {  
       string returnFileName = fileName;  
   
       string phyPath = HttpRuntime.AppDomainAppPath;  
       string fullPath = String.Format("{0}{1}", phyPath, folder);  
       if (!System.IO.Directory.Exists(fullPath)) System.IO.Directory.CreateDirectory(fullPath);  
       string pathToCheck = String.Format("{0}{1}", fullPath, returnFileName);  
   
       // Should just delete the old file (code copied from another project)  
       if (System.IO.File.Exists(pathToCheck))  
       {  
         int counter = 1;  
         while (System.IO.File.Exists(pathToCheck))  
         {  
           returnFileName = counter.ToString() + fileName;  
           pathToCheck = String.Format("{0}{1}", fullPath, returnFileName);  
           counter++;  
         }  
       }  
   
       System.IO.FileStream LabelFile = new System.IO.FileStream(pathToCheck, System.IO.FileMode.Create);  
       LabelFile.Write(labelBuffer, 0, labelBuffer.Length);  
       LabelFile.Close();  
   
       return returnFileName;  
     }  

34 comments:

  1. Thanks for the great post. You saved me a ton of time searching google. Theres not alot out there on this subject. Thanks for refactoring the code in to seperate methods. Made it much easier to read. If you have any more tips/tricks on the UPS API, I'd appreciate anything ur willing to part with.

    ReplyDelete
  2. Thanks for the code,Small help needed.
    How to remove sample word which is printed on Barcode.

    ReplyDelete
  3. Expecting FedEx Shipping Label Api code very soon..

    ReplyDelete
  4. I have copied the above code, but I am getting htmlImage as null and gif file as empty

    ReplyDelete
  5. it worked. Please let me know the way to remove samples.

    ReplyDelete
  6. Hey, can you please upload the entire solution?

    Thank you!

    ReplyDelete
  7. Please explain what the Request object (Request.Url.AbsoluteUrl) in the following. I get an error that says that the object does not contain a definition for Url.

    System.Uri uri = new System.Uri(Request.Url.AbsoluteUri);
    HyperLink1.Text = shippingLabelFileNameHtml1;
    HyperLink1.Target = "_blank";
    HyperLink1.NavigateUrl = string.Format("http://{0}/_labels/{1}", uri.Host, shippingLabelFileNameHtml1);

    ReplyDelete
  8. This comment has been removed by the author.

    ReplyDelete
  9. for multiple packages the response will have one image and tracking number per package:
    for (int i = 0; i < shipmentResponse.ShipmentResults.PackageResults.Count(); i++)
    {
    string graphicImage = shipmentResponse.ShipmentResults.PackageResults[i].ShippingLabel.GraphicImage;
    byte[] byteLabel1 = Convert.FromBase64String(graphicImage);
    string shippingLabelFileName1 = SaveShippingLabelGIF(byteLabel1, "_labels\\", shipmentResponse.ShipmentResults.PackageResults[i].TrackingNumber);
    string htmlImage = shipmentResponse.ShipmentResults.PackageResults[i].ShippingLabel.HTMLImage;
    byte[] htmlLabel = Convert.FromBase64String(htmlImage);
    string shippingLabelFileNameHtml1 = SaveShippingLabelHTML(htmlLabel, "_labels\\", shipmentResponse.ShipmentResults.PackageResults[i].TrackingNumber);
    }

    ReplyDelete
    Replies
    1. This comment has been removed by the author.

      Delete
    2. This comment has been removed by the author.

      Delete
    3. Hi John - Do you have the solution for this? I have the same issue.

      Delete
  10. This comment has been removed by the author.

    ReplyDelete
  11. Hi
    string graphicImage = shipmentResponse.ShipmentResults.PackageResults[0].ShippingLabel.GraphicImage;
    byte[] byteLabel1 = Convert.FromBase64String(graphicImage);
    string shippingLabelFileName1 = SaveShippingLabelGIF(byteLabel1, "Shippinglabels\\", shipmentResponse.ShipmentResults.ShipmentIdentificationNumber);

    The image is not generated because there is an issue with Base64 string. How can i resolve this.
    Could you please help me on this.

    Thanks in advance.

    Ganesh

    ReplyDelete
  12. This comment has been removed by the author.

    ReplyDelete
  13. Hi,

    i want to Shipping rate also into my solution what shal i do using UPSShipping in c#.and one more am getting lots of errors when am pasting these code in my solutions can anyone send me full solution that can help me easyly .please provide with upshipping rates also.my mail id bhagatprasad8@gmail.com

    ReplyDelete
  14. hi, please share the code to generate Shipping Ground Freight Label

    ReplyDelete
    Replies
    1. Hi Flevyy ,

      your code worked perfect .initially am not understand .but after go through their api am able to implement it .and your code was very simple .

      Delete
  15. What is the reason for this error after this line ProcessShipment:
    he underlying connection was closed: An unexpected error occurred on a send.

    ReplyDelete
  16. I spent a week making work the UPS sample code, and when finally working I find this great article, anyways thank you! I know Fedex API is much better but do you happen to have a sample code like this for Fedex?

    And to answer @Anwar probably the issue you are having is because the test server is experiencing high load these days, try switching to production endpoint just to test if that is the issue and if so consider retry the test connection until succeed.

    ReplyDelete
  17. The graphic image is working and is displaying the label perfectly.. however what is this htmlImage for? I have it and am not using it and am wondering if i need to be...

    ReplyDelete
  18. my code is (PHP):

    $post and $head are initialized above where i started copying the code, its just the necessary info

    $ch = curl_init('https://wwwcie.ups.com/rest/Ship');

    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
    curl_setopt($ch, CURLOPT_HTTPHEADER, $head);

    // execute!
    $response = curl_exec($ch);

    // close the connection, release resources used
    curl_close($ch);

    // do anything you want with your response
    $response = json_decode($response, true);
    /* this is a golden bit of code to review the response in a formatted way

    highlight_string("");

    */

    echo $response["ShipmentResponse"]["Response"]["ResponseStatus"]["Description"] . '
    ';
    echo $response["ShipmentResponse"]["ShipmentResults"]["ShipmentIdentificationNumber"] . '
    ';
    echo $response["ShipmentResponse"]["ShipmentResults"]["PackageResults"]["ShippingLabel"]["GraphicImage"] . '
    ';
    echo $response["ShipmentResponse"]["ShipmentResults"]["PackageResults"]["ShippingLabel"]["HTMLImage"] . '
    ';

    $graphicLabel = $response["ShipmentResponse"]["ShipmentResults"]["PackageResults"]["ShippingLabel"]["GraphicImage"];

    echo 'img src="data:image/gif;base64,' . $graphicLabel . '" height="300px" class="rotateimg90"/>';

    ReplyDelete
  19. wow a lot of my code was stripped out by blogger's html stipping sorry guys

    ReplyDelete
  20. hi i am not able to print return shipping label. can u please give me sample code for return ship label ..please send to nitish.dikshit01@gmail.com

    ReplyDelete
  21. A blog must be connected to the person in need. It is really important to understand the actual feel of such necessity and the essence of objective behind it. Author must give proper time to understand every topic before writing it.
    การ ส่ง พัสดุ ไป ต่าง ประเทศ

    ReplyDelete
  22. I just found this blog and have high hopes for it to continue. Keep up the great work, its hard to find good ones. I have added to my favorites. Thank You. best shipping label printer for amazon

    ReplyDelete
  23. Hi there, can any one help me with RETURN SHIPPING LABEL

    ReplyDelete
  24. Found this very helpful to get started on our custom app for UPS shipping. We are moving from FedEx web services to UPS. I have been able to create a test label but for the life of me cannot get a cost center or package id (reference 2 and reference 1 fields respectively) to display in the bottom of the label. I think I am supposed to set the values of /ShipmentRequest/Shipment/CostCenter and /ShipmentRequest/Shipment/PackageID according to the developers guide. But alas, cant seem to get the values to show up. Anyone else have any hints on how to?

    ReplyDelete
  25. How to create PDF of label from the shipment Response

    ReplyDelete
  26. I'm glad I found t web site, I couldn't find any knowledge on this m prior to.Also operate a site and if you are ever interested in doing some visitor writing for me if possible feel free to let me know, i m always look for people to check out my web site. Shipping Services USA

    ReplyDelete
  27. Thanks for your post. I’ve been thinking about writing a very comparable post over the last couple of weeks, I’ll probably keep it short and sweet and link to this instead if thats cool. Thanks. house moving quotes

    ReplyDelete
  28. Efficient solution! UPS API simplifies label retrieval for smoother shipping. Blackstar Logistics

    ReplyDelete