Gutscheine "nur einmal pro Person" + Bestell-E-Mail-Benachrichtigung
1) Gutscheincodes können jetzt im Adminbereich auf "nur einmal pro Person einlösbar" gestellt werden. Wird serverseitig durchgesetzt (neue Spalte orders.gutschein_code + Prüfung in functions/api/orders.js gegen die echte Bestelldatenbank, case-insensitiv nach E-Mail-Adresse) — kann also NICHT durch Löschen von localStorage/einen anderen Browser umgangen werden, anders als die bisherige rein clientseitige Rabattlogik. Stornierte Bestellungen zählen nicht als "schon benutzt". Ausführlich getestet: echter Browser-Checkout mit Einmal-Code funktioniert beim ersten Versuch, wird beim zweiten Versuch (gleiche E-Mail) korrekt mit klarer Fehlermeldung abgelehnt, mit anderer E-Mail weiterhin nutzbar. 2) Bestell-E-Mail-Benachrichtigung an [email protected]: recherchiert und vorbereitet (existierte vorher nirgends im Code). Läuft über Resend (kostenlos bis 3.000 E-Mails/Monat), im Hintergrund per context.waitUntil() nach jeder neuen Bestellung — verzögert nie die Antwort an die Kundschaft und kann eine Bestellung niemals zum Scheitern bringen, selbst wenn der Versand fehlschlägt (mit ungültigem Testschlüssel verifiziert: Bestellung bleibt trotzdem erfolgreich gespeichert). Wird automatisch aktiv, sobald ein RESEND_API_KEY als Secret hinterlegt wird. Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
0c1c8f075f
commit
af729ba571
@@ -9,6 +9,12 @@ export interface Gutschein {
|
||||
prozent?: number;
|
||||
betrag?: number;
|
||||
bis?: string; // ISO-Datum, optional
|
||||
/** true = der Code gilt pro Person (genauer: pro E-Mail-Adresse) nur einmal — wird beim
|
||||
* Abschicken der Bestellung serverseitig geprüft (siehe functions/api/orders.js, Spalte
|
||||
* "gutschein_code" in der orders-Tabelle), kann also NICHT durch Löschen von localStorage/
|
||||
* einen anderen Browser umgangen werden. Ohne dieses Flag (Standard) bleibt ein Code
|
||||
* unbegrenzt mehrfach nutzbar, wie bisher. */
|
||||
einmaligProPerson?: boolean;
|
||||
}
|
||||
|
||||
const gutscheine = (gutscheineRaw as { codes: Gutschein[] }).codes ?? [];
|
||||
|
||||
@@ -377,6 +377,7 @@ import { registriereAbgeschlosseneBestellung, treuebonusEinloesen } from "../../
|
||||
summe: currentTotal,
|
||||
treuebonusVerwendet: treuebonusDiscount() > 0,
|
||||
aboRabattVerwendet: aboDiscount(subtotal) > 0,
|
||||
gutscheinCode: appliedCoupon()?.code ?? null,
|
||||
};
|
||||
|
||||
try {
|
||||
|
||||
@@ -387,6 +387,7 @@ import { registriereAbgeschlosseneBestellung, treuebonusEinloesen } from "../../
|
||||
summe: currentTotal,
|
||||
treuebonusVerwendet: treuebonusDiscount() > 0,
|
||||
aboRabattVerwendet: aboDiscount(subtotal) > 0,
|
||||
gutscheinCode: appliedCoupon()?.code ?? null,
|
||||
};
|
||||
|
||||
try {
|
||||
|
||||
@@ -377,6 +377,7 @@ import { registriereAbgeschlosseneBestellung, treuebonusEinloesen } from "../../
|
||||
summe: currentTotal,
|
||||
treuebonusVerwendet: treuebonusDiscount() > 0,
|
||||
aboRabattVerwendet: aboDiscount(subtotal) > 0,
|
||||
gutscheinCode: appliedCoupon()?.code ?? null,
|
||||
};
|
||||
|
||||
try {
|
||||
|
||||
@@ -377,6 +377,7 @@ import { registriereAbgeschlosseneBestellung, treuebonusEinloesen } from "../../
|
||||
summe: currentTotal,
|
||||
treuebonusVerwendet: treuebonusDiscount() > 0,
|
||||
aboRabattVerwendet: aboDiscount(subtotal) > 0,
|
||||
gutscheinCode: appliedCoupon()?.code ?? null,
|
||||
};
|
||||
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user