SEPA Direct Debit: Privacy and Security
Which data SEPA Direct Debit stores, how the IBAN is encrypted, who can fetch the mandate PDF, what happens on deletion, and which SEPA duties the plugin does not take over.
SEPA Direct Debit: Privacy and Security
Live Demo: Try this and other plugins live — no installation, no risk: demo.markus-michalski.net
This page describes what the plugin does technically. It is not legal advice. You assess retention periods and information and deletion obligations for your shop yourself.
Stored data
The plugin stores one record per mandate in the table mmd_sepa_mandate:
| Field | Content | Stored as |
|---|---|---|
| Customer | Customer UUID | Plain text |
| Mandate reference | Unique reference | Plain text |
| IBAN | The customer's bank account | encrypted |
| BIC | Optional, as entered | Plain text |
| Account holder | Name as entered | Plain text |
| Status | active, revoked or expired |
Plain text |
| Timestamps | Signed, revoked, created, updated | Plain text |
The plugin stores no other data, such as payment or credit information. It also sends no data to external services: the code contains no outgoing requests, and the PDF is generated locally with loading of remote resources disabled.
IBAN encryption
- Method: AES-256-GCM with a random initialization vector per encryption. Tampered data is detected and rejected on decryption.
- Key: It is derived with HKDF-SHA256 from the
APP_SECRETof your Shopware installation. The plugin stores no key of its own. - Timing: The IBAN is passed on encrypted between the checkout validation and the creation of the mandate, and is never stored in plain text in the database.
- Decryption: Only when needed, namely for the mandate PDF and for the masked display (
DE89****3000).
If the
APP_SECRETchanges, already stored IBANs can no longer be decrypted. Mandate PDFs and the masked IBAN at checkout and in the customer account then fail with an error. There is no re-encryption function. Back up theAPP_SECRETand keep it unchanged when you move the shop. See also Troubleshooting.
Where the full IBAN is visible
- Mandate PDF: It contains the full IBAN. Whoever is the logged-in owner or knows the order's
deepLinkCodecan download it. The response is delivered withCache-Control: no-store. - Admin: You do not see the IBAN here. Only the PDF from the admin contains it, retrievable by administrators.
- Storefront and checkout: Only the masked IBAN is shown.
- Developer API:
getDecryptedIban()returns the IBAN to code that calls the service, see Developer API.
Access and abuse protection
- Customer account routes require a login, and forms carry a CSRF token.
- The PDF download via an order checks the owner or
deepLinkCode(constant-time comparison). Failed attempts are logged with order ID, customer and IP address. - The
validate-ibanroute is limited to 10 requests per minute per IP. A hash of the IP address is kept in the cache for that. - When a mandate is created, a log entry with mandate ID, customer ID and mandate reference is written, on revocation one with the mandate ID. The IBAN is not in the log.
Deletion and retention
- Revocation: A revoked mandate remains as a record with status
revokedand a revocation timestamp. The plugin does not delete it. - No retention logic: The plugin has no retention period and does not delete or anonymize anything automatically.
- No change history: There is no history table. Per mandate only the current state exists, with signing and revocation timestamps.
- Customer deleted: If you delete a customer in Shopware, their mandates are deleted with them (foreign key with
ON DELETE CASCADE). - Plugin uninstalled: Without keeping user data the table is dropped completely, see Installation.
What the plugin does not take over for SEPA
| Topic | Status |
|---|---|
| Collecting the direct debit | Not included. There is no export of a SEPA file (pain.008) and no bank connection. |
| Pre-notification | Not included. The plugin sends no e-mails to customers. |
| Mandate expiry | Not included. The plugin monitors no usage periods and never sets the status expired. |
| Chargebacks | Not included. The plugin knows no chargebacks and does not change the order's payment status. |
| Sequence type (first or recurring) | Not included. The PDF generally states "One-off payment / Recurring payments". |
What the plugin does provide: a unique mandate reference (unique across all mandates in the database), capturing the consent with a timestamp, validation of IBAN, BIC and account holder, the configurable mandate text, a mandate PDF, and revocation with a timestamp.