Maybe someone can help me with a problem I am having regarding SimpleXML Objects.
I am integrating with the authorize.net CIM manager and sending in a customer profile. When I sent it in, the raw xml response is passed through a parser and turned into a SimpleXML object.
Here is the code that is used to submit the request:
$content =
"<?xml version=\"1.0\" encoding=\"utf-8\"?>".
"<createCustomerProfileRequest xmlns=\"AnetApi/xml/v1/schema/AnetApiSchema.xsd\">".
MerchantAuthenticationBlock().
"<profile>".
//"<merchantCustomerId>".$userInsertedId."</merchantCustomerId>". // Your own identifier for the customer.
"<description>'New User Purchase'</description>".
"<email>" . $_GET["email"] . "</email>".
"<paymentProfiles>".
"<billTo>".
"<firstName>".$_GET["firstname"]."</firstName>".
"<lastName>".$_GET["lastname"]."</lastName>".
"<address>".$_GET["street"]."</address>".
"<city>".$_GET["city"]."</city>".
"<state>".$_GET["state"]."</state>".
"<zip>".$_GET["zip"]."</zip>".
"<country>".$_GET["country"]."</country>".
"<phoneNumber>".$_GET["phone"]."</phoneNumber>".
"</billTo>".
"<payment>".
"<creditCard>".
"<cardNumber>".$_GET["number"]."</cardNumber>".
"<expirationDate>".$_GET["year"]."-".$_GET["month"]."</expirationDate>". // required format for API is YYYY-MM
"<cardCode>".$_GET["code"]."</cardCode>".
"</creditCard>".
"</payment>".
"</paymentProfiles>".
"</profile>".
"<validationMode>testMode</validationMode>".
"</createCustomerProfileRequest>";
$CCresponse = send_xml_request($content);
//echo($CCresponse);
$parsedresponse = parse_api_response($CCresponse);
function parse_api_response($content)
{
$parsedresponse = simplexml_load_string($content, "SimpleXMLElement", LIBXML_NOWARNING);
if ("Ok" != $parsedresponse->messages->resultCode)
{
echo "The operation failed with the following errors:<br>";
foreach ($parsedresponse->messages->message as $msg)
{
echo "[" . htmlspecialchars($msg->code) . "] " . htmlspecialchars($msg->text) . "<br>";
}
echo "<br>";
}
return $parsedresponse;
}
When I do the following:
$parsedresponse = parse_api_response($CCresponse);
print_r($parsedresponse);
I get the following output:
SimpleXMLElement Object
(
[messages] => SimpleXMLElement Object
(
[resultCode] => Ok
[message] => SimpleXMLElement Object
(
[code] => I00001
[text] => Successful.
)
)
[customerProfileId] => 15642446
[customerPaymentProfileIdList] => SimpleXMLElement Object
(
[numericString] => 13865552
)
[customerShippingAddressIdList] => SimpleXMLElement Object
(
)
[validationDirectResponseList] => SimpleXMLElement Object
(
[string] => 1|1|1|(TESTMODE) This transaction has been approved.|000000|P|0|none|Test transaction for ValidateCustomerPaymentProfile.|1.00|CC|auth_only||*****|******||****|*******|******|******|USA|1234567890||email#email.com|none|none|none|none|none|none|none|none|0.00|0.00|0.00|FALSE|none|207BCBBF78E85CF174C87AE286B472D2|||||||||||||*******|*******||||||||||||||||
)
)
)
)
So from this is looks like all is working. But when I try and drill into the SimpleXML object, and do this:
echo $code = (string) $parsedresponse->messages->resultCode;
I am getting an output of "OkOk", it seems like it is running over it twice. This has been driving me absolutely crazy and I can't figure out what the heck is going on here. Can someone please point me in the right direction here so I can get this working?
Thanks!
Maybe you could try and use the xpath method to navigate the SimpleXMLElement like this:
$code = (string) $parsedresponse->xpath('messages/resultCode');
echo $code;
Related
I am having trouble when trying to use my Livezilla chatbot script to talk to my REST API, both of which I have stored on my local PC. I am using a code snippet very similar from the Livezilla chatbot API page and have modified it, but I am getting some errors.
27.02.19 11:34:11 ::1 ERR# 129 Error connecting USER API, invalid response:
http://localhost/livezilla/programytalk.php (
Notice: Trying to get property 'answer' of non-object in
C:\xampp\htdocs\livezilla\programytalk.php on line 11
) IN LINE 0
the code for programytalk.php is as follows:
<?php
$requestobj = json_decode($_POST["livezilla_user_api_request"]);
$responseNode = array();
$responseNode["ResponseTo"] = "";
$responseNode["Id"] = rand(1111111,9999999);
$responseNode["SearchKB"] = false;
$url = "http://localhost:8989/api/rest/v1.0/ask? question=".rawurlencode($requestobj->Value)."&userid=".$requestobj-
>VisitorId;
$sdata = json_decode(file_get_contents($url));
$responseNode["Value"] = $sdata->answer;
if(!empty($responseNode["Value"]))
echo json_encode($responseNode);
?>
This is the JSON format the API responds in:
[{"response":{"answer":"Good morning.","question":"hello world","userid":"1234567890"}},200]
By that API response you don't need to read
$responseNode["Value"] = $sdata->answer;
instead of that you need to read
$responseNode["Value"] = $sdata[0]->response->answer;
because answer is nested under response...
Hint: just do this
$data = json_decode('[{"response":{"answer":"Good morning.","question":"hello world","userid":"1234567890"}},200]');
print_r($data);
and output will be:
Array
(
[0] => stdClass Object
(
[response] => stdClass Object
(
[answer] => Good morning.
[question] => hello world
[userid] => 1234567890
)
)
[1] => 200
)
Please do this;
<?php
$requestobj = json_decode($_POST["livezilla_user_api_request"]);
$responseNode = array();
$responseNode["ResponseTo"] = "";
$responseNode["Id"] = rand(1111111,9999999);
$responseNode["SearchKB"] = false;
$url = "http://localhost:8989/api/rest/v1.0/ask? question=".rawurlencode($requestobj->Value)."&userid=".$requestobj-
>VisitorId;
$sdata = json_decode(file_get_contents($url), true);
$responseNode["Value"] = $sdata->answer;
if(!empty($responseNode["Value"]))
echo json_encode($responseNode, true);
?>
$res = $client->get( 'https://****', ['auth' => ['****', '****']] );
$statusCode = $res->getStatusCode();
// Check that the res is successful.
if ($statusCode >= 200 && $statusCode < 300)
{
$xml = $res->xml();
//save the feed as a file
$xml->asXML('myfile.xml');
}
//load the contents of the file again
$xml = simplexml_load_file('myfile.xml');
file definitely has xml in it and is about 6mb
pretty print r prints out this only
SimpleXMLElement Object
(
[#attributes] => Array
(
[generation-date] => 2015-03-16T23:56:26.972+01:00
[error-occurred] => false
)
)
any idea what the problem is?
$xml->children() does nothing.
The problem was that I didn't include the namespace when I looped through
e.g.
I was doing
foreach ($xml->children() as $item){
//...
}
but needed to do
foreach ($xml->children('namespace-url-info-here') as $item){
//...
}
The namespace info was in the root element of the xml.
Hi I'm trying to setup an api service with Limoanywhere system. But regardless of what I do I get invalid ApiKey & ApiID. I went into the back system and changed the ApiKey & ApiId multiple times but still no success.
Can anyone tell me if my code is correct?
<?php
$client = new SoapClient('https://qa.book.mylimobiz.com/api/ApiService.asmx?wsdl');
$options = array(
'ApiKey' => '***api key here****',
'ApiID' => '***api id here****'
);
$result = $client->__soapCall('Test', $options);
//var_dump($client->__getFunctions());
print_r($result);
?>
Here is the snippet from the service
http://qa.book.mylimobiz.com/api/ApiService.asmx?op=Test
Here is the result I get from when run my php code.
Array ( [TestResult] => Array ( [ResponseCode] => 1 [ResponseText] => Invalid ApiId or ApiKey ) )
Check this instead of test Test function not working giving error but test of the test all function are working.
<?php
$soapClient = new SoapClient("https://book.mylimobiz.com/api/ApiService.asmx?wsdl");
// Prepare SoapHeader parameters
$sh_param = array('apiId' => 'xxxxxx','apiKey' => 'xxxxxxxxxxxx');
$headers = new SoapHeader('https://book.mylimobiz.com/api/ApiService.asmx?wsdl', 'GetVehicleTypes', $sh_param);
// Prepare Soap Client
$trans = $soapClient->GetVehicleTypes($sh_param)->GetVehicleTypesResult;
echo "<pre>"; print_r($trans);
?>
I'm currently working on a project, where i have to get the status of a packet (sent with DHL). I read about the DHL API, which return an XML, but somehow there are no good examples out there. I have found some code snippets, but i have no clue where to register for API Key's.
Have anyone some links or examples for me?
Best regards,
Lukas
There is also this PHP client that can be used to consume the DHL XML API. It can handle all the different services exposed by DHL.
https://github.com/alfallouji/DHL-API
This client does not rely or depend on any framework and it should be fairly easy to integrate with your own code. You can check the samples folder for example on how to use it.
https://github.com/jklz/DHL-API-Tracking-PHP
It is used to connect into DHL using the XML-PI to track shipments using the Air Way Bill. it can handle a single tracking number or as many as you feed into it (has been tested with 250 and other then taking a little time to run had no problems). automatically takes and breaks the array of tracking numbers into chunks and then sends the request to DHL making sure not to pass the max number that can be tracked per request then returns the results as a array.
Quick and dirty without any third party lib and using official API:
<?php
$mode = 'sandbox'; // sandbox or production
$username = ''; // dhl developer account name, not email
$password = ''; // dhl developer account pass
$appname = 'zt12345'; // sandbox app
$apppass = 'geheim'; // sandbox app
$endpoint = 'https://cig.dhl.de/services/' . $mode . '/rest/sendungsverfolgung';
$payload = simplexml_load_string( '<?xml version="1.0" encoding="UTF-8" standalone="no"?><data appname="' . $appname . '" language-code="de" password="' . $apppass . '" piece-code="" request="d-get-piece-detail"/>' );
$shipmentids = array(
'00340434161094015902' // in sandbox only special numbers are allowed
);
$opts = array(
'http' => array(
'method' => "GET",
'header' => "Authorization: Basic " . base64_encode( "$username:$password" )
)
);
$context = stream_context_create( $opts );
foreach ( $shipmentids as $shipmentid ) {
$payload->attributes()->{'piece-code'} = $shipmentid;
$response = file_get_contents( $endpoint . '?' . http_build_query( array( 'xml' => $payload->saveXML() ) ), false, $context );
$responseXml = simplexml_load_string( $response );
$status = null;
// get last state
foreach ( $responseXml->data->data->data as $event ) {
$status = $event->attributes()->{'event-short-status'};
}
echo "Shipment " . $shipmentid . " is in state: " . $status . "\n";
}
There is a nice blog about this. It is unfortunately in German, but the code that is displayed there should still make sense to you.
Source: https://blog.simlau.net/dhl-tracking-api-php.html
Excerpt:
function dhl_tracking($trackingnumber)
{
$data = '<?xml version="1.0" encoding="ISO-8859-1" ?>';
$data .= '<data appname="nol-public" password="anfang" request="get-status-for-public-user" language-code="de">';
$data .= ' <data piece-code="'.$trackingnumber.'"></data>';
$data .= '</data>';
// URL bauen und File hohlen
$xml = simplexml_load_file(sprintf(
'http://nolp.dhl.de/nextt-online-public/direct/nexttjlibpublicservlet?xml=%s', $data
));
// FALSE, wenn Syntax oder HTTP Error
if ($xml === false) return false;
// Wandelt das SimpleXML Objekt in ein Array um
foreach ($xml->data->data->attributes() as $key => $value) {
$return[$key] = (string) $value;
}
return $return;
}
// Aufruf der Funktion
print_r(dhl_tracking($tracking_number));
This function will give back an array that will contain some tracking information:
Array
(
[status] => Die Sendung wurde erfolgreich zugestellt.
[recipient-id-text] => Nachbar
[product-name] => DHL PAKET
[pan-recipient-name] => SIMON LAUGER
)
(In fact, there is WAY more data in there.)
I hope this will help you in some way.
I am trying to return all inventory from a certain warehouse in Netsuite. I am having some issues and was wondering if anyone could point me in the right direction. The internalId of the warehouse I am trying to query is 16. When I do the search it returns 0 items - but doesn't fail.
Here is the PHP code I am working with.
<?php
require_once 'PHPtoolkit.php';
require_once 'login_info.php';
global $myNSclient;
$internalID = '16'; //Internal ID of the warehouse I want to query to see what inventory it has
$inventorySearch = new nsComplexObject("ItemSearchBasic");
$searchValue = new nsRecordRef(array('type' => 'location', 'internalId' => $internalID ));
$multiSelect = new nsComplexObject('SearchMultiSelectField');
$multiSelect->setFields(array('operator'=>'anyOf','searchValue'=>$searchValue,"operatorSpecified" => true));
$inventorySearch->setFields(array('location'=>$multiSelect));
try
{
$searchResponse = $myNSclient->search($inventorySearch);
$totalRecords = $searchResponse->totalRecords;
if ($totalRecords > 0)
{
echo "records found";
foreach ($searchResponse->recordList as $record)
{
echo "<pre>";
print_r($record);
echo "</pre>";
}
}
else
{
echo "No result found.";
}
}
catch (Exception $e)
{
echo $e;
echo "Item is not found. Please try again.";
exit();
}
Here is the SOAP request
<?xml version="1.0" encoding="UTF-8" ?>
- <Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:core_2011_2.platform.webservices.netsuite.com" xmlns:ns2="urn:common_2011_2.platform.webservices.netsuite.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns3="urn:messages_2011_2.platform.webservices.netsuite.com">
- <Header>
- <passport actor="http://schemas.xmlsoap.org/soap/actor/next">
<email>xxxxx</email>
<password>[Content Removed for Security Reasons]</password>
<account>xxxxxx</account>
<role internalId="3" xsi:type="RecordRef" />
</passport>
</Header>
- <Bod
y>
- <search>
- <searchRecord xsi:type="ItemSearchBasic">
- <location operator="anyOf">
<searchValue internalId="16" type="location" />
</location>
</searchRecord>
</search>
</Body>
</Envelope>
$inventorySearch = new nsComplexObject("ItemSearchBasic");
$inventorySearch->setFields(array(
"location" => array(
"operator" => "anyOf",
"searchValue" => array(
"type" => "location",
"internalId" => $internalId
)
)
));
Then, do your try/catch.
But as I look at this, you are wanting to get item availability. That's a completely different call.
$filter = new nsComplexObject ( 'ItemAvailabilityFilter' );
$filter->setFields ( array (
"location" => array (
"operator" => "anyOf",
"searchValue" => new nsRecordRef ( array (
"type" => "location",
"internalId" => $internalId
) )
)
) );
I've spent significant amount of time building my own custom search using PHPToolKit v2011.2 endpoint, and got them to work after pulling my hair out as there aren't that many examples. With introduction of v2012_2 endpoint, things have changed and I have to relearn the things that I solved before. I "strongly" suggest that you use SAVED SEARCH, instead of trying to invent the way to do all your searches in PHP. Create a saved search in Netsuite, and call the SAVED SEARCH from your PHP with internalId of the search you created.