python-fints
python-fints copied to clipboard
Fix TAN request with response code 3955 during initialization of the dialog
This patch fixed a similar issue as in #155 for me with the "Sparkasse Vorderpfalz": Since a few days a push TAN is required even to request an account balance or get transactions of the last view days. Before, this was working with only the PIN.
I tracked the issue down to two issues by debugging the exchanged messages as described in the documentation, for which I propose a fix here.
-
The string
"DUMMY"sent as thetan_medium_namewas somehow rejected by the bank. Even the call toclient.get_tan_media()inminimal_interactive_cli_bootstrap()already triggered the error as described in #121, with the first response being[...] fints.segments.dialog.HIRMS2( # Rückmeldungen zu Segmenten header = fints.formals.SegmentHeader('HIRMS', 4, 2, 4), # Segmentkopf responses = [ # Rückmeldung fints.formals.Response( # Rückmeldung code = '3920', reference_element = None, text = 'Zugelassene Zwei-Schritt-Verfahren für den Benutzer.', parameters = [ '923', ], ), fints.formals.Response( # Rückmeldung code = '9955', reference_element = None, text = 'Auftrag nicht ausgeführt - Die Gerätebezeichnung ist unbekannt. (MBV07390100255)', ), ], ), [...]followed by
[...] fints.segments.dialog.HIRMG2( # Rückmeldungen zur Gesamtnachricht header = fints.formals.SegmentHeader('HIRMG', 3, 2), # Segmentkopf responses = [ # Rückmeldung fints.formals.Response( # Rückmeldung code = '9050', reference_element = None, text = 'Die Nachricht enthält Fehler.', ), fints.formals.Response( # Rückmeldung code = '9800', reference_element = None, text = 'Dialog abgebrochen', ), fints.formals.Response( # Rückmeldung code = '9010', reference_element = None, text = 'Die angegebene Bankreferenz/Dialog-ID ist nicht gültig.', ), ], ), fints.segments.dialog.HIRMS2( # Rückmeldungen zu Segmenten header = fints.formals.SegmentHeader('HIRMS', 4, 2, 3), # Segmentkopf responses = [ # Rückmeldung fints.formals.Response( # Rückmeldung code = '9010', reference_element = None, text = 'Auftrag wegen genereller Fehler in Auftragsnachricht nicht verarbeitet.', ), ], ), [...]after the subsequent call to
client.get_sepa_accounts()(HKSPA1), likely because the dialog was never actually accepted by the server. Should a 9xxx response code already trigger an exception inFinTSDialog.init()?Sending an empty
tan_medium_nameworks and triggers the response in the next bullet point. So I setclient.selected_tan_medium = ''before callingminimal_interactive_cli_bootstrap(client)to already skip the call toget_tan_media()(with my patch). I guess this only works because there is only one for my account. I tried different strings, the name of my device and the UUID shown in the Push Tan app in "Verbindungen", nothing worked. And evenget_tan_media()requires a TAN when the dialog starts, so it is a kind of chicken-and-egg problem and I have not found a way to not add the HKTAN7 segment to the dialog initialization request triggered byget_tan_media(). -
With the empty
tan_medium_namethe bank server responds with a TAN request and code 3955. That was added in https://github.com/raphaelm/python-fints/pull/162 to the client's_send_with_possible_retry()method to react on a TAN request when sending a request after the dialog has been established, but not inFinTSDialog.init()if the bank already sends that response:[...] fints.segments.dialog.HIRMG2( # Rückmeldungen zur Gesamtnachricht header = fints.formals.SegmentHeader('HIRMG', 3, 2), # Segmentkopf responses = [ # Rückmeldung fints.formals.Response( # Rückmeldung code = '3060', reference_element = None, text = 'Bitte beachten Sie die enthaltenen Warnungen/Hinweise.', ), fints.formals.Response( # Rückmeldung code = '3920', reference_element = None, text = 'Zugelassene Zwei-Schritt-Verfahren für den Benutzer.', parameters = [ '923', ], ), ], ), fints.segments.dialog.HIRMS2( # Rückmeldungen zu Segmenten header = fints.formals.SegmentHeader('HIRMS', 4, 2, 5), # Segmentkopf responses = [ # Rückmeldung fints.formals.Response( # Rückmeldung code = '3955', reference_element = None, text = 'Auftrag empfangen - Bitte Auftrag in Ihrer App freigeben.(MBT62870200005)', ), ], ), fints.segments.auth.HITAN7( # Zwei-Schritt-TAN-Einreichung Rückmeldung, version 7 header = fints.formals.SegmentHeader('HITAN', 5, 7, 5), # Segmentkopf tan_process = '4', # TAN-Prozess task_reference = '3115-09-28-19.28.05.705284', # Auftragsreferenz challenge = 'Bitte Auftrag in Ihrer App freigeben.', # Challenge ), [...]So I assume it was an oversight in #162 to not also patch the other method?
So these two changes work for me with an application similar to the one in the troubleshooting guide. I have not found a way to retrieve transactions without having to confirm that with a push TAN via the app interactively. Ideally there would be a way to remember that "device" at least for a couple of days, like it also works with interactive logins via the web page.
This patch may resolve https://github.com/raphaelm/python-fints/issues/121 and https://github.com/raphaelm/python-fints/issues/165, at least when also setting selected_tan_medium to an empty string (or something else if you already know a valid value) before the call to minimal_interactive_cli_bootstrap(f):
f = FinTS3PinTanClient(*client_args, product_id=product_id)
f.selected_tan_medium = ''
minimal_interactive_cli_bootstrap(f)