I have been working on this for a week now and have trouble executing this code. I want to retrieve data via SOAP and work with it in PHP. My trouble is, that I am having trouble sending the 'RequesterCredentials'.
I will show the XML code so you all can see the information I am trying to send, and then the PHP code I am using.
XML sample code
POST /AuctionService.asmx HTTP/1.1
Host: apiv2.gunbroker.com
Content-Type: text/xml; charset=utf-8
Content-Length: 200
SOAPAction: "GunBrokerAPI_V2/GetItem"
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<RequesterCredentials xmlns="GunBrokerAPI_V2">
<DevKey>devkey</DevKey>
<AppKey>appkey</AppKey>
</RequesterCredentials>
</soap:Header>
<soap:Body>
<GetItem xmlns="GunBrokerAPI_V2">
<GetItemRequest>
<ItemID>312007942</ItemID>
<ItemDetail>Std</ItemDetail>
</GetItemRequest>
</GetItem>
</soap:Body>
</soap:Envelope>
PHP code that I am using to make the call
$client = new SoapClient("http://apiv2.gunbroker.com/AuctionService.asmx?WSDL");
$appkey = 'XXXXXX-XXXXXX-XXXXXX';
$devkey = 'XXXXXX-XXXXXX-XXXXXX';
$header = new SoapHeader('GunBrokerAPI_V2', 'RequesterCredentials', array('DevKey' => $devkey, 'AppKey' => $appkey), 0);
$client->__setSoapHeaders(array($header));
$result = $client->GetItem('312343077');
echo '<pre>', print_r($result, true), '</pre>';
The result I get
stdClass Object
(
[GetItemResult] => stdClass Object
(
[Timestamp] => 2012-11-07T18:17:31.9032903-05:00
[Ack] => Failure
[Errors] => stdClass Object
(
[ShortMessage] => GunBrokerAPI_V2 Error Message : [GetItem]
// You must fill in the 'RequesterCredentialsValue'
// SOAP header for this Web Service method.
[ErrorCode] => 1
)
// The rest if just an array of empty fields that
// I could retrieve if I wasn’t having problems.
I’m not sure if the problem is the way I’m sending the SoapHeaders or if I am misunderstanding the syntax. How can I fix it?
Use an object instead of an associative array for headers:
$obj = new stdClass();
$obj->AppKey = $appkey;
$obj->DevKey = $devkey;
$header = new SoapHeader('GunBrokerAPI_V2', 'RequesterCredentials', $obj, 0);
And the next problem you might face will be at the GetItem call. You also need an object, wrapped in an associative array:
$item = new stdClass;
$item->ItemID = '312343077';
$item->ItemDetail = 'Std';
$result = $client->GetItem(array('GetItemRequest' => $item));
Related
I am trying to make a SOAP call using POSTMAN that will duplicate a call I'm making with a PHP code for testing purposes, but I am getting a "Bad request" error message, so I assume my conversion is incorrect.
The PHP code is:
//Create xml string
$xml=new DomDocument();
$xml->createCDATASection('![CDATA[]]');
$xml->encoding = 'utf-8';
$xml->xmlVersion = '1.0';
$xml->formatOutput = true;
$xsd=$xml->createElement("xsd:schema");
$xml->appendChild($xsd);
$xsdattr=new DOMAttr("xmlns:xsd","http://www.w3.org/2001/XMLSchema");
$xsd->setAttributeNode($xsdattr);
$ZHT=$xml->createElement("ZHT",str_replace(" ","",$username));
$xsd->appendChild($ZHT);
$PASSWORD=$xml->createElement("PASSWORD",str_replace(" ","",$pwd));
$xsd->appendChild($PASSWORD);
$SNL=$xml->createElement("SNL",$date);
$xsd->appendChild($SNL);
$USERNAME=$xml->createElement("USERNAME","");
$xsd->appendChild($USERNAME);
$RETHASIMA=$xml->createElement("RETHASIMA","1");
$xsd->appendChild($RETHASIMA);
$LANG=$xml->createElement("LANG","");
$xsd->appendChild($LANG);
$ROLE=$xml->createElement("ROLE",$role);
$xsd->appendChild($ROLE);
$xmlstring=$xml->saveXML();
//Set SOAP request
$baseURL=$url;
$arrContextOptions=array("ssl"=>array( "verify_peer"=>false, "verify_peer_name"=>false,'crypto_method' => STREAM_CRYPTO_METHOD_TLS_CLIENT));
$options = array(
'soap_version' => SOAP_1_1,
'trace' => true,
'exceptions' => true, // disable exceptions
'features' => SOAP_SINGLE_ELEMENT_ARRAYS,
'encoding' => 'UTF-8',
'cache_wsdl'=>WSDL_CACHE_NONE,
);
$client = new SoapClient($baseURL."?wsdl", $options);
$p=array(
"P_RequestParams" => array (
"RequestID"=>"48",
"InputData"=>$xmlstring
) ,
"Authenticator" => array (
"Password"=>$authpass,
"UserName"=>$authuser
),
);
//SOAP call and response
$response=$client->ProcessRequestJSON($p);
And This is the body I created in POSTMAN:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ProcessRequestJSON xmlns="****">
<P_RequestParams>
<RequestID>48</RequestID>
<InputData>
<?xml version="1.0" encoding="utf-8" ?>
<schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<PARAMS>
<ZHT>****</ZHT>
<PASSWORD>****</PASSWORD>
<SNL>***</SNL>
<USERNAME></USERNAME>
<RETHASIMA>1</RETHASIMA>
<LANG></LANG>
<ROLE>1</ROLE>
</PARAMS>
</schema>
</InputData>
</P_RequestParams>
<Authenticator>
<UserName>****</UserName>
<Password>****</Password>
</Authenticator>
</ProcessRequestJSON>
</soap:Body>
</soap:Envelope>
I'm not sure how to set certain things on POSTMAN.
For example, the following line:
$xsdattr=new DOMAttr("xmlns:xsd","http://www.w3.org/2001/XMLSchema");
How do I set a DOMAttr in POSTMAN?
Or the options?
I set up the headers for XML:
Content-Type: text/xml
SOAPAction: "****/ProcessRequestJSON"
Body: Raw (XML)
I tried putting the inner XML (inside the tag) in "" to indicate a string, but that didn't work either.
The PHP code works correctly, the SOAP call is successful and returns a correct response.
The POSTMAN request returns a "Bad Request" error message.
How can I make Soap request using Curl php by using below soap format and url? I have tried avaliable solutions online and none of them worked out.
$soap_request = '<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:alisonwsdl" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<soap:Header>
<credentials>
<alisonOrgId>9ReXlYlpOThe24AWisE</alisonOrgId>
<alisonOrgKey>C2owrOtRegikaroXaji</alisonOrgKey>
</credentials>
</soap:Header>
<SOAP-ENV:Body>
<q1:login xmlns:q1="urn:alisonwsdl">
<email xsi:type="xsd:string">email</email>
<firstname xsi:type="xsd:string">fname</firstname>
<lastname xsi:type="xsd:string">lname</lastname>
<city xsi:type="xsd:string">city</city>
<country xsi:type="xsd:string">country</country>
<external_id xsi:type="xsd:string"></external_id>
</q1:login>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>';
Url
https://alison.com/api/service.php?wsdl
Assuming you already have php_soap extension installed, you can access the SOAP API like this:
<?php
$client = new SoapClient('https://alison.com/api/service.php?wsdl', array(
'stream_context' => stream_context_create(array(
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
)
))
));
You might want to define the header for authentication as well
$auth = array(
'alisonOrgId' => '9ReXlYlpOThe24AWisE',
'alisonOrgKey' => 'C2owrOtRegikaroXaji'
);
$header = new SoapHeader('https://alison.com/api/service.php?wsdl', 'credentials', $auth, false);
$client->__setSoapHeaders($header);
Then you can get the list of functions available
// Get function list
$functions = $client->__getFunctions ();
echo "<pre>";
var_dump ($functions);
echo "</pre>";
die;
Or call a function right away, like this:
// Run the function
$obj = $client->__soapCall("emailExists", array(
"email" => "test#email.com"
));
echo "<pre>";
var_dump ($obj);
echo "</pre>";
die;
After struggling for a week I was able to find something in this tutorial here on youtube https://www.youtube.com/watch?v=6V_myufS89A and I was able to send requests to the API successifuly, first read my xml format above before continuing with my solution
$options = array('trace'=> true, "exception" => 0);
$client = new \SoapClient('your url to wsdl',$options);
//if you have Authorization parameters in your xml like mine above use SoapVar and SoapHeader as me below
$params = new \stdClass();
$params->alisonOrgId = 'value here';
$params->alisonOrgKey = 'value here';
$authentication_parameters = new \SoapVar($params,SOAP_ENC_OBJECT);
$header = new \SoapHeader('your url to wsdl','credentials',$authentication_parameters);
$client->__setSoapHeaders(array($header));
print_r($client->__soapCall("Function here",'Function parameter here or left it as null if has no parameter'));
//or call your function by
print_r($client->yourFunction($function_parameters));
}
Hope this will help someone out there struggling with soap requests that contains authentication informations
Im trying to get the shipping info of a product, this is my code (I have hidden my app-id).
$endpoint2 = "http://open.api.ebay.com/shopping";
$xmlrequest2 = "<?xml version='1.0' encoding='utf-8'?>\n";
$xmlrequest2 .= "<GetShippingCostsRequest xmlns='urn:ebay:apis:eBLBaseComponents'>\n";
// $xmlrequest2 .= "<DestinationCountryCode>GB</DestinationCountryCode>\n";
// $xmlrequest2 .= "<IncludeDetails>true</IncludeDetails>\n";
$xmlrequest2 .= "<ItemID>".$id."</ItemID>\n";
$xmlrequest2 .= "</GetShippingCostsRequest>\n";
$session2 = curl_init($endpoint2); // create a curl session
curl_setopt($session2, CURLOPT_POST, true);
var_dump($xmlrequest2);
curl_setopt($session2, CURLOPT_POSTFIELDS, $xmlrequest2); // set the body of the POST
curl_setopt($session2, CURLOPT_RETURNTRANSFER, true);
$headers2 = array(
'X-EBAY-API-APP-ID:'.getsetting(2),
'X-EBAY-API-VERSION:849',
'X-EBAY-API-SITE-ID:3',
'X-EBAY-API-CALL-NAME:GetShippingCosts',
'X-EBAY-API-REQUEST-ENCODING:XML',
);
print_r($headers2);
// create a curl session
curl_setopt($session2, CURLOPT_HTTPHEADER, $headers2); //set headers using the above array of headers
$responseXML = curl_exec($session2);
// send the request
//echo $responseXML;
curl_close($session2);
return $responseXML;
And this is the output/errors i get.
string(162) "<?xml version='1.0' encoding='utf-8'?>
<GetShippingCostsRequest xmlns='urn:ebay:apis:eBLBaseComponents'>
<ItemID>300903657321</ItemID>
</GetShippingCostsRequest>
"
Array
(
[0] => X-EBAY-API-APP-ID:1234
[1] => X-EBAY-API-VERSION:849
[2] => X-EBAY-API-SITE-ID:3
[3] => X-EBAY-API-CALL-NAME:GetShippingCosts
[4] => X-EBAY-API-REQUEST-ENCODING:XML
)
<?xml version="1.0" encoding="UTF-8"?>
<GetShippingCostsResponse xmlns="">
<ns1:Ack xmlns:ns1="urn:ebay:apis:eBLBaseComponents">Failure</ns1:Ack>
<ns2:Errors xmlns:ns2="urn:ebay:apis:eBLBaseComponents">
<ns2:ShortMessage>Input data is invalid.</ns2:ShortMessage>
<ns2:LongMessage>Input data for the given tag is invalid or missing. Please check API documentation.</ns2:LongMessage>
<ns2:ErrorCode>1.22</ns2:ErrorCode>
<ns2:SeverityCode>Error</ns2:SeverityCode>
<ns2:ErrorParameters ParamID="0">
<ns2:Value>XML document structures must start and end within the same entity.</ns2:Value>
</ns2:ErrorParameters>
<ns2:ErrorClassification>RequestError</ns2:ErrorClassification>
</ns2:Errors>
<ns3:Build xmlns:ns3="urn:ebay:apis:eBLBaseComponents">E853_CORE_APILW_16579549_R1</ns3:Build>
<ns4:Version xmlns:ns4="urn:ebay:apis:eBLBaseComponents">853</ns4:Version>
</GetShippingCostsResponse>
Any ideas? I can't work out at all what the problem is. Nothing on their documentation seems to help. If i copy and paste the XML into their API Test Tool it works no problems.
I had the same problem with every call of eBay Shopping API. You can fix it adding Content-Type: text/xml;charset=UTF-8 to your headers (this fix the problem for me).
I don't see your credentials listed anywhere. The API tool they give you is a bit deceptive in that it wraps your calls for you with the credentials. http://developer.ebay.com/DevZone/guides/ebayfeatures/Basics/Call-StandardCallData.html#StandardOutputData
<?xml version="1.0" encoding="utf-8"?>
<GeteBayOfficialTimeRequest xmlns="urn:ebay:apis:eBLBaseComponents">
<RequesterCredentials>
<eBayAuthToken> Token goes here </eBayAuthToken>
</RequesterCredentials>
<Version>383</Version>
</GeteBayOfficialTimeRequest>
I'm trying to send user registrations with soap to another server. I'm creating an xml with DOMdocument and than after saveXML I'm running the soap which should return an xml with registration id plus all the data I sent in my xml.
But the Soap returns unknown error. exactly this: stdClass Object ( [RegisztracioInsResult] => stdClass Object ( [any] => 5Unknown error ) )
and this is how I send my xml.
/*xml creation with DOMdocument*/
$xml = saveXML();
$url = 'http://mx.biopont.com/services/Vision.asmx?wsdl';
$trace = '1';
$client = new SoapClient($url, array('trace' => $trace, "exceptions" => 0, 'features' => SOAP_SINGLE_ELEMENT_ARRAYS));
$params = $client->RegisztracioIns(array('xml' => $xml));
$print_r($params);
If I click on the description of the RegisztracioIns service at this URL http://mx.biopont.com/services/Vision.asmx it shows me this:
POST /services/Vision.asmx HTTP/1.1
Host: mx.biopont.com
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://mx.biopont.com/services/RegisztracioIns"
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<RegisztracioIns xmlns="http://mx.biopont.com/services/">
<xml>string</xml>
</RegisztracioIns>
</soap:Body>
</soap:Envelope>
According to this I think I'm doing the upload correctly but maybe not I don't have much experience with soap.
Is there anything I'm missing? I also tried to save the xml to my server an than get the contents with file_get_contents(). but the result was the same.
You should be able to do something like this:
$res = $client->__soapCall( 'RegisztracioIns', array('xml'=>'my string to send'));
To have the wsdl wrap 'my string to send' in the proper tags.
You are doing something similar, but I dont think the wsdl is actually wrapping the string you are trying to pass, and passing nothing instead, resulting in unknown error.
You can examine the outgoing xml using $client->__getLastRequest();.
(Also, you have a small typo in your code on the last line should be print_r($params);.)
Failing that you could try to write the xml yourself using SoapVar() and setting the type to XSD_ANYXML.
It seems cleaner to me when the wsdl wraps everything for you, but its better than banging your head against the wall until it does.
I made an attempt to do just that with your wsdl. Give this a try:
$wsdl = "http://mx.biopont.com/services/Vision.asmx?wsdl";
$client = new SoapClient($wsdl, array( 'soap_version' => SOAP_1_1,
'trace' => true,
));
try {
$xml = "<RegisztracioIns xmlns='http://mx.biopont.com/services/'>
<xml>string</xml>
</RegisztracioIns>";
$args= array(new SoapVar($xml, XSD_ANYXML));
$res = $client->__soapCall( 'RegisztracioIns', $args );
var_dump($res);
} catch (SoapFault $e) {
echo "Error: {$e}";
}
print_r($client->__getLastRequest());
print_r($client->__getLastResponse());
I can't exactly read the response I am getting with that given that it is Hungarian (I think?). So let me know if that works for you.
I've tried everything! I'm using this WSDL and am simply just trying to authenticate. I keep getting this error:
The SOAP action specified on the message, '', does not match the HTTP
SOAP Action, 'http://tempuri.org/IPSShipCarrier/Authenticate'
Here is my code:
$options = array(
"soap_version" => SOAP_1_2,
"trace"=>1,
'UserName'=>'blahremoved',
'Password'=>'blahremoved',
'AuthToken'=>'blahremoved',
'SOAPAction'=>'http://tempuri.org/IPSShipCarrier/Authenticate',
'Action'=>'http://tempuri.org/IPSShipCarrier/Authenticate',
'uri'=>'http://tempuri.org/IPSShipCarrier/Authenticate',
'exceptions'=>true );
$client = new SoapClient( "http://test.psdataservices.com/PSShipCarrierAPI/PSShipCarrier.svc?WSDL", $options );
$auth = array(
'UserName'=>'blahremoved',
'Password'=>'blahremoved',
'AuthToken'=>'blahremoved',
'SOAPAction'=>'http://tempuri.org/IPSShipCarrier/Authenticate',
'Action'=>"Authenticate"
);
$header = new SoapHeader('http://tempuri.org/IPSShipCarrier/Authenticate','Authenticate',$auth,false);
$client->__setSoapHeaders($header);
$params = new StdClass;
$params->Action = "http://tempuri.org/IPSShipCarrier/Authenticate";
$params->SOAPAction = "http://tempuri.org/IPSShipCarrier/Authenticate";
$params->UserName = "blahremoved";
$params->Password = "blahremoved";
$params->AuthToken = "blahremoved";
$client->Authenticate($params);
Let me know what you think?
When trying to access a -yet- unknown webservice, you should start with soapUi. http://www.soapui.org/ That would've shown you in 2 mins, that
it's a SOAP 1.1 service
this is the minimal content for the Authenticate port:
<tem:Authenticate>
<!--Optional:-->
<!--type: string-->
<tem:ClientName>aat</tem:ClientName>
<!--Optional:-->
<!--type: string-->
<tem:UserName>soa</tem:UserName>
<!--Optional:-->
<!--type: string-->
<tem:Password>quaaao</tem:Password>
<!--Optional:-->
<!--type: string-->
<tem:AuthToken>verraauras</tem:AuthToken>
<!--Optional:-->
<!--type: scShipCarrier - enumeration: [scUnknown,scStampsCom,scUPS,scEndicia,scFedEx]-->
<tem:ShipCarr>scUnknown</tem:ShipCarr>
</tem:Authenticate>
their messagerouter must be based on soap-action alone, so using Action is pointless and unnecessary
so yes, using soapUi would've saved your day ;)
Changing the SOAP version definitely gets you a bit further. But then, from looking at the stack trace it seems the Authenticate methods requires parameters that you are not setting. Here is the minimum code you need, without know what the shipCarr object should look like:
$options = array(
"soap_version" => SOAP_1_1,
"trace"=>1,
'exceptions'=>true,
);
$client = new SoapClient( "http://test.psdataservices.com/PSShipCarrierAPI/PSShipCarrier.svc?WSDL", $options );
$params = new StdClass();
$params->UserName = "blahremoved";
$params->Password = "blahremoved";
$params->AuthToken = "blahremoved";
$params->ShipCarr = array();
$params->ClientName = "blahremoved";
$response = $client->Authenticate($params);
var_dump($response);
This is the response:
[a:DeserializationFailed] The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://tempuri.org/:ShipCarr. The InnerException message was 'Invalid enum value 'Array' cannot be deserialized into type 'ShipCarriers.Contract.scShipCarrier'. Ensure that the necessary enum values are present and are marked with EnumMemberAttribute attribute if the type has DataContractAttribute attribute.'. Please see InnerException for more details.
To fix the Content-Type header issues, I switched the soap_version to SOAP_1_1
"soap_version" => SOAP_1_1,
Then I got a more interesting error message, which Christian Burger used to get us a little further to include the ShipCarr parameter.
Building on that, I looked at the XSD and here's an updated $params value that worked:
$params->ShipCarr = 'scUnknown';
This returned:
POST /PSShipCarrierAPI/PSShipCarrier.svc HTTP/1.1
Host: test.psdataservices.com
Connection: Keep-Alive
User-Agent: PHP-SOAP/5.3.8
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://tempuri.org/IPSShipCarrier/Authenticate"
Content-Length: 856
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://tempuri.org/" xmlns:ns2="http://tempuri.org/IPSShipCarrier/Authenticate"><SOAP-ENV:Header><ns2:Authenticate><item><key>UserName</key><value>blahremoved</value></item><item><key>Password</key><value>blahremoved</value></item><item><key>AuthToken</key><value>blahremoved</value></item><item><key>SOAPAction</key><value>http://tempuri.org/IPSShipCarrier/Authenticate</value></item><item><key>Action</key><value>Authenticate</value></item></ns2:Authenticate></SOAP-ENV:Header><SOAP-ENV:Body><ns1:Authenticate><ns1:UserName>blahremoved</ns1:UserName><ns1:Password>blahremoved</ns1:Password><ns1:AuthToken>blahremoved</ns1:AuthToken><ns1:ShipCarr>scUnknown</ns1:ShipCarr></ns1:Authenticate></SOAP-ENV:Body></SOAP-ENV:Envelope>
HTTP/1.1 200 OK
Content-Length: 325
Content-Type: text/xml; charset=utf-8
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET
Date: Mon, 25 Jun 2012 20:34:42 GMT
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><AuthenticateResponse xmlns="http://tempuri.org/"><AuthenticateResult i:nil="true" xmlns:a="http://schemas.datacontract.org/2004/07/ShipCarriers.Contract" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"/></AuthenticateResponse></s:Body></s:Envelope>
However, making subsequent requests gives me a 500 internal server error.