Sage Pay Reporting API - generated signature hash not valid - php

I am trying to invoke the getTransactionDetail end point on sagepay reporting api (https://www.sagepay.co.uk/file/6946/download-document/Reporting_and_Admin_API_Integration_Guideline_31012014.pdf) and the signature I made as per the following instructions:
does not appear to be working, I am getting an invalid signature response.
Here's what I have tried so far:
<?php
$vendor = 'myvendername';
$username = 'my-username';
$password = 'my-password';
$vpstxid = '{my-vpstxid-guid-here}';
$request = [
'command' => 'getTransactionDetail',
'vendor' => $vendor,
'user' => $username,
'vpstxid' => $vpstxid,
];
$signature = _calculate_request_signature($request);
$request_xml = _build_sagepay_request($request, $signature);
$result = _call_sagepay_server('https://test.sagepay.com/access/access.htm', $request_xml);
$xml = simplexml_load_string($result);
$json = json_encode($xml);
$array = json_decode($json,TRUE);
echo '<pre>'; print_r($array); exit;
function _calculate_request_signature($data) {
global $password;
$req = '';
foreach ($data as $key => $value) {
$req .= '<' . $key . '>' . $value . '</' . $key . '>' . PHP_EOL;
}
$req .= '<password>' . $password . '</password>';
return md5($req);
}
function _build_sagepay_request($data, $signature) {
$result = '<vspaccess>' . PHP_EOL;
foreach ($data as $key => $value) {
$result .= "\t" . '<' . $key . '>' . $value . '</' . $key . '>' . PHP_EOL;
}
$result .= "\t" . '<signature>' . $signature . '</signature>' . PHP_EOL;
$result .= '</vspaccess>';
return $result;
}
function _call_sagepay_server($url, $request_xml)
{ ... snipped ... }
Any ideas?

Ok, I've figured it out:
No tabs / PHP_EOL in the request / signature calc, keep it flat one line xml and it works.
function _calculate_request_signature($data) {
global $password;
$req = '';
foreach ($data as $key => $value) {
$req .= '<' . $key . '>' . $value . '</' . $key . '>';
}
$req .= '<password>' . $password . '</password>';
return strtoupper(md5($req));
}
function _build_sagepay_request($data, $signature) {
$result = '<vspaccess>';
foreach ($data as $key => $value) {
$result .= '<' . $key . '>' . $value . '</' . $key . '>';
}
$result .= '<signature>' . $signature . '</signature>';
$result .= '</vspaccess>';
return $result;
}
function _call_sagepay_server($url, $request_xml)
{
global $lastCurlError;
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HEADER, 0);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, 'XML=' . $request_xml);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_TIMEOUT, 45);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
$result = curl_exec($curl);
$lastCurlError = curl_errno($curl);
curl_close($curl);
return $result;
}

Related

Change proxy service on php file

I have this code that I need to edit by replacing PhantomJsCloud services with brightdata service
function ms_getUrl($url){
$json = urlencode('{url:"' . $url . '",renderType:"plainText",outputAsJson:true}');
$res = getUrl('https://PhantomJsCloud.com/api/browser/v2/ak-4sr84-tyab5-0iyd6-d9w6h-6pw35/?request=' . $json);
$res = json_decode('[' . $res . ']' , 1);
$res = $res[0]['pageResponses'][0]['frameData']['content'];
return $res;
echo '<pre>' . print_r( json_decode('[' . $res . ']' , 1) , 1 ) . '</pre>';exit;
}
This is brightdata example provided by them
<?php
echo 'To enable your free eval account and get CUSTOMER, YOURZONE and '
.'YOURPASS, please contact sales#brightdata.com';
$curl = curl_init('http://lumtest.com/myip.json');
curl_setopt($curl, CURLOPT_PROXY, 'http://zproxy.lum-superproxy.io:22225');
curl_setopt($curl, CURLOPT_PROXYUSERPWD, 'brd-customer-hl_2bevke7f-zone-static:0vavfolixyu6q');
curl_exec($curl);
?>
I tried this but it doesn't use brightdata proxies
function ms_getUrl($url){
$json = urlencode('{url:"' . $url . '",renderType:"plainText",outputAsJson:true"}');
$res = getUrl('http://brd-customer-hl_2bjki87f-zone-static:0vavfkjkyu6a#zproxy.lum-superproxy.io:22225' . $json);
$res = json_decode('[' . $res . ']' , 1);
$res = $res[0]['pageResponses'][0]['frameData']['content'];
return $res;
echo '<pre>' . print_r( json_decode('[' . $res . ']' , 1) , 1 ) . '</pre>';exit;
}

