Created
June 15, 2012 02:52
-
-
Save anonymous/2934445 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# DISCLAIMER: Please excuse the horrid formatting and lack of encapsulation, this code was done for a client | |
# who wanted a particular and peculiar style of Perl. It will require some cleanup to work separate from | |
# other shopping cart code that is not included. | |
# | |
# If you find this helpful and wish to give back, please send bitcoin here: | |
# 1KEcqZQFHM53V2Wkv72G15vb1hgBPuVA8V | |
# | |
##SHIPPING FUNCTIONS | |
use XML::DOM; | |
use HTTP::Request; | |
use LWP::UserAgent; | |
################################################################################################################################################################ | |
# gen_fedex_single_xml: generate the xml for a single FedEx rate request | |
sub gen_fedex_single_xml { | |
my $dest_zip = shift; | |
my $weight = shift; | |
my $xmlname = shift; | |
my $req_doc = XML::DOM::Document->new(); | |
my $req_ele = $req_doc->createElement('ns:RateRequest'); | |
$req_doc->appendChild($req_ele); | |
$req_ele->setAttribute('xmlns:ns', 'http://fedex.com/ws/rate/v5'); | |
$req_ele->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance'); | |
$req_ele->setAttribute('xsi:schemaLocation', 'http://fedex.com/ws/rate/v5 RateService_v5.xsd'); | |
# begin authentication | |
my $auth_ele = $req_doc->createElement('ns:WebAuthenticationDetail'); | |
$req_ele->appendChild($auth_ele); | |
my $user_ele = $req_doc->createElement('ns:UserCredential'); | |
$auth_ele->appendChild($user_ele); | |
my $key_ele = $req_doc->createElement('ns:Key'); | |
$user_ele->appendChild($key_ele); | |
my $key_text = $req_doc->createTextNode('e00VRRVx6OsE7527'); | |
$key_ele->appendChild($key_text); | |
my $pass_ele = $req_doc->createElement('ns:Password'); | |
$user_ele->appendChild($pass_ele); | |
my $pass_text = $req_doc->createTextNode('T2MMIh0fUPW5JEdCI7mLhI9tI'); | |
$pass_ele->appendChild($pass_text); | |
my $client_ele = $req_doc->createElement('ns:ClientDetail'); | |
$req_ele->appendChild($client_ele); | |
my $acct_ele = $req_doc->createElement('ns:AccountNumber'); | |
$client_ele->appendChild($acct_ele); | |
my $acct_text = $req_doc->createTextNode('451494384'); | |
$acct_ele->appendChild($acct_text); | |
my $meter_ele = $req_doc->createElement('ns:MeterNumber'); | |
$client_ele->appendChild($meter_ele); | |
my $meter_text = $req_doc->createTextNode('100556521'); | |
$meter_ele->appendChild($meter_text); | |
# end authentication | |
# begin api version info | |
my $vers_ele = $req_doc->createElement('ns:Version'); | |
$req_ele->appendChild($vers_ele); | |
my $svc_ele = $req_doc->createElement('ns:ServiceId'); | |
$vers_ele->appendChild($svc_ele); | |
my $svc_text = $req_doc->createTextNode('crs'); | |
$svc_ele->appendChild($svc_text); | |
my $mjr_ele = $req_doc->createElement('ns:Major'); | |
$vers_ele->appendChild($mjr_ele); | |
my $mjr_text = $req_doc->createTextNode('5'); | |
$mjr_ele->appendChild($mjr_text); | |
my $int_ele = $req_doc->createElement('ns:Intermediate'); | |
$vers_ele->appendChild($int_ele); | |
my $int_text = $req_doc->createTextNode('0'); | |
$int_ele->appendChild($int_text); | |
my $mnr_ele = $req_doc->createElement('ns:Minor'); | |
$vers_ele->appendChild($mnr_ele); | |
my $mnr_text = $req_doc->createTextNode('0'); | |
$mnr_ele->appendChild($mnr_text); | |
# end api version info | |
# begin shipment info | |
my $rship_ele = $req_doc->createElement('ns:RequestedShipment'); | |
$req_ele->appendChild($rship_ele); | |
my $stype_ele = $req_doc->createElement('ns:ServiceType'); | |
$rship_ele->appendChild($stype_ele); | |
my $stype_text = $req_doc->createTextNode($xmlname); | |
$stype_ele->appendChild($stype_text); | |
my $origin_ele = $req_doc->createElement('ns:Shipper'); | |
$rship_ele->appendChild($origin_ele); | |
my $sp_ele = $req_doc->createElement('ns:Address'); | |
$origin_ele->appendChild($sp_ele); | |
my $ozip_ele = $req_doc->createElement('ns:PostalCode'); | |
$sp_ele->appendChild($ozip_ele); | |
my $ozip_text = $req_doc->createTextNode($ourpostal); | |
$ozip_ele->appendChild($ozip_text); | |
my $scountry_ele = $req_doc->createElement('ns:CountryCode'); | |
$sp_ele->appendChild($scountry_ele); | |
my $scountry_text = $req_doc->createTextNode('US'); | |
$scountry_ele->appendChild($scountry_text); | |
my $dest_ele = $req_doc->createElement('ns:Recipient'); | |
$rship_ele->appendChild($dest_ele); | |
my $rp_ele = $req_doc->createElement('ns:Address'); | |
$dest_ele->appendChild($rp_ele); | |
my $dzip_ele = $req_doc->createElement('ns:PostalCode'); | |
$rp_ele->appendChild($dzip_ele); | |
my $dzip_text = $req_doc->createTextNode($dest_zip); | |
$dzip_ele->appendChild($dzip_text); | |
my $dcountry_ele = $req_doc->createElement('ns:CountryCode'); | |
$rp_ele->appendChild($dcountry_ele); | |
my $dcountry_text = $req_doc->createTextNode('US'); | |
$dcountry_ele->appendChild($dcountry_text); | |
my $detail_ele = $req_doc->createElement('ns:PackageDetail'); | |
$rship_ele->appendChild($detail_ele); | |
my $detail_text = $req_doc->createTextNode('INDIVIDUAL_PACKAGES'); | |
$detail_ele->appendChild($detail_text); | |
my $pkg_ele = $req_doc->createElement('ns:RequestedPackages'); | |
$rship_ele->appendChild($pkg_ele); | |
my $bill_ele = $req_doc->createElement('ns:Weight'); | |
$pkg_ele->appendChild($bill_ele); | |
my $unit_ele = $req_doc->createElement('ns:Units'); | |
$bill_ele->appendChild($unit_ele); | |
my $unit_text = $req_doc->createTextNode('LB'); | |
$unit_ele->appendChild($unit_text); | |
my $val_ele = $req_doc->createElement('ns:Value'); | |
$bill_ele->appendChild($val_ele); | |
my $val_text = $req_doc->createTextNode($weight); | |
$val_ele->appendChild($val_text); | |
return $req_doc->toString; | |
} | |
# get_fedex_single_rate_from_xml: retreives a single rate from the xml | |
sub get_fedex_single_rate_from_xml { | |
my $xml = shift; | |
my $parser = new XML::DOM::Parser; | |
my $response = $parser->parse($xml); | |
my $charges = $response->getElementsByTagName('v5:TotalNetCharge'); | |
if ($charges) { | |
if ($charge = $charges->item(0)) { | |
$rates = $charge->getElementsByTagName('v5:Amount'); | |
} else { our $debugxml = $xml; return -1; } | |
} else { our $debugxml = $xml; return -1; } | |
if ($rates) { | |
if ($rate = $rates->item(0)) { | |
return $rate->getFirstChild->getNodeValue; | |
} else { our $debugxml = $xml; return -1; } | |
} else { our $debugxml = $xml; return -1; } | |
} | |
# get_fedex_single_rate: fetches a single FedEx rate for shipping the package | |
sub get_fedex_single_rate { | |
# generate request | |
my $xml = gen_fedex_single_xml(shift, shift, shift); | |
my $content = $xml; | |
my $request = HTTP::Request->new( 'POST', "https://gateway.fedex.com:443/xml" ); | |
$request->header('content-type' => 'text/xml'); | |
$request->header('content-length' => length($content)); | |
$request->content($content); | |
my $response; | |
my $ua = LWP::UserAgent->new; | |
$ua->timeout(5); | |
# make request | |
$response = $ua->request($request); | |
if (!$response->is_success){ | |
return $response->status_line; | |
} | |
# process request | |
return get_fedex_single_rate_from_xml($response->content); | |
} | |
# gen_usps_single_xml: generate the xml for a single USPS rate request | |
sub gen_usps_single_xml { | |
my $dest_zip = shift; | |
my $weight = shift; | |
my $xmlname = shift; | |
my $pounds = int($weight); | |
my $ounces = int(($weight - $pounds)*16); | |
my $req_doc = XML::DOM::Document->new(); | |
my $req_ele = $req_doc->createElement('RateV2Request'); | |
$req_ele->setAttribute('USERID', '900MYWEB2446'); | |
$req_ele->setAttribute('PASSWORD', '697HO61CR382'); | |
$req_doc->appendChild($req_ele); | |
my $pack_ele = $req_doc->createElement('Package'); | |
$pack_ele->setAttribute('ID', '0'); | |
$req_ele->appendChild($pack_ele); | |
my $serv_ele = $req_doc->createElement('Service'); | |
my $serv_text = $req_doc->createTextNode($xmlname); | |
$serv_ele->appendChild($serv_text); | |
$pack_ele->appendChild($serv_ele); | |
my $orig_ele = $req_doc->createElement('ZipOrigination'); | |
my $orig_text = $req_doc->createTextNode($ourpostal); | |
$orig_ele->appendChild($orig_text); | |
$pack_ele->appendChild($orig_ele); | |
my $dest_ele = $req_doc->createElement('ZipDestination'); | |
my $dest_text = $req_doc->createTextNode($dest_zip); | |
$dest_ele->appendChild($dest_text); | |
$pack_ele->appendChild($dest_ele); | |
my $lbs_ele = $req_doc->createElement('Pounds'); | |
my $lbs_text = $req_doc->createTextNode($pounds); | |
$lbs_ele->appendChild($lbs_text); | |
$pack_ele->appendChild($lbs_ele); | |
my $ozs_ele = $req_doc->createElement('Ounces'); | |
my $ozs_text = $req_doc->createTextNode($ounces); | |
$ozs_ele->appendChild($ozs_text); | |
$pack_ele->appendChild($ozs_ele); | |
my $size_ele = $req_doc->createElement('Size'); | |
my $size_text = $req_doc->createTextNode('REGULAR'); | |
$size_ele->appendChild($size_text); | |
$pack_ele->appendChild($size_ele); | |
my $mach_ele = $req_doc->createElement('Machinable'); | |
my $mach_text = $req_doc->createTextNode('true'); | |
$mach_ele->appendChild($mach_text); | |
$pack_ele->appendChild($mach_ele); | |
return $req_doc->toString; | |
} | |
# get_usps_single_rate_from_xml: retreives a single rate from the xml | |
sub get_usps_single_rate_from_xml { | |
my $xml = shift; | |
my $parser = new XML::DOM::Parser; | |
my $response = $parser->parse($xml); | |
my $rates = $response->getElementsByTagName("Rate"); | |
if ($rates->item(0)) { | |
return $rates->item(0)->getFirstChild->getNodeValue; | |
} else { our $debugxml = $xml; return -1; } | |
} | |
# get_usps_single_rate: fetches a single USPS rate for shipping the package | |
sub get_usps_single_rate { | |
# generate request | |
my $xml = gen_usps_single_xml(shift, shift, shift); | |
my $content = "API=RateV2&XML=$xml"; | |
my $request = HTTP::Request->new( 'POST', "http://production.shippingapis.com/ShippingAPI.dll" ); | |
$request->header('content-type' => 'application/x-www-form-urlencoded'); | |
$request->header('content-length' => length($content)); | |
$request->content($content); | |
my $response; | |
my $ua = LWP::UserAgent->new; | |
$ua->timeout(5); | |
# make request | |
$response = $ua->request($request); | |
if (!$response->is_success){ | |
return 0; | |
} | |
# process request | |
return get_usps_single_rate_from_xml($response->content); | |
} | |
# gen_ups_single_xml: generate the xml for a single USPS rate request | |
sub gen_ups_single_xml { | |
my $dest_zip = shift; | |
my $pounds = shift; | |
my $xmlname = shift; | |
my $accreq_doc = XML::DOM::Document->new(); | |
my $acc_ele = $accreq_doc->createElement('AccessRequest'); | |
$accreq_doc->appendChild($acc_ele); | |
my $lic_ele = $accreq_doc->createElement('AccessLicenseNumber'); | |
$acc_ele->appendChild($lic_ele); | |
my $lic_text = $accreq_doc->createTextNode('7C3CBD368FC9E756'); | |
$lic_ele->appendChild($lic_text); | |
my $user_ele = $accreq_doc->createElement('UserId'); | |
$acc_ele->appendChild($user_ele); | |
my $user_text = $accreq_doc->createTextNode('mywebpilot'); | |
$user_ele->appendChild($user_text); | |
my $pass_ele = $accreq_doc->createElement('Password'); | |
$acc_ele->appendChild($pass_ele); | |
my $pass_text = $accreq_doc->createTextNode('rae437ty'); | |
$pass_ele->appendChild($pass_text); | |
my $req_doc = XML::DOM::Document->new(); | |
my $rssr_ele = $req_doc->createElement('RatingServiceSelectionRequest'); | |
$req_doc->appendChild($rssr_ele); | |
my $req_ele = $req_doc->createElement('Request'); | |
$rssr_ele->appendChild($req_ele); | |
my $ra_ele = $req_doc->createElement('RequestAction'); | |
$req_ele->appendChild($ra_ele); | |
my $ra_text = $req_doc->createTextNode('Rate'); | |
$ra_ele->appendChild($ra_text); | |
my $ship_ele = $req_doc->createElement('Shipment'); | |
$rssr_ele->appendChild($ship_ele); | |
my $shipper_ele = $req_doc->createElement('Shipper'); | |
$ship_ele->appendChild($shipper_ele); | |
my $sadd_ele = $req_doc->createElement('Address'); | |
$shipper_ele->appendChild($sadd_ele); | |
my $szip_ele = $req_doc->createElement('PostalCode'); | |
$sadd_ele->appendChild($szip_ele); | |
my $szip_text = $req_doc->createTextNode($ourpostal); | |
$szip_ele->appendChild($szip_text); | |
my $scountry_ele = $req_doc->createElement('CountryCode'); | |
$sadd_ele->appendChild($scountry_ele); | |
my $scountry_text = $req_doc->createTextNode('US'); | |
$scountry_ele->appendChild($scountry_text); | |
my $shipto_ele = $req_doc->createElement('ShipTo'); | |
$ship_ele->appendChild($shipto_ele); | |
my $radd_ele = $req_doc->createElement('Address'); | |
$shipto_ele->appendChild($radd_ele); | |
my $rzip_ele = $req_doc->createElement('PostalCode'); | |
$radd_ele->appendChild($rzip_ele); | |
my $rzip_text = $req_doc->createTextNode($dest_zip); | |
$rzip_ele->appendChild($rzip_text); | |
my $rcountry_ele = $req_doc->createElement('CountryCode'); | |
$radd_ele->appendChild($rcountry_ele); | |
my $rcountry_text = $req_doc->createTextNode('US'); | |
$rcountry_ele->appendChild($rcountry_text); | |
my $shipfrom_ele = $req_doc->createElement('ShipFrom'); | |
$ship_ele->appendChild($shipfrom_ele); | |
my $sfadd_ele = $req_doc->createElement('Address'); | |
$shipfrom_ele->appendChild($sfadd_ele); | |
my $sfzip_ele = $req_doc->createElement('PostalCode'); | |
$sfadd_ele->appendChild($sfzip_ele); | |
my $sfzip_text = $req_doc->createTextNode($ourpostal); | |
$sfzip_ele->appendChild($sfzip_text); | |
my $sfcountry_ele = $req_doc->createElement('CountryCode'); | |
$sfadd_ele->appendChild($sfcountry_ele); | |
my $sfcountry_text = $req_doc->createTextNode('US'); | |
$sfcountry_ele->appendChild($sfcountry_text); | |
my $serv_ele = $req_doc->createElement('Service'); | |
$ship_ele->appendChild($serv_ele); | |
my $scode_ele = $req_doc->createElement('Code'); | |
$serv_ele->appendChild($scode_ele); | |
my $scode_text = $req_doc->createTextNode($xmlname); | |
$scode_ele->appendChild($scode_text); | |
my $pkg_ele = $req_doc->createElement('Package'); | |
$ship_ele->appendChild($pkg_ele); | |
my $pktype_ele = $req_doc->createElement('PackagingType'); | |
$pkg_ele->appendChild($pktype_ele); | |
my $pcode_ele = $req_doc->createElement('Code'); | |
$pktype_ele->appendChild($pcode_ele); | |
my $pcode_text = $req_doc->createTextNode('02'); # 02 = Package | |
$pcode_ele->appendChild($pcode_text); | |
my $pweight_ele = $req_doc->createElement('PackageWeight'); | |
$pkg_ele->appendChild($pweight_ele); | |
my $uom_ele = $req_doc->createElement('UnitOfMeasurement'); | |
$pweight_ele->appendChild($uom_ele); | |
my $uomcode_ele = $req_doc->createElement('Code'); | |
$uom_ele->appendChild($uomcode_ele); | |
my $uomcode_text = $req_doc->createTextNode('LBS'); | |
$uomcode_ele->appendChild($uomcode_text); | |
my $weight_ele = $req_doc->createElement('Weight'); | |
$pweight_ele->appendChild($weight_ele); | |
my $weight_text = $req_doc->createTextNode($pounds); | |
$weight_ele->appendChild($weight_text); | |
return $accreq_doc->toString . $req_doc->toString; | |
} | |
# get_ups_single_rate_from_xml: retreives a single UPS rate from the xml | |
sub get_ups_single_rate_from_xml { | |
my $xml = shift; | |
my $parser = new XML::DOM::Parser; | |
my $response = $parser->parse($xml); | |
my $charges = $response->getElementsByTagName('TotalCharges'); | |
if ($charges->item(0)) { | |
my $rates = $charges->item(0)->getElementsByTagName('MonetaryValue'); | |
} else { our $debugxml = $xml; return -1; } | |
if ($rates->item(0)) { | |
return $rates->item(0)->getFirstChild->getNodeValue; | |
} else { our $debugxml = $xml; return -1; } | |
} | |
# get_ups_single_rate: fetches a single USPS rate for shipping the package | |
sub get_ups_single_rate { | |
# generate request | |
my $content = gen_ups_single_xml(shift, shift, shift); | |
my $request = HTTP::Request->new( 'POST', "https://wwwcie.ups.com/ups.app/xml/Rate" ); | |
$request->header('content-type' => 'text/xml'); | |
$request->header('content-length' => length($content)); | |
$request->content($content); | |
my $response; | |
my $ua = LWP::UserAgent->new; | |
$ua->timeout(5); | |
# make request | |
$response = $ua->request($request); | |
if (!$response->is_success){ | |
return 0; | |
} | |
# process request | |
return get_ups_single_rate_from_xml($response->content); | |
} | |
# update_ship_rate: updates the shipping rate for a given cart | |
sub update_ship_rate { | |
my $sm = $cart->{'shippingmethod'}; | |
$update = $dbh->prepare('UPDATE `shoppingcarts` SET `shippingmethod`=? WHERE `cartid` = ?'); | |
if ($cart->{'shipweight'} < 1.0 && | |
($sm < 6 || $sm > 8) && $sm != 13) { | |
if ($sm < 4) { | |
$update->execute(6, $cartid); | |
} elsif ($sm == 4) { | |
$update->execute(7, $cartid); | |
} else { | |
$update->execute(8, $cartid); | |
} | |
$cartquery->execute($cart->{'cartid'}) or die "SQL Error: $DBI::errstr\n"; | |
$cart = $cartquery->fetchrow_hashref; | |
} elsif ($cart->{'shipweight'} >= 1.0 && | |
$sm > 5 && $sm != 13) { | |
if ($sm == 6) { | |
$update->execute(3, $cartid); | |
} elsif ($sm == 7) { | |
$update->execute(4, $cartid); | |
} else { | |
$update->execute(5, $cartid); | |
} | |
$cartquery->execute($cart->{'cartid'}) or die "SQL Error: $DBI::errstr\n"; | |
$cart = $cartquery->fetchrow_hashref; | |
} | |
my $methodquery = $dbh->prepare('SELECT * FROM `shipmethods` WHERE `shipmethodid` = ?'); | |
$methodquery->execute($cart->{'shippingmethod'}) or die "SQL Error: $DBI::errstr\n"; | |
my $method = $methodquery->fetchrow_hashref; | |
my $newrate; | |
if ($method->{'method'} eq "Free Shipping Ground") { $newrate = 0; } | |
else { | |
my $func; | |
if ($method->{'provider'} eq "FedEx") { $func = "get_fedex_single_rate"; } | |
elsif ($method->{'provider'} eq "USPS") { $func = "get_usps_single_rate"; } | |
elsif ($method->{'provider'} eq "UPS") { $func = "get_ups_single_rate"; } | |
my $insert = $dbh->prepare('INSERT INTO `debugshipping` (`shipmethodid`,`xml`) VALUES (?,?)'); | |
$tries = 0; | |
$error = 0; | |
do { | |
$weight = $cart->{'shipweight'}; | |
$newrate = 0; | |
while ($weight > 70) { | |
$rate = &{$func}($cart->{'shippingpostal'}, 70, $method->{'xmlname'}); | |
if ($rate != -1) { $newrate += $rate; } | |
else { | |
$error = 1; | |
$insert->execute($cart->{'shippingmethod'}, $debugxml) or die "SQL Error: $DBI::errstr\n"; | |
} | |
$weight -= 70; | |
} | |
if (!$error) { | |
$rate = &{$func}($cart->{'shippingpostal'}, $weight, $method->{'xmlname'}); | |
if ($rate != -1) { $newrate += $rate; } | |
else { | |
$error = 1; | |
$insert->execute($cart->{'shippingmethod'}, $debugxml) or die "SQL Error: $DBI::errstr\n"; | |
} | |
} | |
$tries++; | |
} while ($error && $tries < 3); | |
} | |
if ($newrate == -1) { | |
my $insert = $dbh->prepare('INSERT INTO `debugshipping` (`shipmethodid`,`xml`) VALUES (?,?)'); | |
$insert->execute($cart->{'shippingmethod'}, $debugxml) or die "SQL Error: $DBI::errstr\n"; | |
$newrate = 0; | |
} | |
my $update = $dbh->prepare('UPDATE `shoppingcarts` SET `shipcost` = ? WHERE `cartid` = ?'); | |
$update->execute($newrate, $cart->{'cartid'}) or die "SQL Error: $DBI::errstr\n"; | |
return $newrate; | |
} | |
# gen_fedex_all_xml: generate the xml for all FedEx rates | |
sub gen_fedex_all_xml { | |
my $dest_zip = shift; | |
my $weight = shift; | |
my $req_doc = XML::DOM::Document->new(); | |
my $req_ele = $req_doc->createElement('ns:RateRequest'); | |
$req_doc->appendChild($req_ele); | |
$req_ele->setAttribute('xmlns:ns', 'http://fedex.com/ws/rate/v5'); | |
$req_ele->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance'); | |
$req_ele->setAttribute('xsi:schemaLocation', 'http://fedex.com/ws/rate/v5 RateService_v5.xsd'); | |
# begin authentication | |
my $auth_ele = $req_doc->createElement('ns:WebAuthenticationDetail'); | |
$req_ele->appendChild($auth_ele); | |
my $user_ele = $req_doc->createElement('ns:UserCredential'); | |
$auth_ele->appendChild($user_ele); | |
my $key_ele = $req_doc->createElement('ns:Key'); | |
$user_ele->appendChild($key_ele); | |
my $key_text = $req_doc->createTextNode('e00VRRVx6OsE7527'); | |
# test env my $key_text = $req_doc->createTextNode('fMHk0WRwCMnndVsI'); | |
$key_ele->appendChild($key_text); | |
my $pass_ele = $req_doc->createElement('ns:Password'); | |
$user_ele->appendChild($pass_ele); | |
my $pass_text = $req_doc->createTextNode('T2MMIh0fUPW5JEdCI7mLhI9tI'); | |
# test env my $pass_text = $req_doc->createTextNode('DPxzK8bKfsvZx1wvbOkAzZyps'); | |
$pass_ele->appendChild($pass_text); | |
my $client_ele = $req_doc->createElement('ns:ClientDetail'); | |
$req_ele->appendChild($client_ele); | |
my $acct_ele = $req_doc->createElement('ns:AccountNumber'); | |
$client_ele->appendChild($acct_ele); | |
my $acct_text = $req_doc->createTextNode('451494384'); | |
# test env my $acct_text = $req_doc->createTextNode('510087305'); | |
$acct_ele->appendChild($acct_text); | |
my $meter_ele = $req_doc->createElement('ns:MeterNumber'); | |
$client_ele->appendChild($meter_ele); | |
my $meter_text = $req_doc->createTextNode('100556521'); | |
# test env my $meter_text = $req_doc->createTextNode('100000766'); | |
$meter_ele->appendChild($meter_text); | |
# end authentication | |
# begin api version info | |
my $vers_ele = $req_doc->createElement('ns:Version'); | |
$req_ele->appendChild($vers_ele); | |
my $svc_ele = $req_doc->createElement('ns:ServiceId'); | |
$vers_ele->appendChild($svc_ele); | |
my $svc_text = $req_doc->createTextNode('crs'); | |
$svc_ele->appendChild($svc_text); | |
my $mjr_ele = $req_doc->createElement('ns:Major'); | |
$vers_ele->appendChild($mjr_ele); | |
my $mjr_text = $req_doc->createTextNode('5'); | |
$mjr_ele->appendChild($mjr_text); | |
my $int_ele = $req_doc->createElement('ns:Intermediate'); | |
$vers_ele->appendChild($int_ele); | |
my $int_text = $req_doc->createTextNode('0'); | |
$int_ele->appendChild($int_text); | |
my $mnr_ele = $req_doc->createElement('ns:Minor'); | |
$vers_ele->appendChild($mnr_ele); | |
my $mnr_text = $req_doc->createTextNode('0'); | |
$mnr_ele->appendChild($mnr_text); | |
# end api version info | |
# begin shipment info | |
my $rship_ele = $req_doc->createElement('ns:RequestedShipment'); | |
$req_ele->appendChild($rship_ele); | |
my $origin_ele = $req_doc->createElement('ns:Shipper'); | |
$rship_ele->appendChild($origin_ele); | |
my $sp_ele = $req_doc->createElement('ns:Address'); | |
$origin_ele->appendChild($sp_ele); | |
my $ozip_ele = $req_doc->createElement('ns:PostalCode'); | |
$sp_ele->appendChild($ozip_ele); | |
my $ozip_text = $req_doc->createTextNode($ourpostal); | |
$ozip_ele->appendChild($ozip_text); | |
my $scountry_ele = $req_doc->createElement('ns:CountryCode'); | |
$sp_ele->appendChild($scountry_ele); | |
my $scountry_text = $req_doc->createTextNode('US'); | |
$scountry_ele->appendChild($scountry_text); | |
my $dest_ele = $req_doc->createElement('ns:Recipient'); | |
$rship_ele->appendChild($dest_ele); | |
my $rp_ele = $req_doc->createElement('ns:Address'); | |
$dest_ele->appendChild($rp_ele); | |
my $dzip_ele = $req_doc->createElement('ns:PostalCode'); | |
$rp_ele->appendChild($dzip_ele); | |
my $dzip_text = $req_doc->createTextNode($dest_zip); | |
$dzip_ele->appendChild($dzip_text); | |
my $dcountry_ele = $req_doc->createElement('ns:CountryCode'); | |
$rp_ele->appendChild($dcountry_ele); | |
my $dcountry_text = $req_doc->createTextNode('US'); | |
$dcountry_ele->appendChild($dcountry_text); | |
my $detail_ele = $req_doc->createElement('ns:PackageDetail'); | |
$rship_ele->appendChild($detail_ele); | |
my $detail_text = $req_doc->createTextNode('INDIVIDUAL_PACKAGES'); | |
$detail_ele->appendChild($detail_text); | |
my $pkg_ele = $req_doc->createElement('ns:RequestedPackages'); | |
$rship_ele->appendChild($pkg_ele); | |
my $bill_ele = $req_doc->createElement('ns:Weight'); | |
$pkg_ele->appendChild($bill_ele); | |
my $unit_ele = $req_doc->createElement('ns:Units'); | |
$bill_ele->appendChild($unit_ele); | |
my $unit_text = $req_doc->createTextNode('LB'); | |
$unit_ele->appendChild($unit_text); | |
my $val_ele = $req_doc->createElement('ns:Value'); | |
$bill_ele->appendChild($val_ele); | |
my $val_text = $req_doc->createTextNode($weight); | |
$val_ele->appendChild($val_text); | |
return $req_doc->toString; | |
} | |
# get_fedex_all_rate_from_xml: retreives all rates from the xml | |
sub get_fedex_all_rates_from_xml { | |
my $xml = shift; | |
my $methods = shift; | |
my $parser = new XML::DOM::Parser; | |
my $response = $parser->parse($xml); | |
my $rates = $response->getElementsByTagName('v5:RateReplyDetails'); | |
my $n = $rates->getLength; | |
undef %is_name; | |
for (@$methods) { $is_name{$_->{'xmlname'}} = $_->{'shipmethodid'}; } | |
my @return; | |
for my $i (0 .. $n - 1) { | |
my $rate = $rates->item($i); | |
my $svc = $rate->getElementsByTagName('v5:ServiceType')->item(0)->getFirstChild->getNodeValue; | |
if ($is_name{$svc}) { | |
my $details = $rate->getElementsByTagName('v5:RatedShipmentDetails')->item(0); | |
my $charge = $details->getElementsByTagName('v5:TotalNetCharge')->item(0); | |
my $value = $charge->getElementsByTagName('v5:Amount')->item(0)->getFirstChild->getNodeValue; | |
push @return, {$is_name{$svc}, $value}; | |
} | |
} | |
return @return; | |
} | |
# get_fedex_all_rates: fetches all FedEx rates for shipping the package | |
sub get_fedex_all_rates { | |
# generate request | |
my $xml = gen_fedex_all_xml(shift, shift); | |
my $content = $xml; | |
my $request = HTTP::Request->new( 'POST', "https://gateway.fedex.com:443/xml" ); | |
# test env my $request = HTTP::Request->new( 'POST', "https://gatewaybeta.fedex.com:443/xml" ); | |
$request->header('content-type' => 'text/xml'); | |
$request->header('content-length' => length($content)); | |
$request->content($content); | |
my $response; | |
my $ua = LWP::UserAgent->new; | |
$ua->timeout(5); | |
# make request | |
$response = $ua->request($request); | |
if (!$response->is_success) { | |
return $response->status_line; | |
} | |
# process request | |
return get_fedex_all_rates_from_xml($response->content, shift); | |
} | |
# gen_usps_all_xml: generate the xml for all USPS rates | |
sub gen_usps_all_xml { | |
my $dest_zip = shift; | |
my $weight = shift; | |
my $pounds = int($weight); | |
my $ounces = int(($weight - $pounds)*16); | |
my $req_doc = XML::DOM::Document->new(); | |
my $req_ele = $req_doc->createElement('RateV2Request'); | |
$req_ele->setAttribute('USERID', '900MYWEB2446'); | |
$req_ele->setAttribute('PASSWORD', '697HO61CR382'); | |
$req_doc->appendChild($req_ele); | |
my $pack_ele = $req_doc->createElement('Package'); | |
$pack_ele->setAttribute('ID', '0'); | |
$req_ele->appendChild($pack_ele); | |
my $serv_ele = $req_doc->createElement('Service'); | |
my $serv_text = $req_doc->createTextNode('ALL'); | |
$serv_ele->appendChild($serv_text); | |
$pack_ele->appendChild($serv_ele); | |
my $orig_ele = $req_doc->createElement('ZipOrigination'); | |
my $orig_text = $req_doc->createTextNode($ourpostal); | |
$orig_ele->appendChild($orig_text); | |
$pack_ele->appendChild($orig_ele); | |
my $dest_ele = $req_doc->createElement('ZipDestination'); | |
my $dest_text = $req_doc->createTextNode($dest_zip); | |
$dest_ele->appendChild($dest_text); | |
$pack_ele->appendChild($dest_ele); | |
my $lbs_ele = $req_doc->createElement('Pounds'); | |
my $lbs_text = $req_doc->createTextNode($pounds); | |
$lbs_ele->appendChild($lbs_text); | |
$pack_ele->appendChild($lbs_ele); | |
my $ozs_ele = $req_doc->createElement('Ounces'); | |
my $ozs_text = $req_doc->createTextNode($ounces); | |
$ozs_ele->appendChild($ozs_text); | |
$pack_ele->appendChild($ozs_ele); | |
my $size_ele = $req_doc->createElement('Size'); | |
my $size_text = $req_doc->createTextNode('REGULAR'); | |
$size_ele->appendChild($size_text); | |
$pack_ele->appendChild($size_ele); | |
my $mach_ele = $req_doc->createElement('Machinable'); | |
my $mach_text = $req_doc->createTextNode('true'); | |
$mach_ele->appendChild($mach_text); | |
$pack_ele->appendChild($mach_ele); | |
return $req_doc->toString; | |
} | |
# get_usps_all_rate_from_xml: retreives all rates from the xml | |
sub get_usps_all_rates_from_xml { | |
my $xml = shift; | |
my $methods = shift; | |
my $parser = new XML::DOM::Parser; | |
my $response = $parser->parse($xml); | |
my $rates = $response->getElementsByTagName('Postage'); | |
my $n = $rates->getLength; | |
undef %is_name; | |
for (@$methods) { $is_name{$_->{'xmlname'}} = $_->{'shipmethodid'}; } | |
my @return; | |
for my $i (0 .. $n - 1) { | |
my $rate = $rates->item($i); | |
my $svc = $rate->getElementsByTagName('MailService')->item(0)->getFirstChild->getNodeValue; | |
my $code; | |
if ($svc eq "Express Mail") { $code = "EXPRESS"; } | |
elsif ($svc eq "Priority Mail") { $code = "PRIORITY"; } | |
elsif ($svc eq "Parcel Post" ) { $code = "PARCEL"; } | |
if ($is_name{$code}) { | |
my $value = $rate->getElementsByTagName('Rate')->item(0)->getFirstChild->getNodeValue; | |
push @return, {$is_name{$code}, $value}; | |
} | |
} | |
return @return; | |
my $xml = shift; | |
my $xmlnames = shift; | |
return @$xmlnames; | |
my $parser = new XML::DOM::Parser; | |
my $response = $parser->parse($xml); | |
my $rates = $response->getElementsByTagName("Rate"); | |
return $rates->item(0)->getFirstChild->getNodeValue; | |
} | |
# get_usps_all_rates: fetches all USPS rates for shipping the package | |
sub get_usps_all_rates { | |
# generate request | |
my $xml = gen_usps_all_xml(shift, shift); | |
my $content = "API=RateV2&XML=$xml"; | |
my $request = HTTP::Request->new( 'POST', "http://production.shippingapis.com/ShippingAPI.dll" ); | |
$request->header('content-type' => 'application/x-www-form-urlencoded'); | |
$request->header('content-length' => length($content)); | |
$request->content($content); | |
my $response; | |
my $ua = LWP::UserAgent->new; | |
$ua->timeout(5); | |
# make request | |
$response = $ua->request($request); | |
if (!$response->is_success) { | |
return 0; | |
} | |
# process request | |
return get_usps_all_rates_from_xml($response->content, shift); | |
} | |
# gen_ups_all_xml: generate the xml for all USPS rates | |
sub gen_ups_all_xml { | |
my $dest_zip = shift; | |
my $pounds = shift; | |
my $accreq_doc = XML::DOM::Document->new(); | |
my $acc_ele = $accreq_doc->createElement('AccessRequest'); | |
$accreq_doc->appendChild($acc_ele); | |
my $lic_ele = $accreq_doc->createElement('AccessLicenseNumber'); | |
$acc_ele->appendChild($lic_ele); | |
my $lic_text = $accreq_doc->createTextNode('7C3CBD368FC9E756'); | |
$lic_ele->appendChild($lic_text); | |
my $user_ele = $accreq_doc->createElement('UserId'); | |
$acc_ele->appendChild($user_ele); | |
my $user_text = $accreq_doc->createTextNode('mywebpilot'); | |
$user_ele->appendChild($user_text); | |
my $pass_ele = $accreq_doc->createElement('Password'); | |
$acc_ele->appendChild($pass_ele); | |
my $pass_text = $accreq_doc->createTextNode('rae437ty'); | |
$pass_ele->appendChild($pass_text); | |
my $req_doc = XML::DOM::Document->new(); | |
my $rssr_ele = $req_doc->createElement('RatingServiceSelectionRequest'); | |
$req_doc->appendChild($rssr_ele); | |
my $req_ele = $req_doc->createElement('Request'); | |
$rssr_ele->appendChild($req_ele); | |
my $reqopt_ele = $req_doc->createElement('RequestOption'); | |
$req_ele->appendChild($reqopt_ele); | |
my $reqopt_text = $req_doc->createTextNode('Shop'); | |
$reqopt_ele->appendChild($reqopt_text); | |
my $ra_ele = $req_doc->createElement('RequestAction'); | |
$req_ele->appendChild($ra_ele); | |
my $ra_text = $req_doc->createTextNode('Rate'); | |
$ra_ele->appendChild($ra_text); | |
my $ship_ele = $req_doc->createElement('Shipment'); | |
$rssr_ele->appendChild($ship_ele); | |
my $shipper_ele = $req_doc->createElement('Shipper'); | |
$ship_ele->appendChild($shipper_ele); | |
my $sadd_ele = $req_doc->createElement('Address'); | |
$shipper_ele->appendChild($sadd_ele); | |
my $szip_ele = $req_doc->createElement('PostalCode'); | |
$sadd_ele->appendChild($szip_ele); | |
my $szip_text = $req_doc->createTextNode($ourpostal); | |
$szip_ele->appendChild($szip_text); | |
my $scountry_ele = $req_doc->createElement('CountryCode'); | |
$sadd_ele->appendChild($scountry_ele); | |
my $scountry_text = $req_doc->createTextNode('US'); | |
$scountry_ele->appendChild($scountry_text); | |
my $shipto_ele = $req_doc->createElement('ShipTo'); | |
$ship_ele->appendChild($shipto_ele); | |
my $radd_ele = $req_doc->createElement('Address'); | |
$shipto_ele->appendChild($radd_ele); | |
my $rzip_ele = $req_doc->createElement('PostalCode'); | |
$radd_ele->appendChild($rzip_ele); | |
my $rzip_text = $req_doc->createTextNode($dest_zip); | |
$rzip_ele->appendChild($rzip_text); | |
my $rcountry_ele = $req_doc->createElement('CountryCode'); | |
$radd_ele->appendChild($rcountry_ele); | |
my $rcountry_text = $req_doc->createTextNode('US'); | |
$rcountry_ele->appendChild($rcountry_text); | |
my $shipfrom_ele = $req_doc->createElement('ShipFrom'); | |
$ship_ele->appendChild($shipfrom_ele); | |
my $sfadd_ele = $req_doc->createElement('Address'); | |
$shipfrom_ele->appendChild($sfadd_ele); | |
my $sfzip_ele = $req_doc->createElement('PostalCode'); | |
$sfadd_ele->appendChild($sfzip_ele); | |
my $sfzip_text = $req_doc->createTextNode($ourpostal); | |
$sfzip_ele->appendChild($sfzip_text); | |
my $sfcountry_ele = $req_doc->createElement('CountryCode'); | |
$sfadd_ele->appendChild($sfcountry_ele); | |
my $sfcountry_text = $req_doc->createTextNode('US'); | |
$sfcountry_ele->appendChild($sfcountry_text); | |
my $pkg_ele = $req_doc->createElement('Package'); | |
$ship_ele->appendChild($pkg_ele); | |
my $pktype_ele = $req_doc->createElement('PackagingType'); | |
$pkg_ele->appendChild($pktype_ele); | |
my $pcode_ele = $req_doc->createElement('Code'); | |
$pktype_ele->appendChild($pcode_ele); | |
my $pcode_text = $req_doc->createTextNode('02'); # 02 = Package | |
$pcode_ele->appendChild($pcode_text); | |
my $pweight_ele = $req_doc->createElement('PackageWeight'); | |
$pkg_ele->appendChild($pweight_ele); | |
my $uom_ele = $req_doc->createElement('UnitOfMeasurement'); | |
$pweight_ele->appendChild($uom_ele); | |
my $uomcode_ele = $req_doc->createElement('Code'); | |
$uom_ele->appendChild($uomcode_ele); | |
my $uomcode_text = $req_doc->createTextNode('LBS'); | |
$uomcode_ele->appendChild($uomcode_text); | |
my $weight_ele = $req_doc->createElement('Weight'); | |
$pweight_ele->appendChild($weight_ele); | |
my $weight_text = $req_doc->createTextNode($pounds); | |
$weight_ele->appendChild($weight_text); | |
return $accreq_doc->toString . $req_doc->toString; | |
} | |
# get_ups_all_rate_from_xml: retreives all UPS rates from the xml | |
sub get_ups_all_rates_from_xml { | |
my $xml = shift; | |
my $methods = shift; | |
my $parser = new XML::DOM::Parser; | |
my $response = $parser->parse($xml); | |
my $rates = $response->getElementsByTagName('RatedShipment'); | |
my $n = $rates->getLength; | |
undef %is_name; | |
for (@$methods) { $is_name{$_->{'xmlname'}} = $_->{'shipmethodid'}; } | |
my @return; | |
for my $i (0 .. $n - 1) { | |
my $rate = $rates->item($i); | |
my $svc = $rate->getElementsByTagName('Service')->item(0); | |
my $code = $svc->getElementsByTagName('Code')->item(0)->getFirstChild->getNodeValue; | |
if ($is_name{$code}) { | |
my $charges = $rate->getElementsByTagName('TotalCharges'); | |
my $values = $charges->item(0)->getElementsByTagName('MonetaryValue'); | |
my $value = $values->item(0)->getFirstChild->getNodeValue; | |
push @return, {$is_name{$code}, $value}; | |
} | |
} | |
return @return; | |
} | |
# get_ups_all_rates: fetches all USPS rates for shipping the package | |
sub get_ups_all_rates { | |
# generate request | |
my $content = gen_ups_all_xml(shift, shift); | |
my $request = HTTP::Request->new( 'POST', "https://wwwcie.ups.com/ups.app/xml/Rate" ); | |
$request->header('content-type' => 'text/xml'); | |
$request->header('content-length' => length($content)); | |
$request->content($content); | |
my $response; | |
my $ua = LWP::UserAgent->new; | |
$ua->timeout(5); | |
# make request | |
$response = $ua->request($request); | |
if (!$response->is_success) { | |
return 0; | |
} | |
# process request | |
return get_ups_all_rates_from_xml($response->content, shift); | |
} | |
# update_ship_rate: updates the shipping rate for a given cart | |
sub get_ship_rates { | |
my $pquery = $dbh->prepare('SELECT * FROM `shipmethods`'); | |
$pquery->execute or die "SQL Error: $DBI::errstr\n"; | |
my $phash = $pquery->fetchall_hashref('provider'); | |
my @providers = keys %$phash; | |
my @rates; | |
my $query = $dbh->prepare('SELECT `xmlname`, `shipmethodid` FROM `shipmethods` WHERE `provider` = ?'); | |
foreach my $p (@providers) { | |
# don't get a rate for free shipping | |
if (!$p) { next; } | |
$query->execute($p); | |
my $func; | |
if ($p eq "FedEx") { $func = "get_fedex_all_rates"; } | |
elsif ($p eq "USPS") { $func = "get_usps_all_rates"; } | |
elsif ($p eq "UPS") { $func = "get_ups_all_rates"; } | |
push @rates, &{$func}($cart->{'shippingpostal'}, $cart->{'shipweight'}, | |
$query->fetchall_arrayref({})); | |
} | |
return @rates; | |
} | |
################################################################################################################################################################ | |
#END FUNCTION; RETURN TRUE | |
1; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment