Google Answers Logo
View Question
 
Q: UPS Shipping API ( Answered 5 out of 5 stars,   2 Comments )
Question  
Subject: UPS Shipping API
Category: Computers > Programming
Asked by: mononexo-ga
List Price: $15.00
Posted: 04 Jan 2006 11:27 PST
Expires: 03 Feb 2006 11:27 PST
Question ID: 429083
Hi!
I'm looking for an easy to install UPS Shipping API that will take the
following information (minimally):
sendor zip
recipient zip
weight of package
(size of package?)

And will return:
expected cost of shipping

We already have a token for UPS.com to use their api's, but we are
unable to have it successfully integrate into our applications.

Preferably, the solution should cooperate with PHP.

Thanks,
Matt

Request for Question Clarification by bookface-ga on 04 Jan 2006 12:54 PST
Is an ASP-based solution acceptable?

bookface-ga
Answer  
Subject: Re: UPS Shipping API
Answered By: bookface-ga on 04 Jan 2006 14:02 PST
Rated:5 out of 5 stars
 
http://www.phpbuilder.com/lists/php-general/2001022/0287.php
*****************************************************

<?php
/*

Copyright (c) 2000, Jason Costomiris
All rights reserved.

Don't be scared, it's just a BSD-ish license.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

1. Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.
3. All advertising materials mentioning features or use of this software
   must display the following acknowledgement:
   This product includes software developed by Jason Costomiris.
4. The name of the author may not be used to endorse or promote products
   derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE AUTHOR COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

  class Ups

    function
Product($prod){
       /*

         1DM == Next Day Air Early AM
     1DA == Next Day Air
     1DP == Next Day Air Saver
     2DM == 2nd Day Air Early AM
     2DA == 2nd Day Air
     3DS == 3 Day Select
     GND == Ground
     STD == Canada Standard
     XPR == Worldwide Express
     XDM == Worldwide Express Plus
     XPD == Worldwide Expedited
       
    */
      $this->upsProductCode = $prod;
    }
     
    function origin($postal, $country){
      $this->originPostalCode = $postal;
      $this->originCountryCode = $country;
    }

    function dest($postal, $country){
      $this->destPostalCode = $postal;
          $this->destCountryCode = $country;
    }

    function rate($foo){
      switch($foo){
        case "RDP":
          $this->rateCode = "Regular+Daily+Pickup";
          break;
        case "OCA":
          $this->rateCode = "On+Call+Air";
          break;
        case "OTP":
          $this->rateCode = "One+Time+Pickup";
          break;
        case "LC":
          $this->rateCode = "Letter+Center";
          break;
        case "CC":
          $this->rateCode = "Customer+Counter";
          break;
      }
    }

    function container($foo){
          switch($foo){
        case "CP": // Customer Packaging
          $this->containerCode = "00";
          break;
               case "ULE": // UPS Letter Envelope
          $this->containerCode = "01";
          break;
        case "UT": // UPS Tube
          $this->containerCode = "03";
          break;
        case "UEB": // UPS Express Box
          $this->containerCode = "21";
          break;
        case "UW25": // UPS Worldwide 25 kilo
          $this->containerCode = "24";
          break;
        case "UW10": // UPS Worldwide 10 kilo
          $this->containerCode = "25";
          break;
      }
    }
     
    function weight($foo){
      $this->packageWeight = $foo;
    }

    function rescom($foo){
          switch($foo){

        case "RES": // Residential Address
          $this->resComCode = "1";
          break;
        case "COM": // Commercial Address
          $this->resComCode = "2";
          break;
          }
    }

    function
Quote(){
          $upsAction = "3"; // You want 3. Don't change unless you are sure.
      $url = join("&",
               array("http://www.ups.com/using/services/rave/qcostcgi.cgi?accept_UPS_license_agreement=yes",
                     "10_action=$upsAction",
                     "13_product=$this->upsProductCode",
                     "14_origCountry=$this->originCountryCode",
                     "15_origPostal=$this->originPostalCode",
                     "19_destPostal=$this->destPostalCode",
                     "22_destCountry=$this->destCountryCode",
                     "23_weight=$this->packageWeight",
                     "47_rateChart=$this->rateCode",
                     "48_container=$this->containerCode",
                     "49_residential=$this->resComCode"
           )
                );
      $fp = fopen($url, "r");
      while(!feof($fp)){
        $result = fgets($fp, 500);
        $result = explode("%", $result);
        $errcode = substr($result[0], -1);
        switch($errcode){
          case 3:
            $returnval = $result[8];
                break;
          case 4:
            $returnval = $result[8];
            break;
          case 5:
            $returnval = $result[1];
            break;
          case 6:
            $returnval = $result[1];
            break;
        }
      }
      fclose($fp);
          if(! $returnval) { $returnval = "error"; }
      return $returnval;
    }
  }

