Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Kreissparkasse Soltau: FinTSDialogInitError #107

Open
pritzky opened this issue Mar 23, 2020 · 2 comments
Open

Kreissparkasse Soltau: FinTSDialogInitError #107

pritzky opened this issue Mar 23, 2020 · 2 comments

Comments

@pritzky
Copy link

pritzky commented Mar 23, 2020

Hello,

I tried to connect to Kreissparkasse Soltau (BLZ: 25851660) but I can't establish a connection. maybe you can help me.

My Code (it's the example code):

import datetime
import getpass
import logging
import sys
from decimal import Decimal

from fints.client import FinTS3PinTanClient, NeedTANResponse, FinTSUnsupportedOperation
from fints.hhd.flicker import terminal_flicker_unix
from fints.utils import minimal_interactive_cli_bootstrap

logging.basicConfig(level=logging.DEBUG)

client_args = (
    '25851660',  # BLZ
    'XXX',  # USER
    getpass.getpass('PIN: '),
    'https://banking.s-fints-pt-ni.de/PinTanServlet'  # ENDPOINT
)

f = FinTS3PinTanClient(*client_args)
minimal_interactive_cli_bootstrap(f)


def ask_for_tan(response):
    print("A TAN is required")
    print(response.challenge)
    if getattr(response, 'challenge_hhduc', None):
        try:
            terminal_flicker_unix(response.challenge_hhduc)
        except KeyboardInterrupt:
            pass
    tan = input('Please enter TAN:')
    return f.send_tan(response, tan)


# Open the actual dialog
with f:
    # Since PSD2, a TAN might be needed for dialog initialization. Let's check if there is one required
    if f.init_tan_response:
        ask_for_tan(f.init_tan_response)

    # Fetch accounts
    accounts = f.get_sepa_accounts()
    if isinstance(accounts, NeedTANResponse):
        accounts = ask_for_tan(accounts)
    if len(accounts) == 1:
        account = accounts[0]
    else:
        print("Multiple accounts available, choose one")
        for i, mm in enumerate(accounts):
            print(i, mm.iban)
        choice = input("Choice: ").strip()
        account = accounts[int(choice)]

    # Test pausing and resuming the dialog
    dialog_data = f.pause_dialog()

client_data = f.deconstruct(including_private=True)

f = FinTS3PinTanClient(*client_args, from_data=client_data)
with f.resume_dialog(dialog_data):
    while True:
        operations = [
            "End dialog",
            "Fetch transactions of the last 30 days",
            "Fetch transactions of the last 120 days",
            "Fetch transactions XML of the last 30 days",
            "Fetch transactions XML of the last 120 days",
            "Fetch information",
            "Fetch balance",
            "Fetch holdings",
            "Fetch scheduled debits",
            "Fetch status protocol",
            "Make a simple transfer"
        ]

        print("Choose an operation")
        for i, o in enumerate(operations):
            print(i, o)
        choice = int(input("Choice: ").strip())
        try:
            if choice == 0:
                break
            elif choice == 1:
                res = f.get_transactions(account, datetime.date.today() - datetime.timedelta(days=30),
                                         datetime.date.today())
                while isinstance(res, NeedTANResponse):
                    res = ask_for_tan(res)
                print("Found", len(res), "transactions")
            elif choice == 2:
                res = f.get_transactions(account, datetime.date.today() - datetime.timedelta(days=120),
                                         datetime.date.today())
                while isinstance(res, NeedTANResponse):
                    res = ask_for_tan(res)
                print("Found", len(res), "transactions")
            elif choice == 3:
                res = f.get_transactions_xml(account, datetime.date.today() - datetime.timedelta(days=30),
                                             datetime.date.today())
                while isinstance(res, NeedTANResponse):
                    res = ask_for_tan(res)
                print("Found", len(res[0]) + len(res[1]), "XML documents")
            elif choice == 4:
                res = f.get_transactions_xml(account, datetime.date.today() - datetime.timedelta(days=120),
                                             datetime.date.today())
                while isinstance(res, NeedTANResponse):
                    res = ask_for_tan(res)
                print("Found", len(res[0]) + len(res[1]), "XML documents")
            elif choice == 5:
                print(f.get_information())
            elif choice == 6:
                res = f.get_balance(account)
                while isinstance(res, NeedTANResponse):
                    res = ask_for_tan(res)
                print(res)
            elif choice == 7:
                res = f.get_holdings(account)
                while isinstance(res, NeedTANResponse):
                    res = ask_for_tan(res)
                print(res)
            elif choice == 8:
                res = f.get_scheduled_debits(account)
                while isinstance(res, NeedTANResponse):
                    res = ask_for_tan(res)
                print(res)
            elif choice == 9:
                res = f.get_status_protocol()
                while isinstance(res, NeedTANResponse):
                    res = ask_for_tan(res)
                print(res)
            elif choice == 10:
                res = f.simple_sepa_transfer(
                    account=accounts[0],
                    iban=input('Target IBAN:'),
                    bic=input('Target BIC:'),
                    amount=Decimal(input('Amount:')),
                    recipient_name=input('Recipient name:'),
                    account_name=input('Your name:'),
                    reason=input('Reason:'),
                    endtoend_id='NOTPROVIDED',
                )

                if isinstance(res, NeedTANResponse):
                    ask_for_tan(res)
        except FinTSUnsupportedOperation as e:
            print("This operation is not supported by this bank:", e)

My error message:

WARNING:fints.client:You should register your program with the ZKA and pass your own product_id as a parameter.
DEBUG:fints.connection:Sending >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
        fints.message.FinTSCustomerMessage([
            fints.segments.message.HNHBK3( # Nachrichtenkopf
                header = fints.formals.SegmentHeader('HNHBK', 1, 3), # Segmentkopf
                message_size = 408, # Größe der Nachricht (nach Verschlüsselung und Komprimierung)
                hbci_version = 300, # HBCI-Version
                dialog_id = '0', # Dialog-ID
                message_number = 1, # Nachrichtennummer
            ),
            fints.segments.message.HNVSK3( # Verschlüsselungskopf, version 3
                header = fints.formals.SegmentHeader('HNVSK', 998, 3), # Segmentkopf
                security_profile = fints.formals.SecurityProfile( # Sicherheitsprofil
                        security_method = fints.formals.SecurityMethod.PIN, # Sicherheitsverfahren
                        security_method_version = 1, # Version des Sicherheitsverfahrens
                    ),
                security_function = '998', # Sicherheitsfunktion, kodiert
                security_role = fints.formals.SecurityRole.ISS, # Rolle des Sicherheitslieferanten, kodiert: Erfasser, Erstsignatur
                security_identification_details = fints.formals.SecurityIdentificationDetails( # Sicherheitsidentifikation, Details
                        identified_role = fints.formals.IdentifiedRole.MS, # Message Sender
                        cid = None,
                        identifier = '0',
                    ),
                security_datetime = fints.formals.SecurityDateTime( # Sicherheitsdatum und -uhrzeit
                        date_time_type = fints.formals.DateTimeType.STS, # Sicherheitszeitstempel
                        date = datetime.date(2020, 3, 23),
                        time = datetime.time(11, 53, 44, 785537),
                    ),
                encryption_algorithm = fints.formals.EncryptionAlgorithm( # Verschlüsselungsalgorithmus
                        usage_encryption = fints.formals.UsageEncryption.OSY, # Owner Symmetric
                        operation_mode = fints.formals.OperationMode.CBC, # Cipher Block Chaining
                        encryption_algorithm = fints.formals.EncryptionAlgorithmCoded.TWOKEY3DES, # 2-Key-Triple-DES
                        algorithm_parameter_value = b'\x00\x00\x00\x00\x00\x00\x00\x00',
                        algorithm_parameter_name = fints.formals.AlgorithmParameterName.KYE, # Symmetrischer Schlüssel, verschlüsselt mit symmetrischem Schlüssel
                        algorithm_parameter_iv_name = fints.formals.AlgorithmParameterIVName.IVC, # Initialization value, clear text
                    ),
                key_name = fints.formals.KeyName( # Schlüsselname
                        bank_identifier = fints.formals.BankIdentifier(
                                country_identifier = '280',
                                bank_code = '25851660',
                            ),
                        user_id = 'XXX',
                        key_type = fints.formals.KeyType.V, # Schlüsselart: Chiffrierschlüssel
                        key_number = 0,
                        key_version = 0,
                    ),
                compression_function = fints.formals.CompressionFunction.NULL, # Komprimierungsfunktion: Keine Kompression
            ),
            fints.segments.message.HNVSD1( # Verschlüsselte Daten, version 1
                header = fints.formals.SegmentHeader('HNVSD', 999, 1), # Segmentkopf
                data = fints.types.SegmentSequence([ # Daten, verschlüsselt
                        fints.segments.message.HNSHK4( # Signaturkopf, version 4
                            header = fints.formals.SegmentHeader('HNSHK', 2, 4), # Segmentkopf
                            security_profile = fints.formals.SecurityProfile( # Sicherheitsprofil
                                    security_method = fints.formals.SecurityMethod.PIN, # Sicherheitsverfahren
                                    security_method_version = 1, # Version des Sicherheitsverfahrens
                                ),
                            security_function = '999', # Sicherheitsfunktion, kodiert
                            security_reference = '2357092', # Sicherheitskontrollreferenz
                            security_application_area = fints.formals.SecurityApplicationArea.SHM, # Bereich der Sicherheitsapplikation, kodiert: Signaturkopf und HBCI-Nutzdaten
                            security_role = fints.formals.SecurityRole.ISS, # Rolle des Sicherheitslieferanten, kodiert: Erfasser, Erstsignatur
                            security_identification_details = fints.formals.SecurityIdentificationDetails( # Sicherheitsidentifikation, Details
                                    identified_role = fints.formals.IdentifiedRole.MS, # Message Sender
                                    cid = None,
                                    identifier = '0',
                                ),
                            security_reference_number = 1, # Sicherheitsreferenznummer
                            security_datetime = fints.formals.SecurityDateTime( # Sicherheitsdatum und -uhrzeit
                                    date_time_type = fints.formals.DateTimeType.STS, # Sicherheitszeitstempel
                                    date = datetime.date(2020, 3, 23),
                                    time = datetime.time(11, 53, 44, 785179),
                                ),
                            hash_algorithm = fints.formals.HashAlgorithm( # Hashalgorithmus
                                    usage_hash = '1',
                                    hash_algorithm = '999',
                                    algorithm_parameter_name = '1',
                                ),
                            signature_algorithm = fints.formals.SignatureAlgorithm( # Signaturalgorithmus
                                    usage_signature = '6',
                                    signature_algorithm = '10',
                                    operation_mode = '16',
                                ),
                            key_name = fints.formals.KeyName( # Schlüsselname
                                    bank_identifier = fints.formals.BankIdentifier(
                                            country_identifier = '280',
                                            bank_code = '25851660',
                                        ),
                                    user_id = 'XXX',
                                    key_type = fints.formals.KeyType.S, # Schlüsselart: Signierschlüssel
                                    key_number = 0,
                                    key_version = 0,
                                ),
                        ),
                        fints.segments.auth.HKIDN2( # Identifikation, version 2
                            header = fints.formals.SegmentHeader('HKIDN', 3, 2), # Segmentkopf
                            bank_identifier = fints.formals.BankIdentifier( # Kreditinstitutskennung
                                    country_identifier = '280',
                                    bank_code = '25851660',
                                ),
                            customer_id = 'XXX', # Kunden-ID
                            system_id = '0', # Kundensystem-ID
                            system_id_status = fints.formals.SystemIDStatus.ID_NECESSARY, # Kundensystem-Status: Kundensystem-ID wird benötigt
                        ),
                        fints.segments.auth.HKVVB3( # Verarbeitungsvorbereitung, version 3
                            header = fints.formals.SegmentHeader('HKVVB', 4, 3), # Segmentkopf
                            bpd_version = 0, # BPD-Version
                            upd_version = 0, # UPD-Version
                            language = fints.formals.Language2.DE, # Dialogsprache: Deutsch, 'de', Subset Deutsch, Codeset 1 (Latin 1)
                            product_name = 'DC333D745719C4BD6A6F9DB6A', # Produktbezeichnung
                            product_version = '3.0.0', # Produktversion
                        ),
                        fints.segments.dialog.HKSYN3( # Synchronisierung, version 3
                            header = fints.formals.SegmentHeader('HKSYN', 5, 3), # Segmentkopf
                            synchronization_mode = fints.formals.SynchronizationMode.NEW_SYSTEM_ID, # Neue Kundensystem-ID zurückmelden
                        ),
                        fints.segments.message.HNSHA2( # Signaturabschluss, version 2
                            header = fints.formals.SegmentHeader('HNSHA', 6, 2), # Segmentkopf
                            security_reference = '2357092', # Sicherheitskontrollreferenz
                            user_defined_signature = fints.formals.UserDefinedSignature( # Benutzerdefinierte Signatur
                                    pin = '***',
                                ),
                        ),
                    ]),
            ),
            fints.segments.message.HNHBS1( # Nachrichtenabschluss
                header = fints.formals.SegmentHeader('HNHBS', 7, 1), # Segmentkopf
                message_number = 1, # Nachrichtennummer
            ),
        ])

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): banking.s-fints-pt-ni.de:443
Traceback (most recent call last):
  File "C:\Users\breitzke\Desktop\test\.venv\lib\site-packages\urllib3\connectionpool.py", line 665, in urlopen
    httplib_response = self._make_request(
  File "C:\Users\breitzke\Desktop\test\.venv\lib\site-packages\urllib3\connectionpool.py", line 376, in _make_request
    self._validate_conn(conn)
  File "C:\Users\breitzke\Desktop\test\.venv\lib\site-packages\urllib3\connectionpool.py", line 994, in _validate_conn
    conn.connect()
  File "C:\Users\breitzke\Desktop\test\.venv\lib\site-packages\urllib3\connection.py", line 352, in connect
    self.sock = ssl_wrap_socket(
  File "C:\Users\breitzke\Desktop\test\.venv\lib\site-packages\urllib3\util\ssl_.py", line 370, in ssl_wrap_socket
    return context.wrap_socket(sock, server_hostname=server_hostname)
  File "C:\Program Files\Python38\lib\ssl.py", line 500, in wrap_socket
    return self.sslsocket_class._create(
  File "C:\Program Files\Python38\lib\ssl.py", line 1040, in _create
    self.do_handshake()
  File "C:\Program Files\Python38\lib\ssl.py", line 1309, in do_handshake
    self._sslobj.do_handshake()
ConnectionResetError: [WinError 10054] Eine vorhandene Verbindung wurde vom Remotehost geschlossen

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\breitzke\Desktop\test\.venv\lib\site-packages\requests\adapters.py", line 439, in send
    resp = conn.urlopen(
  File "C:\Users\breitzke\Desktop\test\.venv\lib\site-packages\urllib3\connectionpool.py", line 719, in urlopen
    retries = retries.increment(
  File "C:\Users\breitzke\Desktop\test\.venv\lib\site-packages\urllib3\util\retry.py", line 400, in increment
    raise six.reraise(type(error), error, _stacktrace)
  File "C:\Users\breitzke\Desktop\test\.venv\lib\site-packages\urllib3\packages\six.py", line 734, in reraise
    raise value.with_traceback(tb)
  File "C:\Users\breitzke\Desktop\test\.venv\lib\site-packages\urllib3\connectionpool.py", line 665, in urlopen
    httplib_response = self._make_request(
  File "C:\Users\breitzke\Desktop\test\.venv\lib\site-packages\urllib3\connectionpool.py", line 376, in _make_request
    self._validate_conn(conn)
  File "C:\Users\breitzke\Desktop\test\.venv\lib\site-packages\urllib3\connectionpool.py", line 994, in _validate_conn
    conn.connect()
  File "C:\Users\breitzke\Desktop\test\.venv\lib\site-packages\urllib3\connection.py", line 352, in connect
    self.sock = ssl_wrap_socket(
  File "C:\Users\breitzke\Desktop\test\.venv\lib\site-packages\urllib3\util\ssl_.py", line 370, in ssl_wrap_socket
    return context.wrap_socket(sock, server_hostname=server_hostname)
  File "C:\Program Files\Python38\lib\ssl.py", line 500, in wrap_socket
    return self.sslsocket_class._create(
  File "C:\Program Files\Python38\lib\ssl.py", line 1040, in _create
    self.do_handshake()
  File "C:\Program Files\Python38\lib\ssl.py", line 1309, in do_handshake
    self._sslobj.do_handshake()
urllib3.exceptions.ProtocolError: ('Connection aborted.', ConnectionResetError(10054, 'Eine vorhandene Verbindung wurde vom Remotehost geschlossen', None, 10054, None))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\breitzke\Desktop\test\.venv\lib\site-packages\fints\dialog.py", line 85, in init
    retval = self.send(*segments, internal_send=True)
  File "C:\Users\breitzke\Desktop\test\.venv\lib\site-packages\fints\dialog.py", line 137, in send
    response = self.client.connection.send(message)
  File "C:\Users\breitzke\Desktop\test\.venv\lib\site-packages\fints\connection.py", line 25, in send
    r = requests.post(
  File "C:\Users\breitzke\Desktop\test\.venv\lib\site-packages\requests\api.py", line 119, in post
    return request('post', url, data=data, json=json, **kwargs)
  File "C:\Users\breitzke\Desktop\test\.venv\lib\site-packages\requests\api.py", line 61, in request
    return session.request(method=method, url=url, **kwargs)
  File "C:\Users\breitzke\Desktop\test\.venv\lib\site-packages\requests\sessions.py", line 530, in request
    resp = self.send(prep, **send_kwargs)
  File "C:\Users\breitzke\Desktop\test\.venv\lib\site-packages\requests\sessions.py", line 643, in send
    r = adapter.send(request, **kwargs)
  File "C:\Users\breitzke\Desktop\test\.venv\lib\site-packages\requests\adapters.py", line 498, in send
    raise ConnectionError(err, request=request)
requests.exceptions.ConnectionError: ('Connection aborted.', ConnectionResetError(10054, 'Eine vorhandene Verbindung wurde vom Remotehost geschlossen', None, 10054, None))

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "c:/Users/breitzke/Desktop/test/fints_test.py", line 21, in <module>
    minimal_interactive_cli_bootstrap(f)
  File "C:\Users\breitzke\Desktop\test\.venv\lib\site-packages\fints\utils.py", line 310, in minimal_interactive_cli_bootstrap
    client.fetch_tan_mechanisms()
  File "C:\Users\breitzke\Desktop\test\.venv\lib\site-packages\fints\client.py", line 1129, in fetch_tan_mechanisms
    self._ensure_system_id()
  File "C:\Users\breitzke\Desktop\test\.venv\lib\site-packages\fints\client.py", line 1141, in _ensure_system_id
    response = dialog.init(
  File "C:\Users\breitzke\Desktop\test\.venv\lib\site-packages\fints\dialog.py", line 103, in init
    raise FinTSDialogInitError("Couldn't establish dialog with bank, Authentication data wrong?") from e
fints.exceptions.FinTSDialogInitError: Couldn't establish dialog with bank, Authentication data wrong?

Thanks in advance!

@Bouni
Copy link

Bouni commented Jul 16, 2020

Hi, I just used your code to fetch my balance from Sparkasse Hochrhein successfully.
The only difference is the the endpoint: https://banking-bw1.s-fints-pt-bw.de/fints30
Over in the Jamaica wiki is a line that says "the URL should end with /fints30"
So I guess that your endpoint is not correct!?

@raphaelm
Can you give an explanation how to get the correct endpoint for a bank?
The same wiki entry for jamaica says "after entering the bank identifier the URL is inserted automatically". So i guess there is either a list of bank identifiers and the corresponding URLs or there is some API that can be used to get the right endpoint URL.

@raphaelm
Copy link
Owner

There is a list, but it may not be embedded in software or publicly shared. Some googling usually yields the correct results.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants