Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Shipping Script

Status
Not open for further replies.

fludan

Technical User
Feb 1, 2002
41
US
Hi
I have a shopping cart written in perl. I need to install a real-time shipping script to get data from Canada Post server but I have no idea how to do this. Canada Post server uses XML without API. My shopping cart came with USPS script, here is the script of USPS and the file of Canada Post (xml). Hopefully someone will be able to help me with this.

Thanks
Frank webmaster@fludan.com

USPS Script
**********************************************
package Business::USPS;

use HTTP::Request::Common qw(POST);
use LWP::UserAgent;
use strict;
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
require 5.003;

require Exporter;

@ISA = qw(Exporter AutoLoader);

#########
######### Items to export into callers namespace by default.
######### Note: do not export names by default without a
######### very good reason. Use EXPORT_OK instead. Do not simply
######### export all your public functions/methods/constants.
#########

@EXPORT = qw(
getUSPSdom
getUSPSint
);

#########
######### Copyright 2002 Nick Hendler <webmaster@kryptronic.com>
######### See GNU GPL. This work is derived from the excellent
######### module Business::UPS which is Copyright 1998 Mark Solomon
######### <msolomon@seva.net>. Major mods include the use of
######### HTTP::Request::Common and the post method to handle
######### the post/response. Also, USPS uses XML but does not
######### require XML::parser.
#########
######### This module was written as part of the development
######### of the ClickCartPro Version 5 (CCP5) e-commerce
######### application. For details, please visit:
######### or
######### #########

#########
######### Version must be all one line, for MakeMaker.
#########