?>

Example
<?
    require("ups.php");
    $rate = new Ups;
    $rate->upsProduct("1DM"); // See upsProduct() function for codes
    $rate->origin("08033", "US"); // Use ISO country codes!
    $rate->dest("90210", "US"); // Use ISO country codes!
    $rate->rate("RDP"); // See the rate() function for codes
    $rate->container("CP"); // See the container() function for codes
    $rate->weight("17");
    $rate->rescom("RES"); // See the rescom() function for codes
    $quote = $rate->getQuote();
    echo $quote;
?> 



I first found this apparently older version, which doesn't have the
copyright notice if that's an issue for you, and still seems to work
fine:

http://lists.nyphp.org/pipermail/talk/2003-January/001944.html

<?php

/*

    Version: 0.06 (29 November, 1999)

    UPS Shipping calculator.  Much of this is re-organized stuff that was
    borrowed from shawnblue at radiotakeover.com.  I fixed a couple of bugs,
    and optimized much of the code for speed (ie switch(), rather than
    a bunch of if() statements, join(), rather than a lot of .=
    statements, etc..  I tested this using the sample code below (using
    various values for my paramaters), and it works pretty well.  Happy
    shipping.

    Sample usage:
    $rate = new Ups;
    $rate->upsProduct("1DM");    // See upsProduct() function for codes
    $rate->origin("08033", "US"); // Use ISO country codes!
    $rate->dest("90210", "US");      // Use ISO country codes!
    $rate->rate("RDP");        // See the rate() function for codes
    $rate->container("CP");    // See the container() function for codes
    $rate->weight("2");
    $rate->rescom("RES");    // See the rescom() function for codes
    $quote = $rate->getQuote();
    echo $quote;

*/

  class Ups {

    function upsProduct($prod){
/*

     1DM == Next Day Air Early AM
     1DA == Next Day Air
     1DP == Next Day Air Saver
     2DM == 2nd Day Air Early AM
     2DA == 2nd Day Air
     3DS == 3 Day Select
     GND == Ground
     STD == Canada Standard
     XPR == Worldwide Express
     XDM == Worldwide Express Plus
     XPD == Worldwide Expedited

*/
      $this->upsProductCode = $prod;
    }

    function origin($postal, $country){
      $this->originPostalCode = $postal;
      $this->originCountryCode = $country;
    }

    function dest($postal, $country){
      $this->destPostalCode = $postal;
          $this->destCountryCode = $country;
    }

    function rate($foo){
      switch($foo){
        case "RDP":
          $this->rateCode = "Regular+Daily+Pickup";
          break;
        case "OCA":
          $this->rateCode = "On+Call+Air";
          break;
        case "OTP":
          $this->rateCode = "One+Time+Pickup";
          break;
        case "LC":
          $this->rateCode = "Letter+Center";
          break;
        case "CC":
          $this->rateCode = "Customer+Counter";
          break;
      }
    }

    function container($foo){
          switch($foo){
        case "CP":            // Customer Packaging
          $this->containerCode = "00";
          break;
        case "ULE":        // UPS Letter Envelope
          $this->containerCode = "01";
          break;
        case "UT":            // UPS Tube
          $this->containerCode = "03";
          break;
        case "UEB":            // UPS Express Box
          $this->containerCode = "21";
          break;
        case "UW25":        // UPS Worldwide 25 kilo
          $this->containerCode = "24";
          break;
        case "UW10":        // UPS Worldwide 10 kilo
          $this->containerCode = "25";
          break;
      }
    }

    function weight($foo){
      $this->packageWeight = $foo;
    }

    function rescom($foo){
          switch($foo){
        case "RES":            // Residential Address
          $this->resComCode = "1";
          break;
        case "COM":            // Commercial Address
          $this->resComCode = "2";
          break;
          }
    }

    function getQuote(){
          $upsAction = "3"; // You want 3.  Don't change unless you are
sure.
      $url = join("&",

array("http://www.ups.com/using/services/rave/qcostcgi.cgi?accept_UPS_licens
e_agreement=yes",
                     "10_action=$upsAction",
                     "13_product=$this->upsProductCode",
                     "14_origCountry=$this->originCountryCode",
                     "15_origPostal=$this->originPostalCode",
                     "19_destPostal=$this->destPostalCode",
                     "22_destCountry=$this->destCountryCode",
                     "23_weight=$this->packageWeight",
                     "47_rateChart=$this->rateCode",
                     "48_container=$this->containerCode",
                     "49_residential=$this->resComCode"
           )
                );
      $fp = fopen($url, "r");
      while(!feof($fp)){
        $result = fgets($fp, 500);
        $result = explode("%", $result);
        $errcode = substr($result[0], -1);
        switch($errcode){
          case 3:
            $returnval = $result[8];
                break;
          case 4:
            $returnval = $result[8];
            break;
          case 5:
            $returnval = $result[1];
            break;
          case 6:
            $returnval = $result[1];
            break;
        }
      }
      fclose($fp);
          if(! $returnval) { $returnval = "error"; }
      return $returnval;
    }
  }

