Solved

Need help with sending and receiving xml data using php

Posted on 2008-10-16
22
691 Views
Last Modified: 2013-12-13
I am trying to setup a script to send xml data to a cc processing company, and then also to receive their results xml data back.
I have tried sending using curl, which their server doesn't seem to be getting correct information from.
And I'm battling on receive the results data back, and parsing into variables i can use in php.
I have attached the basic code snippet of how i'm sending and attempting to receive.
I would appreciate any input on this, and a code snippet(s) to sort it out , or a better way of doing it would be great.

//here is how I send the xml data
 
$data = "<xml>";
$data .= "<header>";
$data .= "<responsetype>direct</responsetype>";
$data .= "<mid>$mid</mid>";
$data .= "<user>$user</user>";
$data .= "<password>$password</password>";
$data .= "<type>charge</type>";
$data .= "</header>";
$data .= "<request>";
$data .= "<charge>";
$data .= "<etan>$etan</etan>";
$data .= "<card>";
$data .= "<cctype>$cctype</cctype>";
$data .= "<cc>$cc</cc>";
$data .= "<expire>$expire</expire>";
$data .= "<cvv>$cvv</cvv>";
$data .= "</card>";
$data .= "<cardholder>";
$data .= "<firstname>$firstname</firstname>";
$data .= "<lastname>$lastname</lastname>";
$data .= "<street>$street</street>";
$data .= "<housenumber>$housenumber</housenumber>";
$data .= "<zip>$zip</zip>";
$data .= "<city>$city</city>";
$data .= "<country>$country</country>";
$data .= "<state>$state</state>";
$data .= "<telephone>$telephone</telephone>";
$data .= "<email>$email</email>";
$data .= "<ip>$ip</ip>";
$data .= "</cardholder>";
$data .= "<amount>";
$data .= "<currency>$currency</currency>";
$data .= "<exponent>2</exponent>";
$data .= "<value>$value</value>";
$data .= "</amount>";
$data .= "</charge>";
$data .= "<webtransaction>";
$data .= "<transactionresponseurl>$responseurl</transactionresponseurl>";
$data .= "<webuserredirecturl>$redirecturl</webuserredirecturl>";
$data .= "</webtransaction>";
$data .= "</request>";
$data .= "</xml>";
 
//send messages
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"$urladdress");
curl_setopt($ch, CURLOPT_POST, 1); 
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec ($ch); 
curl_close ($ch);
$captured = substr($result, 0, 2);
 
if ($captured === "520" || $captured === "550") $status = "Accepted";
else $status = "Declined";
 
 
// here is how i receive the data - not sure how to parse into variables
$xml = $GLOBALS["HTTP_RAW_POST_DATA"]; 
 
echo($GLOBALS["HTTP_RAW_POST_DATA"]);

Open in new window

0
Comment
Question by:leevee1606
  • 12
  • 9
22 Comments
 
LVL 2

Expert Comment

by:wellso
ID: 22728924
http://uk2.php.net/domxml has some excellent functions for creating XML documents. I'll have a quick look through the fucntions to see which ones you would need and where to use them, I havnt used them for a few months since I was doing a PHP Google Maps project.
0
 
LVL 6

Expert Comment

by:James Looney
ID: 22730610
Hi,
Which payment processor is this for? I currently have sites using Authorize.net, PayPal, ViaKlix and VirtualMerchant. Just let me know and I can help you out.
0
 

Author Comment

by:leevee1606
ID: 22730856
edelweisscard.com

they simply ask for the xml data to be sent to them, and they send back an xml result.
I'm battling to deal with this within php.

I can do it with a normal html form send, but that does not help. I need to get it working using curl and read the result back from them immediately.
0
NAS Cloud Backup Strategies

This article explains backup scenarios when using network storage. We review the so-called “3-2-1 strategy” and summarize the methods you can use to send NAS data to the cloud

 
LVL 6

Expert Comment

by:James Looney
ID: 22730967
Ok. I don't know anything about edelweiss - so I don't know what they are supposed to be returning to you when you do the curl. For example, Authorize.net returns a whole lot of data. So I set up the curl almost exactly how you do, however I am not sure what they are returning to you when you do:
$result = curl_exec ($ch);

Do you have their developers documentation that tells what they are sending back? Or, can you post here what you get if you do this:

$result = curl_exec ($ch);
var_dump($result);

