How to handle SoapClient Fault In PHP - php

I am calling a third party web service to get the user detail by the supplied credential. Below is my Soap Client Request.
$client = new \SoapClient($url, array("exception" => 0));
$auth = '
<wsse:Security SOAP-ENV:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken>
<wsse:Username>' . $userName . '</wsse:Username>
<wsse:Password>' . $password . '</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>';
$authvalues = new \SoapVar($auth, XSD_ANYXML);
$header1 = new \SoapHeader("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "Security", $authvalues, true);
$header2 = new \SoapHeader("http://xmlns.myweb.com/FulfillProductRequest/V1", "v1");
$header3 = new \SoapHeader("http://xmlns.myweb.com/ParameterType/V2", "v2");
$header4 = new \SoapHeader("http://xmlns.myweb.com/RequestHeader/V3", "v3");
$header = array();
$header[] = $header1;
$header[] = $header2;
$header[] = $header3;
$header[] = $header4;
$client->__setSoapHeaders($header);
$res = $client->FulfillProduct($FulfillProductRequest);
When i am calling the WSDL,if i am getting the success response then there is no issue.
But if there is any error come in soapFault then my code shows fatal error.
Anybody have any idea how to handle the SoapFault plz share.
Thanks in anvance.

You can try to wrap your $res = $client→FulfillProduct($FulfillProductRequest); in a try { } catch() {}.
For example:
try {
$res = $client→FulfillProduct($FulfillProductRequest);
} catch(Exception $e) {
// An error has occured.
// All information about the error has been stored in variable $e
print_r($e);
}
Be aware, that you can set the SoapClient to never throw exceptions with your settings, so look into that first.

Maybe it will help someone.
$options = ['trace' => true,
'debug' => false,
"exceptions" => true,
'version' => SOAP_1_2,
'connection_timeout' => 15];
$wsdl = "http://test.com?wsdl";
try {
$soapClient=new SoapClient($wsdl,$options);
} catch (SoapFault $e) {
logError($e->getMessage(),$e->getCode());
}

Related

WP/PHP SoapClient: The server was unable to process the request due to an internal error

Im trying to connect to a web service from php (WorkPress)whit soapClient and i'm getting this: 'The server was unable to process the request due to an internal error. For more information about the error, either turn on IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute or from the configuration behavior) on the server in order to send the exception information back to the client, or turn on tracing as per the Microsoft .NET Framework SDK documentation and inspect the server trace logs.'
Any idea?
This is what I´m doing, the responce is a true or false.
$wsdlUrl = 'https://#####.svc?wsdl';
$client = new SoapClient($wsdlUrl);
var_dump($client->__getTypes());
echo '</br>';
$xmlr = new SimpleXMLElement('<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">
<soapenv:Header/>
<soapenv:Body>
<tem:ExisteMiembro>
<!--Optional:-->
<tem:carnet>######</tem:carnet>
<!--Optional:-->
<tem:key>#######</tem:key>
</tem:ExisteMiembro>
</soapenv:Body>
</soapenv:Envelope>');
$params = new stdClass();
$params->xml = $xmlr->asXML();
$result = new SimpleXMLElement($client->ExisteMiembro($params));
Solved, I used this code instead and it works,
ini_set('soap.wsdl_cache_enabled', 0);
ini_set('soap.wsdl_cache_ttl', 900);
ini_set('default_socket_timeout', 15);
try {
$opts = array(
'http' => array(
'user_agent' => 'PHPSoapClient'
)
);
$context = stream_context_create($opts);
$wsdlUrl = 'https://######.svc?wsdl';
$soapClientOptions = array(
'stream_context' => $context,
'cache_wsdl' => WSDL_CACHE_NONE
);
$client = new SoapClient($wsdlUrl, $soapClientOptions);
$checkVatParameters = array(
'carnet' => '###',
'key' => '###'
);
$result = $client->ExisteMiembro($checkVatParameters);
print_r($result);
return true;
}
catch(Exception $e) {
echo $e->getMessage();
var_dump("entro al msj de error");
}

Sample PHP code to programmatically check SOAP connection in Magento 2

I tried the below code though I am not sure whether these are the required set of scripts, but it didn't work and gives
SOAP-ERROR: Parsing WSDL: Couldn't load from : Start tag expected, '<' not found
$wsdlUrl = 'http://localhost/magento20_0407/soap/default?wsdl_list=1';
$apiUser = 'testUser';
$apiKey = 'admin123';
$token = 'xioxnuuebn7tlh8ytu7781t14w7ftwmp';
$opts = array('http' => array('method' => "GET", 'header' => "Accept-language: en\r\nConnection: close\r\n"));
$context = stream_context_create($opts);
stream_context_set_option($context, "http", "protocol_version", 1.1);
fpassthru(fopen($wsdlUrl, 'r', false, $context));
$opts = array('http'=>array('header' => 'Authorization: Bearer '.$token));
$serviceArgs = array("id"=>1);
try{
$context = stream_context_create($opts);
$soapClient = new SoapClient($wsdlUrl, array('version' => SOAP_1_2, 'context' => $context));
$soapResponse = $soapClient->customerCustomerAccountServiceV1($serviceArgs);
}catch(Exception $e){
$e->getMessage();
}
var_dump($soapResponse);exit;
Can anyone share the code to make SOAP connection in Magento2.x
In Magento1.x the below code works fine to connect SOAP
$apiUrl = 'http://localhost/magento_28_03/index.php/api/soap?wsdl';
$apiUser = 'testUser';
$apiKey = 'admin123';
ini_set("soap.wsdl_cache_enabled", "0");
try{
$client = new SoapClient($apiUrl, array('cache_wsdl' => WSDL_CACHE_NONE));
} catch (SoapFault $e) {
echo 'Error in Soap Connection : '.$e->getMessage();
}
try {
$session = $client->login($apiUser, $apiKey);
if($session) echo 'SOAP Connection Successful.';
else echo 'SOAP Connection Failed.';
} catch (SoapFault $e) {
echo 'Wrong Soap credentials : '.$e->getMessage();
}
But the above doesn't work for Magento 1. Can anyone say, what changes the above code needs to work fine for Magento 2?
For SOAP API call follow the below
test.php
<?php
$token = 'YOUR_ACCESS_TOKEN';
require('vendor/zendframework/zend-server/src/Client.php');
require('vendor/zendframework/zend-soap/src/Client.php');
require('vendor/zendframework/zend-soap/src/Client/Common.php');
$addArgs = array('num1'=>2, 'num2'=>1);// Get Request
$sumArgs = array('nums'=>array(2,1000));// Post request
//$wsdlUrl = YOUR_BASE_URL."soap?wsdl&services=customerAccountManagementV1,customerCustomerRepositoryV1,alanKentCalculatorWebServiceCalculatorV1";//To declar multiple
$wsdlUrl = YOUR_BASE_URL."soap?wsdl&services=alanKentCalculatorWebServiceCalculatorV1";
try{
$opts = ['http' => ['header' => "Authorization: Bearer " . $token]];
$context = stream_context_create($opts);
$soapClient = new \Zend\Soap\Client($wsdlUrl);
$soapClient->setSoapVersion(SOAP_1_2);
$soapClient->setStreamContext($context);
}catch(Exception $e){
echo 'Error1 : '.$e->getMessage();
}
try{
$soapResponse = $soapClient->alanKentCalculatorWebServiceCalculatorV1Add($addArgs);print_r($soapResponse);
$soapResponse = $soapClient->alanKentCalculatorWebServiceCalculatorV1Sum($sumArgs);print_r($soapResponse);
}catch(Exception $e){
echo 'Error2 : '.$e->getMessage();
}
?>
http://YOUR_BASE_URL/test.php
SOAP-ERROR: Parsing WSDL: Couldn't load from : Start tag expected, '<' not found
Tells you all you need to know; the URL you're trying to load isn't a proper WSDL.
What are the contents of: http://localhost/magento20_0407/soap/default?wsdl_list=1

How to call web service with auth using php

I need to make a call to the webservice bellow, but so far failed to create the code for it.
https://www.nightline-delivers.com/ParcelMotel_UAT/RetailService.svc?wsdl
The request needs to look like the following:
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ret="Retail">
<soapenv:Header>
<UserName>WebServiceSample</UserName>
<Password>password</Password>
</soapenv:Header>
<soapenv:Body>
<ret:ValidateCredentials>
<ret:motelId>BAC032</ret:motelId>
<ret:mobileNumber>0865596800</ret:mobileNumber>
</ret:ValidateCredentials>
</soapenv:Body>
</soapenv:Envelope>
My code so far looks like this:
$client = new SoapClient("https://www.nightline-delivers.com/ParcelMotel_UAT/RetailService.svc?wsdl");
$location = new StdClass();
$location->motelId = 'BAC032';
$location->mobileNumber = '0866696800';
$auth = array(
'UserName'=>'WebServiceSample',
'Password'=>'password',
);
$header = new SoapHeader('NAMESPACE','Auth',$auth,false);
$client->__setSoapHeaders( $header );
try {
$response = $client->ValidateLocation( $location );
var_dump($response);
} catch( Exception $e ) {
echo $e->getMessage();
}
According to this it is impossible in PHP to get a header element without namespace (which is the case in your example) so that is not possible with SoapClient. However you may try to send request where both UserName and Password fields are in the Retail namespace, maybe server will accept this:
<?php
$client = new SoapClient("https://www.nightline-delivers.com/ParcelMotel_UAT/RetailService.svc?wsdl", array('trace' => TRUE));
$location = new StdClass();
$location->motelId = 'BAC032';
$location->mobileNumber = '0866696800';
$auth = array(
'UserName'=>'WebServiceSample',
'Password'=>'password',
);
$headers = array();
foreach($auth as $k=>$v) {
$headers[] = new SoapHeader('Retail', $k, $v);
}
$client->__setSoapHeaders( $headers );
try {
$response = $client->ValidateCredentials( $location );
var_dump($response);
} catch( Exception $e ) {
echo "REQUEST: ".$client->__getLastRequest();
echo $e->getMessage();
}
This code also will show you request if an exception occurs, and I have changed ValidateLocation to ValidateCredentials as in your example message. It produces following message:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="Retail">
<SOAP-ENV:Header>
<ns1:UserName>WebServiceSample</ns1:UserName>
<ns1:Password>password</ns1:Password>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<ns1:ValidateLocation>
<ns1:motelId>BAC032</ns1:motelId>
<ns1:mobileNumber>0866696800</ns1:mobileNumber>
</ns1:ValidateLocation>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
I got it working. Here is the code:
<?php
$username = 'WebServiceSample';
$password = 'password';
function formatXML($xml)
{
libxml_use_internal_errors(true);
$doc = new DOMDocument();
$doc->preserveWhiteSpace = false;
$doc->formatOutput = true;
$doc->loadXML($xml);
return $doc->saveXML();
}
try {
$client = new SoapClient("https://www.nightline-delivers.com/ParcelMotel_UAT/RetailService.svc?wsdl", array(
'trace' => true,
));
$headers = array();
$headers[] = new SoapHeader('Retail', 'UserName', 'WebServiceSample');
$headers[] = new SoapHeader('Retail', 'Password', 'password');
$client->__setSoapHeaders($headers);
$params = array(
'motelId' => 'BAz031',
'mobileNumber' => '0866696800'
);
$result = $client->__soapCall('ValidateLocation', array('ValidateLocation' => $params), array(
'location' => 'https://www.nightline-delivers.com/ParcelMotel_UAT/RetailService.svc/basic?APIKey=7C3A0EA9-C8D6-4DB0-ADF0-615BFD29DC1D'
));
} catch (SoapFault $e) {
exit($e->getMessage());
}
$request = $client->__getLastRequest();
$response = $client->__getLastResponse();
echo '<pre>';
echo htmlspecialchars( formatXML($request) );
echo "\n";
echo htmlspecialchars( formatXML($response) );

Savon header authentication problems

I am trying to authenticate a site. I found an example for PHP, but I'm having some trouble rewriting it to Ruby.
Example code:
class HRDConfig {
public $uid = "myuid";
public $pass = "mypassword123";
const NS = "https://www.tested.site.com/partnerAPI/";
const PARTNER = "https://www.tested.site.com/partnerAPI/Partner.php?wsdl";
}
ini_set("soap.wsdl_cache_enabled", "1");
$soap = new SoapClient(HRDConfig::PARTNER, array("encoding"=>"UTF-8", "exceptions" => true));
$soap->__setSoapHeaders(array(new SoapHeader(HRDConfig::NS, "AuthHeader", new HRDConfig())));
My code:
client = Savon.client(
wsdl: 'https://www.tested.site.com/partnerAPI/Partner.php?wsdl',
soap_header:{
'AuthHeader' => {'uid'=>'myuid','pass'=>'mypass'}
})
What I'm doing wrong?
$client = new SoapClient(
'http://service.example.com?wsdl',
array('soap_version' => '1.2',
'connect_timeout' => 10,
'compression' => (SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_GZIP),
'cache_wdsl' => WSDL_CACHE_NONE));
$header = new SoapHeader(
'http://service.example.com?wsdl',
'AuthenticateRequest',
new SoapVar(array('apiKey' => '***api******'), SOAP_ENC_OBJECT),
true);
$client->__setSoapHeaders($header);
try {
echo("\n[SOAP response]\n");
$response = $client->__soapCall('your function', array());
echo("\n[After response]\n");
echo("\n{$response }\n");
}
catch (Exception $e) {
echo($e->getMessage());
}
Note: here "apiKey" is my params to authenticate api, your can be different

CRM dynamic "an error occurred when verifying security for the message"

I am tring to access http://xxxxxxxxxxx/CRM2011/XRMServices/2011/Organization.svc?wsdl
I can able to see functions list. means i can access to webservice. But while i tring to write data using function create it through "an error occurred when verifying security for the message" my code is below
<?php
date_default_timezone_set("Asia/Kolkata");
ini_set("soap.wsdl_cache_enabled", "0");
$location = "http://182.18.175.29/CRM2011/XRMServices/2011/Organization.svc?wsdl";
$config['Username'] = 'xxxxxxx';
$config['Password'] = 'xxxxxx';
$config['soap_version'] = SOAP_1_2;
$config['trace'] = 1; // enable trace to view what is happening
$config['use'] = SOAP_LITERAL;
$config['style'] = SOAP_DOCUMENT;
$config['exceptions'] = 0; // disable exceptions
$config["cache_wsdl"] = WSDL_CACHE_NONE; // disable any caching on the wsdl, encase you alter the wsdl server
$config["features"] = SOAP_SINGLE_ELEMENT_ARRAYS;
include_once 'ntlmSoap.php';
$client = new NTLMSoapClient($location, $config);
print('<pre>');
print_r($client->__getFunctions());
$HeaderSecurity = array("UsernameToken" => array("Username" => 'xxxxxx', "Password" => 'xxxxxx'));
$header[] = new SoapHeader($location, "Security", $HeaderSecurity);
$client->__setSoapHeaders($header);
$params = array(
"bmw_firstname" => "test",
"bmw_lastname" => "test"
);
try {
$response = $client->__soapCall("Create", $params);
var_dump($response);
} catch (Exception $e) {
print_r($e);
}
// display what was sent to the server (the request)
echo "<p>Request :" . htmlspecialchars($client->__getLastRequest()) . "</p>";
// display the response from the server
echo "<p>Response:" . htmlspecialchars($client->__getLastResponse()) . "</p>";

Categories