Petru Tanas
Petru Tanas

Reputation: 1237

Python SOAP requests issues

I am trying to connect to BankConnect WSDL (a mobile banking service) (test endpoint: here), and call getBankCertificate method, but I am unable to get it working.

I have tried 2 methods: suds and zeep. With suds I have failed to connect with [WinError 10061]:

from suds.client import Client

url="https://stest.bankconnect.dk/2019/04/04/services/CorporateService?wsdl"
client = Client(url) # [WinError 10061]

With zeep I have managed to get a bit further, but got a NullPointerException

from zeep import Client as cl
from requests import Session
from zeep.transports import Transport

session = Session()
session.verify = False  # For some reason SSL validation fails and I had to ignore it. This is unacceptable and needs to be addressed, but it is outside of the scope of this question.
transport = Transport(session=session)
client = cl(url, transport=transport)
client.service.getBankCertificate() # Fault: NullPointerException

Edit 1: The following example XML SOAP Envelope is offered for getBankCertificate:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Header>
    <technicalAddress xmlns="http://bankconnect.dk/schema/2014" xmlns:ns2="http://www.w3.org/2000/09/xmldsig#"/>
    <activationHeader xmlns="http://bankconnect.dk/schema/2014" xmlns:ns2="http://www.w3.org/2000/09/xmldsig#">
      <organisationIdentification>
        <mainRegistrationNumber>8079</mainRegistrationNumber>
        <isoCountryCode>DK</isoCountryCode>
      </organisationIdentification>
      <functionIdentification>112233445566778899</functionIdentification>
      <erpInformation/>
      <endToEndMessageId>49d1de38a3eb4b9f8a44a77286ceb9c8</endToEndMessageId>
      <createDateTime>2015-06-11T10:08:32.710+02:00</createDateTime>
    </activationHeader>
  </soap:Header>
  <soap:Body>
    <getBankCertificate xmlns="http://bankconnect.dk/schema/2014" xmlns:ns2="http://www.w3.org/2000/09/xmldsig#"/>
  </soap:Body>
</soap:Envelope>

Please advise on how to correctly connect to this service. (Any method is acceptable, not only this 2 particular modules)

Upvotes: 0

Views: 499

Answers (1)

Alexandra Dudkina
Alexandra Dudkina

Reputation: 4462

When enabling history plugin and logging the request and response, it's visible that NullPointerException is returned from the server:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <soap:Fault>
      <faultcode>soap:Server</faultcode>
      <faultstring>NullPointerException</faultstring>
    </soap:Fault>
  </soap:Body>
</soap:Envelope>

Most probably that happens because of some missing information from the request. The missing part seems to be SOAP headers. Here is code, which constructs same header as in your example message and retrieves a non-fault response from the server:

from zeep import Client as cl
from requests import Session
from zeep.transports import Transport
from zeep.plugins import HistoryPlugin
from lxml import etree

url="https://stest.bankconnect.dk/2019/04/04/services/CorporateService?wsdl"

history = HistoryPlugin()
session = Session()
session.verify = False  # For some reason SSL validation fails and I had to ignore it. This is unacceptable and needs to be addressed, but it is outside of the scope of this question.
transport = Transport(session=session)
client = cl(url, transport=transport, plugins=[history])

headers = {
    'technicalAddress': '{http://bankconnect.dk/schema/2014}technicalAddress',
    'activationHeader': {
        'organisationIdentification':  {
            'mainRegistrationNumber': '8079',
            'isoCountryCode': 'DK'
        },
        'functionIdentification': '112233445566778899',
        'erpInformation': '{http://bankconnect.dk/schema/2014}erpInformation',
        'endToEndMessageId': '49d1de38a3eb4b9f8a44a77286ceb9c8',
        'createDateTime': '2015-06-11T10:08:32.710+02:00'
    }

}

try:
    client.service.getBankCertificate(_soapheaders=headers)
except Exception as e:
    print(e)

sent = etree.tostring(history.last_sent["envelope"], encoding="unicode", pretty_print=True)
received = etree.tostring(history.last_received["envelope"], encoding="unicode", pretty_print=True)

print(sent)
print(received)

It also logs request and response, which could be useful for debugging.

Upvotes: 1

Related Questions