Das Anlegen von Lastschriften ist eine wichtige Funktion, wenn man Kunden neben Zahlungsarten wie Rechnung, PayPal, Kreditkarte et cetera auch noch die Möglichkeit geben möchte, die Bankverbindung anzugeben, um den Betrag zum Fälligkeitsdatum einfach abbuchen zu lassen. Das ist gerade für wiederkehrende Leistungen wie Abonnements praktisch. Dazu sind jedoch erstens einige Voraussetzungen zu erfüllen wie zum Beispiel das Aktivieren der Möglichkeiten zum Einziehen von Lastschriften und das Beantragen einer sogenannten Gläubiger-Identifikationsnummer. Schließlich benötigen wir noch den passenden VBA-Code. Allein damit kommen wir aber nicht aus: Wenn wir gemütlich von unserer Datenbankanwendung aus Lastschriften anlegen wollen, benötigen wir eine zusätzliche Bibliothek. Dabei handelt es sich um die in vielen Anwendungen verwendete DDBAC-Bibliothek. Wie wir die einzelnen Schritte erledigen, um unsere Anwendung zum Anlegen von Lastschriften verwenden zu können, zeigen wir in diesem Beitrag.
Hinweis
Zum Umsetzen der Beispiele aus diesem Beitrag ist eine kostenpflichtige Lizenz der DDBAC-Komponenten Voraussetzung. Sie erhalten diese auf der folgenden Webseite:
https://www.andreminhorst.de/ddbac
Benötigte Informationen für eine Lastschrift
Für eine SEPA-Lastschrift benötigen wir diese Informationen:
- Daten des Zahlungspflichtigen (Zahlungsempfängers)
- Name und Adresse des Kontoinhabers
- IBAN des Kontos
- BIC (bei internationalen Lastschriften außerhalb des SEPA-Raums)
- Gläubiger-Identifikationsnummer (CID): Wird von der Bundesbank oder der jeweiligen nationalen Zentralbank vergeben und kennzeichnet den Zahlungsempfänger eindeutig.
- Mandatsreferenz: Eindeutige Nummer, die das Mandat identifiziert. Wird vom Zahlungsempfänger vergeben und muss einmalig sein.
- Mandatserteilung: Schriftliches oder elektronisches SEPA-Lastschriftmandat. Enthält Erlaubnis zur Abbuchung vom Konto des Zahlungspflichtigen und muss vom Zahlungspflichtigen unterschrieben werden.
Außerdem benötigen wir folgende Angaben:
- Betrag der Abbuchung
- Fälligkeitsdatum (Einzugstermin)
- Verwendungszweck (z. B. Rechnungsnummer)
- Wiederkehrende oder einmalige Lastschrift
Zusätzliche Anforderungen:
- Pre-Notification: Der Zahlungspflichtige muss mindestens 14 Tage vor Abbuchung über den Einzug informiert werden (es sei denn, eine kürzere Frist wurde vereinbart)
Schritt für Schritt
Wie bereits eingangs erwähnt, sind einige Schritte nötig, die wir uns in der folgenden Reihenfolge ansehen:
- Aktivieren der Lastschrift-Funktionen für das Bankkonto
- Beantragen einer Gläubiger-Identifikationsnummer
- Beantragen einer Registrierungsnummer für Onlinebanking
- Holen der DDBAC-Komponenten
- Holen des Lastschrift-Mandats
- Herstellen einer Verbindung per Onlinebanking
- Programmieren der Lastschrift-Funktionen
Aktivieren der Lastschrift-Funktionen für das Bankkonto
Ein Bankkonto ist normalerweise nicht für den Einsatz von Lastschriften vorgesehen. Dies müssen wir zuerst aktivieren. In meinem Fall reichte es aus, meinen Ansprechpartner bei der Bank anzurufen und ihn zu bitten, dies einzurichten. Man muss dazu ein, zwei Formulare ausfüllen. Der Hintergrund ist, dass es bei einer Lastschrift nicht sichergestellt ist, dass das Geld auch auf dem Konto verbleibt. Der Kunde hat immer die Möglichkeit, eine Lastschrift zurückzuholen. Die Aktivierung von Lastschriften ging in unserem Fall recht schnell – es hängt aber von der jeweiligen Bank ab.
Beantragen einer Gläubiger-Identifikationsnummer
Wie oben beschreiben, benötigen wir auch eine Gläubiger-Identifikationsnummer. Diese können wir bei der Deutschen Bundesbank beantragen. Die Startseite dort sieht beispielsweise wie in Bild 1 aus. Der Vorgang ist hier gut dokumentiert und es sind keine weiteren Voraussetzungen zu erfüllen, um diese ID zu erhalten. Der Erhalt sollte in der Regel innerhalb eines Werktages zu bewerkstelligen sein.
Bild 1: Start der Beantragung einer Gläubiger-Identifikationsnummer
Wem dies zu lange dauert, der kann auch eine Gläubiger-Identifikationsnummer zum Testen holen. Diese finden wir auf der Seite mit den häufig gestellten Fragen zu der Gläubiger-Identifikationsnummer.
Die Test-ID lautet: DE98ZZZ09999999999
Beantragen einer Registrierungsnummer für Onlinebanking
Wer mit Komponenten wie den DDBAC-Komponenten Onlinebanking betreiben möchte, benötigt dazu eine eigene Registrierungsnummer.
Diese kann hier beantragt werden (siehe Bild 2):
Bild 2: Seite zum Registrieren einer FinTS-Nummer
https://www.fints.org/de/hersteller/produktregistrierung
Hier finden wir unter dem Link Registrierungsprozess ein Formular, in das wir die notwendigen Informationen eintragen können.
Die Vergabe dieser Nummer dauerte bei uns einige Tage, aber wir wissen nicht, wie schnell der Prozess aktuell durchgeführt wird.
Diese Nummer machen wir im VBA-Projekt beispielsweise über eine wie folgt angelegte Konstante verfügbar:
Public Const cstrFints As String = "XXXXXXXXXXXXXXXXXXXXX"
Holen der DDBAC-Komponenten
Schließlich benötigen wir die kostenpflichtigen DDBAC-Komponenten. Diese finden wir auf der folgenden Webseite:
https://www.andreminhorst.de/ddbac
Installieren der DDBAC-Komponenten
Im Download der DDBAC-Komponenten befinden sich zwei Zip-Dateien. Wir installieren die aus der Zipdatei DDBACNetWrapper-Version-x-x-x-x.zip.
Hier finden wir wiederum drei Verzeichnisse, von denen wir das Verzeichnis DDBACWrapper auswählen. Hier installieren wir abhängig davon, ob das installierte Windows 32-Bit oder 64-Bit verwendet, die Datei DDBACSetup.msi oder DDBACSetupx64.msi.
Die meisten Windows-Versionen haben derzeit 64-Bit.
Holen des Lastschrift-Mandats
Ein sehr wichtiger Faktor ist, dass wir von dem Kunden, von dem wir Geld per Lastschrift einziehen wollen, ein Lastschriftmandat erhalten müssen. Zu beschreiben, wie dieser Vorgang abläuft, würde hier den Rahmen sprengen. Wichtig ist jedoch, dass die Lastschrift mit Zustimmung des Kunden geschieht.
Herstellen einer Verbindung per Onlinebanking
Wenn die Onlinebanking-Komponenten installiert sind, benötigen wir vor dem eigentlichen Programmieren erst einmal eine Verbindung zum Bankserver.
Dazu starten wir eine Anwendung, die wir in der Systemsteuerung unter dem Namen Homebanking Administrator (32-Bit) finden (siehe Bild 3).
Bild 3: Anlegen eines neuen Banking-Kontakts
Hier klicken wir auf die Schaltfläche Neu… und finden einen weiteren Dialog namens HBCI/FinTS-Kontakt vor. Hier geben wir beispielsweise die Bankleitzahl oder den Banknamen ein, um die Bank zu finden. Nachdem wir die Bank ausgewählt haben, klicken wir auf Weiter (siehe Bild 4).
Bild 4: Auswahl der Bank
Das Programm ermittelt dann die verfügbaren Zugangsdaten (siehe Bild 5).
Bild 5: Ermitteln der Zugangsdaten
Die verfügbaren Zugangsarten erscheinen dann im folgenden Dialog zur Auswahl. Hier wählt man in der Regel PIN/TAN, was üblicherweise auch alle aktuellen Zugangsarten wie photoTan abdeckt (siehe Bild 6).
Bild 6: Auswahl der Zugangsart
Anschließend müssen wir den Benutzernamen beziehungsweise die Teilnehmernummer eingeben. Das ist die gleiche Nummer, unter der Sie sich vermutlich auch beim Onlinebanking anmelden (siehe Bild 7).
Bild 7: Angabe der Teilnehmernummer
Schließlich benötigen wir zum Synchronisieren mit diesem Bankkontakt noch die Eingabe der PIN (siehe Bild 8).
Bild 8: Eingabe des PIN
Danach folgen je nach Bank und Zugangsart noch weitere Abfragen beispielsweise zum Sicherheitsverfahren. Abschließend erhalten wir die Meldung über die erfolgreiche Synchronisierung (siehe Bild 9).
Bild 9: Erfolgsmeldung
Damit liegen die grundlegenden Daten nun auf dem aktuellen Rechner und wir können von Access aus per VBA auf die Informationen nicht nur des Bank Kontakts, sondern auch auf die darin enthaltenen Bankverbindungen zugreifen.
Bank Kontakt und Konten einsehen
Bleiben wir noch kurz im Administrator für Homebanking Kontakte und schauen uns an, wie wir die Konten zu diesem Kontakt einsehen können. Dazu klicken wir auf den Banking Kontakt und dann auf die Schaltfläche Bearbeiten (siehe Bild 10).
Bild 10: Der neue Banking Kontakt in der Liste der Kontakte
Dies öffnet einen weiteren Dialog (siehe Bild 11). Hier finden wir neben einigen anderen Möglichkeiten, unseren Banking Kontakt zu bearbeiten, auch den Link Konten verwalten.
Bild 11: Bearbeiten eines Banking Kontakts
Wenn wir diesen anklicken, landen wir auf einer weiteren Seite, die uns alle Konten anzeigt, die mit diesem Banking Kontakt verknüpft sind (siehe Bild 12).
Bild 12: Dialog zum Verwalten der Konten
Programmieren der Lastschrift-Funktionen
Damit kommen wir zum eigentlichen Thema dieses Beitrags, nämlich dem Programmieren der Lastschrift.
Dazu wechseln wir in unserer Beispieldatenbank als Erstes zum VBA-Editor und fügen einen Verweis auf die benötigte Bibliothek der DDBAC-Komponenten hinzu.
Dabei handelt es sich um den Eintrag DataDesign DDBAC FinTS 4.0 (siehe Bild 13).
Bild 13: Verweis auf die DDBAC-Komponente
Unterschiede zwischen SEPA-Basislastschrift und SEPA-Firmenlastschrift
Für SEPA-Lastschriften gibt es zwei Verfahren: die SEPA-Basislastschrift und die SEPA-Firmenlastschrift.
- Die SEPA-Basislastschrift (CORE) kann sowohl von Verbrauchern als auch Unternehmen genutzt werden. Nach einer Belastung hat der Zahler die Möglichkeit, die Lastschrift innerhalb von acht Wochen ohne Angabe von Gründen zurückzugeben. Die Buchung wird dabei rückgängig gemacht.
- Die SEPA-Firmenlastschrift (B2B) ist ausschließlich für Geschäftskunden (Nicht-Verbraucher) vorgesehen und dient als zusätzliches Verfahren zur Vereinfachung der geschäftlichen Zahlungsabwicklung. Im Gegensatz zur Basislastschrift besteht bei der Firmenlastschrift keine Möglichkeit zur Rückgabe der Lastschrift.
Unabhängig vom Verfahren kann eine nicht autorisierte Lastschrift – also ein Lastschrifteinzug ohne gültiges Mandat – innerhalb von 13 Monaten nach der Kontobelastung vom Zahler zurückgegeben werden.
Banking Kontakte und Accounts in Access einlesen
Damit wir von Access aus per VBA Lastschriften einreichen können, müssen wir auf die entsprechenden Banking Kontakte und die darin enthaltenen Konten zugreifen können.
Dabei handelt es sich um die Informationen, die wir soeben bereits über die Anwendung Homebanking Administrator in der Systemsteuerung hinterlegt haben.
Die Banking Kontakte wollen wir in einem Formular in ein Kombinationsfeld einlesen. Der Benutzer kann dann einen der Einträge auswählen.
Nachdem dies geschehen ist, sollen die Accounts, also die Konten, dieses Banking Kontakts in einem zweiten Auswahlfeld bereitgestellt werden. Hat der Benutzer auch hier einen Wert selektiert, haben wir schon einmal die Informationen zu dem Konto, zu dessen Gunsten die Lastschrift ausfallen soll.
Formular anlegen
Dazu legen wir als Erstes ein neues, leeres Formular an. Diesem fügen wir ein Kombinationsfeld namens cboBankingkontakte für die Banking Kontakte hinzu und ein weiteres Kombinationsfeld namens cboAccounts für die Konten.
Für beide Kombinationsfelder stellen wir die Eigenschaft Datensatzherkunft auf den Eintrag Wertliste ein (siehe Bild 14).
Bild 14: Formular zur Auswahl der Banking Kontakte und Accounts
Banking Kontakte füllen
Beim Füllen der Banking Kontakte wollen wir direkt berücksichtigen, ob diese überhaupt das Hinzufügen von Lastschriften erlauben.
Dies können wir ebenfalls aus den Informationen abfragen, die für unsere Banking Kontakte gespeichert wurden.
Dazu nutzen wir die Funktion getContacts aus Listing 1. Für die Liste der Bankkontakte stellen wir eine Variable namens m_Contacts bereit, in der wir die Kontakte temporär speichern. Diese deklarieren wir wie folgt:
Public Function GetContacts(Optional bolReset As Boolean) As BACContacts If m_Contacts Is Nothing Then Set m_Contacts = New BACContacts m_Contacts.Populate "" Else If bolReset = True Then m_Contacts.Populate "" End If End If Dim objContact As BACContact For Each objContact In m_Contacts objContact.Fields("ProductName") = cstrFints objContact.Fields("Produktbezeichnung") = cstrFints Next objContact Set GetContacts = m_Contacts End Function
Listing 1: Einlesen aller Kontakte
Private m_Contacts As BACContacts
Die Funktion GetContacts prüft, ob m_Contacts bereits eingelesen wurde. Falls nicht, füllen wir es mit einer neuen Instanz der Klasse BACContacts und rufen ihre Populate-Methode auf.
Sollte m_Contacts bereits gefüllt sein, wird es einfach als Datenquelle verwendet – außer in dem Fall, dass wir den Parameter bolReset der Funktion auf den Wert True einstellen.
Dann rufen wir auch in diesem Fall die Populate-Methode auf, um m_Contacts erneut zu füllen.
Nun deklarieren wir eine Variable namens objContact mit dem Datentyp BACContact. Diesen verwenden wir als Laufvariable für die folgende For Each-Schleife, in der wir alle Elemente der Auflistung aus m_Contacts durchlaufen.
Anschließend weisen wir den Feldern ProductName und Produktbezeichnung den FinTS-Registrierungsschlüssel zu und geben den Inhalt von m_Contacts an die aufrufende Prozedur zurück.
Zum Testen können wir die folgende Prozedur verwenden:
Public Sub Test_GetContacts() Dim objContact As BACContact For Each objContact In GetContacts Debug.Print objContact.BankCode, objContact.UserID Next objContact End Sub
Dies gibt beispielsweise die Bankleitzahl und die Benutzerkennung für diesen Banking Kontakt im Direktbereich aus.
Banking Kontakte unter Berücksichtigung der Verfügbarkeit einer Funktion holen
Wir wollen im Kombinationsfeld zur Anzeige der Banking Kontakte auch gleich anzeigen, ob der jeweilige Kontakt überhaupt die Möglichkeit bietet, Lastschriften anzulegen. Manchen Banken bieten diese Funktion grundsätzlich nicht an.
Dazu fügen wir die Funktion GetContactListWithFeature hinzu, mit der wir das Segment, also die Funktion, angeben, auf die wir den Banking Kontakt untersuchen wollen (siehe Listing 2). Außerdem übergeben wir auch hier den Parameter bolReset, um gegebenenfalls die Kontakte neu einlesen zu können.
Public Function GetContactListWithFeature(strSegment As String, Optional bolReset As Boolean) As String Dim objContact As BACContact Dim strContacts As String Dim i As Integer Dim bolFeature As Boolean Dim objContacts As BACContacts Set objContacts = GetContacts(bolReset) For i = 0 To objContacts.Count - 1 Set objContact = objContacts.Item(i) If BACBPDSegmentVorhanden(objContact, strSegment) Then bolFeature = True Else bolFeature = False End If strContacts = strContacts & i & ";" & objContact.UserID & ";" _ & objContact.BankCode & ";" _ & IIf(bolFeature = True, "[x] ", "[-] ") _ & objContact("Contact") _ & "|" & objContact.BankCode _ & "|" & objContact.UserID & ";" Next i GetContactListWithFeature = strContacts End Function
Listing 2: Einlesen der Kontaktlisten für ein bestimmtes Feature
Hier legen wir erneut eine Variable des Typs BACContact namens objContact an, mit der wir die Kontakte aus objContacts (Datentyp BACContacts) durchlaufen. objContacts füllen wir mit der oben beschriebenen Funktion GetContacts.
Dann durchlaufen wir alle Elemente in einer For…Next-Schleife von 0 bis zur Anzahl der Elemente minus eins. Hier nutzen wir eine For…Next-Schleife statt einer For Each-Schleife, weil wir den Index des aktuellen Elements benötigen.
Innerhalb der Schleife weisen wir den aktuellen Kontakt der Variablen objContact zu. Dann rufen wir die Funktion BACPDSegmentVorhanden auf und übergeben dieser mit objContact den Kontakt und mit strSegment das zu untersuchende Segment. Liefert diese Funktion den Wert True zurück, stellen wir die Variable bolFeature auf den Wert True ein – anderenfalls auf False.
Nun stellen wir in der Variablen strContacts eine per Semikola separierte Liste mit verschiedenen Informationen zusammen. Diese enthält den Wert der Zählervariablen i, die Felder UserID und BankCode des Kontakts und einen aus diesen Informationen zusammengestellten Ausdruck. Das Ergebnis wird schließlich an die aufrufende Routine zurückgegeben und sieht beispielsweise wie folgt aus:
0;735160;70000997;[x] B+S Banksysteme Demobank FinTS3|70000997|735160;
Funktionen eines Banking Kontakts ermitteln
Die Funktion BACBPDSegmentVorhanden erwartet einen Verweis auf den zu untersuchenden Banking Kontakt sowie das zu prüfende Segment als Parameter (siehe Listing 3).
Public Function BACBPDSegmentVorhanden(objContact As BACContact, strSegment As String) As Boolean Dim intSegment As Integer intSegment = objContact.BankData.Segments.FindSegmentType(strSegment) If intSegment = -1 Then BACBPDSegmentVorhanden = True End If End Function
Listing 3: Prüfen, ob ein Banking Kontakt eine bestimmte Funktion aufweist
Woher wissen wir, welche Funktion welche Segmentzeichenkette verwendet? Zum Beispiel für das Abfragen von Umsätzen oder Kontoständen oder zum Durchführen von Überweisungen oder zum Anlegen von Lastschriften?
Dies erfahren wir aus der Datei FinTS Segmente.html, die wir nach dem Installieren der DDBAC-Komponenten etwa im Verzeichnis C:\Program Files (x86)\DataDesign\DDBACSDK vorfinden.
Hier können wir beispielsweise nach Lastschrift einreichen suchen.
Die Einträge mit HI… sind jeweils die Antworten, die mit HK… sind die zum Einreichen von Aufträgen.
Ende des frei verfügbaren Teil. Wenn Du mehr lesen möchtest, hole Dir ...
den kompletten Artikel im PDF-Format mit Beispieldatenbank
diesen und alle anderen Artikel mit dem Jahresabo