What concerns me is this line:
$captured = substr($result, 0, 2);

Let me know what you get on that var_dump and then we can proceed.  :)
0
 

Author Comment

by:leevee1606
ID: 22732286
herewith var dump; it seems their server is not happy with the xml post data i am sending them, yet i cannot fault it??; it always comes up with this "xml post data not found" when sending it using curl, yet if I use a standard html post form, it works fine....

<xml><header><responsetype>direct</responsetype><mid>0</mid></header><response><error><errorcode>-1</errorcode><errormessage>xml post data not found</errormessage><tranID></tranID></error></response></xml>

and here is their example from their api manual;
<xml>
<header>
<responsetype>direct</responsetype>
<mid>42</mid>
<user>APIuser01</user>
<password>I4uZA7tRcf</password>
<type>charge</type>
</header>
<request>
<charge>
<etan></etan>
<card>
<cctype>visa</cctype>
<cc>5123456789012346</cc>
<expire>01/12</expire>
<cvv>123</cvv>
</card>
<cardholder>
<firstname>John</firstname>
<lastname>Doe</lastname>
<street>Nowhere city</street>
<housenumber>1</housenumber>
<zip>1234</zip>
<city>NonCity</city>
<country>us</country>
<state>ca</state>
<telephone>1234567890</telephone>
<email>jdoe@email.com</email>
<ip>123.456.789.123</ip>
</cardholder>
<amount>
<currency>USD</currency>
<exponent>2</exponent>
<value>100</value>
</amount>
</charge>
</request>
</xml>
0
 

Author Comment

by:leevee1606
ID: 22732317
oh - ignore the line; $captured = substr($result, 0, 2);
and the subsquent 2 lines, they were for a result code i was expecting, but obviously not getting!

The main thing now is getting it to accept the xml format sent from curl right
0
 
LVL 6

Expert Comment

by:James Looney
ID: 22732452
Ya, that is weird. Everything here looks fine (though I forgot to curl_close on mine):
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"$urladdress");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec ($ch);
curl_close ($ch);

And the curl must be working since you get a response back from them.

The only other thing that I don't do with Authorize.net that you are doing here, is I don't include the <xml></xml> tags - can't imagine that makes a difference, but guess you never know.

Anyway you can attach the API doc here so i can download it?
0
 

Author Comment

by:leevee1606
ID: 22732742
yup - curl is working - but their server doesn't like something there - it always returns "xml post data not found". If we can get past that to accept the post data sent from curl, that will be great, then we just need to read the reply result xml data from them.
If i send via html post, i get the following result; I guess i could wotk around by using this method, only, how do i read that result data??

- <xml>
- <header>
  <responsetype>direct</responsetype>
  <mid>42</mid>
  <type>charge</type>
  </header>
- <response>
- <success>
  <tan>925157</tan>
  <etan />
  <message>Transaction sucessfully charged</message>
  </success>
  </response>
  </xml>
API-Documentation-v-1.4.pdf
0
 

Author Comment

by:leevee1606
ID: 22733128
herewith example of how the code (i believe) should work. The below $data works perfectly sent from an html form post.
Their server however doesn't like something - try it and see for yourself - maybe there's something small that needs to change?

This is getting rather urgent now - if you can get the send and receive working for me - i'll even pay you something, apart from awarding points here!
<?php
$xml = "
<xml>
<header>
<responsetype>direct</responsetype>
<mid>42</mid>
<user>APIuser01</user>
<password>I4uZA7tRcf</password>
<type>charge</type>
</header>
<request>
<charge>
<etan></etan>
<card>
<cctype>visa</cctype>
<cc>5123456789012346</cc>
<expire>01/12</expire>
<cvv>123</cvv>
</card>
<cardholder>
<firstname>John</firstname>
<lastname>Doe</lastname>
<street>Nowhere city</street>
<housenumber>1</housenumber>
<zip>1234</zip>
<city>NonCity</city>
<country>us</country>
<state>ca</state>
<telephone>1234567890</telephone>
<email>jdoe@email.com</email>
<ip>123.456.789.123</ip>
</cardholder>
<amount>
<currency>USD</currency>
<exponent>2</exponent>
<value>100</value>
</amount>
</charge>
</request>
</xml>
";
 
$url ='https://v-pg.net/api/interface.aspx';
$port = 443;
 
