Solved

Need help with sending and receiving xml data using php

Posted on 2008-10-16
22
686 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
 
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
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 

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

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

This article will explain how to display the first page of your Microsoft Word documents (e.g. .doc, .docx, etc...) as images in a web page programatically. I have scoured the web on a way to do this unsuccessfully. The goal is to produce something …
Foreword (July, 2015) Since I first wrote this article, years ago, a great many more people have begun using the internet.  They are coming online from every part of the globe, learning, reading, shopping and spending money at an ever-increasing ra…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.

760 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

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now