how to send curl request for delete image from s3 bucket in php

function S3_delete($s3_array)
{
$AWSAccessKeyId = 'youraccesskey';
$AWSSecretAccessKey = 'yoursecretaccesskey';
$BucketName = 'yourbucket';
$AWSRegion = 'ap-south-1';
$canonical_uri="/images/coupon_images/medium_banner/2019091810352344157.jpg";
$encoded_uri = str_replace('%2F', '/', rawurlencode($canonical_uri));
if($AWSRegion == 'us-east-1') {
$hostname = trim($BucketName .".s3.amazonaws.com");
$header_string = "host:" . $hostname . "\n";
$signed_headers_string = "host";
} else {
$hostname = trim($BucketName . ".s3-" . $AWSRegion . ".amazonaws.com");
$header_string = "host:" . $hostname . "\n";
$signed_headers_string = "host";
}
$date_text = gmdate('Ymd', time());
$time_text = gmdate('Ymd\THis\Z');
$algorithm = 'AWS4-HMAC-SHA256';
$scope = $date_text . "/" . $AWSRegion . "/s3/aws4_request";
$x_amz_params = array(
'X-Amz-Algorithm' => $algorithm,
'X-Amz-Credential' => $AWSAccessKeyId . '/' . $scope,
'X-Amz-Date' => $time_text,
'X-Amz-SignedHeaders' => $signed_headers_string
);
$expires = 72000;
if ($expires > 0) {
$x_amz_params['X-Amz-Expires'] = $expires;
}
ksort($x_amz_params);
$query_string = "";
foreach ($x_amz_params as $key => $value) {
$query_string .= rawurlencode($key) . '=' . rawurlencode($value) . "&";
}
$query_string = substr($query_string, 0, -1);
$canonical_request = "DELETE\n" . $encoded_uri . "\n" . $query_string . "\n" . $header_string . "\n" . $signed_headers_string . "\nUNSIGNED-PAYLOAD";
$string_to_sign = $algorithm . "\n" . $time_text . "\n" . $scope . "\n" . hash('sha256', $canonical_request, false);
$signing_key = hash_hmac('sha256', 'aws4_request', hash_hmac('sha256', 's3', hash_hmac('sha256', $AWSRegion, hash_hmac('sha256', $date_text, 'AWS4' . $AWSSecretAccessKey, true), true), true), true);
$signature = hash_hmac('sha256', $string_to_sign, $signing_key);
$url = 'https://' . $hostname . $encoded_uri . '?' . $query_string . '&X-Amz-Signature=' . $signature;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_HTTPHEADER);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_exec($ch);
return $httpcode = curl_getinfo($ch);
}
above code give response like this,
SignatureDoesNotMatchThe request signature we calculated does not
match the signature you provided. Check your key and signing
method.AKIAJKLJAHRPH4X4FSMQAWS4-HMAC-SHA256 20190919T053115Z
20190919/ap-south-1/s3/aws4_request
100% work the below code..
S3_delete('201909251745545.jpg','imagesbook/post_blog/'); //call function
function S3_delete($filename,$path)
{
$file_name = $filename;
$file_delete_path = $path;
$aws_access_key_id = 'your-accress-key';
$aws_secret_access_key = 'your-secret-access-key';
$bucket_name = 'your-bucket-name';
$aws_region = 'your-region'; // Enter your aws region Ex. us-east-1
$host_name = $bucket_name . '.s3.amazonaws.com';
$content_acl = 'public-read';
$content_type = '';
$content='';
$content_title = $file_delete_path.$file_name;
$aws_service_name = 's3';
$timestamp = gmdate('Ymd\THis\Z');
$date = gmdate('Ymd');
$request_headers = array();
$request_headers['Content-Type'] = $content_type;
$request_headers['Date'] = $timestamp;
$request_headers['Host'] = $host_name;
$request_headers['x-amz-acl'] = $content_acl;
$request_headers['x-amz-content-sha256'] = hash('sha256',"");
ksort($request_headers);
$canonical_headers = [];
foreach($request_headers as $key => $value)
{
$canonical_headers[] = strtolower($key) . ":" . $value;
}
$canonical_headers = implode("\n", $canonical_headers);
$signed_headers = [];
foreach($request_headers as $key => $value)
{
$signed_headers[] = strtolower($key);
}
$signed_headers = implode(";", $signed_headers);
$canonical_request = [];
$canonical_request[] = "DELETE";
$canonical_request[] = "/" . $content_title;
$canonical_request[] = "";
$canonical_request[] = $canonical_headers;
$canonical_request[] = "";
$canonical_request[] = $signed_headers;
$canonical_request[] = hash('sha256', $content);
$canonical_request = implode("\n", $canonical_request);
$hashed_canonical_request = hash('sha256', $canonical_request);
$scope = [];
$scope[] = $date;
$scope[] = $aws_region;
$scope[] = $aws_service_name;
$scope[] = "aws4_request";
$string_to_sign = [];
$string_to_sign[] = "AWS4-HMAC-SHA256";
$string_to_sign[] = $timestamp;
$string_to_sign[] = implode('/', $scope);
$string_to_sign[] = $hashed_canonical_request;
$string_to_sign = implode("\n", $string_to_sign);
$kSecret = 'AWS4' . $aws_secret_access_key;
$kDate = hash_hmac('sha256', $date, $kSecret, true);
$kRegion = hash_hmac('sha256', $aws_region, $kDate, true);
$kService = hash_hmac('sha256', $aws_service_name, $kRegion, true);
$kSigning = hash_hmac('sha256', 'aws4_request', $kService, true);
$signature = hash_hmac('sha256', $string_to_sign, $kSigning);
$authorization = [
'Credential=' . $aws_access_key_id . '/' . implode('/', $scope),
'SignedHeaders=' . $signed_headers,
'Signature=' . $signature
];
$authorization = 'AWS4-HMAC-SHA256' . ' ' . implode( ',', $authorization);
$curl_headers = [ 'Authorization: ' . $authorization ];
foreach($request_headers as $key => $value)
{
$curl_headers[] = $key . ": " . $value;
}
$url = 'https://' . $host_name . '/' . $content_title;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, $curl_headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
return curl_exec($ch); // return response data 1
//$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
//curl_close($ch);
//return $httpcode;
}

