Externer Widerruf Button für den Prestashop
86
Externer Widerruf-Button für einen PrestaShop. Ein kleiner Go-Dienst im Docker-Container,
den man unter einer eigenen Subdomain (z. B. https://return.example.com) mountet: Der Kunde
gibt seine Bestellnummer ein, bestätigt den Widerruf, und kpbounce verschickt eine
Empfangsbestätigung an die hinterlegte Kundenadresse sowie ein internes Ticket an den
Shop. Die eigentliche Rückabwicklung erfolgt weiterhin manuell im Backend.
kpbounce liest die Bestelldaten read-only aus der PrestaShop-DB, hält keine eigene
Persistenz und lauscht HTTP auf :8080 (TLS muss ein vorgelagerte Reverse-Proxy erledigen).
Alles Shop-Spezifische wird über Environment-Variablen gesetzt — im Image ist nichts
eincompiliert.
Alle Einstellungen und Secrets kommen ausschließlich aus der Umgebung.
KPBOUNCE_PORT — HTTP-Listen-Port (Default 8080)TZ — Zeitzone des Containers (Europe/Berlin setzen, sonst läuft das
Runtime-Image auf UTC und Bestätigungsmails nennen eine um Stunden falsche Uhrzeit)KPBOUNCE_BASE_URL — öffentliche Adresse des Tools (z. B. https://return.example.com)KPBOUNCE_SHOP_URL — Ziel des „Zum Shop"-Buttons auf der Ergebnisseite; leer = Full-Stall (z. B. https://example.com)KPBOUNCE_SHOP_NAME — Branding-Text in Seiten/Mails (optional, z. B. example.com)KPBOUNCE_FRIST_TAGE — Frist-Gate: Button erscheint, solange heute ≤ Versanddatum + N (Default 21)KPBOUNCE_DB_HOST — DB-HostKPBOUNCE_DB_PORT — DB-Port (Default 3306)KPBOUNCE_DB_USER — DB-User (nur SELECT-Rechte)KPBOUNCE_DB_PASS — DB-PasswortKPBOUNCE_DB_NAME — DatenbanknameKPBOUNCE_DB_PREFIX — Tabellen-Präfix (Default ps_)KPBOUNCE_SMTP_HOST — SMTP-HostKPBOUNCE_SMTP_PORT — SMTP-Port (passend zum TLS-Modus, siehe unten)KPBOUNCE_SMTP_USER — SMTP-User (leer zusammen mit _PASS = kein AUTH, nur für Dev-Catch-all)KPBOUNCE_SMTP_PASS — SMTP-PasswortKPBOUNCE_SMTP_FROM — Absenderadresse (z. B. [email protected])KPBOUNCE_SMTP_TLS — TLS-Modus (Default starttls)KPBOUNCE_NOTIFY_EMAIL — Empfänger des internen Tickets (z. B. [email protected])KPBOUNCE_SUPPORT_EMAIL — öffentlich gezeigte Fallback-Adresse (Default = KPBOUNCE_NOTIFY_EMAIL)KPBOUNCE_SMTP_TLS)| Wert | Aliase | Bedeutung | üblicher Port |
|---|---|---|---|
implicit | ssl, smtps, 465 | TLS ab dem ersten Byte (SMTPS) | 465 |
starttls | tls | Klartext-Verbindung, dann zwingend STARTTLS; bietet der Server es nicht an, wird abgebrochen | 587 |
none | off | keine Verschlüsselung, kein AUTH — nur Entwicklung (z. B. MailHog) | 1025 |
Die Werte sind case-insensitiv. Default ist starttls, damit eine vergessene Variable
niemals Zugangsdaten im Klartext verschickt. AUTH (PLAIN/LOGIN) läuft ausschließlich
über den bereits verschlüsselten Kanal.
Für einen normalen Submission-Server (z. B. mailcow) ist 465 + implicit die
empfohlene Kombination: kein Downgrade-Fenster, in dem ein MITM die STARTTLS-Ankündigung
strippen könnte.
Die Kundenbestätigung geht immer an die in der DB hinterlegte Original-E-Mail der Bestellung — dafür gibt es bewusst keine Variable und kein Eingebefeld.
| Route | Methode | Zweck |
|---|---|---|
/ | GET | Formular mit dem einen Feld „Bestellnummer" |
/pruefen | POST | Lookup → Übersicht, „nicht gefunden" oder „ältere Bestellung" |
/widerrufen | POST | Widerruf erklären → zwei Mails → Ergebnisseite |
/healthz | GET | 200 ok für Healthcheck/Reverse-Proxy |
Die Bestellnummer wird bei jedem Schritt frisch aus der DB geprüft; das Formular trägt zwischen den Seiten nur die Nummer selbst, nie ein Ergebnis. Alle POST-Routen sind mit einem CSRF-Token abgesichert (HMAC-signierter Ablaufzeitpunkt, prozesslokaler Schlüssel — ein Neustart entwertet offene Formulare, was einen erneuten Klick kostet und keinen gemeinsamen Schlüssel braucht).
Read-only, ein einziges SELECT über ps_orders + ps_customer. kpbounce schreibt
nie in die Shop-DB; der DB-User braucht nur SELECT.
Als Versanddatum dient ps_orders.delivery_date (0000-00-00 = noch nicht versandt).
Das ist am realen Schema verifiziert: Der Wert stimmt bei allen versandten Bestellungen
exakt mit dem ersten Übergang in einen Status mit shipped=1 aus ps_order_history
überein. ps_order_carrier.date_add ist nicht brauchbar — dort steht der Zeitpunkt der
Bestellung, nicht der des Versands.
Eine PrestaShop-reference ist kein Primärschlüssel: ein auf mehrere Shops/Carrier
aufgeteilter Warenkorb erzeugt mehrere ps_orders-Zeilen mit derselben Nummer. kpbounce
faltet sie zu einer Bestellung zusammen (frühestes date_add; als versandt gilt sie erst,
wenn jede Teillieferung raus ist — eine teilversandte Bestellung bleibt also in der
Frist). Bestellungen ohne zugehörigen Kundendatensatz (PrestaShop-Demodaten, gelöschte
Kunden) laufen bewusst in denselben Sackgassen-Pfad wie eine unbekannte Nummer: ohne
hinterlegte Adresse gibt es niemanden, dem man bestätigen könnte.
Runtime-Image: gcr.io/distroless/base-debian11, USER 80:80, EXPOSE 8080, CGO_ENABLED=0.
Im Betrieb läuft der Container im selben Compose-Netz wie PrestaShop + DB; ein Reverse-Proxy
terminiert TLS für die gewählte Subdomain und leitet auf Port 8080 weiter.
services:
kpbounce:
image: cssdata/kpbounce
restart: unless-stopped
environment:
TZ: Europe/Berlin
KPBOUNCE_BASE_URL: https://return.example.com
KPBOUNCE_SHOP_URL: https://example.com
KPBOUNCE_SHOP_NAME: example.com
KPBOUNCE_DB_HOST: db
KPBOUNCE_DB_USER: kpbounce_ro
KPBOUNCE_DB_PASS: ${KPBOUNCE_DB_PASS}
KPBOUNCE_DB_NAME: prestashop
KPBOUNCE_SMTP_HOST: mail.example.com
KPBOUNCE_SMTP_PORT: "465"
KPBOUNCE_SMTP_TLS: implicit
KPBOUNCE_SMTP_USER: [email protected]
KPBOUNCE_SMTP_PASS: ${KPBOUNCE_SMTP_PASS}
KPBOUNCE_SMTP_FROM: [email protected]
KPBOUNCE_NOTIFY_EMAIL: [email protected]
Der passende DB-User ist ausdrücklich nur lesend:
CREATE USER 'kpbounce_ro'@'%' IDENTIFIED BY '…';
GRANT SELECT ON prestashop.* TO 'kpbounce_ro'@'%';
Content type
Image
Digest
sha256:00b7a2de8…
Size
14.6 MB
Last updated
about 2 months ago
docker pull cssdata/kpbounce