$VERSION = do { my @r = (q$Revision: 1.00 $ =~ /\d+/g); sprintf &quot;%d.&quot;.&quot;%02d&quot; x $#r, @r };

#######################################################################
# getUSPSdom #
#######################################################################

sub getUSPSdom {

#########
######### This routine gets domestic (US to US) USPS rates.
#########

my ($merchantCPID,$url,$ziporigin,$zipdest,$pounds) = @_;

my $api = &quot;Rate&quot;;
my $pkgid = &quot;0&quot;;
my $container = &quot;None&quot;;
my $size = &quot;Regular&quot;;
my $machinable = &quot;False&quot;;
my $ounces = &quot;&quot;;

($pounds,$ounces) = getweight($pounds);

my $xml = &quot;<eparcel merchantCPID=\&quot;$merchantCPID\&quot;><fromPostalCode>$ziporigin</fromPostalCode><postalCode>$zipdest</postalCode><Weight>$pounds<Weight></eparcel>&quot;;

$xml = encode($xml);

my ($return_status,$return_service,$return_postage) = handleconnectdom($url,$api,$xml);

return ($return_status,$return_service,$return_postage);

} ######### End of subroutine.

#######################################################################
# getUSPSint #
#######################################################################

sub getUSPSint {

#########
######### This routine gets international (US to Non-US) USPS rates.
#########

my ($username,$password,$url,$country,$pounds) = @_;

my $api = &quot;IntlRate&quot;;
my $mailtype = &quot;Package&quot;;
my $pkgid = &quot;0&quot;;
my $ounces = &quot;&quot;;

($pounds,$ounces) = getweight($pounds);

my $xml = &quot;<IntlRateRequest USERID=\&quot;$username\&quot; PASSWORD=\&quot;$password\&quot;><Package ID=\&quot;$pkgid\&quot;><Pounds>$pounds</Pounds><Ounces>$ounces</Ounces><MailType>$mailtype</MailType><Country>$country</Country></Pakage></IntlRateRequest>&quot;;

$xml = encode($xml);

my ($return_status,@return_service) = handleconnectint($url,$api,$xml);

return ($return_status,@return_service);

} ######### End of subroutine.

#######################################################################
# GetWeight #
#######################################################################

sub getweight {

#########
######### This routine handles the calculation of total pounds
######### and ounces from a decimal based pounds number.
#########

my $pounds = shift;

my $ounces = &quot;&quot;;
my $whole_pounds = sprintf(&quot;%.0f&quot;, $pounds);
my $partial_pounds = &quot;0&quot;;

if ($whole_pounds > &quot;$pounds&quot;) {

$whole_pounds = ($whole_pounds - 1);

} ######### End of if statement.

my $partial_pounds = ($pounds - $whole_pounds);

if ($partial_pounds eq &quot;0&quot;) {

$ounces = &quot;0&quot;;

} else {

$ounces = (16 * $partial_pounds);
$ounces = sprintf(&quot;%.0f&quot;, $ounces);

} ######### End of if statement.

return ($whole_pounds,$ounces);

} ######### End of subroutine.

#######################################################################
# Encode #
#######################################################################

sub encode {

#########
######### This routine handles the mime encoding of the XML string
######### for posting to the USPS URL.
#########

$_ = shift;

s/\|//gs;
s/\n//gs;

return $_;

} ######### End of subroutine.

#######################################################################
# HandleConnectDom #
#######################################################################

sub handleconnectdom {

#########
######### This routine handles the connection to the USPS server and
######### the parsing of the XML response.
#########

my ($url,$api,$xml) = @_;

my $return_status = &quot;&quot;;
my $return_service = &quot;&quot;;
my $return_postage = &quot;&quot;;

#########
######### Make the connection to the USPS server.
#########

my $field_api = &quot;API&quot;;
my $field_xml = &quot;XML&quot;;

my $ua = LWP::UserAgent->new;

my $response = $ua->request(POST $url,
[$field_api => $api,
$field_xml => $xml]);

#########
######### If the response is a success, we parse the output
######### as XML and return the service name and price.
#########

if ($response->is_success) {

my $reply = $response->content;

#########
######### Get information from the Service node.
#########

$reply =~ s/<Service>(.*?)<\/Service>//gs;

$return_service = &quot;$1&quot;;

#########
######### Get information from the Postage node.
#########

$reply =~ s/<Postage>(.*?)<\/Postage>//gs;

$return_postage = &quot;$1&quot;;

#########
######### Base our return value on whether we
######### have a failure or not.
#########

if ($return_service eq &quot;&quot; || $return_postage eq &quot;&quot;) {

$return_status = &quot;FAIL_ERROR&quot;;

} else {

$return_status = &quot;ACCEPT&quot;;

} ######### End of if statement.

#########
######### If there was no response, we return an error.
#########

} else {

$return_status = &quot;FAIL_CONNECT&quot;;

} ######### End of if statement.

return ($return_status,$return_service,$return_postage);

} ######### End of subroutine.

#######################################################################
# HandleConnectInt #
#######################################################################

sub handleconnectint {

#########
######### This routine handles the connection to the USPS server and
######### the parsing of the XML response.
#########

my ($url,$api,$xml) = @_;

my $return_status = &quot;&quot;;
my $return_service = &quot;&quot;;
my $return_postage = &quot;&quot;;
my @return_service = ();
my @return_servicedet = ();
my $reply_prefix = &quot;&quot;;
my $reply_id = &quot;&quot;;
my $reply_contents = &quot;&quot;;

#########
######### Make the connection to the USPS server.
#########

my $field_api = &quot;API&quot;;
my $field_xml = &quot;XML&quot;;

my $ua = LWP::UserAgent->new;

my $response = $ua->request(POST $url,
[$field_api => $api,
$field_xml => $xml]);

#########
######### If the response is a success, we parse the output
######### as XML and return the service name and price.
#########

if ($response->is_success) {

my $reply = $response->content;

while ($reply =~ /<Service ID=&quot;.*?&quot;>.*?<\/Service>/) {

@return_servicedet = ();

$reply =~ s/^(.*?)<Service ID=&quot;(.*?)&quot;>(.*?)<\/Service>//s;

$reply_prefix = &quot;$1&quot;;
$reply_id = &quot;$2&quot;;
$reply_contents = &quot;$3&quot;;

#########
######### Get information from the SvcDescription node.
#########

$reply_contents =~ s/<SvcDescription>(.*?)<\/SvcDescription>//gs;

$return_service = &quot;$1&quot;;

#########
######### Get information from the Postage node.
#########

$reply_contents =~ s/<Postage>(.*?)<\/Postage>//gs;

$return_postage = &quot;$1&quot;;

if ($return_service ne &quot;&quot; && $return_postage ne &quot;&quot;) {

@return_servicedet = ($return_service,$return_postage);

push(@return_service,[@return_servicedet]);

} ######### End of if statement.

} ######### End of while statement.

#########
######### Base our return value on whether we
######### have a failure or not.
#########

if (!(@return_service)) {

$return_status = &quot;FAIL_ERROR&quot;;

} else {

@return_service = reverse(@return_service);

$return_status = &quot;ACCEPT&quot;;

} ######### End of if statement.

#########
######### If there was no response, we return an error.
#########

} else {

$return_status = &quot;FAIL_CONNECT&quot;;

} ######### End of if statement.

return ($return_status,@return_service);

} ######### End of subroutine.

#######################################################################
# Return True Value For End Of File #
#######################################################################

END {}

1;

__END__

=head1 NAME

Business::USPS - A USPS Interface Module

=head1 AUTHOR

Nick Hendler <webmaster@kryptronic.com>

mailto:webmaster@kryptronic.com


NOTE: USPS is a registered trademark of the United States
Postal Service.

=head1 SEE ALSO

perl(1).

=cut

******************************************
Canada Post File
******************************************

<?xml version=&quot;1.0&quot; ?>
- <!--

***********************************************************************
This file is an example of XML file sent to the Sell Online server
to get the shipping rates and delivery dates of a shopping bag.

It is sent to Sell Online by opening a TCP socket port on:
IP address : 206.191.4.228
TCP Port : 30000

You can use an HTTP POST and submit this XML document to the server
(same IP and same TCP Port). We highly recommand you to open this url
to see an interactive example of the HTTP POST:

Note: The address below is for test purpose. If your web site
is going live, please contact eparcel@canadapost.ca to get the
IP address of our production server (or look at the FAQ)
***********************************************************************


-->
<!DOCTYPE eparcel (View Source for full doctype...)>
- <eparcel>
- <!--

************************************
* Language of choice :
* en=ENGLISH
* fr=FRENCH
* Note: This parameter is OPTIONAL (english = default)
************************************

-->
<language>en</language>
- <ratesAndServicesRequest>
- <!--

************************************
* Merchant ID assigned by Canada Post
* If you don't have one, send a request
* to eparcel@canadapost.ca
* Note: The merchant ID is used by the Sell Online
* server to retrieve the :
* - list of boxes used to pack the items
* - origin postal code
* - ...
************************************

-->
<merchantCPCID>{Insert your merchant ID here}</merchantCPCID>
- <!--
**********************************
From Postal Code.
This parameter will overwrite the one
defined in the merchant's profile
Note: This parameter is OPTIONAL
**********************************

-->
<fromPostalCode>{Insert the postal code your are shipping from}</fromPostalCode>
- <!--
**********************************
Turnaroundtime in hours
If declared here, this parameter will
overwrite the one
defined in the merchant's profile
Note: This parameter is OPTIONAL
**********************************

-->
<turnAroundTime>{Insert your turnaround time}</turnAroundTime>
- <!--

************************************
Total price of the items in this request.
Price is in CA$ and should not include
taxes.
The items price is used to calculate
the insurance and signature fees.
Note: This parameter is OPTIONAL
************************************

-->
<itemsPrice>{Insert items $ here}</itemsPrice>
- <!--

************************************
* Insert here the items in the shopping basket
* The example below show 2 different items
* Each item has the following attributes:
* - Quantity
* - Weight in kg
* - Length, Width and Height in cm
* - Description
************************************


-->
- <lineItems>
- <item>
- <!--

************************************
Item #1 (ordered 3 times)
************************************


-->
<quantity>3</quantity>
<weight>0.6</weight>
<length>10.0</length>
<width>25.0</width>
<height>5.0</height>
<description>My Item #1</description>
</item>
- <item>
- <!--

************************************
Item #2 (ordered 1 time)
************************************


-->
<quantity>3</quantity>
<weight>0.2</weight>
<length>5.0</length>
<width>2.0</width>
<height>1.0</height>
<description>My Item #2</description>
</item>
</lineItems>
- <!--

************************************
Address of destination

(*) For a canadian destination, 'country' and 'postalCode' have
to be valid ('city', 'provOrState' are not used).

(*) For a US destination, 'country' and 'provOrState' have
to be valid. ('city', 'postalCode' are not used for now but zip
code will be used in the future). State can be either full state
name or state code.

(*) For an International destination, only 'country' has
to be valid ('city', 'postalCode' and 'provOrState' are not used).

Country can be fullname or 2-letters country code (ISO 3166)
************************************


-->
<city>Longueuil</city>
<provOrState>Quebec</provOrState>
<country>Canada</country>
<postalCode>J9J1K1</postalCode>
</ratesAndServicesRequest>
</eparcel>
 
Frank,

Do you have a specific problem or a question about these scripts? Mike

Want to get great answers to your Tek-Tips questions? Have a look at faq219-2884

It's like this; even samurai have teddy bears, and even teddy bears get drunk.
 
Sorry can some one right this script for me?
Thanks
 
First, is this script copyrighted? If so, you shouldn't be posting it on the forum.

Second, if you want someone to write it for you, you're going to have to hire professionals. While plenty of us here could do so, this forum is not intended to be used for selling or recruiting. If you post this project at I'll bid on it, along with plenty of other developers.
Sincerely,

Tom Anderson
CEO, Order amid Chaos, Inc.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top