python-fints
python-fints copied to clipboard
Sparkasse Leipzig: Secure Customer Auhentication, synchronisation, return code 9391
Describe the bug
Starting by Oct 7th, 2024, the connection to a bank account at Sparkasse Leipzig failed with the error Error during dialog initialization, could not fetch BPD. Please check that you passed the correct bank identifier to the HBCI URL of the correct bank.
Upon further investigation, I found out that Sparkasse Leipzig now requires a FinTS feature called "SCA - Secure Customer Authentication". Apparently there is a return code 9391 that needs to be handled. The server will issue a customer system ID that is used to recognize the client application.
Extracts of email responses from the bank:
Seit 07.10. ist die Geräteerkennung bei der Anmeldung per Software obligatorisch. Dafür nutzt die Finanz Informatik den in der FinTS-Spezifikation definierten Standard. Zudem wurden alle (bekannten) Softwarehersteller von der Finanz Informatik seit März 2023 über die künftige Nutzung informiert. Die Finanz Informatik hat dafür auch eine Info-Seite unter https://www.f-i.de/fints zur Verfügung gestellt.
In der OB-Recherche haben wir erkannt, dass der Kunden die Rückmeldung "Auftrag nicht ausgeführt - Die Gerätebezeichnung ist unbekannt. (MBV07390100255)" erhält. Hier sollte der Kunde in den Einstellungen der Software/Bankzugangsdaten eine Synchronisierung durchführen und prüfen, ob bei der Gerätebezeichnung anschließend "Alle Geräte" hinterlegt ist. Ggf. muss er dies manuell anpassen (bitte Groß- und Kleinschreibung beachten). Danach soll er den Zugang nochmals versuchen.
After having searched for "9391" and "Kundensystem-ID" in the FinTS docs
- https://www.hbci-zka.de/dokumente/spezifikation_deutsch/FinTS_Rueckmeldungscodes_2023-03-27_final_version.pdf
- https://www.hbci-zka.de/dokumente/spezifikation_deutsch/fintsv3/FinTS_3.0_Formals_2017-10-06_final_version.pdf
my understanding is that the server returns 9391 if there is no customer system ID provided yet. In order to obtain the customer system ID, a "synchronisation" request has to be made. Once the customer system ID is obtained, it has to be sent when authenticating to the server.
I looked for "9391" in the project's source code, but could not find any occurences. I found the sysid branch that might be related.
Bank I tested this with Name of the bank: Sparkasse Leipzig FinTS URL: https://banking-sn5.s-fints-pt-sn.de/fints30
Expected behavior
- The return code 9391 should be handled.
- It should be possible to perform a "synchronisation" so that the client application is listed in the Sparkasse's web interface in the list of known devices.
Code required to reproduce
# Just the debug code with my bank credentails. See gist below for the output.
Log output / error message
See https://gist.github.com/lutuh/86a598b51e2daa9e26a7bff937cce5fc
Additional context Add any other context about the problem here.
Thank you for this amazing library! I am happy to assist with testing and even coding, if you validate this feature request and point me into the right direction as to where the code changes need to happen.
Hi! We are having the same problem with Spk Rosenheim. I've been trying to solve this for us, but could not get far.
Here you can find our logs, maybe they could help @raphaelm in debugging the problem: https://gist.github.com/garpeer/4dd11da0667f15ab53b6fbbae8d26271
Same for me :-( It looks like all of the Sparkassen introduced this new feature :-( Does anyone tried a workaround? I understand this 'sync' as a one time task.
Likely same as #165, I can only help debugging once my Sparkasse rolled it out too
Likely same as #165, I can only help debugging once my Sparkasse rolled it out too
Please try again with python-fints 4.2.0 and storing the system ID and passing it to the next run: https://python-fints.readthedocs.io/en/latest/tans.html#system-ids
If the issue persists, feel free to reopen.
Morning Raphel, thanks for the adjustment! The sync process with the system_id is working now, but I think there is a bug. Or I'm just using the software in a different way ;-) Let me describe it:
This code should work, but it doesn't:
f = FinTS3PinTanClient(*client_args, product_id=product_id,system_id='CHANGED_FOR_POST') f.get_sepa_accounts()
It throws an error message:
Traceback (most recent call last):
File "check_banking_has.py", line 67, in
As workaround I'm doeing this and everything works, I can access see my accounts, see the transactions without the need of a TAN:
f = FinTS3PinTanClient(*client_args, product_id=product_id,system_id='CHANGED_FOR_POST') f.fetch_tan_mechanisms() mechanisms = list(f.get_tan_mechanisms().items()) f.get_sepa_accounts()
If you need more informations, I can provice some debug logs. Thanks in advance!
Best regards, Gerd
This is… weird, but I have no idea what it is and probably not have the time to debug it if there is a simple workaround
I get the same response error as @gerdsteiner . But his workaround does not work for me, either.
@raphaelm Could you confirm that this is the right way to obtain the system ID?
client = FinTS3PinTanClient(...) # without specifying system_id
minimal_interactive_cli_bootstrap(client)
print(client.system_id)
And, does your python application show up in the Sparkasse settings interface ("Geräteverwaltung") upon confirmation of the 2FA request with the title "Gerät als vertrauenswürdig speichern"?
Yes, I can see my Application in the Sparkasse app at Einstellungen -> Kontozugriffe -> Dienste und Anwendungen. And yes, that looks right with the system ID. I printed/saved it at the end of my script but that shouldn't make a large difference hopefully
Maybe something is wrong with your connector, when you try to connect with system_id? I do the connection in this way:
`def connector_bank(config_input): blz = read_config_parameter(config_input,'allgemein','kto_blz') account = read_config_parameter(config_input,'allgemein','kto_account') pin = read_config_parameter(config_input,'allgemein','kto_pin') endpoint = read_config_parameter(config_input,'allgemein','kto_endpoint') product_id = read_config_parameter(config_input,'allgemein','kto_product_id') system_id = read_config_parameter(config_input,'allgemein','kto_system_id')
# Connect to the bank
f = FinTS3PinTanClient(
blz, # Your bank's BLZ
account, # Your login name
pin, # Your banking PIN
endpoint,
product_id=product_id,
system_id=system_id
) f.fetch_tan_mechanisms() mechanisms = list(f.get_tan_mechanisms().items())
return f`
My working code can be found in #174. Thank you, @raphaelm !