Twitter authentication via OAuth using php cURL - php

I'm trying to show tweets based on a searchword submitted by a visitor. My code is:
function searchTwitter($query) {
$searchquery = urlencode($query);
//Filter for language
if (isset($_GET['lang'])) {
$langs = array("fr", "en", "es", "de", "it", "pt", "nl", "no", "sv", "fi", "da", "pl", "th", "en-gb");
if(in_array($_GET['lang'], $langs)) {
$lang = '&lang='.$_GET['lang'];
} else {
$lang = "";
}
}
$oauth_hash = '';
$oauth_hash .= 'lang='.$lang.'&';
$oauth_hash .= 'oauth_consumer_key=XXXX&';
$oauth_hash .= 'oauth_nonce=' . time() . '&';
$oauth_hash .= 'oauth_signature_method=HMAC-SHA1&';
$oauth_hash .= 'oauth_timestamp=' . time() . '&';
$oauth_hash .= 'oauth_token=XXXX&';
$oauth_hash .= 'oauth_version=1.0';
$oauth_hash .= 'q='.$searchquery.'&';
$oauth_hash .= 'result_type=recent';
$base = '';
$base .= 'GET';
$base .= '&';
$base .= rawurlencode('https://api.twitter.com/1.1/search/tweets.json');
$base .= '&';
$base .= rawurlencode($oauth_hash);
$key = '';
$key .= rawurlencode('XXXX');
$key .= '&';
$key .= rawurlencode('XXXX');
$signature = base64_encode(hash_hmac('sha1', $base, $key, true));
$signature = rawurlencode($signature);
$oauth_header = '';
$oauth_header .= 'lang="'.$lang.'", ';
$oauth_header .= 'oauth_consumer_key="XXXX", ';
$oauth_header .= 'oauth_nonce="' . time() . '", ';
$oauth_header .= 'oauth_signature="' . $signature . '", ';
$oauth_header .= 'oauth_signature_method="HMAC-SHA1", ';
$oauth_header .= 'oauth_timestamp="' . time() . '", ';
$oauth_header .= 'oauth_token="XXXX", ';
$oauth_header .= 'oauth_version="1.0", ';
$oauth_header .= 'q="'.$searchquery.'", ';
$oauth_header .= 'result_type="recent", ';
$curl_header = array("Authorization: Oauth {$oauth_header}", 'Expect:');
$curl_request = curl_init();
curl_setopt($curl_request, CURLOPT_HTTPHEADER, $curl_header);
curl_setopt($curl_request, CURLOPT_HEADER, false);
curl_setopt($curl_request, CURLOPT_URL, 'https://api.twitter.com/1.1/search/tweets.json? count=100'.$lang.'$q='.$searchquery.'&result_type=recent');
curl_setopt($curl_request, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl_request, CURLOPT_SSL_VERIFYPEER, false);
$json_content = curl_exec($curl_request);
curl_close($curl_request);
$tweets = $tweets = json_decode($json_content, true);
print_r($tweets);
I'm getting an error 32: Could not authenticate you. I've searched all over the internet and a lot of people are having this problem, but I can't find the solution. I prefer writing my own script instead of using plugins, because I also want to learn it.

Related

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;
}

Separate sitemap to multiple files

