Need help with sending and receiving xml data using php

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

leevee1606Asked:
Who is Participating?

Improve company productivity with a Business Account.Sign Up

x
 
James LooneyConnect With a Mentor Sr. Programmer/AnalystCommented:
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
 
wellsoCommented:
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
 
James LooneySr. Programmer/AnalystCommented:
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
Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

 
leevee1606Author Commented:
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
 
James LooneySr. Programmer/AnalystCommented:
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
 
leevee1606Author Commented:
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
 
leevee1606Author Commented:
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
 
James LooneySr. Programmer/AnalystCommented:
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
 
leevee1606Author Commented:
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
 
leevee1606Author Commented:
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
 
James LooneySr. Programmer/AnalystCommented:
Ok, giving it a shot right now.
0
 
James LooneySr. Programmer/AnalystCommented:
can you use the "Attach File" feature on here to attach their API doc?
0
 
leevee1606Author Commented:
i did already - look further up.......!
0
 
James LooneySr. Programmer/AnalystCommented:
Ack, sorry. :)
0
 
James LooneySr. Programmer/AnalystCommented:
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
 
leevee1606Author Commented:
ah yes - well spotted!!

now - how do i read those xml fields in as variables from that response??
0
 
James LooneySr. Programmer/AnalystCommented:
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
 
James LooneySr. Programmer/AnalystCommented:
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
 
leevee1606Author Commented:
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
 
James LooneySr. Programmer/AnalystCommented:
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
 
leevee1606Author Commented:
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
 
James LooneySr. Programmer/AnalystCommented:
Hehehe, well you don't have to but a drink sounds tasty.  

 jrlooney@gmail.com  :)
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.