Just to answer myself, in case anyone else would like to also know how I solved it.
The problem was the following, the request XML for one of the webservices had to be in this format:
<?xml version="1.0" encoding="utf-8" ?>
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 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:Body>
<ns123:IsTokenValid xmlns:ns123="http://www.xxxxxxx.com">
<ns123:token xsi:type="xsd:string">'.$this->loginToken.'</ns123:token>
</ns123:IsTokenValid>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
When I mention the prefix, I'm referring to the ns123 part. The problem is that none of the libraries produced the correct XML to send to the server, they would never put the prefix, so the request never worked.
I first solved it, by going directly to the NuSoap class and changed the code in one the classes, but then I discovered I could make my own request XML with NuSoap, witch resulted in the following code:
$nsValue = rand(1000, 9000);
$requestXml = '<?xml version="1.0" encoding="utf-8" ?>
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 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:Body>
<ns'.$nsValue.':IsTokenValid xmlns:ns'.$nsValue.'="http://www.xxxxxxx.com">
<ns'.$nsValue.':token xsi:type="xsd:string">'.$this->loginToken.'</ns'.$nsValue.':token>
</ns'.$nsValue.':IsTokenValid>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>';
$result = WebService::CallWebService($this->endPoint, 'http://www.xxxxxxx.com/IsTokenValid', $requestXml, $this->httpUser, $this->httpPass);
The WebService::CallWebService is just a wrapper to NuSoap class that does something like this ( and also has error handling, set's HTTP authentication etc ):
$client = new nusoap_client($webServiceLink, false);
$result = $client->send($request, $soapAction, '', self::$timeout, self::$responseTimeout);
Iain and everyone else, hope this is clear.
At a glance, I would say SOAP 1.2
is not SOAP 1.1
(PHP's default).
For 1.2 services, use:
$s = new SoapServer(DOCROOT.'wsdls/IShopClientWS.wsdl',
array('soap_version' => SOAP_1_2));
Also, transport should be "http://schemas.xmlsoap.org/soap/http"
AFAIK, not http://www.w3.org/2003/05/soap/bindings/HTTP/
.
<soap12:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
To be honest, I do not strictly know why, just that it is in my wsdl's and it just works. If anyone is masochistic enough to delve in the specs feel free to link to the relevant portion.
Here is some differencies between 1.1 and 1.2 specs: http://schemas.xmlsoap.org/wsdl/soap12/soap12WSDL.htm
And there is no transport like
http://www.w3.org/2003/05/soap/bindings/HTTP/
So my thoughts that this is just QIWI payment system bug.
Best Answer
When you say you don't want to deploy two service hosts, I assume you're self-hosting a single ServiceHost in a Windows Service. I solved this problem by building a generic service host that can host as many service impls internally as I want (eg, it new's a ServiceHost for each service entry in the config). That way, I can flexibly host as many service impls in a single Windows Service as I need. This would solve your problem by allowing you to separate the basicHttp bound service from the others to keep the WSDL clean. There are some open-source examples of this floating around (here's one).
The only other way I could think of to do it would be to expose your own custom metadata endpoint built from WsdlExporter (see here)
Good luck!