I am trying to test segapay in test page but its throwing an error
X911911INVALID T_TERMINAL_NUMBER 00P 0000000000000
X911911INVALID T_TERMINAL_NUMBER 00P 0000000000000X911911INVALID T_TERMINAL_NUMBER 00P 0000000000000
Approval Indicator: X
Approval/Error Code: 911911
Approval/Error Message: INVALID T_TERMINAL_NUMBER
Front-End Indicator: 00
CVV Indicator: P
AVS Indicator:
Risk Indicator: 00
Reference: 0000000000
Order Number:
<?php
// Marchant ID
$mid = "713558155666";
$mkey = "J1M3S4C5N5E9";
$amount = "10.00";
$cardholder_name = "Brijesh";
$billing_address = "Test";
$billing_state = "AL";
$billing_city = "Test";
$cardnumber = "5555555555554444";
$exp_Date = "1109";
$billing_zip = "12345";
$email_addr = "brijesss#xxx.com";
$ordernum = "3333333";
//set the URL that will be posted to.
$eftsecure_url = "https://www.sagepayments.net/cgi-bin/eftbankcard.dll?transaction";
//make your query.
$data = "m_id=" . $mid; //your eftsecure merchant id.
$data .= "&m_key=" . $mkey; // your eftsecure merchant key;
$data .= "&T_amt=" . urlencode($amount); // The amount to be charged. Always encode
// any data given to you over the web. it is more
// secure and reliable.
$data .= "&C_name=" . urlencode($cardholder_name);
$data .= "&C_address=" . urlencode($billing_address);
$data .= "&C_state=" . urlencode($billing_state);
$data .= "&C_city=" . urlencode($billing_city);
$data .= "&C_cardnumber=" . urlencode($cardnumber);
$data .= "&C_exp=" . urlencode($exp_Date);
$data .= "&C_zip=" . urlencode($billing_zip);
$data .= "&C_email=" . urlencode($email_addr);
$data .= "&T_code=02"; // transaction type indicator
$data .= "&T_ordernum=" . urlencode($ordernum);
//HTTPS Bankcard Specifications 18
//now we will make the transaction. the first method is the preferred internal method
//using the built in CURL functions.
$ch = curl_init(); //initialize the CURL library.
curl_setopt($ch, CURLOPT_URL, $eftsecure_url); // set the URL to post to.
curl_setopt($ch, CURLOPT_POST, 1); // tell it to POST not GET (you can GET but POST is
//preferred)
curl_setopt($ch, CURLOPT_POSTFIELDS, $data); // set the data to be posted.
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // this tells the library to return the
// data to you instead of writing it to
// a file
$res = curl_exec($ch); // make the post.
curl_close($ch); // shut down the curl library.
echo $res . "<br>\n"; // this is the response.
// or you can also use the curl executable directly.
$curl = "/usr/bin/curl"; // the location of the curl executable.
$fp=popen("$curl --data \"$data\" $eftsecure_url","r"); // this allows you to get the
// data directly from curl
while(!feof($fp)) $res .= fread($fp, 1024); // read all the output.
pclose($fp); // close the connection to curl.
//HTTPS Bankcard Specifications 19
echo "$res" . "<br>\n"; // this is the response.
// once you have the response then you need to parse its different components.
echo "<br><hr><br>\n";
echo "Approval Indicator: " . $res[1] . "<br>"; //A is approved E is
declined/error.
echo "Approval/Error Code: " . substr($res, 2, 6) . "<br>\n";
echo "Approval/Error Message: " . substr($res, 8, 32) . "<br>\n";
echo "Front-End Indicator: " . substr($res, 40, 2) . "<br>\n";
echo "CVV Indicator: " . $res[42] . "<br>\n";
echo "AVS Indicator: " . $res[43] . "<br>\n";
echo "Risk Indicator: " . substr($res, 44, 2) . "<br>\n";
echo "Reference: " . substr($res, 46, 10) . "<br>\n";
echo "Order Number: " . substr($res, strpos($res, chr(28)) + 1,strrpos($res, chr(28) - 1)) . "<br>\n";
?>
Related
So, I'm fairly new to working with APIs, and am just trying to play around with using the Etsy API to display a certain set of listings.
By default, the API returns a set of 25 results, and can do a max of 100 at a time. I'd like to show more than that, so I'm trying to add pagination to my call. Here's what I've got so far:
<?php
//setting API key
define("API_KEY", XXX);
//setting request url
$url = "https://openapi.etsy.com/v2/listings/active?keywords=unicorn,unicorns&includes=Images:1:0&api_key=" . API_KEY;
while (isset($url) && $url != '') {
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$response_body=curl_exec($curl);
curl_close($curl);
$response = json_decode($response_body);
foreach ($response->results as $listing) {
echo "<li>" . $listing->title . " ~*~ " . $listing->price . " " . $listing->currency_code . " ~*~ " . 'View on Etsy!' . "</li>" . "<br>";
}
$url = $response->pagination->next_page;
}
?>
I thought this would loop through and return the next set of 25 results, but it didn't. Anyone have experience working with this? Is there somewhere I'm getting tripped up?
Thanks!
In your while block, you are assigning the value of the next_page property to $url.
But the actual value is an int, 2, not an url.
Instead append the next_page to the initial url, as a query string variable.
$url .= "&page=" . $response->pagination->next_page;
See below an example on how you can isolate each process to a function.
We move the curl operation into its own function where it returns an object from json_decode.
We move the whole processing of the listings into a separate function, where for now, it just prints out the listings.
This second function is recursive, meaning, that if the next page exists it will call the first function, get the response, then process it.
<?php
//setting API key
define("API_KEY", 'br4j52uzdtlcpp6qxb6we3ge');
function get_listings($page=1){
$url = "https://openapi.etsy.com/v2/listings/active?keywords=unicorn,unicorns&includes=Images:1:0&api_key=" . API_KEY;
$url .= "&page=$page";
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$response_body=curl_exec($curl);
curl_close($curl);
$responseObject = json_decode($response_body);
return $responseObject;
}
function process_listings($responseObject){
foreach ($responseObject->results as $listing) {
echo "Title: " . $listing->title . PHP_EOL .
"Price " . $listing->price . PHP_EOL .
"Currency code " . $listing->currency_code . PHP_EOL .
'URL ' . $listing->url . PHP_EOL;
}
print PHP_EOL . "Pagination " . $responseObject->pagination->next_page . PHP_EOL;
$next_page = $responseObject->pagination->next_page;
if ($next_page) {
$nextPageResponse = get_listings($next_page);
process_listings($nextPageResponse);
}
}
$firstPage = get_listings(); // page 1 is default
process_listings($firstPage);
I am integrating the API from our monitoring software (PRTG) into our website and attempting to use a function that generates a list of data in XML format. As it is generated as needed, the URL doesn't point to an existing file.
I tried using "simplexml_load_file" and "simplexml_load_string" and passing the URL with no luck. I've also tried use "file_put_contents" to first save the file, but it also fails since the URL doesn't actually point to a file.
How can this be made to work?
<?php
$prtg_url = "http://prtg.domain.net:8080/";
$prtg_user = "username";
$prtg_hash = "passwordhash";
function getSensorData($deviceid)
{
$sensor_xml_file = $GLOBALS['prtg_url'] . "api/table.xml?content=sensors&output=xml&columns=objid,type,device,sensor,status&id=" . $deviceid . "&username=" . $GLOBALS['prtg_user'] . "&passhash=" . $GLOBALS['prtg_hash'];
file_put_contents("sensor.xml", fopen($sensor_xml_file, 'r'));
$sensors = simplexml_load_file("sensor.xml");
foreach ($sensors->item as $sensor)
{
$sensor_ping = $sensor->ping;
$sensor_id = $sensor->objid;
$sensor_type = $sensor->type;
$sensor_typeraw = $sensor->type_raw;
echo $sensor_ping . "</br>";
echo $sensor_id . "</br>";
echo $sensor_type . "</br>";
echo $sensor_typeraw . "</br>";
}
}
getSensorData("3401");
?>
It may be something to do with the file handler. You could try using simplexml_load_file() with your URL. For example:
$url = $GLOBALS['prtg_url']
. "api/table.xml?content=sensors&output=xml&columns=objid,type,device,sensor,status&id="
. $deviceid . "&username=" . $GLOBALS['prtg_user']
. "&passhash=" . $GLOBALS['prtg_hash']);
$xml = simplexml_load_file($url);
try this:
$c = curl_init();
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($c, CURLOPT_URL, $sensor_xml_file);
$xmlString = curl_exec($c);
curl_close($c);
$sensors = simplexml_load_string($xmlString);
$opts = array('http' =>
array(
'method' => 'GET',
'header' => "Content-Type: text/xml\r\n",
'timeout' => 60
)
);
$context = stream_context_create($opts);
$url = $GLOBALS['prtg_url']
. "api/table.xml?content=sensors&output=xml&columns=objid,type,device,sensor,status&id="
. $deviceid . "&username=" . $GLOBALS['prtg_user']
. "&passhash=" . $GLOBALS['prtg_hash']);
$result = file_get_contents($url, false, $context);
echo $results;
This forces a 60 second timeout on the operation, that way you can see if it actually fetches any results. If it does return incomplete results, switch to using XMLReader for your parser.
USPS suggests to send request XML to
secure.shippingapis.com/ShippingAPI.dll?API=MerchandiseReturnV4&XML=
I have tried with the example XML given at
https://www.usps.com/business/web-tools-apis/merchandise-return-service-labels-v10-2a.htm
$url="https://secure.shippingapis.com/ShippingAPI.dll";
$api="API=MerchandiseReturnV4&XML=";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $api . $xml);
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$result = curl_exec($ch);
$error = curl_error($ch);
echo result;
but it is returning nothing.....
If the request is approaching the API then it would return the response which can be the proper expected response or the error code with some error detail.
The problem for not getting the proper response might be of the following here-
Wrong XML passed to the query string
Missed some required fields in the XML
Invalid Web Tools Credentials
In order to know the exact Error Code and Details you need to parse the returned XML from the API Server.
You can get the response stream and read the stream to the Stream Reader
string result = null;
using (HttpWebResponse response = httpWebRequest.GetResponse() as HttpWebResponse)
{
StreamReader reader = new StreamReader(response.GetResponseStream());
result = reader.ReadToEnd();
}
However I implemented this in .Net MVC but it might help for a head start to find the exact problem.
I forget to put the answers after solving my problem.
Function for connect to usps :-
public function connectToUSPS($url, $api, $xml) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $api . $xml);
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$result = curl_exec($ch);
$error = curl_error($ch);
if (empty($error)) {
return $result;
} else {
return false;
}
}
Function to generate USPS label :-
function create_UspsLabel($shipId, $userId) {
$row = 'contains user data';
$uspsUserName = 'a valid usps user name';
$uspsPassword = 'a valid usps user password';
$retailerName = 'retailer name';
$retailerAddress ='retailer address';
$permitNumber = 'a valid permit number';
$retailerState = 'retailer state;
$retailerCity = 'retailer city';
$retailerZip = 'retailer zip code';
$PDUPoBox = 'pdu box number';
$PDUCity = 'pdu city name';
$PDUState = 'pdu state name';
$PDUZip = 'pdu zip code';
$PDUZip2 = 'pdu zip code2';
$oid = 'order id';
$packageId = "KR" . str_pad(($oid + 1), 5, "0", STR_PAD_LEFT);
$state = 'state';
$xml = '<EMRSV4.0Request USERID="' . $uspsUserName . '" PASSWORD="' . $uspsPassword . '">
<Option>RIGHTWINDOW</Option>
<CustomerName>' . $row->name.' '.$row->lastName . '</CustomerName>
<CustomerAddress1>' . $row->suit . '</CustomerAddress1>';
$xml.=' <CustomerAddress2>' . $row->address1 . '</CustomerAddress2>
<CustomerCity>' . $row->city . '</CustomerCity>
<CustomerState>' . $state . '</CustomerState>
<CustomerZip5>' . $row->zipcode . '</CustomerZip5>
<CustomerZip4 />
<RetailerName>' . $retailerName . '</RetailerName>
<RetailerAddress>' . $retailerAddress . '</RetailerAddress>
<PermitNumber>' . $permitNumber . '</PermitNumber>
<PermitIssuingPOCity>' . $retailerCity . '</PermitIssuingPOCity>
<PermitIssuingPOState>' . $retailerState . '</PermitIssuingPOState>
<PermitIssuingPOZip5>' . $retailerZip . '</PermitIssuingPOZip5>
<PDUPOBox>' . $PDUPoBox . '</PDUPOBox>
<PDUCity>' . $PDUCity . '</PDUCity>
<PDUState>' . $PDUState . '</PDUState>
<PDUZip5>' . $PDUZip . '</PDUZip5>
<PDUZip4>' . $PDUZip2 . '</PDUZip4>
<ServiceType>Priority Mail</ServiceType>
<DeliveryConfirmation>False</DeliveryConfirmation>
<InsuranceValue />
<MailingAckPackageID>' . $packageId . '</MailingAckPackageID>
<WeightInPounds>0</WeightInPounds>
<WeightInOunces>10</WeightInOunces>
<RMA>RMA 123456</RMA>
<RMAPICFlag>False</RMAPICFlag>
<ImageType>TIF</ImageType>
<RMABarcode>False</RMABarcode>
<AllowNonCleansedDestAddr>False</AllowNonCleansedDestAddr>
</EMRSV4.0Request>';
$result = $this->connectToUSPS('https://secure.shippingapis.com/ShippingAPI.dll', 'API=MerchandiseReturnV4&XML=', $xml);
$xml = new SimpleXMLElement($result);
$string = base64_decode($xml->MerchandiseReturnLabel);
if ($string) {
$img_file = fopen(__USPSLABELIMAGE__ . "uspsLabel.tif", "w");
fwrite($img_file, $string);
fclose($img_file);
$imageMagickPath = "/usr/bin/convert";
$dest = __USPSLABELIMAGE__ . "uspsLabel.tif";
$filename = time() . ".png";
$pngDestPath = __USPSLABELIMAGE__ . $filename;
exec("$imageMagickPath -density 72 -channel RGBA -colorspace RGB -background none -fill none -dither None $dest $pngDestPath");
return $filename;
} else {
return "error";
}
}
I've got a problem with part of a CodeIgniter-based application I'm building.
I have to connect to a remote server and have a reasonably detailed set of instructions from the third-party about how to open a socket, send some XML data and receive a response - in VB script. I've translated this into the PHP code below. At the moment, according to my log, data is being written to the server (the log output is shown below). However the fgets() part of the code just seems to be timing out, with no errors or anything... makes things pretty hard to debug.
From what I've read about fsockopen() and fgets(), the following should work, but obviously it doesn't. The problem is with no error messages etc to go on, I'm at a bit of a loss as to how to debug it.
I would appreciate it if anyone who has a spare minute could cast an eye over it just to see if I've made an obvious mistake (or to confirm that what I'm doing is correct for that matter).
Here's the code (I've had to blank out some of it sorry).
public function makeBooking($orderId) {
// get entire XML file as a string
$xmlString = $this->getXmlString();
// replace non-alphanumeric characters
$xmlString = $this->replaceChars($xmlString);
// get length of xml string
$xmlStrCount = mb_strlen($xmlString) + 7;
// attempt to open socket
$fp = fsockopen('xxx.xx.xxx.xx', '81', $errno, $errstr, 10);
if (!$fp) {
// couldn't open socket
log_message('ERROR', "*** Couldn't open socket: $errno $errstr " . ' | line ' . __LINE__ . ' of ' . __FILE__);
} else {
log_message('DEBUG', "*** Socket open, connected to remote server ");
$lf = chr(13).chr(10);
// opened socket, prepare output
$output = '"POST xxxxxxxxxxxx.asp HTTP/1.0"' . $lf;
$output .= '"Accept: */*"' . $lf;
$output .= '"User-Agent: xxxxxxxxxxx_socket/1.0";' . $lf;
$output .= '"Content-type: application/x-www-form-urlencoded";' . $lf;
$output .= '"Content-length: ' . $xmlStrCount . '";' . $lf;
$output .= '""' . $lf;
$output .= '"xml_in='.$xmlString.'"';
// attempt to write output
$result = fwrite($fp, $output);
log_message('DEBUG', "*** Bytes written: $result " . ' | line ' . __LINE__ . ' of ' . __FILE__);
if($result) {
log_message('DEBUG', "*** Wrote output:$lf$lf$output$lf");
} else {
log_message('ERROR', "*** Failed to write output:$lf$lf$output$lf");
}
// read data from server until no more responses are sent
// while (!feof($fp)) {
if(!feof($fp)) {
log_message('DEBUG',"*** Requesting line 1 from remote server" );
//$line = fgets($fp);
$line = fgets($fp);
if($line) {
log_message('DEBUG',"*** Retreived line 1: " . print_r($line,TRUE) );
} else {
log_message('ERROR',"*** Could not retreive line 1" );
}
}
fclose($fp);
log_message('DEBUG',"*** Closed connection to remote server" );
}
}
The log. Obviously a lot of it is how I've interpreted the associated results. I've truncated the URL encoded XML data:
DEBUG - 2012-09-21 14:50:01 --> *** Socket open, connected to remote server
DEBUG - 2012-09-21 14:50:01 --> *** Bytes written: 8801 | line 57
DEBUG - 2012-09-21 14:50:01 --> *** Wrote output:
"POST xxxxxxxxxxxx.asp HTTP/1.0"
"Accept: */*"
"User-Agent: xxxxxxxxxxxxx_socket/1.0";
"Content-type: application/x-www-form-urlencoded";
"Content-length: 8630";
""
"xml_in=%26lt%3B%3Fxml+version%3D%26quot%3B1.0%26quot%3B..."
DEBUG - 2012-09-21 14:50:01 --> *** Requesting line 1 from remote server
ERROR - 2012-09-21 14:51:01 --> *** Could not retreive line 1
DEBUG - 2012-09-21 14:51:01 --> *** Closed connection to remote server
Any ideas of where to look would be much appreciated.
-------------- EDIT --------------
Just incase anyone stumbles across this thread with a similar issue, here's what I did in the end, based on robbie's suggestions:
public function createBooking($orderId) {
// http://php.net/manual/en/book.curl.php
// get entire XML file as a string
$xmlString = $this->getXmlString();
// replace non-alphanumeric characters - can't use htmlentities or htmlspecialchars
// because remote server uses different codes
$xmlString = $this->replaceChars($xmlString);
// get length of xml string
$xmlStrCount = mb_strlen($xmlString) + 7;
// prepare output
$lf = chr(13).chr(10);
$output = '"Accept: */*"' . $lf;
$output .= '"User-Agent: xxxxx_socket/1.0";' . $lf;
$output .= '"Content-type: application/x-www-form-urlencoded";' . $lf;
$output .= '"Content-length: ' . $xmlStrCount . '";' . $lf;
$output .= '""' . $lf;
$output .= '"xml_in='.$xmlString.'"';
// set curl options
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"http://xxxxx:xx/xxxxx.asp");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $output);
// Request the header information in the response.
curl_setopt($ch,CURLOPT_HEADER,true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Now execute the query
$response = curl_exec ($ch);
if(!$response) {
log_message('ERROR', "*** Curl error: " . curl_error($ch) . ' | line ' . __LINE__ . ' of ' . __FILE__);
show_error(DEFAULT_ERR_MSG);
}
curl_close ($ch);
// Response is the data.
$aLines = explode("\n", $response); // Splits the resposne into an array so you can process individual lines.
// etc
print_r($aLines);
}
Not sure of the error, but you need while (!$feof($fp)) and not 'if' - the while will loop until you get all the responses. That still doesn't fix your problem, so...
You may find this easier if you implement using curl. Much shorter, neater and easier to debug too. http://php.net/manual/en/book.curl.php
<?php
$ch = curl_init();
// Set the various options. replace the xxxx's
curl_setopt($ch, CURLOPT_URL,"xxxxxxxxxxxx.asp");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, 'xml_in=' . $xmlString);
curl_setopt($ch,CURLOPT_USERAGENT,'xxxxxxxxxxx_socket/1.0');
// Request the header information in the response. You're example gets the header, but you may not need it, so change to false if not
curl_setopt($ch,CURLOPT_HEADER,true);
// Now execute the query
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec ($ch);
curl_close ($ch);
// Response is the data.
$aLines = explode("\n", $response); // Splits the resposne into an array so you can process individual lines.
// etc
?>
I've been putting this off for a while as I just don't seem to have a clue with what I'm doing. I'm trying to use PHP and Curl to talk to the Barclaycard ePDQ MPI. I've done this before using the HSBC XML API but the Barclaycard ePDQ MPI seems to be giving me a few headaches. I have a form which posts card details/address details and the to a page that contains the following functions Please note that I have SSL set up on the domain, CURL is installed on the server, I had the HSBC XML API working just fine on the same box/URL.
<?php
function process_card($users_ip, $Temp_Order_ID, $User_NameX, $First_Name, $Surname, $Address_Line1, $Address_Line2, $Town, $Country, $Postcode, $CardNumber, $CardExpiryDate, $issue_node, $CardCVV, $totalCost ) {
if ($CardCVV == "")
$cvvindicator = 0;
else
$cvvindicator=1;
global $status;
//$amount = $amount * 100;
$xml = '
<?XML version="1.0" encoding="UTF-8"?>
<EngineDocList>
<DocVersion>1.0</DocVersion>
<EngineDoc>
<IPAddress>' . $users_ip . '</IPAddress>
<ContentType>OrderFormDoc</ContentType>
<User>
<Name>XXXXX</Name>
<Password>XXXXXXX</Password>
<ClientId DataType="S32">12345</ClientId>
</User>
<Instructions>
<Pipeline>Payment</Pipeline>
</Instructions>
<OrderFormDoc>
<Mode>T</Mode>
<Id>' . $Temp_Order_ID. '</Id>
<Consumer>
<Email>' . $User_NameX . '</Email>
<BillTo>
<Location>
<Address>
<FirstName>' . $First_Name . '</FirstName>
<LastName>' . $Surname .'</LastName>
<Street1>' . $Address_Line1 . '</Street1>
<Street2>' . $Address_Line2 . '</Street2>
<Street3></Street3>
<City>' . $Town . '</City>
<StateProv>' . $Country . '</StateProv>
<PostalCode>' . $Postcode . '</PostalCode>
<Country>' . getCuntCode($Country) . '</Country>
</Address>
</Location>
</BillTo>
<ShipTo>
<Location>
<Address>
<FirstName>' . $First_Name . '</FirstName>
<LastName>' . $Surname .'</LastName>
<Street1>' . $Address_Line1 . '</Street1>
<Street2>' . $Address_Line2 . '</Street2>
<Street3></Street3>
<City>' . $Town . '</City>
<StateProv>' . $Country . '</StateProv>
<PostalCode>' . $Postcode . '</PostalCode>
<Country>' . getCuntCode($Country) . '</Country>
</Address>
</Location>
</ShipTo>
<PaymentMech>
<CreditCard>
<Type DataType="S32">1</Type>
<Number>' . $CardNumber . '</Number>
<Expires DataType="ExpirationDate" Locale="826">' . $CardExpiryDate . '</Expires>
' . $issue_node . '
<Cvv2Indicator>' . $cvvindicator . '</Cvv2Indicator>
<Cvv2Val>' . $CardCVV . '</Cvv2Val>
</CreditCard>
</PaymentMech>
</Consumer>
<Transaction>
<Type>Auth</Type>
<CurrentTotals>
<Totals>
<Total DataType="Money" Currency="826">' . $totalCost . '</Total>
</Totals>
</CurrentTotals>
<CardholderPresentCode DataType="S32"></CardholderPresentCode>
<PayerSecurityLevel DataType="S32"></PayerSecurityLevel>
<PayerAuthenticationCode></PayerAuthenticationCode>
<PayerTxnId></PayerTxnId>
</Transaction>
</OrderFormDoc>
</EngineDoc>
</EngineDocList>';
$url = "https://secure2.epdq.co.uk:11500";
$params = array("CLRCMRC_XML" => $xml);
$params = formatData($params);
$response = post_to_epdq($url, $xml);
$auth_code = strstr($response, "<AuthCode>");
echo "auth_code=" . $auth_code;
if ($auth_code <> "") {
$splt = split("</AuthCode>", $auth_code);
$status = strip_tags($splt[0]);
return $xml . "<hr/>" . $response . "Good";
} else {
$error = strstr($response, "<Text>");
$splt = split("</Text>", $error);
$status = strip_tags($splt[0]);
return $xml . "<hr/>" . $response . "Bad";
}
}
function post_to_epdq($url, $data) {
set_time_limit(120);
$output = array();
$curlSession = curl_init();
curl_setopt($curlSession, CURLOPT_URL, $url);
curl_setopt($curlSession, CURLOPT_PORT, 443);
curl_setopt($curlSession, CURLOPT_HEADER, 0);
curl_setopt($curlSession, CURLOPT_POST, 1);
curl_setopt($curlSession, CURLOPT_POSTFIELDS, $data);
curl_setopt($curlSession, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curlSession, CURLOPT_TIMEOUT, 60);
#$response = split(chr(10),curl_exec ($curlSession));
$response = curl_exec($curlSession);
if (curl_error($curlSession)) {
$this->error = curl_error($curlSession);
return "ERROR";
}
curl_close($curlSession);
return $response;
}
function formatData($data) {
$output = "";
foreach ($data as $key => $value)
$output .= "&" . $key . "=" . urlencode($value);
$output = substr($output, 1);
return $output;
}
Needless to say I validate the user input, generate their IP and determine a country code, I then call the above function:
process_card($users_ip,$Temp_Order_ID,$User_NameX,$First_Name,$Surname,$Address_Line1,$Address_Line2,$Town,$Country,$Postcode,$CardNumber, $CardExpiryDate, $issue_node, $CardCVV, $totalCost );
I don't get a response? I'm unsure if the port and url items are incorrect or if the whole CURL request is wrong. Nothing is returned from the request.
Sorry about this being a long post but this is really doing my head in!
Has anyone done this before?
I've managed to fix my problem now. It turned out that the CURL connection to the Barclays website was blocked by a firewall on the server which was why I was getting no error message back.
I modified the CURL code a bit to check for errors:
$data = curl_exec($ch);
if(curl_errno($ch)) {
print curl_error($ch);
}
curl_close ($ch);
This then says: couldn't connect to host at which point I tried it on another server and it got past this error.
The error I am getting now is: "Insufficient permissions to perform requested operation." I have tried all the accounts I have been given but if I log into the EPDQ control panel I seem to only be able to assign up to EPDQ Level 4 and CPI access with no mention of MPI and even though it says technical support is available from 8AM until 12PM, it is not. It is really just office hours for anything but the most basic queries.
Is there any advantage to using this over SagePay? SagePay allows you to send through the individual transaction details as well where Barclays only lets you send the total amount payable and they really do offer support out of office hours.
The only reason I am changing the site to MPI is the fact that with CPI the customer can close the browser before returning to the website so the order details and invoice are not sent so there is no way of knowing what has been purchased.
Thanks
Robin
Howdy, after some playing around here's the correct CURL set up you have to do...
I realise that the variables could be better and I should make this as an object but I just want to get a quick answer up there. The script also needs to sift through the different accept and error messages but this is what I've got so far...
$ch = curl_init();
$url = "https://secure2.epdq.co.uk:11500"; // Don't need to add curl_setopt($curlSession, CURLOPT_PORT, 443); as port is included
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $vars); // $vars is your XML
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 120);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$data = curl_exec($ch);
curl_close ($ch);
$xml = new domDocument;
$xml->loadXML($data);
if (!$xml) {
echo 'Error while parsing the document - Please Contact to determine if payment has gone though';
exit;
}
$x = $xml->getElementsByTagName( "CcErrCode" );
$approved = $x->item(0)->nodeValue;
$xx = $xml->getElementsByTagName( "CcReturnMsg" );
$CcReturnMsg = $xx->item(0)->nodeValue;
if($approved) {
// the card is valid.
$y = $xml->getElementsByTagName( "Id" );
$BCardId = $y->item(1)->nodeValue;
$z = $xml->getElementsByTagName( "MessageList" );
$MessageList = $z->item(0)->nodeValue;
$zz = $xml->getElementsByTagName( "AvsRespCode" );
$AvsRespCode = $zz->item(0)->nodeValue;
$zzz = $xml->getElementsByTagName( "AvsDisplay" );
$AvsDisplay = $zzz->item(0)->nodeValue;
$zzzz = $xml->getElementsByTagName( "ProcReturnMsg" );
$ProcReturnMsg = $zzzz->item(0)->nodeValue;
if($approved == "1"){
echo "approved!<br />";
echo "BCardId: " . $BCardId . ", MessageList=" . $MessageList . ", " . $AvsRespCode . ", " . $AvsDisplay . ", " . $ProcReturnMsg;
die();
}else{
// raise that it's been partially accepted,
echo "partially approved";
echo "BCardId: " . $BCardId . ", MessageList=" . $MessageList . ", " . $AvsRespCode . ", " . $AvsDisplay . ", " . $ProcReturnMsg;
die();
}
}else{
echo "you have been completely knocked back";
$zzzzz = $xml->getElementsByTagName( "Text" );
$BCard_Text = $zzzzz->item(0)->nodeValue;
echo "The reason:" . $BCard_Text;
die();
}
hope this helps other people who have to set this up!