Integration SmartTurn webservice API with SOAP, XML in PHP - php

i am new to SOAP . I am trying to integrate my application to SmartTurn webservice API(its a inventry management company). They are SOAP and wsdl for their API operations. i am new to soap so i have no idea that how i can do this in php. here is xml that i want to use.
<?xml version="1.0" encoding="UTF-8" ?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body><saveSalesOrder
xmlns="http://www.smartturn.com/services/OccamService/sales-order">
<inCredential>
<ns1:UserId
xmlns:ns1="http://www.smartturn.com/services/occamtypes">webservice#fithoop.com.au</ns1:UserId>
<ns2:Password
xmlns:ns2="http://www.smartturn.com/services/occamtypes">secret</ns2:Password>
</inCredential>
<inSalesOrders>
<ns3:externalNumber xmlns:ns3="http://www.smartturn.com/services/sales-order-types">Ext-id-00502</ns3:externalNumber>
<ns4:type xmlns:ns4="http://www.smartturn.com/services/sales-order-types">EXTERNAL</ns4:type>
<ns5:date xmlns:ns5="http://www.smartturn.com/services/sales-order-types">2012-10-20T00:04:34.479Z</ns5:date>
<ns6:dateDue xmlns:ns6="http://www.smartturn.com/services/sales-order-types">2012-10-20T00:04:34.479Z</ns6:dateDue>
<ns7:customerName xmlns:ns7="http://www.smartturn.com/services/sales-order-types">customer name</ns7:customerName>
<ns8:customerContact
xmlns:ns8="http://www.smartturn.com/services/sales-order-types">customer contact</ns8:customerContact>
<ns9:customerContactPhone
xmlns:ns9="http://www.smartturn.com/services/sales-order-types">customer phone</ns9:customerContactPhone>
<ns10:customerAddress
xmlns:ns10="http://www.smartturn.com/services/sales-order-types">
<ns11:addressLine1
xmlns:ns11="http://www.smartturn.com/services/occamtypes">the main street</ns11:addressLine1>
<ns12:addressLine2
xmlns:ns12="http://www.smartturn.com/services/occamtypes">broadway</ns12:addressLine2>
<ns13:city
xmlns:ns13="http://www.smartturn.com/services/occamtypes">Oakland</ns13:city>
<ns14:state
xmlns:ns14="http://www.smartturn.com/services/occamtypes">California</ns14:state>
<ns15:country
xmlns:ns15="http://www.smartturn.com/services/occamtypes">USA</ns15:country>
<ns16:postalCode
xmlns:ns16="http://www.smartturn.com/services/occamtypes">94607</ns16:postalCode>
</ns10:customerAddress>
<ns17:salesRep xmlns:ns17="http://www.smartturn.com/services/sales-order-types">sales rep</ns17:salesRep>
<ns18:useShipToAsBillAddress
xmlns:ns18="http://www.smartturn.com/services/sales-order-types">false</ns18:useShipToAsBillAddress>
<ns19:shipToName xmlns:ns19="http://www.smartturn.com/services/sales-order-types">ship to name</ns19:shipToName>
<ns20:shipToContact
xmlns:ns20="http://www.smartturn.com/services/sales-order-types">ship to contact</ns20:shipToContact>
<ns21:shipToContactPhone
xmlns:ns21="http://www.smartturn.com/services/sales-order-types">ship to contact phone</ns21:shipToContactPhone>
<ns22:status xmlns:ns22="http://www.smartturn.com/services/sales-order-types">NEW</ns22:status>
<ns23:item xmlns:ns23="http://www.smartturn.com/services/sales-order-types">
<ns23:itemMasterId>BB-10</ns23:itemMasterId>
<ns23:description>this is a desc</ns23:description>
<ns23:details>these are details</ns23:details>
<ns23:orderedQuantity>
<ns26:value
xmlns:ns26="http://www.smartturn.com/services/occamtypes">10.0</ns26:value>
<ns27:unitAbbreviation
xmlns:ns27="http://www.smartturn.com/services/occamtypes">ea</ns27:unitAbbreviation>
</ns23:orderedQuantity>
<ns23:customerRequestDate>2007-03-
20T00:04:34.479Z</ns23:customerRequestDate>
<ns23:price>
<ns28:value
xmlns:ns28="http://www.smartturn.com/services/occamtypes">100.0</ns28:value>
<ns29:type
xmlns:ns29="http://www.smartturn.com/services/occamtypes">$10</ns29:type>
</ns23:price>
<ns23:vendorItemId>vendor item id</ns23:vendorItemId>
<ns23:manufacturerItemId>manf item id</ns23:manufacturerItemId>
<ns23:upcCode>UPC Code</ns23:upcCode>
<ns23:manufacturerId>manf id</ns23:manufacturerId>
</ns23:item>
<ns30:comments xmlns:ns30="http://www.smartturn.com/services/sales-order-types">This is a comment</ns30:comments>
</inSalesOrders>
</saveSalesOrder>
</soapenv:Body>
</soapenv:Envelope>
`
and the url is
$url = "https://services.smartturn.com/occam/services/OccamService?wsdl";
and the operation that i want to perform is 'saveSalesOrder'
how can i do that in php.
Thanks in advance .

First, you'll need PHP's SOAP extension installed and enabled. Then:
$url = "https://services.smartturn.com/occam/services/OccamService?wsdl";
$data = array(
"UserId" => "secret",
"Password" => "secret",
"type" => "EXTERNAL",
"date" => "2012-10-20T00:04:34.479Z",
"dateDue" => "2012-10-20T00:04:34.479Z",
"externalNumber" => "Ext-id-00502",
"customerName" => "test ",
"customerContact" => "customer Contact",
"customerContactPhone" => "123456789",
"salesRep" => "w salesRep",
);
try {
$soapClient = new SoapClient($url, array(
'trace' => true, // for debugging, disable in production
//"connection_timeout" => 1
));
// List types to get an idea how to call methods, since it looks like
// there are no help pages as in .asmx services
// var_dump($soapClient->__getTypes());
$soapClient->saveSalesOrder($data);
} catch (Exception $e) {
trigger_error("SOAP error: ".$e->getMessage(), E_USER_WARNING);
}
Links:
Overall SmartTurn service listing
PHP SoapClient documentation
Edit: updated example based on comment.

This is a great answer from Halil and really helped me to figure out what to do. You will need to add more arrays to create your request as the nested values of the XML request need to be put in arrays.
Also there is a minimum number of fields to fill out, so you're best to look at the API doc and see the sample request, then format your arrays to match the nested values.
For example:
$url = "https://stdemo.smartturn.com/occam/services/OccamService?wsdl"; //DEMO URL
// $url = "https://app.smartturn.com/occam/services/OccamService?wsdl"; //LIVE URL
$data = array(
"inCredential" => array("UserId" => "secret", "Password" => "secret"),
"inSalesOrders" => array("type" => "EXTERNAL",
"date" => "2012-10-20T00:04:34.479Z",
"dateDue" => "2012-10-20T00:04:34.479Z",
"externalNumber" => "Ext-id-00502",
"customerName" => "test ",
"customerContact" => "customer Contact",
"customerContactPhone" => "123456789",
"salesRep" => "w salesRep",
...
)
);
try {
$soapClient = new SoapClient($url, array(
'trace' => true, // for debugging, disable in production
//"connection_timeout" => 1
));
// List types to get an idea how to call methods, since it looks like
// there are no help pages as in .asmx services
// var_dump($soapClient->__getTypes());
$soapClient->saveSalesOrder($data);
} catch (Exception $e) {
trigger_error("SOAP error: ".$e->getMessage(), E_USER_WARNING);
}
The only issue with using this method for generating the SOAP envelopes is that as you are using an associative array, you can only sent 1 item object with each sales order request. As soon as you have multiple items in an order, this doesn't work. You could investigate SoapVar, I ended up forming the complete XML document and then sending it with CURL.

Related

Brandbank API PHP Extract Data

I am working on a project that requires access to Brandbank API, however their documentation seems pretty limited as to how to access their information.
I have been given access keys and the documentation seems to direct you to extract data via SOAP siting this link https://api.brandbank.com/svc/feed/extractdata.asmx?WSDL
Can anyone provide an example of how to access the product feed of this API?
At a minimum you will need code that looks like this:
$wsdl = "https://api.brandbank.com/svc/feed/extractdata.asmx?WSDL";
try {
$soapclient = new SoapClient($wsdl, array(
'soap_version' => SOAP_1_1,
'trace' => 1,
'exceptions' => true,
)
);
$parameters = new stdClass();
$response = $soapclient->GetUnsentProductData($parameters);
} catch (Exception $e) {
var_dump($e ->getMessage());
}
The call won't work until you finish it with your access credentials, but it provides an example of how most SOAP calls look in PHP.

PHP get data from soap service

I need to get data from http://ws.jrtwebservices.com/jrtlowfaresearch/jrtlfs.asmx, this service need credential information.such as ID, userid and system value. I put these information into one string:
$xml_post_string = "<POS><Source> <RequestorID Type='21' ID='xxx'/> </Source> <TPA_Extensions> <Provider><System>xxx</System> <Userid>xxx</Userid> </Provider></TPA_Extensions></POS>"
And i also defined SoapClient:
$client = new SoapClient(null, array('uri' => "http://ws.jrtwebservices.com",
'location => "http://ws.jrtwebservices.com/jrtlowfaresearch/jrtlfs.asmx") );
I call soapCall as:
$response = $client->__soapCall('do_LowfareSearch',array($xml_post_string),array('soapaction' => 'http://jrtechnologies.com/do_LowfareSearch'));
Does anybody know why i get empty response?
Thanks very much!
Using your code, the request looks like this:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xm...">
<SOAP-ENV:Body>
<ns1:do_LowfareSearch>
<param0 xsi:type="xsd:string">
"<POS><Source> <RequestorID Type='21' ID='xxx'/> </Source> <TPA_Extensions> <Provider <System>xxx</System> <Userid>xxx</Userid> </Provider></TPA_Extensions></POS>"
</param0>
</ns1:do_LowfareSearch>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
The client used the method you passed but could not structure the parameters the way you gave them. All of your parameters are just in " " inside of <param0>.
(Also, you are missing a ' after location. 'location => "http:...)
When you make your SOAP client you want to set the WSDL, it will do all the XML formatting for you.
The WSDL should have the location in it so you do not need to worry about that.
I like to use a WSDL validator to test out the methods and see their parameters.
You should structure the information you want to pass as arrays or a classes and let the SOAP client and WSDL convert it into the XML you need.
So something like this is what you are looking for:
<?php
//SOAP Client
$wsdl = "http://ws.jrtwebservices.com/jrtlowfaresearch/jrtlfs.asmx?WSDL";
$client = new SoapClient($wsdl, array( 'soap_version' => SOAP_1_1,
'trace' => true, //to debug
));
try {
$args = array(
'companyname'=> 'xxx',
'name'=> 'xxx',
'system'=> 'xxx',
'userid'=> 'xxx',
'password'=> 'xxx',
'conversationid'=>'xxx',
'entry'=> 'xxx',
);
$result = $client->__soapCall('do_LowfareSearch', $args);
return $result;
} catch (SoapFault $e) {
echo "Error: {$e}";
}
//to debug the xml sent to the service
echo($client->__getLastRequest());
//to view the xml sent back
echo($client->__getLastResponse());
?>

PHP SOAP Errormessage - System.NullReferenceException: Object reference not set to an instance of an object

I have this problem, currently I am learning soap and developing online booking system with wsdl of http://vanillatours.com in PHP
their required headers are soapaction, and charset. which I have included, soapaction changes for desired request. for example, currently trying to do checklogin() function.
I tried print_r($client->__getFunctions()) to see if functions are attached, they are!
I tried print_r($client) to see if headers are attached and they are
the problem is that I can not figure out why I get this errormessage.
System.NullReferenceException: Object reference not set to an instance of an object.
at WcfService.Wcf.CheckLogin(LoginHeaderWcfRequest loginHeader)
Tried everything! I am very new with soap and any help would be appreciated. maybe I am not using correctly data "request"?
thank you!
<?php
$wsdl = "http://xmltest.vanillatours.com/Wcf.svc?wsdl";
$client = new SoapClient($wsdl);
$data = array(
"request" => array(
"a:AgentId" => blabla,
"a:Language" => "En",
"a:Password" => "blabla",
"a:Username" => "blabla"
)
);
$header = array();
$header[] = new SoapHeader('http://tempuri.org/IWcf/CheckLogin','SOAPAction');
$header[] = new SoapHeader('text/xml; charset=utf-8','ContentType');
$client->__setSoapHeaders($header);
$response = $client->__soapCall('CheckLogin', $data);
echo '<pre>';
print_r($client->__getFunctions()); // functions seem to show pretty well
echo '<br>------------------------------------------------------<br><br>';
print_r($client); // headers are attached
echo '<br>------------------------------------------------------<br><br>';
print_r($response); // errormessage, can not figure out what is the problem.
echo '</pre>';
?>
this is how to connect from their documentation, if I can use other method, would appreciate too.
CheckLogin function checks the user credentials is valid or not.
SOAPAction value is http://tempuri.org/IWcf/CheckLogin
3.1.2 Request
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<CheckLogin xmlns="http://tempuri.org/">
<loginHeader xmlns:a="http://schemas.datacontract.org/2004/07/WcfService"
xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:AgentId>Your Agent Id</a:AgentId>
<a:Language>Your preferred language</a:Language>
<a:Password>Your Password</a:Password>
<a:Username>Your username</a:Username>
</loginHeader>
</CheckLogin>
</s:Body>
</s:Envelope>
The structure of $data is not right. It should be:
$data = array(
"loginHeader" => array(
"AgentId" => blabla,
"Language" => "En",
"Password" => "blabla",
"Username" => "blabla"
)
);

SOAP fault: object not set to an instance of an object

I found this question on here:
PHP Soap Issue: Server was unable to process request. ---> Object reference not set to an instance of an object
I have a similar issue, only the WSDL is private, so I figured I'd try and get a basic timezone SOAP Client working.
The solution in the other question isn't possible for me to use with the private WSDL.
$response = $client->getTimeZoneTime(array('timezone'=>'ZULU'));
Really what I need is a way of taking a multidimensional PHP array and putting it into the SOAP formed XML document, without it going crazy and producing stuff like, for this example, this:-
<key>GetTimeZoneTime</key>
<item>ZULU</item>
Here's my PHP:
try {
$WSDL = 'http://www.nanonull.com/TimeService/TimeService.asmx?WSDL';
$client = new SoapClient($WSDL,
array(
"trace" => 1,
"exceptions" => 1,
"soap_version" => SOAP_1_1
));
$xml = '<GetTimeZoneTime><timezone>ZULU</timezone></GetTimeZoneTime>';
$xmlvar = new SoapVar(
$xml,
XSD_ANYXML
);
$response = $client->getTimeZoneTime($xmlvar);
echo "<pre>\n";
echo "Request :\n".htmlspecialchars($client->__getLastRequest()) ."\n";
echo "Response:\n".htmlspecialchars($client->__getLastResponse())."\n";
echo "</pre>";
} catch (SoapFault $exception) {
echo "<pre>\n";
echo "Request :\n".htmlspecialchars($client->__getLastRequest()) ."\n";
echo "Response:\n".htmlspecialchars($client->__getLastResponse())."\n";
echo $exception;
echo "</pre>";
}
This is the request it produces:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.Nanonull.com/TimeService/">
<SOAP-ENV:Body>
<GetTimeZoneTime>
<timezone>ZULU</timezone>
</GetTimeZoneTime>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
And the SOAP Fault is:
Server was unable to process request. ---> Object reference not set to an instance of an object.
What's the correct way of turning a multidimensional PHP array into the appropriate format for a SOAP request?
What does the SOAP fault returned actually mean?
Edit: After some searching around elsewhere I thought I'd try the approach of creating a PHP class to mirror the variables on the server. This doesn't work either.
class TimeZone {
public function __construct ()
{
$this->timezone = 'ZULU';
}
}
$WSDL = 'http://www.nanonull.com/TimeService/TimeService.asmx?WSDL';
$client = new SoapClient($WSDL,
array(
"trace" => 1,
"exceptions" => 1,
"soap_version" => SOAP_1_1
));
$xmlvar = new SoapVar(new TimeZone(), SOAP_ENC_OBJECT, "TimeZone");
$response = $client->getTimeZoneTime($xmlvar);
For the Timezone one, adding the classmap parameter made it work:
$client = new SoapClient($WSDL,
array(
"trace" => 1,
"exceptions" => 1,
"soap_version" => SOAP_1_1,
"classmap" => array('timezone' => 'TimeZone')
));
$obj = new TimeZone();
$response = $client->getTimeZoneTime($obj);
echo "<h1>".$response->getTimeZoneTimeResult."</h1>";
For the main problem I'm having, it warrants a new question.
I may be wrong, but I gather the meaning of the error message to be twofold:
The object passed into the soap call may not be an object at all.
The object passed into the soap call may be an object, but if all of its attributes do not match what the server expects it will return that error.

SOAP authentication with PHP

I need to connect to a web service that requires authentication credentials in the form of a plain text user name and password.
I have a basic understanding of SOAP and have managed to connect to other open web services that do not require a username or password using NuSOAP.
The following was sent to me:
<?php
// Set up security options
$security_options = array("useUsernameToken" => TRUE);
$policy = new WSPolicy(array("security" => $security_options));
$security_token = new WSSecurityToken(array(
"user" => "xxx",
"password" => "xxx",
"passwordType" => "basic"));
// Create client with options
$client = new WSClient(array("wsdl" => "https://xxx.asmx?wsdl",
"action" => "http://xxx",
"to" => "https://xxx",
"useWSA" => 'submission',
"CACert" => "cert.pem",
"useSOAP" => 1.1,
"policy" => $policy,
"securityToken" => $security_token));
// Send request and capture response
$proxy = $client->getProxy();
$input_array = array("From" => "2010-01-01 00:00:00",
"To" => "2010-01-31 00:00:00");
$resMessage = $proxy->xxx($input_array);
?>
After some research I understand that the above implementation uses wso2. I need to be able to do this without using wso2.
I have tried my best to look for resources (Google, forums, etc) about the above but haven't been able to find anything. I have read some tutorials on SOAP and have been able to set up a SOAP client using PHP but cannot get my head around all the authentication and "policies".
An explanation of how to achieve this and maybe some links to further reading about this would be very much appreciated as I am tearing my hair out! Ideally I would like some links to resources for an absolute beginner to the SOAP authentication.
Thanks. P.S some of the links/credentials in the above could have been xxx'd for privacy.
If you have the SOAP extension enabled in php (php version >= 5.0.1), you can use the SoapClient class to process your request. To authenticate, you can pass the username and password to the class with the target URL:
$soapURL = "https://www.example.com/soapapi.asmx?wsdl" ;
$soapParameters = Array('login' => "myusername", 'password' => "mypassword") ;
$soapFunction = "someFunction" ;
$soapFunctionParameters = Array('param1' => 42, 'param2' => "Search") ;
$soapClient = new SoapClient($soapURL, $soapParameters);
$soapResult = $soapClient->__soapCall($soapFunction, $soapFunctionParameters) ;
if(is_array($soapResult) && isset($soapResult['someFunctionResult'])) {
// Process result.
} else {
// Unexpected result
if(function_exists("debug_message")) {
debug_message("Unexpected soapResult for {$soapFunction}: ".print_r($soapResult, TRUE)) ;
}
}
If you're not sure about the functions you can call, you can view the target URL (e.g. ending in ".asmx?wsdl") in your browser. You should get an XML response that tells you the available SOAP functions you can call, and the expected parameters of those functions.
Check out the soap_wsse library

Categories