I'm using opencart 2 and default sitemap generator generate everything in one file I mean all products,category,image and so on , its take a long time when you open the file . How can I make something like:
products to be stored in sitemap-product.xml
category to be stored in sitemap-category.xml
image to be stored in sitemap-image.xml
and all to append to sitemap.xml
public function index() {
if ($this->config->get('google_sitemap_status')) {
$output = '<?xml version="1.0" encoding="UTF-8"?>';
$output .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1">';
$this->load->model('catalog/product');
$this->load->model('tool/image');
$products = $this->model_catalog_product->getProducts();
foreach ($products as $product) {
if ($product['image']) {
$output .= '<url>';
$output .= '<loc>' . $this->url->link('product/product', 'product_id=' . $product['product_id']) . '</loc>';
$output .= '<changefreq>weekly</changefreq>';
$output .= '<priority>1.0</priority>';
$output .= '<image:image>';
$output .= '<image:loc>' . $this->model_tool_image->resize($product['image'], $this->config->get('config_image_popup_width'), $this->config->get('config_image_popup_height')) . '</image:loc>';
$output .= '<image:caption>' . $product['name'] . '</image:caption>';
$output .= '<image:title>' . $product['name'] . '</image:title>';
$output .= '</image:image>';
$output .= '</url>';
}
}
$this->load->model('catalog/category');
$output .= $this->getCategories(0);
$this->load->model('catalog/manufacturer');
$manufacturers = $this->model_catalog_manufacturer->getManufacturers();
foreach ($manufacturers as $manufacturer) {
$output .= '<url>';
$output .= '<loc>' . $this->url->link('product/manufacturer/info', 'manufacturer_id=' . $manufacturer['manufacturer_id']) . '</loc>';
$output .= '<changefreq>weekly</changefreq>';
$output .= '<priority>0.7</priority>';
$output .= '</url>';
$products = $this->model_catalog_product->getProducts(array('filter_manufacturer_id' => $manufacturer['manufacturer_id']));
foreach ($products as $product) {
$output .= '<url>';
$output .= '<loc>' . $this->url->link('product/product', 'manufacturer_id=' . $manufacturer['manufacturer_id'] . '&product_id=' . $product['product_id']) . '</loc>';
$output .= '<changefreq>weekly</changefreq>';
$output .= '<priority>1.0</priority>';
$output .= '</url>';
}
}
$this->load->model('catalog/information');
$informations = $this->model_catalog_information->getInformations();
foreach ($informations as $information) {
$output .= '<url>';
$output .= '<loc>' . $this->url->link('information/information', 'information_id=' . $information['information_id']) . '</loc>';
$output .= '<changefreq>weekly</changefreq>';
$output .= '<priority>0.5</priority>';
$output .= '</url>';
}
$output .= '</urlset>';
$this->response->addHeader('Content-Type: application/xml');
$this->response->setOutput($output);
}
}
What you can do is simple. The controller you are trying to extend is the url:
index.php?route=feed/google_sitemap
or
index.php?route=extension/feed/google_sitemap if you are using opencart 2.3.x
The above url loads public function index(), so it's the same as:
index.php?route=feed/google_sitemap/index
Now, copy public function index () and create a new function with name products. It should look like this:
public function products() {
if ($this->config->get('google_sitemap_status')) {
$output = '<?xml version="1.0" encoding="UTF-8"?>';
$output .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1">';
$this->load->model('catalog/product');
$this->load->model('tool/image');
$products = $this->model_catalog_product->getProducts();
foreach ($products as $product) {
if ($product['image']) {
$output .= '<url>';
$output .= '<loc>' . $this->url->link('product/product', 'product_id=' . $product['product_id']) . '</loc>';
$output .= '<changefreq>weekly</changefreq>';
$output .= '<priority>1.0</priority>';
$output .= '<image:image>';
$output .= '<image:loc>' . $this->model_tool_image->resize($product['image'], $this->config->get('config_image_popup_width'), $this->config->get('config_image_popup_height')) . '</image:loc>';
$output .= '<image:caption>' . $product['name'] . '</image:caption>';
$output .= '<image:title>' . $product['name'] . '</image:title>';
$output .= '</image:image>';
$output .= '</url>';
}
}
$output .= '</urlset>';
$this->response->addHeader('Content-Type: application/xml');
$this->response->setOutput($output);
}
}
Now if call the url:
index.php?route=feed/google_sitemap/products
it should load only the products. It won't create the file you want, but it will create the sitemap xml for products on the fly.
Edit / Additional info :
If you have thousands of products you can add some limits easily.
public function products() {
if ($this->config->get('google_sitemap_status')) {
$output = '<?xml version="1.0" encoding="UTF-8"?>';
$output .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1">';
$this->load->model('catalog/product');
$this->load->model('tool/image');
$data = [];
if (isset($this->request->get['start'])) {
$data['start'] = $this->request->get['start'];
} else {
$data['start'] = 0;
}
if (isset($this->request->get['limit'])) {
$data['limit'] = $this->request->get['limit'];
} else {
$data['limit'] = 2000; /* Change the default value for the limit */
}
$products = $this->model_catalog_product->getProducts($data);
foreach ($products as $product) {
if ($product['image']) {
$output .= '<url>';
$output .= '<loc>' . $this->url->link('product/product', 'product_id=' . $product['product_id']) . '</loc>';
$output .= '<changefreq>weekly</changefreq>';
$output .= '<priority>1.0</priority>';
$output .= '<image:image>';
$output .= '<image:loc>' . $this->model_tool_image->resize($product['image'], $this->config->get('config_image_popup_width'), $this->config->get('config_image_popup_height')) . '</image:loc>';
$output .= '<image:caption>' . $product['name'] . '</image:caption>';
$output .= '<image:title>' . $product['name'] . '</image:title>';
$output .= '</image:image>';
$output .= '</url>';
}
}
$output .= '</urlset>';
$this->response->addHeader('Content-Type: application/xml');
$this->response->setOutput($output);
}
}
Let's say that you have 50000 products.
Example of the url to get the first 25000 products:
index.php?route=feed/google_sitemap/products&start=0&limit=25000
Then get the rest 25000 products
index.php?route=feed/google_sitemap/products&start=25000&limit=25000
You can do the same for categories, images, information pages etc.
PS: Of course to load the above urls, you need to add your domain name as prefix :D
Hope this helped you.

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.

Sage Pay Reporting API - generated signature hash not valid

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;
}

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