Live Demo: Teste dieses und weitere Plugins live — ohne Installation, ohne Risiko: demo.markus-michalski.net
Mmd\SepaPayment\Payment\SepaPaymentHandler erweitert AbstractPaymentHandler und ist als shopware.payment.method registriert. Die Zahlung ist synchron, es gibt keine Weiterleitung. Der Handler unterstützt weder Erstattungen noch wiederkehrende Zahlungen (supports() liefert immer false).
Ablauf in validate():
sepaUseExistingMandate=true muss ein aktives Mandat des Kunden existieren.sepaIban, sepaAccountHolder und sepaMandateAgreement=true vorhanden und die IBAN gültig sein. Die IBAN wird danach verschlüsselt in einem Struct an pay() übergeben.Ablauf in pay():
MandateCreatedEvent aus.| Klasse | Aufgabe |
|---|---|
MmdSepaPayment |
Plugin-Klasse; legt die Zahlungsart an, (de)aktiviert sie und entfernt bei der Deinstallation ohne Datenerhalt Tabelle und Konfiguration |
Service\SepaMandateService |
Anlegen, Ändern, Widerrufen und Lesen von Mandaten |
Service\EncryptionService |
AES-256-GCM-Verschlüsselung der IBAN, Schlüssel per HKDF-SHA256 aus APP_SECRET |
Service\IbanValidator |
Normalisierung, Format-, Längen- und Modulo-97-Prüfung, Maskierung |
Service\MandateReferenceGenerator |
Erzeugt {Präfix}{JJJJMMTT}-{8 Zeichen} |
Service\MandatePdfGenerator |
Rendert das Twig-Template documents/sepa-mandate.html.twig mit dompdf zu einem A4-PDF |
Service\PaymentMethodInstaller |
Legt die Zahlungsart payment_sepa_direct_debit an |
Subscriber\CheckoutSubscriber |
Stellt auf der Bestätigungs- und der Abschlussseite des Checkouts das aktive Mandat samt maskierter IBAN als Seitenerweiterung mmdSepaMandate bereit |
Storefront\Controller\SepaMandateController |
Kundenkonto-Seite, Anlegen, Widerruf, IBAN-Prüfung, PDF-Downloads |
Controller\Api\SepaMandateController |
Admin-Routen für PDF, Widerruf und maskierte IBAN |
Event\MandateCreatedEvent |
Event für andere Plugins |
Die Services sind über die Interfaces in Service\Contract austauschbar, zum Beispiel SepaMandateServiceInterface, IbanValidatorInterface und EncryptionServiceInterface.
Tabelle mmd_sepa_mandate (Entität mmd_sepa_mandate):
| Spalte | Typ | Hinweis |
|---|---|---|
id |
BINARY(16) | Primärschlüssel |
customer_id |
BINARY(16) | Fremdschlüssel auf customer.id, ON DELETE CASCADE |
mandate_reference |
VARCHAR(255) | Eindeutig |
iban |
LONGTEXT | Base64 aus Initialisierungsvektor, Auth-Tag und verschlüsselten Daten |
bic |
VARCHAR(11) | Optional, unverschlüsselt |
account_holder |
VARCHAR(255) | |
status |
VARCHAR(50) | active, revoked, expired; Standard active |
signed_at |
DATETIME(3) | |
revoked_at |
DATETIME(3) | Optional |
created_at, updated_at |
DATETIME(3) |
Indizes: eindeutig auf mandate_reference, normal auf status, auf customer_id und auf (customer_id, status). Die zweite Migration entfernt die ursprüngliche Eindeutigkeit auf customer_id. Mehrere Datensätze pro Kunde sind damit möglich, dass es höchstens ein aktives Mandat gibt, stellt die Anwendungslogik sicher, nicht die Datenbank.
| Was | Wo |
|---|---|
| Zahlungsart | payment_method, technischer Name payment_sepa_direct_debit, afterOrderEnabled aus, Position 10 |
| Konfiguration | system_config, Schlüssel MmdSepaPayment.config.* |
| Storefront-Texte | Snippet-Dateien mmd-sepa-payment.de-DE.json und mmd-sepa-payment.en-GB.json, Namensraum mmdSepaPayment |
| Admin-Modul | mmd-sepa-mandate, Menüeintrag unter "Bestellungen" |
payment-method.html.twig (Felder im Checkout), die Seitenleiste des Kundenkontos, die Bestelldetails und die Bestellabschluss-Details.SepaPaymentFieldsPlugin formatiert IBAN und BIC, prüft die IBAN im Browser und übergibt die Felder an das Bestellformular.mmd-sepa-mandate mit PDF-Button; der Widerruf in der Detailseite speichert Status und Zeitpunkt über das Repository.bcmod() aus der PHP-Erweiterung bcmath.validate-iban liegt im Anwendungs-Cache (cache.app).