$response = xml_post($xml, $url, $port);
$xmlresp = nl2br(htmlentities($response));
echo $xmlresp;
 
	function xml_post($post_xml, $url, $port)
	{
		$user_agent = $_SERVER['HTTP_USER_AGENT'];
 
		$ch = curl_init();    // initialize curl handle
		curl_setopt($ch, CURLOPT_URL, $url); // set url to post to
		curl_setopt($ch, CURLOPT_FAILONERROR, 1);              // Fail on errors
		curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);	// allow redirects
		curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); // return into a variable
		curl_setopt($ch, CURLOPT_PORT, $port);			//Set the port number
		curl_setopt($ch, CURLOPT_TIMEOUT, 15); // times out after 15s
		curl_setopt($ch, CURLOPT_POSTFIELDS, $post_xml); // add POST fields
		curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
 
		if($port==443)
		{
			curl_setopt($ch, CURLOPT_SSL_VERIFYHOST,  2);
			curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
		}
 
		$data = curl_exec($ch);
 
		curl_close($ch);
 
		return $data;
	}
?>

Open in new window

0
 
LVL 6

Expert Comment

by:James Looney
ID: 22733307
Ok, giving it a shot right now.
0
 
LVL 6

Expert Comment

by:James Looney
ID: 22733387
can you use the "Attach File" feature on here to attach their API doc?
0
 

Author Comment

by:leevee1606
ID: 22733488
i did already - look further up.......!
0
 
LVL 6

Expert Comment

by:James Looney
ID: 22733517
Ack, sorry. :)
0
 
LVL 6

Expert Comment

by:James Looney
ID: 22733603
Ok just got a successful transaction ("Transaction sucessfully charged") - funny they misspell successfully. They are looking for a specific POST param called 'xml' so when you set the POSTFIELDS you gotta use an array so as to be able to give it the specific name. Like so:

curl_setopt($ch, CURLOPT_POSTFIELDS, array('xml'=>$post_xml));
0
 

Author Comment

by:leevee1606
ID: 22733755
ah yes - well spotted!!

now - how do i read those xml fields in as variables from that response??
0
 
LVL 6

Expert Comment

by:James Looney
ID: 22734468
There is built in PHP functions for XML, this code will take the response and parse it into two arrays. Here is the info page on this function (http://us3.php.net/manual/en/function.xml-parse-into-struct.php).



<?php
$xml = "
<xml>
<header>
<responsetype>direct</responsetype>
<mid>42</mid>
<user>APIuser01</user>
<password>I4uZA7tRcf</password>
<type>charge</type>
</header>
<request>
<charge>
<etan></etan>
<card>
<cctype>visa</cctype>
<cc>5123456789012346</cc>
<expire>01/12</expire>
<cvv>123</cvv>
</card>
<cardholder>
<firstname>John</firstname>
<lastname>Doe</lastname>
<street>Nowhere city</street>
<housenumber>1</housenumber>
<zip>1234</zip>
<city>NonCity</city>
<country>us</country>
<state>ca</state>
<telephone>1234567890</telephone>
<email>jdoe@email.com</email>
<ip>123.456.789.123</ip>
</cardholder>
<amount>
<currency>USD</currency>
<exponent>2</exponent>
<value>100</value>
</amount>
</charge>
</request>
</xml>
";
 
$url ='https://v-pg.net/api/interface.aspx';
$port = 443;
 
$response = xml_post($xml, $url, $port);
#$xmlresp = nl2br(htmlentities($response));
 
 
$p = xml_parser_create();
xml_parse_into_struct($p, $response, $vals, $index);
xml_parser_free($p);
echo "Index array\n";
print_r($index);
echo "\nVals array\n";
print_r($vals);
 
 
 
function xml_post($post_xml, $url, $port)
{
	$user_agent = $_SERVER['HTTP_USER_AGENT'];
 
	$ch = curl_init();    // initialize curl handle
	curl_setopt($ch, CURLOPT_URL, $url); // set url to post to
	curl_setopt($ch, CURLOPT_FAILONERROR, 1);              // Fail on errors
	curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);    // allow redirects
	curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); // return into a variable
	curl_setopt($ch, CURLOPT_PORT, $port);                  //Set the port number
	curl_setopt($ch, CURLOPT_TIMEOUT, 15); // times out after 15s
	curl_setopt($ch, CURLOPT_POSTFIELDS, $post_xml); // add POST fields
	curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
 
	if($port==443)
	{
			curl_setopt($ch, CURLOPT_SSL_VERIFYHOST,  2);
			curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
	}
 
	$data = curl_exec($ch);
 
	curl_close($ch);
 
	return $data;
}
?>