?>


Although as you can see that code is a bit old, it works for all the
cases I tested it for. You can find more derivations by searching for
"$this->upsProductCode" but nothing really seemed like much of an
improvment over these two copies.


I also found this snippet from
http://www.phpbuilder.com/snippet/detail.php?type=snippet&id=411 :

function getUPSprice
($shipType,$sendZipcode,$recieveZipcode,$recieveCountry,$weight) {
	$tmp = "AppVersion=1.2&AcceptUPSLicenseAgreement=yes&ResponseType=application/x-ups-rss&ActionCode=3".
		"&RateChart=Regular+Daily+Pickup&DCISInd=0&SNDestinationInd1=0&SNDestinationInd2=0&ResidentialInd=0&PackagingType=00".
		"&ServiceLevelCode=$shipType&ShipperPostalCode=".substr($sendZipcode,
0, 5)."&ConsigneePostalCode=". substr($recieveZipcode, 0, 5).
		"&ConsigneeCountry=$recieveCountry&PackageActualWeight=$weight&DeclaredValueInsurance=0\n\r";
			
	$request = "POST /using/services/rave/qcost_dss.cgi
HTTP/1.0\nContent-type:
application/x-www-form-urlencoded\nContent-length: " .
		strlen($tmp) . "\n\n" . $tmp;
				
	$this->socket = fsockopen("www.ups.com", 80);
	fputs($this->socket, $request);	
	strtok(fread ($this->socket, 4096), "%");

	for ($i = 0; $i < 12 ;$i++)
		$price = strtok("%");

	fclose($this->socket);
	
	return($price);
}

but it didn't work for me. It may be that I'm not passing the
arguments in the form it expects, but I didn't bother playing around
with it too much since the other form works.

In other languages:

Perl support for UPS:
http://www.kavod.com/Business-Shipping/
http://www.uspharmd.com/scripts/cgi-bin/module/Business/UPS.pm

An ASP script:
http://www.scripts.com/asp-scripts/ecommerce-software/product-shipping-scripts/ups-shipping-rates-calculator-realtime/

As a user-contributed plugin for osCommerce, an open-source storefront package:
http://www.oscommerce.com/community/contributions,528

Another open-source storefront package that supports UPS with a native module:
http://www.fishcart.org

Search strategy:
://www.google.com/search?hl=en&lr=&q=ups+php+calculate+submit
://www.google.com/search?hl=en&lr=&q=ups+php+calculate+weight
://www.google.com/search?q=%24this-%3EupsProductCode+2005

Hope this helps you with your project!

- bookface-ga
mononexo-ga rated this answer:5 out of 5 stars
Thanks, sorry for the delay.

Comments  
Subject: Re: UPS Shipping API
From: mhuffs9017-ga on 06 Jan 2006 07:51 PST
 
bookface--

I'm trying to use your script here and I keep receiving the following error.

