Using curl with an api token and getting the XML elements into working variables or to at least view in html format.
Here is the code used that is doing a vardump:
$curl = curl_init('https://mywebsite.highrisehq.com/people.xml');
curl_setopt($curl,CURLOPT_RETURNTRANSFER,true);
curl_setopt($curl,CURLOPT_USERPWD,'myapitoken12345:x');
curl_setopt($curl,CURLOPT_SSL_VERIFYPEER,0);
curl_setopt($curl,CURLOPT_SSL_VERIFYHOST,0);
$data = curl_exec($curl);
curl_close($curl);
$people_xml = new SimpleXMLElement($data);
var_dump($people_xml);
When doing the var_dump, the output isn't something I am familiar with.
object(SimpleXMLElement) #1 (2) {
["#attributes"]=> array(1) {
["type"]=> string(5) "array" }
["person"]=> array(128) { ... etc. etc. etc...
The XML structure that HighriseHQ.com shows is like this for clues on how to retrieve elements.
<people type="array">
<person>
<first-name>John</first-name>
</person>
<person>
<first-name>Jane</first-name>
</person>
</people>
.... etc. etc.
How or where do I translate the part that says $people = simplexml_load_string($xml); into variables that I can work with? Eventually I want to either display, edit, or store those people as i'll be syncing a website database with highrise - so that notes, and contacts aren't outdated.
Found the solution.
$curl = curl_init('https://my_website_goes_here.highrisehq.com/people.xml');
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_USERPWD, 'my_api_token_goes_here:x');
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
$data = curl_exec($curl);
curl_close($curl);
$people_xml = new SimpleXMLElement($data);
foreach($people_xml->person as $person) {
echo "<strong>" . $person->{'first-name'} . " " . $person->{'last-name'} . "</strong><br />";
echo "Title: " . $person->{'title'} . "<br />";
echo "Background: " . $person->{'background'} . "<br />";
echo "Email: " . $person->{'email-address'} . "<br />";
echo "ID: " . $person->id . "<br /><br />";
}
Related
First question! Woho!
I'm currently coding a Dashboard for a Discord bot in PHP.
Recently, when trying to select a server, it would only display 3 malfunctioning items. So I checked the complete array using print_r() and it turned out it rate-limited me.
Now, I got no idea why that happened, as I'm the only person on the server. So what am I doing wrong? Here is the code for listing the selection page:
$all = DiscordAPI("/users/#me/guilds");
foreach ($all as $guild) {
echo "<a href='/?server=" . $guild['id'] . "'><p>";
if ($guild['icon']) {
if (substr($guild['icon'], 0, 2) == "a_") {
echo "<img class='server-icon' src='https://cdn.discordapp.com/icons/" . $guild['id'] . "/" . $guild['icon'] . ".gif?size=64'>";
} else {
echo "<img class='server-icon' src='https://cdn.discordapp.com/icons/" . $guild['id'] . "/" . $guild['icon'] . ".webp?size=64'>";
}
} else {
$words = explode(" ", $guild['name']);
$acronym = "";
foreach ($words as $w) {
$acronym .= $w[0];
}
echo "<img class='server-icon' src='https://cdn.statically.io/avatar/s=64/" . $acronym . "'>";
}
echo $guild['name'];
echo "</p></a>";
}
And here is the code for the DiscordAPI() function:
function DiscordAPI($endpoint)
{
if (!$_SESSION['token']) {
die("No token provided");
}
$ch = curl_init("https://discord.com/api" . $endpoint);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Authorization: Bearer " . $_SESSION['token']
));
$data = curl_exec($ch);
curl_close($ch);
return json_decode($data, true);
}
There are 2 API calls before this code to verify that there is a valid token.
Quick sidenote: I got Autism, so I might understand stuff a bit differently. Don't be scared to ask if I worded something hard to understand. Thank you for trying to understand me.
I am using xml with cURL to contact Canada post and
get shipping labels.
This is the code I use.
The platform is ExpressionEngine
<?php
/**
* Sample code for the CreateShipment Canada Post service.
*
* The CreateShipment service is used to create a new shipping item, to
* request the generation of a softcopy image of shipping labels, and to provide
* links to these shipping labels and other information associated with the
* shipping item..
*
* This sample is configured to access the Developer Program sandbox environment.
* Use your development key username and password for the web service credentials.
*
**/
// Your username, password and customer number are imported from the following file
// CPCWS_Shipping_PHP_Samples\REST\shipping\user.ini
$userProperties = parse_ini_file(realpath(dirname($_SERVER['SCRIPT_FILENAME'])) . '/../user.ini');
$username = $userProperties['username'];
$password = $userProperties['password'];
$mailedBy = $userProperties['customerNumber'];
$mobo = $userProperties['customerNumber'];
// REST URL
$service_url = 'https://ct.soa-gw.canadapost.ca/rs/' . $mailedBy . '/' . $mobo . '/shipment';
// Create CreateShipment request xml
$groupId = '4326432';
$requestedShippingPoint = 'H2B1A0';
$mailingDate = '2012-10-24';
$contractId = '0040662521';
$xmlRequest = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<shipment xmlns="http://www.canadapost.ca/ws/shipment">
<group-id>{$groupId}</group-id>
<requested-shipping-point>{$requestedShippingPoint}</requested-shipping-point>
<expected-mailing-date>{$mailingDate}</expected-mailing-date>
<delivery-spec>
<service-code>DOM.EP</service-code>
<sender>
<name>Bulma</name>
<company>Capsule Corp.</company>
<contact-phone>1 (514) 820 5879</contact-phone>
<address-details>
<address-line-1>502 MAIN ST N</address-line-1>
<city>MONTREAL</city>
<prov-state>QC</prov-state>
<country-code>CA</country-code>
<postal-zip-code>H2B1A0</postal-zip-code>
</address-details>
</sender>
<destination>
<name>Ryuko Saito</name>
<company>Kubere</company>
<address-details>
<address-line-1>23 jardin private</address-line-1>
<city>Ottawa</city>
<prov-state>ON</prov-state>
<country-code>CA</country-code>
<postal-zip-code>K1K4T3</postal-zip-code>
</address-details>
</destination>
<options>
<option>
<option-code>DC</option-code>
</option>
</options>
<parcel-characteristics>
<weight>15</weight>
<dimensions>
<length>6</length>
<width>12</width>
<height>9</height>
</dimensions>
<unpackaged>true</unpackaged>
<mailing-tube>false</mailing-tube>
</parcel-characteristics>
<notification>
<email>ryuko.saito#kubere.com</email>
<on-shipment>true</on-shipment>
<on-exception>false</on-exception>
<on-delivery>true</on-delivery>
</notification>
<print-preferences>
<output-format>8.5x11</output-format>
</print-preferences>
<preferences>
<show-packing-instructions>true</show-packing-instructions>
<show-postage-rate>false</show-postage-rate>
<show-insured-value>true</show-insured-value>
</preferences>
<settlement-info>
<contract-id>{$contractId}</contract-id>
<intended-method-of-payment>Account</intended-method-of-payment>
</settlement-info>
</delivery-spec>
</shipment>
XML;
$curl = curl_init($service_url); // Create REST Request
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($curl, CURLOPT_CAINFO, realpath(dirname($argv[0])) . '/../../../third-party/cert/cacert.pem'); // Signer Certificate in PEM format
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $xmlRequest);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($curl, CURLOPT_USERPWD, $username . ':' . $password);
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/vnd.cpc.shipment-v2+xml', 'Accept: application/vnd.cpc.shipment-v2+xml'));
$curl_response = curl_exec($curl); // Execute REST Request
if(curl_errno($curl)){
echo 'Curl error: ' . curl_error($curl) . "\n";
}
echo 'HTTP Response Status: ' . curl_getinfo($curl,CURLINFO_HTTP_CODE) . "\n";
curl_close($curl);
// Example of using SimpleXML to parse xml response
libxml_use_internal_errors(true);
$xml = simplexml_load_string('<root>' . preg_replace('/<\?xml.*\?>/','',$curl_response) . '</root>');
if (!$xml) {
echo 'Failed loading XML' . "\n";
echo $curl_response . "\n";
foreach(libxml_get_errors() as $error) {
echo "\t" . $error->message;
}
} else {
if ($xml->{'shipment-info'} ) {
$shipment = $xml->{'shipment-info'}->children('http://www.canadapost.ca/ws/shipment');
if ( $shipment->{'shipment-id'} ) {
echo 'Shipment Id: ' . $shipment->{'shipment-id'} . "\n";
foreach ( $shipment->{'links'}->{'link'} as $link ) {
echo $link->attributes()->{'rel'} . ': ' . $link->attributes()->{'href'} . "\n";
}
}
}
if ($xml->{'messages'} ) {
$messages = $xml->{'messages'}->children('http://www.canadapost.ca/ws/messages');
foreach ( $messages as $message ) {
echo 'Error Code: ' . $message->code . "\n";
echo 'Error Msg: ' . $message->description . "\n\n";
}
}
}
?>
I received error below
HTTP Response Status: 500 Error Code: Server Error Msg: illegal character 'X' at offset 37 of /rs/0000000000/0000000000/shipment
(I changed customer number to "0000000000")
Can someone explain what is the meaning of above message?
Thank you very much
The provider is probably (like all "enterprise" providers) not using a proper XML parser. Try putting a space before the closing characters of the PI, or failing that remove the PI entirely.
37 characters puts you right at the end of the XML Prolog
<?xml version="1.0" encoding="UTF-8"?>
Either the host does not handle this or you have may have a DOS/UNIX End-of-Line issue.
First, try removing the XML Prolog and see if that helps.
If that doesn't help, then (depending on your editor) save the PHP source as a UNIX file to get the end of line markers right. If that doesn't work, try saving it as a DOS file.
I'm trying to send some information to our CRM from a form on our site and am getting stuck on inserting the variables into the XML. Here is a simplified version of my code. Notice where I'm trying to insert the $email variable within the XML variable...which is not working.
<?php
$email = $_GET["email"];
$xml = '<xmlrequest>
<details>
<emailaddress>$email</emailaddress>
<mailinglist>8</mailinglist>
<format>html</format>
<confirmed>no</confirmed>
</details>
</xmlrequest>
';
$ch = curl_init('http://mysite.com/xml.php');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
$result = #curl_exec($ch);
if ($result === false) {
echo "Error performing request";
} else {
$xml_doc = simplexml_load_string($result);
header( "Location: http://mysite.com/confirmation?email=$email" ) ;
//echo 'Status is ', $xml_doc -> status, '<br/>';
if ($xml_doc -> status == 'SUCCESS') {
echo 'Data is ', $xml_doc -> data, '<br/>';
} else {
echo 'Error is ', $xml_doc -> errormessage, '<br/>';
}
}
?>
If I just type in an email address value for the API works fine. However, I'm clueless on how to pull this in dynamically from a PHP variable. Any help is greatly appreciated!
The string definition is bad
use this
$xml = "<xmlrequest>
<details>
<emailaddress>{$email}</emailaddress>
<mailinglist>8</mailinglist>
<format>html</format>
<confirmed>no</confirmed>
</details>
</xmlrequest>";
or this
$xml = '<xmlrequest>
<details>
<emailaddress>' . $email . '</emailaddress>
<mailinglist>8</mailinglist>
<format>html</format>
<confirmed>no</confirmed>
</details>
</xmlrequest>';
Because this variable probably can be various string I think it's better if you use <![CDATA[]]> section around the email.
I am trying to send this query:
http://api.geonames.org/search?featureCode=PRK&maxRows=10&username=demo&country=US&style=full&adminCode1=AK
To a web service and pull down and parse a bunch of fields there, namely these:
// 1) totalResultsCount
// 2) name
// 3) lat
// 4) lng
// 5) countryCode
// 6) countryName
// 7) adminName1 - gives full state name
// 8) adminName2 - owner of the park.
I am doing this:
$query_string = "http://api.geonames.org/search?featureCode=PRK&maxRows=10&username=demo&country=US&style=full&adminCode1=AK";
Could someone please provide the right code to loop through the results and get values?
Since the response is XML, you can use SimpleXML:
$url = "http://api.geonames.org/search?featureCode=PRK&maxRows=10&username=demo&country=US&style=full&adminCode1=AK";
$xml = new SimpleXMLElement($url, null, true);
echo "totalResultsCount: " . $xml->totalResultsCount . "<br />";
foreach($xml->geoname as $geoname) {
echo $geoname->toponymName . "<br />";
echo $geoname->lat . "<br />";
echo $geoname->countryCode . "<br />";
echo $geoname->countryName . "<br />";
echo $geoname->adminName1 . "<br />";
echo $geoname->adminName2 . "<br />";
}
Which will displays the results as follows:
totalResultsCount: 225
Glacier Bay National Park and Preserve
58.50056
US
United States
Alaska
US.AK.232
...
Firstly, looks like that web service is returning XML rather than JSON. You can use SimpleXML to parse that out.
Secondly, you may want to check out curl
An Example:
$ch = curl_init("http://api.geonames.org/search?featureCode=PRK&maxRows=10&username=demo&country=US&style=full&adminCode1=AK");
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$content = curl_exec($ch);
curl_close($ch);
fopen will give you a resource, no the file. Since you're doing a json decode, you'll want to just the whole thing as a string. Easiest way to do this is file_get_contents.
$query = 'http://api.geonames.org/search?featureCode=PRK&maxRows=10&username=demo&country=US&style=full&adminCode1=AK';
$response = file_get_contents($query);
// You really should do error handling on the response here.
$decoded = json_decode($response, true);
echo '<p>Decoded: '.$decoded['lat'].'</p>';
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!