Paypal Payflow FAILURE: Invalid account number [23]

I want to implement Paypal Payflow on my Web Application, i am using PHP language as backend. Since Paypal Payflow SDK has support only for .NET and Java i need to implement myself manually with curl calls.
My code for making a request to Paypal Payflow is following:
$user = 'user1'; // API User Username
$password = '123456'; // API User Password
$vendor = 'mainvendor'; // Merchant Login ID
$cardno=str_replace(' ', '', $_POST["cardNumber"]);
$expdate=str_replace(' ', '', $_POST["cardExpiry"]);
$cvv2=$_POST["cardCVC"];
// Reseller who registered you for Payflow or 'PayPal' if you registered
// directly with PayPal
$partner = 'PayPalCA';
$amount = $_POST["amountcurrency"];
$currency = $currencies["currency"];
$url ='https://payflowpro.paypal.com';
$request = 'USER=' . urlencode($user);
$request .= '&VENDOR=' . urlencode($vendor);
$request .= '&PWD=' . $password;
$request .= '&PARTNER=' . urlencode($partner);
$request .= '&TRXTYPE=S';
$request .= '&TENDER=C';
$request .= '&ACCT=' . str_replace(' ', '', $cardno);
$request .= '&EXPDATE=' . $expdate;
$request .= '&CVV2=' . $cvv2;
$request .= '&AMT=' . $amount;
$request .= '&CURRENCY=' . $currency;
$request .= '&COMMENT1=Bet Deposit';
$request .= '&BILLTOFIRSTNAME=' . $userinfo["user_name"];
$request .= '&BILLTOLASTNAME=' . $userinfo["user_surname"];
$request .= '&BILLTOSTREET=' . $userinfo["street_number"];
$request .= '&BILLTOCITY =' . $userlocation->cityname;
$request .= '&BILLTOSTATE =' . $userlocation->subcountryname;
$request .= '&BILLTOZIP=' . str_replace(' ', '',
$userinfo["postal_code"]);
$request .= '&BILLTOCOUNTRY=' . $userinfo["country"];
$request .= '&CUSTIP=' . $iusers->get_ip_address();
$request .= '&EMAIL=' . $userinfo["user_email"];
$headers = array();
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
$headers[] = 'Content-Length: ' . strlen($request);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $request);
curl_setopt($ch, CURLOPT_HEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);
// Parse results
$response = array();
$result = strstr($result, 'RESULT');
$valArray = explode('&', $result);
foreach ($valArray as $val) {
$valArray2 = explode('=', $val);
$response[$valArray2[0]] = $valArray2[1];
}
if ($response['RESULT'] == 0) {
echo '<span style="color: white;">SUCCESS!</span>';
} else {
echo '<span style="color: white;">FAILURE: ' . $response['RESPMSG'] . ' ['. $response['RESULT'] . ']</span>';
}
When i make the request i get the following response:
FAILURE: Invalid account number [23]
Can someone help me with this issue?
Thanks in advance.

