I have been trying to build a USPS Rate Calculator for a site, but unfortunately the test url from USPS does not seem to work. In any case, my code does not return anything at the moment, not even the error message about the url...
Would you take a look to see if I am doing the right thing? I get a bit lost with XML on PHP...
CODE:
$zip = 90002;
$pounds = 0.1;
function USPSParcelRate($pounds,$zip) {
$url = "https://secure.shippingapis.com/ShippingAPITest.dll";
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
// parameters to post
curl_setopt($ch, CURLOPT_POST, 1);
$xml = "API=RateV4&XML=<RateV4Request USERID='USERNAME' >
<Revision/>
<Package ID='1ST'>
<Service>PRIORITY</Service>
<ZipOrigination>10025</ZipOrigination>
<ZipDestination>$zip</ZipDestination>
<Pounds>$pounds</Pounds>
<Ounces>0</Ounces>
<Container></Container>
<Size>REGULAR</Size>
<Width></Width>
<Length></Length>
<Height></Height>
<Girth></Girth>
</Package>
</RateV4Request>";
// send the POST values to USPS
curl_setopt($ch, CURLOPT_POSTFIELDS,$xml);
$result = curl_exec($ch);
$data = strstr($result, '<?');
$xml_parser = xml_parser_create();
xml_parse_into_struct($xml_parser, $data, $vals, $index);
xml_parser_free($xml_parser);
$params = array();
$level = array();
echo "TEST";
foreach ($vals as $xml_elem) {
if ($xml_elem['type'] == 'open') {
if (array_key_exists('attributes',$xml_elem)) {
list($level[$xml_elem['level']],$extra) = array_values($xml_elem['attributes']);
} else {
$level[$xml_elem['level']] = $xml_elem['tag'];
}
}
if ($xml_elem['type'] == 'complete') {
$start_level = 1;
$php_stmt = '$params';
while($start_level < $xml_elem['level']) {
$php_stmt .= '[$level['.$start_level.']]';
$start_level++;
}
$php_stmt .= '[$xml_elem[\'tag\']] = $xml_elem[\'value\'];';
eval($php_stmt);
}
}
curl_close($ch);
echo '<pre>'; print_r($params); echo'</pre>'; // Uncomment to see xml tags
return $params['RateV4Response']['1ST']['1']['RATE'];
}
USPSParcelRate($pounds,$zip)
You are missing the curl_init() function since $ch is not defined
$ch = curl_init();
Also you are not printing the response:
**echo** USPSParcelRate($pounds,$zip);
Lastly, you can print the response from curl, change:
echo "TEST";
to:
print "RESPONSE: $result";
I'm getting that RateV4 is not authorized, where is RateV4 coming from?
TEST HTTP/1.1 200 Connection established
HTTP/1.1 200 OK
Connection: close
Date: Mon, 10 Jun 2013 17:16:17 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
<Error>
<Number>80040b1a</Number>
<Description>API Authorization failure. RateV4 is not a valid API name for this protocol.</Description>
<Source>UspsCom::DoAuth</Source>
</Error>
Hope this at least helps with debugging..
RateV4 is a sevice name at USPS API.
check following link - http://uspsship.blogspot.in/
Related
I have been working on a clients WP site which lists deals from Groupon. I am using the Groupon's official XML feed, importing via WP All Import. This works without much hassle. Now the issue is Groupon doesn't update that feed frequently but some of their deals get sold out or off the market often. So to get this resolved what I am trying is using a CURL script to crawl the links and check if the deal is available or not then turn the unavailable deals to draft posts (Once a day only).
The custom script is working almost perfectly, only after the first 14/24 requests the server starts responding with 502/503 HTTP status codes. To overcome the issue I have used the below precautions -
Using the proper header (captured from the requests made by the browser)
Parsing cookies from response header and sending back.
Using proper referrer and user agent.
Using proxies.
Trying to send request after a set interval. PHP - sleep(5);
Unfortunately, none of this got me the solution I wanted. I am attaching my code and I would like to request your expert insights on the issue, please.
Thanks in advance for your time.
Shahriar
PHP SCRIPT - https://pastebin.com/FF2cNm5q
<?php
// Error supressing and extend maximum execution time
error_reporting(0);
ini_set('max_execution_time', 50000);
// Sitemap URL List
$all_activity_urls = array();
$sitemap_url = array(
'https://www.groupon.de/sitemaps/deals-local0.xml.gz'
);
$cookies = Array();
// looping through sitemap url for scraping activity urls
for ($u = 0; $u < count($sitemap_url); $u++)
{
$ch1 = curl_init();
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch1, CURLOPT_USERAGENT, 'Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:38.0) Gecko/20100101 Firefox/38.0');
curl_setopt($ch1, CURLOPT_REFERER, "https://www.groupon.de/");
curl_setopt($ch1, CURLOPT_TIMEOUT, 40);
// curl_setopt($ch1, CURLOPT_COOKIEFILE, "cookie.txt");
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch1, CURLOPT_URL, $sitemap_url[$u]);
curl_setopt($ch1, CURLOPT_SSL_VERIFYPEER, FALSE);
// Parsing Cookie from the response header
curl_setopt($ch1, CURLOPT_HEADERFUNCTION, "curlResponseHeaderCallback");
$activity_url_source = curl_exec($ch1);
$status_code = curl_getinfo($ch1, CURLINFO_HTTP_CODE);
curl_close($ch1);
if ($status_code === 200)
{
// Parsing XML sitemap for activity urls
$activity_url_list = json_decode(json_encode(simplexml_load_string($activity_url_source)));
for ($a = 0; $a < count($activity_url_list->url); $a++)
{
array_push($all_activity_urls, $activity_url_list->url[$a]->loc);
}
}
}
if (count($all_activity_urls) > 0)
{
// URL Loop count
$loop_from = 0;
$loop_to = (count($all_activity_urls) > 0) ? 100 : 0;
// $loop_to = count($all_activity_urls);
$final_data = array();
echo 'script start - ' . date('h:i:s') . "<br>";
for ($u = $loop_from; $u < $loop_to; $u++)
{
//Pull source from webpage
$headers = array(
'accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
'accept-language: en-US,en;q=0.9,bn-BD;q=0.8,bn;q=0.7,it;q=0.6',
'cache-control: max-age=0',
'cookie: ' . implode('; ', $cookies),
'upgrade-insecure-requests: 1',
'user-agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'
);
$site = $all_activity_urls[$u];
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_REFERER, "https://www.groupon.de/");
curl_setopt($ch, CURLOPT_TIMEOUT, 40);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, $site);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
// Parsing Cookie from the response header
curl_setopt($ch, CURLOPT_HEADERFUNCTION, "curlResponseHeaderCallback");
$data = curl_exec($ch);
$status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status_code === 200)
{
// Ready data for parsing
$document = new DOMDocument();
$document->loadHTML('<meta http-equiv="content-type" content="text/html; charset=utf-8">' . $data);
$xpath = new DOMXpath($document);
$title = '';
$availability = '';
$price = '';
$base_price = '';
$link = '';
$image = '';
$link = $all_activity_urls[$u];
// Scraping Availability
$raw_availability = $xpath->query('//div[#data-bhw="DealHighlights"]/div[0]/div/div');
$availability = $raw_availability->item(0)->nodeValue;
// Scraping Title
$raw_title = $xpath->query('//h1[#id="deal-title"]');
$title = $raw_title->item(0)->nodeValue;
// Scraping Price
$raw_price = $xpath->query('//div[#class="price-discount-wrapper"]');
$price = trim(str_replace(array("$", "€", "US", " "), array("", "", "", ""), $raw_price->item(0)->nodeValue));
// Scraping Old Price
$raw_base_price = $xpath->query('//div[contains(#class, "value-source-wrapper")]');
$base_price = trim(str_replace(array("$", "€", "US", " "), array("", "", "", ""), $raw_base_price->item(0)->nodeValue));
// Creating Final Data Array
array_push($final_data, array(
'link' => $link,
'availability' => $availability,
'name' => $title,
'price' => $price,
'baseprice' => $base_price,
'img' => $image,
));
}
else
{
$link = $all_activity_urls[$u];
if ($status_code === 429)
{
$status_msg = ' - Too Many Requests';
}
else
{
$status_msg = '';
}
array_push($final_data, array(
'link' => $link,
'status' => $status_code . $status_msg,
));
}
echo 'before break - ' . date('h:i:s') . "<br>";
sleep(5);
echo 'after break - ' . date('h:i:s') . "<br>";
flush();
}
echo 'script end - ' . date('h:i:s') . "<br>";
// Converting data to XML
$activities = new SimpleXMLElement("<?xml version=\"1.0\"?><activities></activities>");
array_to_xml($final_data, $activities);
$xml_file = $activities->asXML('activities.xml');
if ($xml_file)
{
echo 'XML file have been generated successfully.';
}
else
{
echo 'XML file generation error.';
}
}
else
{
$activities = new SimpleXMLElement("<?xml version=\"1.0\"?><activities></activities>");
$activities->addChild("error", htmlspecialchars("No URL scraped from sitemap. Stoping script."));
$xml_file = $activities->asXML('activities.xml');
if ($xml_file)
{
echo 'XML file have been generated successfully.';
}
else
{
echo 'XML file generation error.';
}
}
// Recursive Function for creating XML Nodes
function array_to_xml($array, &$activities)
{
foreach ($array as $key => $value)
{
if (is_array($value))
{
if (!is_numeric($key))
{
$subnode = $activities->addChild("$key");
array_to_xml($value, $subnode);
}
else
{
$subnode = $activities->addChild("activity");
array_to_xml($value, $subnode);
}
}
else
{
$activities->addChild("$key", htmlspecialchars("$value"));
}
}
}
// Cookie Parsing Function
function curlResponseHeaderCallback($ch, $headerLine)
{
global $cookies;
if (preg_match('/^Set-Cookie:\s*([^;]*)/mi', $headerLine, $cookie) == 1)
{
$cookies[] = $cookie[1];
}
return strlen($headerLine); // Needed by curl
}
There is a mess of cookies in your snippet. The callback function just appends cookies to the array regardingless of whether they already exist or not. Here is a new version which at least seems to work in this case since there are no semicolon-seperated multiple cookie definitions. Usually the cookie string should be even parsed. If you have installed the http extension you can use http_parse_cookie.
// Cookie Parsing Function
function curlResponseHeaderCallback($ch, $headerLine)
{
global $cookies;
if (preg_match('/^Set-Cookie:\s*([^;]+)/mi', $headerLine, $match) == 1)
{
if(false !== ($p = strpos($match[1], '=')))
{
$replaced = false;
$cname = substr($match[1], 0, $p+1);
foreach ($cookies as &$cookie)
if(0 === strpos($cookie, $cname))
{
$cookie = $match[1];
$replaced = true;
break;
}
if(!$replaced)
$cookies[] = $match[1];
}
var_dump($cookies);
}
return strlen($headerLine); // Needed by curl
}
My PayPal IPN code receives the post data sent back from PayPal upon purchase completion but doesn't insert the data into the database. I had the code send me an email if it fails to insert the data into the database. If I take that post data and paste it into the address bar after ipn.php?, it works perfectly. What am I doing wrong? Do I have to post the data back to PayPal?
My IPN Listener
<?php
include 'includes/class.user.php';
$user = new USER();
$emailtext = "";
$raw_post_data = file_get_contents('php://input');
$raw_post_array = explode('&', $raw_post_data);
$myPost = array();
foreach ($raw_post_array as $keyval) {
$keyval = explode ('=', $keyval);
if (count($keyval) == 2)
$myPost[$keyval[0]] = urldecode($keyval[1]);
}
$req = 'cmd=_notify-validate';
if(function_exists('get_magic_quotes_gpc')) {
$get_magic_quotes_exists = true;
}
foreach ($myPost as $key => $value) {
$value = urlencode($value);
$req .= "&$key=$value";
}
$paypalURL = "https://ipnpb.paypal.com/cgi-bin/webscr";
$ch = curl_init($paypalURL);
if ($ch == FALSE) {
return FALSE;
}
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $req);
curl_setopt($ch, CURLOPT_SSLVERSION, 6);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close', 'User-Agent: Company name removed for security, LLC.'));
$res = curl_exec($ch);
$tokens = explode("\r\n\r\n", trim($res));
$res = trim(end($tokens));
//Payment data
$txn_id = $_GET['txn_id'];
$payment_gross = $_GET['mc_gross'];
$currency_code = $_GET['mc_currency'];
$pay_status = $_GET['payment_status'];
$payer_email = $_GET['payer_email'];
$date = date("m-d-y");
$invNum = md5($date);
$orderNum = md5($txn_id);
$fullname = $_GET['address_name'];
$address = $_GET['address_street'];
$city = $_GET['address_city'];
$state = $_GET['address_state'];
$zip = $_GET['address_zip'];
if($user->verify_txnid($txn_id)){
exit();
}else{
$insertPayment = $user->insert_purchase($fullname,$address,$city,$state,$zip,"0000000000",$payer_email,$orderNum,$date,$txn_id,$invNum,$pay_status);
if($insertPayment === TRUE){
$num_cart_items = $_GET['num_cart_items'];
for ($i = 0; $i <= $num_cart_items; $i++) {
$order_item_name = $_GET['item_name' . $i];
$order_item_quantity = $_GET['quantity' . $i];
$order_item_gross_amount = $_GET['mc_gross_' . $i];
$order_item_custom = $_GET['option_selection1_' . $i];
$user->insert_order($txn_id, $order_item_name, $order_item_quantity, $order_item_gross_amount, $order_item_custom);
}
}else{
foreach ($_GET as $key => $value)
{
$emailtext .= $key . " = " .$value ."\n\n";
}
mail('myemail#gmail.com', 'Insert Payment FAILED', $emailtext."\r\n".$req."\r\n".$res);
}
}
header("HTTP/1.1 200 OK");
I have confirmed that the post from PayPal matches the post back to PayPal but I still get an INVALID response and none of the data gets inserted into the database. If I take the raw post data string from PayPal's initial POST and paste it into the address bar, it inserts into the database just fine. I can't figure out for the life of me why it's not inserting the data into the database on its own. My IPN history on PayPal show an html response of 500 and that its retrying.
If IPN message you POST back does not exactly match the one PayPal sent to you, INVALID status will be occurred. You can double check if there have mess code in the IPN message you POST back, such as non-English characters. But if you still cannot find out the root cause, you have to contact PayPal technical support via https://www.paypal-techsupport.com/app/ask/ and provide PayPal transaction ID for the further checking.
Had the exactly same problem on sandbox.
Got it working by switching off "Negative Testing" on the account profile settings and removing the date from the ipn simulator.
That simple code made it work
$ipn_post_data = $_POST;
// Choose url
if (array_key_exists('test_ipn', $ipn_post_data) && 1 === (int) $ipn_post_data['test_ipn']){
$url = 'https://www.sandbox.paypal.com/cgi-bin/webscr';
}else{
$url = 'https://www.paypal.com/cgi-bin/webscr';
}
// Set up request to PayPal
$request = curl_init();
curl_setopt_array($request, array
(
CURLOPT_URL => $url,
CURLOPT_POST => TRUE,
CURLOPT_POSTFIELDS => http_build_query(array('cmd' => '_notify-validate') + $ipn_post_data),
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_HEADER => FALSE,
));
// Execute request and get response and status code
$response = curl_exec($request);
$status = curl_getinfo($request, CURLINFO_HTTP_CODE);
// Close connection
curl_close($request);
if ($status == 200 && $response == 'VERIFIED') {
$today = date("Y_m_d");
$file = fopen("LogIPN.$today.txt", "ab");
$hour = date("H:i:s T");
fwrite($file, "Verified\r\n");
} else {
$today = date("Y_m_d");
$file = fopen("LogIPN.$today.txt", "ab");
$hour = date("H:i:s T");
fwrite($file, $response."\r\n");
fwrite($file, $status."\r\n");
}
I would never use that code in production for many reasons.
Hope this can make things easy for u.
so my issue is according to the documentation (wich is pretty slim and not the greatest) the xml i have is everything that is required, but im getting this error code back
<?xml version="1.0" encoding="UTF-8"?>
<Error><Number>80040B19</Number><Description>XML Syntax Error: Please check the XML request to see if it can be parsed.</Description><Source>USPSCOM::DoAuth</Source></Error>
this doesnt make much sense to me because my account is in production mode, and as i said according to the documentation i have everything that is required, i have spent the last 2 days trying to get this to work and nothing.
the VerifyAddress function works fine, but the RateCheck function does not work.
class USPS
{
protected $Endpoint = 'http://production.shippingapis.com/ShippingAPI.dll';
protected $SecureEndpoint = 'https://secure.shippingapis.com/ShippingAPI.dll';
protected $TestEndpoint = 'http://stg-production.shippingapis.com/ShippingAPI.dll';
protected $TestSecureEndpoint = 'https://stg-secure.shippingapis.com/ShippingAPI.dll';
private $username = 'example’;
function VerifyAddress($address1, $address2, $city, $state, $zip)
{
$xml = '<AddressValidateRequest%20USERID="'.$this->username.'">
<Address>
<Address1>'.$address1.'</Address1>
<Address2>'.$address2.'</Address2>
<City>'.$city.'</City>
<State>'.$state.'</State>
<Zip5>'.$zip.'</Zip5>
<Zip4></Zip4>
</Address>
</AddressValidateRequest>';
//build the data
$data = $this->AddressVerify . $xml;
//send for the request
$verified = $this->Request($data);
//return he results
return $verified;
}
function RateCheck($packages, $zipDest, $service='PRIORITY', $zipOrigin='93274', $pounds='3', $ounces='0',
$container='RECTANGULAR', $size='LARGE', $width='13', $length='14', $height='6', $girth='38')
{
$packageIDS = array('1ST'=>1, '2ND'=>2, '3RD'=>3, '4TH'=>4, '5TH'=>5, '6TH'=>6, '7TH'=>7, '8th'=>8,'9TH'=>9,
'10th'=>10);
$packagexml = array();
for($i=1;$i<=$packages;$i++)
{
$PackageID = array_search($i, $packageIDS);
$packagexml[] = '<Package ID="'.$PackageID.'">
<Service>'.$service.'</Service>
<ZipOrigination>'.$zipOrigin.'</ZipOrigination>
<ZipDestination>'.$zipDest.'</ZipDestination>
<Pounds>'.$pounds.'/Pounds>
<Ounces>'.$ounces.'</Ounces>
<Container>'.$container.'</Container>
<Size>'.$size.'</Size>
<Width>'.$width.'</Width>
<Length>'.$length.'</Length>
<Height>'.$height.'</Height>
<Girth>'.$girth.'</Girth>
</Package>';
}
$xml2 = '';
foreach($packagexml as $package)
{
$xml2 .= $package;
}
$data = 'API=RateV4&XML=<RateV4Request USERID="'.$this->username.'"><Revision>2</Revision>'.$xml2.'</RateV4Request>';
$RateResult = $this->Request($data);
return $RateResult;
}
function Request($data)
{
$ch = curl_init();
// set the target url
curl_setopt($ch, CURLOPT_URL,$this->Endpoint);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
//curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
// parameters to post
curl_setopt($ch, CURLOPT_POST, 1);
// send the POST values to usps
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
//curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$result=curl_exec ($ch);
curl_close($ch);
$Parseresult = $this->parseResult($result);
return $Parseresult;
}
function parseResult($responce)
{
$data = strstr($responce, '<?');
echo '<!-- '. $data. ' -->'; // Uncomment to show XML in comments
$xml_parser = xml_parser_create();
xml_parse_into_struct($xml_parser, $data, $vals, $index);
xml_parser_free($xml_parser);
$params = array();
$level = array();
foreach ($vals as $xml_elem) {
if ($xml_elem['type'] == 'open') {
if (array_key_exists('attributes',$xml_elem)) {
list($level[$xml_elem['level']],$extra) = array_values($xml_elem['attributes']);
} else {
$level[$xml_elem['level']] = $xml_elem['tag'];
}
}
if ($xml_elem['type'] == 'complete') {
$start_level = 1;
$php_stmt = '$params';
while($start_level < $xml_elem['level']) {
$php_stmt .= '[$level['.$start_level.']]';
$start_level++;
}
$php_stmt .= '[$xml_elem[\'tag\']] = $xml_elem[\'value\'];';
eval($php_stmt);
}
}
return $params;
}
}
The reason I was getting this was because I had unescaped ampersands in my XML that I was posting to the USPS API. Before you POST the XML, print the XML out on your screen just to see exactly what is being posted. I'm not sure how to do this in php (maybe echo?) but in python I would do print(my_xml_string).
Like I said, my generated xml had ampersand characters in it &, I fixed the problem by replacing those with &. Again, I'm not way familiar with php but python would be my_xml_string.replace('&', '&'). This is because an ampersand in XML needs to be 'closed' with a ;.
soultion form Viable works .. by adding the following code in appropriate format
'.$pounds.'
i have demonstrated at usps tracking site and its now works well
I got following error to my site usps tracking : when i manually entered field i got result . but through the form i got that error mentioned below.
80040B19XML Syntax Error: Please check the XML request to see if it can be parsed.(B)USPSCOM::DoAuth
Finally revising quote . i got solution.
DONOT defin the value in the loop or xml tag
right <Pounds>'.$pounds.'</Pounds>
wrong <Pounds>'if($_POST['unit']=="Pounds"){ ...'</Pounds> This is creating xml VALIDATION ISSUE ..
http://benalman.com/code/projects/php-simple-proxy/examples/simple/
I am exactly following above Blog for Using PHP Proxy setting for Cross Domain. I am using XHR. I am able to successful to use GET method. But While using POST I am getting error CODE 200 and Empty XML in reply object.
However when i am using the simple XHR Code without phpproxy with below setting of google. chrome.exe --disable-web-security. I am successful for GET and POST both.
I am sure i am wrong somewhere in XHR.Send(Mydata). But if i was wrong in this method than i could not have been able to send success full post method.
Please help. I am novice in PHP i am sure i am missing something in PHP code that would enable me to post successfull. Below is crux of PHP code.
$enable_jsonp = true;
$enable_native = false;
$valid_url_regex = '/.*/';
$url = $_GET['url'];
if (!$url)
{
// Passed url not specified.
$contents = 'ERROR: url not specified';
$status = array(
'http_code' => 'ERROR'
);
}
else if (!preg_match($valid_url_regex, $url)) {
// Passed url doesn't match $valid_url_regex.
$contents = 'ERROR: invalid url';
$status = array(
'http_code' => 'ERROR'
);
}
else
{
$ch = curl_init($url);
if (strtolower($_SERVER['REQUEST_METHOD']) == 'post')
{
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $_POST);
}
if ($_GET['send_cookies'])
{
$cookie = array();
foreach ($_COOKIE as $key => $value)
{
$cookie[] = $key . '=' . $value;
}
if ($_GET['send_session'])
{
$cookie[] = SID;
}
$cookie = implode('; ', $cookie);
curl_setopt($ch, CURLOPT_COOKIE, $cookie);
}
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERAGENT, $_GET['user_agent'] ? $_GET['user_agent'] : $_SERVER['HTTP_USER_AGENT']);
list($header, $contents) = preg_split('/([\r\n][\r\n])\\1/', curl_exec($ch), 2);
$status = curl_getinfo($ch);
curl_close($ch);
}
// Split header text into an array.
$header_text = preg_split('/[\r\n]+/', $header);
if ($_GET['mode'] == 'native')
{
if (!$enable_native)
{
$contents = 'ERROR: invalid mode';
$status = array(
'http_code' => 'ERROR'
);
}
// Propagate headers to response.
foreach ($header_text as $header)
{
if (preg_match('/^(?:Content-Type|Content-Language|Set-Cookie):/i', $header))
{
header($header);
}
}
print $contents;
}
else
{
// $data will be serialized into JSON data.
$data = array();
// Propagate all HTTP headers into the JSON data object.
if ($_GET['full_headers'])
{
$data['headers'] = array();
foreach ($header_text as $header)
{
preg_match('/^(.+?):\s+(.*)$/', $header, $matches);
if ($matches)
{
$data['headers'][$matches[1]] = $matches[2];
}
}
}
// Propagate all cURL request / response info to the JSON data object.
if ($_GET['full_status'])
{
$data['status'] = $status;
}
else
{
$data['status'] = array();
$data['status']['http_code'] = $status['http_code'];
}
// Set the JSON data object contents, decoding it from JSON if possible.
$decoded_json = json_decode($contents);
$data['contents'] = $decoded_json ? $decoded_json : $contents;
// Generate appropriate content-type header.
$is_xhr = strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest';
header('Content-type: application/' . ($is_xhr ? 'json' : 'x-javascript'));
// Get JSONP callback.
$jsonp_callback = $enable_jsonp && isset($_GET['callback']) ? $_GET['callback'] : null;
// Generate JSON/JSONP string`enter code here`
$json = json_encode($data);
print $jsonp_callback ? "$jsonp_callback($json)" : $json;
}
OK, I have this php file for my HSBC bank processing using the API, I have this working fine on 2 of my other websites, however the SAME file is failing on the other two sites, I have no idea why. My web developer is stumped and decided to create a test file, Here is the code from the test file:
<?php
echo "payment processing...";
$amount = 100;// round($_POST["realamount"], 2) * 100;
$fullName = "test";//$_POST['name'];
$Address1 = "test";//$_POST['address1'];
$Address2 = "test";//$_POST['address2'];
$city ="test";// $_POST['city'];
$county = $city;
$postcode = "test";//$_POST['zipcode'];
$country = "GRB";//$_POST['country'];
$phone = "test";//$_POST['telephone'];
$email = "a#a.com";//$_POST['emailaddress'];
$cardNumber = "337877666233434";//$_POST['cardNumber'];
$cardExp = "03/2011";//$_POST['ccmonth'] . "/" . substr($_POST["ccyear"],2,2);
$cvdIndicator = "111";//$_POST['cvdIndicator'];
$cvdValue = "111";//$_POST['cvdValue'];
$issueNumber = "111";//$_POST['issueNumber'];
$cardType = "VI";//$_POST['cardType'];
$testRead = "<?xml version='1.0' encoding='UTF-8'?>
<EngineDocList>
<DocVersion>1.0</DocVersion>
<EngineDoc>
<ContentType>OrderFormDoc</ContentType>
<User>
<Name>xxx</Name>
<Password>xxx</Password>
<ClientId>xxx</ClientId>
</User>
<Instructions>
<Pipeline>PaymentNoFraud</Pipeline>
</Instructions>
<OrderFormDoc>
<Mode>P</Mode>
<Comments/>
<Consumer>
<Email/>
<PaymentMech>
<CreditCard>
<Number>".$cardNumber."</Number>
<Expires DataType='ExpirationDate' Locale='840'>".$cardExp."</Expires>
<Cvv2Val>".$cvdValue."</Cvv2Val>
<Cvv2Indicator>".$cvdIndicator."</Cvv2Indicator>
<IssueNum>".$issueNumber."</IssueNum>
</CreditCard>
</PaymentMech>
</Consumer>
<Transaction>
<Type>Auth</Type>
<CurrentTotals>
<Totals>
<Total DataType='Money' Currency='826'>".$amount."</Total>
</Totals>
</CurrentTotals>
</Transaction>
</OrderFormDoc>
</EngineDoc>
</EngineDocList>";
?>
<?php
//$url = "https://www.uat.apixml.netq.hsbc.com";
$url = "https://www.secure-epayments.apixml.hsbc.com/";
$ch = curl_init();
curl_setopt($ch, CURLOPT_POST,1);
curl_setopt($ch, CURLOPT_POSTFIELDS,$testRead);
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
$result_tmp = curl_exec ($ch);
curl_close ($ch);
///////////////////////////////////////
// use XML Parser result
$xml_parser = xml_parser_create();
xml_parser_set_option($xml_parser,XML_OPTION_CASE_FOLDING,0);
xml_parser_set_option($xml_parser,XML_OPTION_SKIP_WHITE,1);
xml_parse_into_struct($xml_parser, $result_tmp, $vals, $index);
xml_parser_free($xml_parser);
//print_r($vals); // print all the arrays.
//print_r($vals[29]); // print only the selected array.
$val1 = $vals[21];
// ProcReturnMsg
$paymentResult = $val1[value];
$result_tmp = "";
$k=0;
$findthis = false;
$findthis2 = false;
foreach ($vals as $val) {
$result_tmp.= $k."{";
foreach($val as $d => $a) {
$result_tmp.="[".$d."]".$a;
if($d=="tag" && $a=="TransactionStatus"){
$findthis = true;
}
if($d=="value" && $findthis){
$tResult = $a;
$findthis = false;
}
if($d=="tag" && $a=="Text"){
$findthis2 = true;
}
if($d=="value" && $findthis2){
$tResult2 = $a;
$findthis2 = false;
}
}
$result_tmp.= "}";
$k++;
}
echo $tResult2.$tResult;
?>
Here is an example of one of the sites not working gs.net
The output is:
payment processing... The HTTP method received is not valid. Only POST is accepted.
Whereas when I upload this exact same file to some of my other web hosts such as:
HGL working example
The output here is payment processing... Unable to determine card type. ('length' is '15')E
This sounds like an error message, but basically that error is not important, so the latter is what we are trying to achieve in the first link.
I have even uploaded this file to some really basic hosting accounts of mine, sometimes it will work sometimes it won't, so I'm guessing it's something to do with what the hosting company are allowing or have switched On/Off.
Any ideas please?
Thank you
This seems to have been caused by a PHP upgrade applied to the server and it was driving me crazy.
The solution is to set the following SSL options when specifying the CURL connection.
curl_setopt($ch, CURLOPT_SSLVERSION, 3);
curl_setopt($ch, CURLOPT_SSL_CIPHER_LIST, 'RC4-MD5');
check if curl is enabled on those servers that don't work for starters. use phiinfo() function to check.