Open in new window

0
 
LVL 6

Expert Comment

by:James Looney
ID: 22734476
Oh - and the code there contains the xml stuff, it outputs to screen so you can view source in your browser and see the arrays.
0
 

Author Comment

by:leevee1606
ID: 22734572
Ok - almost there - i see the arrays - below is from my output screen - it's a bit confusing still - now how do I assign variables to them? for instance;  $message = ????

Index array Array ( [XML] => Array ( [0] => 0 [1] => 13 ) [HEADER] => Array ( [0] => 1 [1] => 5 ) [RESPONSETYPE] => Array ( [0] => 2 ) [MID] => Array ( [0] => 3 ) [TYPE] => Array ( [0] => 4 ) [RESPONSE] => Array ( [0] => 6 [1] => 12 ) [SUCCESS] => Array ( [0] => 7 [1] => 11 ) [TAN] => Array ( [0] => 8 ) [ETAN] => Array ( [0] => 9 ) [MESSAGE] => Array ( [0] => 10 ) ) Vals array Array ( [0] => Array ( [tag] => XML [type] => open [level] => 1 ) [1] => Array ( [tag] => HEADER [type] => open [level] => 2 ) [2] => Array ( [tag] => RESPONSETYPE [type] => complete [level] => 3 [value] => direct ) [3] => Array ( [tag] => MID [type] => complete [level] => 3 [value] => 42 ) [4] => Array ( [tag] => TYPE [type] => complete [level] => 3 [value] => charge ) [5] => Array ( [tag] => HEADER [type] => close [level] => 2 ) [6] => Array ( [tag] => RESPONSE [type] => open [level] => 2 ) [7] => Array ( [tag] => SUCCESS [type] => open [level] => 3 ) [8] => Array ( [tag] => TAN [type] => complete [level] => 4 [value] => 925999 ) [9] => Array ( [tag] => ETAN [type] => complete [level] => 4 ) [10] => Array ( [tag] => MESSAGE [type] => complete [level] => 4 [value] => Transaction sucessfully charged ) [11] => Array ( [tag] => SUCCESS [type] => close [level] => 3 ) [12] => Array ( [tag] => RESPONSE [type] => close [level] => 2 ) [13] => Array ( [tag] => XML [type] => close [level] => 1 ) )
0
 
LVL 6

Expert Comment

by:James Looney
ID: 22734872
Well the $index array gives the index in the $vals array. So to check the MESSAGE returned, you'd do

echo $vals[$index['MESSAGE']]['value'];

or

accessing the TYPE value:

echo $vals[$index['TYPE']]['value'];


The values they return may make more sense once you are submitting to a live account, because some of their response parameters don't make muchh sense.

Like notice that $index[SUCCESS] contains two values - for some reason they return it twice. Not sure why.

Also - if you view the dumped arrays in your browser "View Source", it's better formatted (in case you didn't know).
0
 
LVL 6

Accepted Solution

by:
James Looney earned 500 total points
ID: 22734877
Oh woops, that code should actually be like:

echo $vals[$index['MESSAGE'][0]]['value'];

or

accessing the TYPE value:

echo $vals[$index['TYPE'][0]]['value'];
0
 

Author Comment

by:leevee1606
ID: 22734999
OK - gotit !
excellent! thank you !
ur a star!

(if u post ur paypal email, i'll send u something to buy urself a drink!)
0
 
LVL 6

Expert Comment

by:James Looney
ID: 22735110
Hehehe, well you don't have to but a drink sounds tasty.  

 jrlooney@gmail.com  :)
0

Featured Post

Ransomware: The New Cyber Threat & How to Stop It

This infographic explains ransomware, type of malware that blocks access to your files or your systems and holds them hostage until a ransom is paid. It also examines the different types of ransomware and explains what you can do to thwart this sinister online threat.  

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Part of the Global Positioning System A geocode (https://developers.google.com/maps/documentation/geocoding/) is the major subset of a GPS coordinate (http://en.wikipedia.org/wiki/Global_Positioning_System), the other parts being the altitude and t…
This article discusses how to create an extensible mechanism for linked drop downs.
The viewer will learn how to count occurrences of each item in an array.
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.

832 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question