Parse error: parse error, expecting `'{'' in
C:\apachefriends\xampp\htdocs\filesup\ups.php on line 39

Can you advise on what may be happening?

thanks!
Subject: Re: UPS Shipping API
From: cc96ai-ga on 12 Jan 2006 10:59 PST
 
I found out there has couple typo inside the code,
this should be work
<?php
/*

Copyright (c) 2000, Jason Costomiris
All rights reserved.

Don't be scared, it's just a BSD-ish license.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

1. Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.
3. All advertising materials mentioning features or use of this software
   must display the following acknowledgement:
   This product includes software developed by Jason Costomiris.
4. The name of the author may not be used to endorse or promote products
   derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE AUTHOR COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

  class Ups{

    function upsProduct($prod){
       /*

         1DM == Next Day Air Early AM
     1DA == Next Day Air
     1DP == Next Day Air Saver
     2DM == 2nd Day Air Early AM
     2DA == 2nd Day Air
     3DS == 3 Day Select
     GND == Ground
     STD == Canada Standard
     XPR == Worldwide Express
     XDM == Worldwide Express Plus
     XPD == Worldwide Expedited
       
    */
      $this->upsProductCode = $prod;
    }
     
    function origin($postal, $country){
      $this->originPostalCode = $postal;
      $this->originCountryCode = $country;
    }

    function dest($postal, $country){
      $this->destPostalCode = $postal;
          $this->destCountryCode = $country;
    }

    function rate($foo){
      switch($foo){
        case "RDP":
          $this->rateCode = "Regular+Daily+Pickup";
          break;
        case "OCA":
          $this->rateCode = "On+Call+Air";
          break;
        case "OTP":
          $this->rateCode = "One+Time+Pickup";
          break;
        case "LC":
          $this->rateCode = "Letter+Center";
          break;
        case "CC":
          $this->rateCode = "Customer+Counter";
          break;
      }
    }

    function container($foo){
          switch($foo){
        case "CP": // Customer Packaging
          $this->containerCode = "00";
          break;
               case "ULE": // UPS Letter Envelope
          $this->containerCode = "01";
          break;
        case "UT": // UPS Tube
          $this->containerCode = "03";
          break;
        case "UEB": // UPS Express Box
          $this->containerCode = "21";
          break;
        case "UW25": // UPS Worldwide 25 kilo
          $this->containerCode = "24";
          break;
        case "UW10": // UPS Worldwide 10 kilo
          $this->containerCode = "25";
          break;
      }
    }
     
    function weight($foo){
      $this->packageWeight = $foo;
    }

    function rescom($foo){
          switch($foo){

        case "RES": // Residential Address
          $this->resComCode = "1";
          break;
        case "COM": // Commercial Address
          $this->resComCode = "2";
          break;
          }
    }

    function getQuote(){
          $upsAction = "3"; // You want 3. Don't change unless you are sure.
      $url = join("&",
               array("http://www.ups.com/using/services/rave/qcostcgi.cgi?accept_UPS_license_agreement=yes",
                     "10_action=$upsAction",
                     "13_product=$this->upsProductCode",
                     "14_origCountry=$this->originCountryCode",
                     "15_origPostal=$this->originPostalCode",
                     "19_destPostal=$this->destPostalCode",
                     "22_destCountry=$this->destCountryCode",
                     "23_weight=$this->packageWeight",
                     "47_rateChart=$this->rateCode",
                     "48_container=$this->containerCode",
                     "49_residential=$this->resComCode"
           )
                );
      $fp = fopen($url, "r");
      while(!feof($fp)){
        $result = fgets($fp, 500);
        $result = explode("%", $result);
        $errcode = substr($result[0], -1);
        switch($errcode){
          case 3:
            $returnval = $result[8];
                break;
          case 4:
            $returnval = $result[8];
            break;
          case 5:
            $returnval = $result[1];
            break;
          case 6:
            $returnval = $result[1];
            break;
        }
      }
      fclose($fp);
          if(! $returnval) { $returnval = "error"; }
      return $returnval;
    }
  }

?>

Exmaple

<?
    require("ups.php");
    $rate = new Ups;
    $rate->upsProduct("1DM"); // See upsProduct() function for codes
    $rate->origin("08033", "US"); // Use ISO country codes!
    $rate->dest("10210", "US"); // Use ISO country codes!
    $rate->rate("RDP"); // See the rate() function for codes
    $rate->container("CP"); // See the container() function for codes
    $rate->weight("17");
    $rate->rescom("RES"); // See the rescom() function for codes
    $quote = $rate->getQuote();
    echo $quote;

?>

Important Disclaimer: Answers and comments provided on Google Answers are general information, and are not intended to substitute for informed professional medical, psychiatric, psychological, tax, legal, investment, accounting, or other professional advice. Google does not endorse, and expressly disclaims liability for any product, manufacturer, distributor, service or service provider mentioned or any opinion expressed in answers or comments. Please read carefully the Google Answers Terms of Service.

If you feel that you have found inappropriate content, please let us know by emailing us at answers-support@google.com with the question ID listed above. Thank you.
Search Google Answers for
Google Answers  


Google Home - Answers FAQ - Terms of Service - Privacy Policy