php cURL doesnt print out anything

I am trying to send a HTML form POST data with a cURL, but it seems the response is always empty. I first save all the POST data in an array, and use an implode function. When I echo out the implode string it does return the values, but after the cURL it's just empty.
This is the setup. I call this function after submitting the form
$this->OCIcURL($this->request->post);
public function OCIcURL($post) {
$data_oci = array();
$items_oci = array();
$counter = 0;
$data_oci['~caller'] = 'CTLG';
foreach ($post['item'] as $key => $value)
{
$counter++;
$data_oci['NEW_ITEM-DESCRIPTION[' . $counter . ']'] = $value;
$data_oci['NEW_ITEM-MATNR[' . $counter . ']'] = "";
$data_oci['NEW_ITEM-QUANTITY[' . $counter . ']'] = $post['amount'][$counter];
$data_oci['NEW_ITEM-UNIT[' . $counter . ']'] = "";
$data_oci['NEW_ITEM-PRICE[' . $counter . ']'] = $post['price'][$counter];
$data_oci['NEW_ITEM-CURRENCY[' . $counter . ']'] = $this->session->data['currency'];
$data_oci['NEW_ITEM-PRICEUNIT[' . $counter . ']'] = 1;
$data_oci['NEW_ITEM-LEADTIME[' . $counter . ']'] = "";
$data_oci['NEW_ITEM-VENDOR[' . $counter . ']'] = "";
$data_oci['NEW_ITEM-VENDORMAT[' . $counter . ']'] = "";
$data_oci['NEW_ITEM-MANUFACTCODE[' . $counter . ']'] = "";
$data_oci['NEW_ITEM-MANUFACTMAT[' . $counter . ']'] = "";
$data_oci['NEW_ITEM-MATGROUP[' . $counter . ']'] = "";
$data_oci['NEW_ITEM-SERVICE[' . $counter . ']'] = "";
$data_oci['NEW_ITEM-CONTRACT[' . $counter . ']'] = "";
$data_oci['NEW_ITEM-CONTRACT_ITEM[' . $counter . ']'] = "";
$data_oci['NEW_ITEM-EXT_QUOTE_ID[' . $counter . ']'] = "";
$data_oci['NEW_ITEM-EXT_QUOTE_ITEM[' . $counter . ']'] = "";
$data_oci['NEW_ITEM-EXT_PRODUCT_ID[' . $counter . ']'] = "";
$data_oci['NEW_ITEM-ATTACHMENT[' . $counter . ']'] = "";
$data_oci['NEW_ITEM-ATTACHMENT_TITLE[' . $counter . ']'] = "";
$data_oci['NEW_ITEM-ATTACHMENT_PURPOSE[' . $counter . ']'] = "";
$data_oci['NEW_ITEM-EXT_SCHEMA_TYPE[' . $counter . ']'] = "";
$data_oci['NEW_ITEM-EXT_CATEGORY_ID[' . $counter . ']'] = "";
$data_oci['NEW_ITEM-CUST_FIELD1[' . $counter . ']'] = 21;
$data_oci['NEW_ITEM-PARENT_ID[' . $counter . ']'] = "";
$data_oci['NEW_ITEM-ITEM_TYPE[' . $counter . ']'] = "";
}
foreach ($data_oci as $key => $value)
{
$items_oci[] = $key . '=' . $value;
}
$string_oci = implode('&', $items_oci);
If I echo out the $string_oci I do get a result. After this I use the cURL to send the string to a link.
$url = "http://localhost/test.php";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $string_oci);
curl_setopt($ch, CURLOPT_RETURNTRANSFER , 1); // RETURN THE CONTENTS OF THE CALL
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
$response = curl_exec($ch);
var_dump($response);
}
The var_dump is always empty, returning string(0) "". I also tried this on the live website, same result.
I used this piece of code to see any errors, but it seems it there arent any error at all, but the var_dump is always empty.
if (curl_exec($ch) === FALSE)
{
print_r(curl_getinfo($ch));
die("Curl error: " . curl_error($ch));
}
else
{
curl_close($ch);
}
$endpoint="http://localhost/test3.php";
$session = curl_init($endpoint);
curl_setopt($session, CURLOPT_POST, true);
curl_setopt($session, CURLOPT_HEADER, true);
curl_setopt($session, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($session, CURLOPT_POSTFIELDS, $string_oci);
curl_setopt($session, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($session);
var_dump($response);
curl_close($session);
You need a header in your curl request and your curl_init needs a url. Try the code i attach.

Fedex shipping error

I've searched Google and Stackoverlow about this problem which a lot of people appear to be running into, but not one single definitive answer.
I'm using Opencart vs 1.5.5.1 and the Fedex module doesn't display any shipping options during checkout, it simply displays ERROR.
I have verified that my key, password, account and meter number are correct. I am using a production account, not a testing account. Below is the exact XML (sensitive information removed) I am sending to: https://gateway.fedex.com/web-services/
<?xml version="1.0"?>
<soap-env:envelope xmlns:ns1="http://fedex.com/ws/rate/v10" xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
<soap-env:body>
<ns1:raterequest>
<ns1:webauthenticationdetail>
<ns1:usercredential>
<ns1:key>ThisIsMyKey</ns1:key>
<ns1:password>ThisIsMyPassword</ns1:password>
</ns1:usercredential>
</ns1:webauthenticationdetail>
<ns1:clientdetail>
<ns1:accountnumber>123456789</ns1:accountnumber>
<ns1:meternumber>987654321</ns1:meternumber>
</ns1:clientdetail>
<ns1:version>
<ns1:serviceid>crs</ns1:serviceid>
<ns1:major>10</ns1:major>
<ns1:intermediate>0</ns1:intermediate>
<ns1:minor>0</ns1:minor>
</ns1:version>
<ns1:returntransitandcommit>true</ns1:returntransitandcommit>
<ns1:requestedshipment>
<ns1:shiptimestamp>2013-09-11T11:35:31-05:00</ns1:shiptimestamp>
<ns1:dropofftype>REGULAR_PICKUP</ns1:dropofftype>
<ns1:packagingtype>FEDEX_ENVELOPE</ns1:packagingtype>
<ns1:shipper>
<ns1:contact>
<ns1:personname>Jägermein</ns1:personname>
<ns1:companyname>Jägermein</ns1:companyname>
<ns1:phonenumber>123-456-7890</ns1:phonenumber>
</ns1:contact>
<ns1:address>
<ns1:stateorprovincecode>IL</ns1:stateorprovincecode>
<ns1:postalcode>61422</ns1:postalcode>
<ns1:countrycode>US</ns1:countrycode>
</ns1:address>
</ns1:shipper>
<ns1:recipient>
<ns1:contact>
<ns1:personname>test test</ns1:personname>
<ns1:companyname></ns1:companyname>
<ns1:phonenumber></ns1:phonenumber>
</ns1:contact>
<ns1:address>
<ns1:streetlines>test</ns1:streetlines>
<ns1:city>test</ns1:city>
<ns1:stateorprovincecode>IL</ns1:stateorprovincecode>
<ns1:postalcode>61554</ns1:postalcode>
<ns1:countrycode>US</ns1:countrycode>
<ns1:residential>false</ns1:residential>
</ns1:address>
</ns1:recipient>
<ns1:shippingchargespayment>
<ns1:paymenttype>SENDER</ns1:paymenttype>
<ns1:payor>
<ns1:accountnumber>123456789</ns1:accountnumber>
<ns1:countrycode>US</ns1:countrycode>
</ns1:payor>
</ns1:shippingchargespayment>
<ns1:raterequesttypes>LIST</ns1:raterequesttypes>
<ns1:packagecount>1</ns1:packagecount>
<ns1:requestedpackagelineitems>
<ns1:sequencenumber>1</ns1:sequencenumber>
<ns1:grouppackagecount>1</ns1:grouppackagecount>
<ns1:weight>
<ns1:units>LB</ns1:units>
<ns1:value>19.541</ns1:value>
</ns1:weight>
<ns1:dimensions>
<ns1:length>20</ns1:length>
<ns1:width>20</ns1:width>
<ns1:height>10</ns1:height>
<ns1:units>IN</ns1:units>
</ns1:dimensions>
</ns1:requestedpackagelineitems>
</ns1:requestedshipment>
</ns1:raterequest>
</soap-env:body>
</soap-env:envelope>
Opencart is sending this request through CURL as follows:
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $xml);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_TIMEOUT, 30);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($curl);
curl_close($curl);
If I var_dump the response it gives me the following:
ERRORERRORprof1000Authentication Failed crs 10 0 0
Any ideas where the problem might be?
I finally managed to resolve this with the help of Fedex support.
It turns out the account credentials I was using were the same for another parent company, so I needed to register a separate account.
I have Fixed Fedex not showing error
Please find the file catalog/model/shipping/fedex.php
change the code with my code
if you see ERROR after it then don't forget to check your product weight
<?php
class ModelShippingFedex extends Model {
function getQuote($address) {
$this->load->language('shipping/fedex');
$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "zone_to_geo_zone WHERE geo_zone_id = '" . (int)$this->config->get('fedex_geo_zone_id') . "' AND country_id = '" . (int)$address['country_id'] . "' AND (zone_id = '" . (int)$address['zone_id'] . "' OR zone_id = '0')");
if (!$this->config->get('fedex_geo_zone_id')) {
$status = true;
} elseif ($query->num_rows) {
$status = true;
} else {
$status = false;
}
$error = '';
$quote_data = array();
if ($status) {
$weight = $this->weight->convert($this->cart->getWeight(), $this->config->get('config_weight_class_id'), $this->config->get('fedex_weight_class_id'));
$weight_code = strtoupper($this->weight->getUnit($this->config->get('fedex_weight_class_id')));
$date = time();
$day = date('l', $date);
if ($day == 'Saturday') {
$date += 172800;
} elseif ($day == 'Sunday') {
$date += 86400;
}
$this->load->model('localisation/country');
$country_info = $this->model_localisation_country->getCountry($this->config->get('config_country_id'));
$this->load->model('localisation/zone');
$zone_info = $this->model_localisation_zone->getZone($this->config->get('config_zone_id'));
if (!$this->config->get('fedex_test')) {
$url = 'https://gateway.fedex.com/web-services/';
} else {
$url = 'https://gatewaybeta.fedex.com/web-services/';
}
// Whoever introduced xml to shipping companies should be flogged
$xml = '<?xml version="1.0"?>';
$xml .= '<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://fedex.com/ws/rate/v10">';
$xml .= ' <SOAP-ENV:Body>';
$xml .= ' <ns1:RateRequest>';
$xml .= ' <ns1:WebAuthenticationDetail>';
$xml .= ' <ns1:UserCredential>';
$xml .= ' <ns1:Key>' . $this->config->get('fedex_key') . '</ns1:Key>';
$xml .= ' <ns1:Password>' . $this->config->get('fedex_password') . '</ns1:Password>';
$xml .= ' </ns1:UserCredential>';
$xml .= ' </ns1:WebAuthenticationDetail>';
$xml .= ' <ns1:ClientDetail>';
$xml .= ' <ns1:AccountNumber>' . $this->config->get('fedex_account') . '</ns1:AccountNumber>';
$xml .= ' <ns1:MeterNumber>' . $this->config->get('fedex_meter') . '</ns1:MeterNumber>';
$xml .= ' </ns1:ClientDetail>';
$xml .= ' <ns1:Version>';
$xml .= ' <ns1:ServiceId>crs</ns1:ServiceId>';
$xml .= ' <ns1:Major>10</ns1:Major>';
$xml .= ' <ns1:Intermediate>0</ns1:Intermediate>';
$xml .= ' <ns1:Minor>0</ns1:Minor>';
$xml .= ' </ns1:Version>';
$xml .= ' <ns1:ReturnTransitAndCommit>true</ns1:ReturnTransitAndCommit>';
$xml .= ' <ns1:RequestedShipment>';
$xml .= ' <ns1:ShipTimestamp>' . date('c', $date) . '</ns1:ShipTimestamp>';
$xml .= ' <ns1:DropoffType>' . $this->config->get('fedex_dropoff_type') . '</ns1:DropoffType>';
$xml .= ' <ns1:PackagingType>' . $this->config->get('fedex_packaging_type') . '</ns1:PackagingType>';
$xml .= ' <ns1:Shipper>';
$xml .= ' <ns1:Contact>';
$xml .= ' <ns1:PersonName>' . $this->config->get('config_owner') . '</ns1:PersonName>';
$xml .= ' <ns1:CompanyName>' . $this->config->get('config_name') . '</ns1:CompanyName>';
$xml .= ' <ns1:PhoneNumber>' . $this->config->get('config_telephone') . '</ns1:PhoneNumber>';
$xml .= ' </ns1:Contact>';
$xml .= ' <ns1:Address>';
if ($country_info['iso_code_2'] == 'US') {
$xml .= ' <ns1:StateOrProvinceCode>' . ($zone_info ? $zone_info['code'] : '') . '</ns1:StateOrProvinceCode>';
} else {
$xml .= ' <ns1:StateOrProvinceCode>' . ($zone_info ? $zone_info['name'] : '') . '</ns1:StateOrProvinceCode>';
}
$xml .= ' <ns1:PostalCode>' . $this->config->get('fedex_postcode') . '</ns1:PostalCode>';
$xml .= ' <ns1:CountryCode>' . $country_info['iso_code_2'] . '</ns1:CountryCode>';
$xml .= ' </ns1:Address>';
$xml .= ' </ns1:Shipper>';
$xml .= ' <ns1:Recipient>';
$xml .= ' <ns1:Contact>';
$xml .= ' <ns1:PersonName>' . $address['firstname'] . ' ' . $address['lastname'] . '</ns1:PersonName>';
$xml .= ' <ns1:CompanyName>' . $address['company'] . '</ns1:CompanyName>';
$xml .= ' <ns1:PhoneNumber>' . $this->customer->getTelephone() . '</ns1:PhoneNumber>';
$xml .= ' </ns1:Contact>';
$xml .= ' <ns1:Address>';
$xml .= ' <ns1:StreetLines>' . $address['address_1'] . '</ns1:StreetLines>';
$xml .= ' <ns1:City>' . $address['city'] . '</ns1:City>';
if ($address['iso_code_2'] == 'US') {
$xml .= ' <ns1:StateOrProvinceCode>' . $address['zone_code'] . '</ns1:StateOrProvinceCode>';
} else {
$xml .= ' <ns1:StateOrProvinceCode>' . $address['zone'] . '</ns1:StateOrProvinceCode>';
}
$xml .= ' <ns1:PostalCode>' . $address['postcode'] . '</ns1:PostalCode>';
$xml .= ' <ns1:CountryCode>' . $address['iso_code_2'] . '</ns1:CountryCode>';
$xml .= ' <ns1:Residential>' . ($address['company'] ? 'true' : 'false') . '</ns1:Residential>';
$xml .= ' </ns1:Address>';
$xml .= ' </ns1:Recipient>';
$xml .= ' <ns1:ShippingChargesPayment>';
$xml .= ' <ns1:PaymentType>SENDER</ns1:PaymentType>';
$xml .= ' <ns1:Payor>';
$xml .= ' <ns1:AccountNumber>' . $this->config->get('fedex_account') . '</ns1:AccountNumber>';
$xml .= ' <ns1:CountryCode>' . $country_info['iso_code_2'] . '</ns1:CountryCode>';
$xml .= ' </ns1:Payor>';
$xml .= ' </ns1:ShippingChargesPayment>';
$xml .= ' <ns1:RateRequestTypes>' . $this->config->get('fedex_rate_type') . '</ns1:RateRequestTypes>';
$xml .= ' <ns1:PackageCount>1</ns1:PackageCount>';
$xml .= ' <ns1:RequestedPackageLineItems>';
$xml .= ' <ns1:SequenceNumber>1</ns1:SequenceNumber>';
$xml .= ' <ns1:GroupPackageCount>1</ns1:GroupPackageCount>';
$xml .= ' <ns1:Weight>';
$xml .= ' <ns1:Units>' . $weight_code . '</ns1:Units>';
$xml .= ' <ns1:Value>' . $weight . '</ns1:Value>';
$xml .= ' </ns1:Weight>';
$xml .= ' <ns1:Dimensions>';
$xml .= ' <ns1:Length>20</ns1:Length>';
$xml .= ' <ns1:Width>20</ns1:Width>';
$xml .= ' <ns1:Height>10</ns1:Height>';
$xml .= ' <ns1:Units>IN</ns1:Units>';
$xml .= ' </ns1:Dimensions>';
$xml .= ' </ns1:RequestedPackageLineItems>';
$xml .= ' </ns1:RequestedShipment>';
$xml .= ' </ns1:RateRequest>';
$xml .= ' </SOAP-ENV:Body>';
$xml .= '</SOAP-ENV:Envelope>';
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $xml);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_TIMEOUT, 30);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($curl);
curl_close($curl);
$dom = new DOMDocument('1.0', 'UTF-8');
$dom->loadXml($response);
if ($dom->getElementsByTagName('HighestSeverity')->item(0)->nodeValue == 'FAILURE' || $dom->getElementsByTagName('HighestSeverity')->item(0)->nodeValue == 'ERROR') {
$error = $dom->getElementsByTagName('HighestSeverity')->item(0)->nodeValue;
} else {
$rate_reply_details = $dom->getElementsByTagName('RateReplyDetails');
foreach ($rate_reply_details as $rate_reply_detail) {
$code = strtolower($rate_reply_detail->getElementsByTagName('ServiceType')->item(0)->nodeValue);
if (in_array(strtoupper($code), $this->config->get('fedex_service'))) {
$title = $this->language->get('text_' . $code);
if ($this->config->get('fedex_display_time')) {
$title .= ' (' . $this->language->get('text_eta') . ' ' . date($this->language->get('date_format_short') . ' ' . $this->language->get('time_format'), strtotime($rate_reply_detail->getElementsByTagName('DeliveryTimestamp')->item(0)->nodeValue)) . ')';
}
$total_net_charge = $rate_reply_detail->getElementsByTagName('RatedShipmentDetails')->item(0)->getElementsByTagName('ShipmentRateDetail')->item(0)->getElementsByTagName('TotalNetCharge')->item(0);
$cost = $total_net_charge->getElementsByTagName('Amount')->item(0)->nodeValue;
$currency = $total_net_charge->getElementsByTagName('Currency')->item(0)->nodeValue;
$quote_data[$code] = array(
'code' => 'fedex.' . $code,
'title' => $title,
'cost' => $this->currency->convert($cost, $currency, $this->config->get('config_currency')),
'tax_class_id' => $this->config->get('fedex_tax_class_id'),
'text' => $this->currency->format($this->tax->calculate($this->currency->convert($cost, $currency, $this->currency->getCode()), $this->config->get('fedex_tax_class_id'), $this->config->get('config_tax')), $this->currency->getCode(), 1.0000000)
);
}
}
}
}
$method_data = array();
if ($quote_data || $error) {
$title = $this->language->get('text_title');
if ($this->config->get('fedex_display_weight')) {
$title .= ' (' . $this->language->get('text_weight') . ' ' . $this->weight->format($weight, $this->config->get('fedex_weight_class_id')) . ')';
}
$method_data = array(
'code' => 'fedex',
'title' => $title,
'quote' => $quote_data,
'sort_order' => $this->config->get('fedex_sort_order'),
'error' => $error
);
}
return $method_data;
}
}
?>

Categories