=== SlotPress ===
Contributors: herzigkev
Tags: booking, appointment, termin, calendar, reservierung
Requires at least: 5.8
Tested up to: 6.8
Stable tag: 3.0.2
Requires PHP: 7.4
License: GPL-2.0-or-later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Professionelles Terminbuchungssystem – Kunden buchen Sitzungen direkt auf Ihrer Website, mit E-Mail-Bestätigung per Double Opt-In. Inklusive Yoast SEO Schema-Integration (Service, ReserveAction) und llms.txt-Unterstützung für optimale SEO und GEO.

== Beschreibung ==

**SlotPress** ermöglicht Ihren Kunden, Termine bequem online zu buchen. Keine monatlichen Gebühren – bezahlt wird wahlweise vor Ort, per Vorauskasse (Banküberweisung) oder optional online über Stripe Checkout.

**Das Plugin ist speziell für Einzelpersonen und kleine Betriebe konzipiert**, die ihre Terminverwaltung einfach und zuverlässig abwickeln möchten.

= Funktionen =

* **Sitzungstypen** – Legen Sie verschiedene Angebote als eigene Sitzungstypen an, mit Name, Beschreibung, Dauer und Preis
* **Terminslots** – Verwalten Sie Verfügbarkeiten flexibel: einzeln oder automatisch für ganze Tage per Zeitraster (optional mit Mittagspause)
* **Mehrstufiges Buchungsformular** – Geführter Buchungsprozess in 4 Schritten: Sitzung → Datum → Uhrzeit → Kontaktdaten; optionale Zusatzfelder Telefon, Bemerkung und Rechnungsanschrift
* **Double Opt-In** – Buchungen werden erst verbindlich, wenn der Kunde den Link in der E-Mail öffnet und auf der Bestätigungsseite per Button bestätigt (Schutz vor E-Mail-Scannern)
* **Buchungsmodi** – Standard (sofort verbindlich), Auf Bestätigung (manuelle Freigabe) oder Zahlung vorab
* **Stripe Checkout** – Optionale Online-Zahlung (Test- und Live-Modus, Webhook mit Signaturprüfung); abgebrochene Checkouts geben den Slot nach 45 Minuten wieder frei
* **Vorauskasse** – Zahlungsaufforderung mit IBAN, Verwendungszweck und Zahlungsfrist; Zahlungseingang wird im Backend bestätigt
* **Rechnung** – Österreichkonforme PDF-Rechnung (§ 11 UStG, Kleinunternehmer oder Normalbesteuerung) als Anhang zur Buchungsbestätigung, fortlaufende Nummerierung, Archivierung im Upload-Ordner
* **Automatische E-Mails** – DOI-Link, Buchungsbestätigung, Eingangsbestätigung, Zahlungsaufforderung und Admin-Benachrichtigungen; Texte, Betreffzeilen, Absender, Logo, Farben und Schriften unter Einstellungen → E-Mails konfigurierbar
* **Erinnerungen** – Optionale Erinnerungs-E-Mail X Stunden vor dem Termin
* **iCal-Anhang** – Kalendereinladung (.ics) in der Buchungsbestätigung
* **E-Mail-Log** – Protokoll aller ausgehenden E-Mails mit Status und Fehlergrund
* **Du/Sie-Anrede** – Anrede für Formular und Kunden-E-Mails wählbar oder automatisch aus der WordPress-Sprache
* **Admin-Bereich** – Dashboard und Buchungsübersicht mit Suche, Statusfilter, Freigabe, Zahlungsbestätigung, Stornierung und Rechnungs-Download
* **Design-Anpassung** – Skins (Standard, Bold, Dark, Soft, Glass, Neon), Akzentfarbe, Button-Farbe und Eckenradius im Backend frei einstellbar
* **Vorselektion per Shortcode** – Direkt zur richtigen Sitzung springen mit [[termin_buchung session="mein-angebot"]]
* **reCAPTCHA v3** – Optionaler Spam-Schutz, einfach per API-Schlüssel aktivierbar
* **Datenschutzfreundlich** – Kein Tracking, alle Skripte (inkl. Datepicker) lokal eingebunden. Externe Dienste nur, wenn Sie sie aktivieren: Google reCAPTCHA (optional) und Stripe (optional)

= SEO & GEO =

* **schema.org/Service** – Sitzungstypen werden auf Buchungsseiten automatisch als strukturierte Daten ausgegeben (Name, Beschreibung, Preis, potentialAction: ReserveAction); bei aktiver Vorselektion per Shortcode nur der jeweilige Service
* **Yoast SEO Integration** – Service-Nodes werden nahtlos in den Yoast-@graph eingehängt; kein separater Script-Tag; WebPage-Node auf Buchungsseiten wird automatisch um ReserveAction ergänzt; termin_session-CPT wird aus der Yoast-Sitemap ausgeschlossen
* **Standalone-Fallback** – Ist Yoast SEO nicht installiert, gibt SlotPress ein eigenes JSON-LD-Script im &lt;head&gt; aus
* **llms.txt (GEO)** – SlotPress stellt immer eine eigene /llms.txt-Route bereit mit allen Sitzungstypen, direkten Buchungslinks und aktuellen Seiten; unabhängig von Yoast, da Sitzungstypen intern (nicht-öffentlich) sind

== Installation ==

1. Plugin-ZIP über **Plugins → Installieren → Plugin hochladen** installieren
2. Plugin aktivieren
3. Im Menü **SlotPress → Sitzungstypen** die bei der Aktivierung angelegten Beispiel-Sitzungstypen prüfen und anpassen (Name, Dauer, Preis)
4. Unter **SlotPress → Terminslots** Slots für die gewünschten Tage und Uhrzeiten erstellen
5. Shortcode [[termin_buchung]] auf einer beliebigen Seite einfügen
6. Unter **SlotPress → Einstellungen** Buchungsmodus, Admin-E-Mail, Anrede und Design anpassen
7. Optional: Unter **SlotPress → Einstellungen → Zahlung** Stripe (API-Key **und** Webhook Signing Secret) bzw. Vorauskasse und Rechnung einrichten

== Verwendung ==

= Shortcodes =

**Vollständiges Buchungsformular** (alle Sitzungstypen zur Auswahl):
[[termin_buchung]]

**Formular mit vorgewählter Sitzung** (überspringt Schritt 1):
[[termin_buchung session="mein-angebot"]]

Den Slug finden Sie unter **SlotPress → Sitzungstypen** im Slug-Feld des jeweiligen Eintrags.

**DOI-Bestätigungsseite** (wird automatisch angelegt, normalerweise nicht manuell benötigt):
[[termin_doi_result]]

= Terminslots anlegen =

1. **SlotPress → Terminslots → Slots generieren**
2. Sitzungstyp wählen
3. Datum auswählen (Kalender)
4. Von / Bis Uhrzeit eingeben (z. B. 09:00 – 17:00)
5. Optional: „Mittagspause einplanen“ anhaken und Pausenzeit definieren (z. B. 12:00 – 13:00)
6. Maximale Buchungen pro Slot festlegen
7. **Slots speichern** – das Plugin erstellt automatisch alle Slots entsprechend der Sitzungsdauer (bereits vorhandene werden übersprungen)

Einzelne Zusatztermine legen Sie im Formular **Einzelnen Slot hinzufügen** auf derselben Seite an.

= E-Mail-Bestätigung (Double Opt-In) =

Nach dem Absenden des Formulars:
1. Der Slot wird sofort reserviert, der Kunde erhält einen Bestätigungslink per E-Mail (gültig 24 Stunden)
2. Der Link öffnet eine Bestätigungsseite; erst der Klick auf den Button dort bestätigt die Buchung (je nach Buchungsmodus: bestätigt, wartet auf Freigabe oder weiter zur Zahlung)
3. Kunde und Admin werden per E-Mail informiert
4. Abgelaufene, nicht bestätigte Buchungen werden automatisch bereinigt und der Slot freigegeben

= Status-Übersicht =

| Status | Bedeutung |
| --- | --- |
| Ausstehend | Buchung wartet auf E-Mail-Bestätigung des Kunden |
| Wartet auf Freigabe | Kunde hat bestätigt, Admin-Freigabe erforderlich (Modus „Auf Bestätigung“) |
| Vorauskasse ausstehend | Zahlungsaufforderung versendet, Zahlungseingang noch nicht bestätigt |
| Zahlung ausstehend | Kunde wurde zu Stripe Checkout weitergeleitet, Zahlung noch offen (Slot wird nach 45 Min. freigegeben) |
| Bestätigt | Buchung verbindlich |
| Storniert | Vom Admin storniert oder abgelehnt |
| Abgelaufen | Bestätigungslink nicht rechtzeitig genutzt |

= Einstellungen =

Unter **SlotPress → Einstellungen** können Sie konfigurieren:

* **Buchungsprozess** – Buchungsmodus und Zusatzfelder (Telefon, Bemerkung, Rechnungsanschrift)
* **Allgemein** – Admin-E-Mail, Formular-Titel, Du/Sie-Anrede
* **E-Mails** – Absender, Texte, Betreffzeilen, Erinnerung, iCal, E-Mail-Design
* **Sicherheit** – reCAPTCHA v3 Site Key und Secret Key (optional)
* **Zahlung** – Stripe (API-Keys, Webhook Signing Secret), Vorauskasse, Rechnungseinstellungen
* **Design & Farben** – Skin, Akzentfarbe, Button-Farbe (oder „wie Akzentfarbe“), Button-Textfarbe, Eckenradius

Geheime Schlüssel (reCAPTCHA Secret, Stripe Secret Keys, Webhook Secret) werden nach dem Speichern nicht mehr im Formular angezeigt; ein leeres Feld lässt den gespeicherten Wert unverändert.

= Stripe-Webhook =

Bei aktivierten Stripe-Zahlungen ist der Webhook Pflicht. Im Stripe-Dashboard die auf der Einstellungsseite angezeigte URL als Endpoint anlegen und die Events `checkout.session.completed`, `checkout.session.async_payment_succeeded` und `checkout.session.expired` abonnieren. Das Signing Secret (`whsec_…`) muss eingetragen werden – ohne Secret werden alle Webhooks abgelehnt.

= Rechnungsarchiv =

PDF-Rechnungen werden unter `wp-content/uploads/slotpress-invoices/` archiviert (Aufbewahrungspflicht nach BAO: 7 Jahre). Unter Apache schützt eine `.htaccess` den Ordner; auf Nginx muss der Zugriff in der Server-Konfiguration gesperrt werden:

`location ^~ /wp-content/uploads/slotpress-invoices/ { deny all; }`

== Häufige Fragen ==

= Der Bestätigungslink in der E-Mail landet im Spam. Was kann ich tun? =

Das liegt am E-Mail-Versand über den Webserver (PHP `mail()`). Empfohlen: ein SMTP-Plugin wie **WP Mail SMTP** installieren und einen echten E-Mail-Provider (z. B. SendGrid, Mailgun, Gmail SMTP) einrichten. Das verbessert die Zustellbarkeit erheblich.

= Wie kann ich die Sitzungstypen anpassen? =

Sitzungstypen sind eigene Beitragstypen unter **SlotPress → Sitzungstypen**. Dort können Sie Name, Beschreibung, Preis (`_termin_price`) und Dauer in Minuten (`_termin_duration`) direkt bearbeiten.

= Kann ich mehrere Buchungsformulare auf verschiedenen Seiten einbinden? =

Ja. Der Shortcode [[termin_buchung session="slug"]] lässt sich mehrfach verwenden, auch mit unterschiedlichen Sitzungstypen vorgewählt.

= Was passiert mit Slots, für die eine Buchung storniert wurde? =

Stornierte Buchungen geben den Slot automatisch wieder frei (`current_bookings` wird dekrementiert), sodass er erneut buchbar ist.

= Wie oft werden abgelaufene Buchungen bereinigt? =

Automatisch zweimal täglich per WordPress-Cron. Sie können die Bereinigung auch manuell anstoßen, indem Sie das Plugin deaktivieren und reaktivieren (der Cron wird dabei neu geplant).

= Das Buchungsformular sieht auf meiner Seite anders aus als erwartet. =

Das Plugin verwendet einen ID-Selektor (`#termin-booking`) mit hoher CSS-Spezifität, um Theme-Overrides zu verhindern. Falls trotzdem Abweichungen auftreten, können Sie die Farben unter **SlotPress → Einstellungen → Design & Farben** anpassen.

= Kann ich das Plugin mit Elementor verwenden? =

Ja. SlotPress bringt ein eigenes Elementor-Widget mit. Alternativ fügen Sie den Shortcode [[termin_buchung]] in ein Elementor-Shortcode-Widget ein. Das Design passt sich an die eingestellten Farben an und überschreibt Elementor-Button-Styles automatisch.

= Wo finde ich die vollständige Dokumentation? =

Im WordPress-Backend unter **SlotPress → Handbuch** (nur für Administratoren sichtbar).

== Anforderungen ==

* WordPress 5.8 oder höher
* PHP 7.4 oder höher
* MySQL 5.7 / MariaDB 10.3 oder höher
* `admin-ajax.php` muss für Besucher erreichbar sein (Buchungsformular und Stripe-Webhook)
* Für Stripe: HTTPS

== Changelog ==

= 3.0.2 =
* Neu: Updates kommen direkt von herzigkev.in und erscheinen wie gewohnt im WordPress-Backend. Weder die Abfrage noch der Download nennen die Adresse Ihrer Website.

= 3.0.1 =
* Fix: Unterseiten (E-Mail-Protokoll, Feste Termine, Kategorien, Warteliste …) zeigten „Du bist leider nicht berechtigt, auf diese Seite zuzugreifen“.
* Fix: Speichern einer Leistung überschrieb eigene Seitentitel der verknüpften Seite – der Titel ändert sich jetzt nur noch bei einer echten Umbenennung und nur, wenn die Seite bisher gleich hieß.

= 3.0.0 =
* Neu: Arbeitszeiten-basierte Verfügbarkeit (Wochenpläne, Ausnahmen/Urlaub, Feiertage AT/DE/CH, Puffer, Mindest-/Maximalvorlauf, Slot-Raster, Tages-/Wochen-/Kundenlimits, Gültigkeitszeitraum). Feste Slots funktionieren weiter.
* Neu: Mitarbeiter (eigene Zeiten, Preise, Foto, Login mit eigenem Kalender), Standorte, Ressourcen, automatische Zuteilung (Round Robin / geringste Auslastung).
* Neu: Kategorien, Varianten, Zusatzleistungen, Gruppentermine/Kurse, Warteliste.
* Neu: Google Calendar und Outlook (2-Wege), Zoom/Google Meet/Teams-Links, Terminart vor Ort/Online/Telefon/Hausbesuch.
* Neu: Selfservice (Stornieren/Umbuchen mit Fristen und Gebühren, Stripe-Erstattung, Gutschrift), Kundenkonto per Magic Link, Wieder buchen.
* Neu: Formular-Builder mit Bedingungslogik, Datei-Upload, Einwilligungen (inkl. Art. 9 DSGVO), Anamnese vor dem Termin, Verschlüsselung sensibler Felder.
* Neu: Mehrere Erinnerungen, Follow-ups (Danke, Bewertung, Wieder buchen), Geburtstags-/Reaktivierungsmails, Vorlagen je Leistung/Mitarbeiter/Sprache.
* Neu: Anzahlungen (Prozent/fix).
* Neu: Buchungs-App mit Monats-, Wochen- und Listenansicht, „Schnellster Termin“, mehrere Formulare pro Seite, Gutenberg-Block, Share-Link und iframe-Einbettung, hCaptcha/Friendly Captcha, WPML/Polylang, Barrierefreiheit (WCAG 2.2 AA).
* Neu: Admin-Kalender mit Drag & Drop, Mitarbeiter-Spalten, manuelle/telefonische Buchungen, Abwesenheiten.
* Neu: Leistungsseiten – verknüpfte Seiten, Titel-Sync, Shortcodes [termin_leistung] / [termin_leistung_name] u. a. und Elementor Dynamic Tags.
* Neu: Funktionen ein-/ausschalten mit Grundmodi (Einfach, Praxis, Team/Studio, Alles) – ausgeschaltete Funktionen verschwinden aus Menü, Einstellungen und Buchungsformular, Daten bleiben erhalten.
* Neu: Übersichtlicheres Admin – 8 Hauptmenüpunkte mit Reitern je Bereich, Einstellungen mit gruppierter Seitennavigation, neue Übersicht mit „Heute“, „Zu erledigen“ und Erste-Schritte-Checkliste.
* Bestehende Buchungen, Slots und Einstellungen werden beim Update automatisch übernommen.

= 2.1.0 =
* Neu: Einstellung „Anrede“ (Einstellungen → Allgemein) – Du, Sie oder automatisch aus der WordPress-Sprache. Gilt für Buchungsformular, Bestätigungsseiten und Standardtexte der Kunden-E-Mails.
* Entfernt: Peak-Publisher-Update-Bootstrap und Pro-Lizenzprüfung – alle Funktionen (Bestätigungsmodus, Stripe, Vorauskasse, Rechnung, E-Mail-Design, E-Mail-Log, Skins, Zusatzfelder) sind ohne Lizenz verfügbar.
* Neu: Optionales Feld „Rechnungsanschrift“ im Buchungsformular (Einstellungen → Buchungsprozess); Anzeige in der Buchungsübersicht.
* Neu: Archivierte Rechnungen in der Buchungsübersicht herunterladbar; Rechnungsnummer wird angezeigt.
* Neu: Formular „Einzelnen Slot hinzufügen“ im Slot-Manager (doppelte Slots werden übersprungen).
* Sicherheit: Stripe Webhook Signing Secret ist bei aktiviertem Stripe Pflicht – Warnung im Zahlung-Tab und Hinweis beim Speichern, wenn es fehlt.
* Sicherheit: Geheime Schlüssel (reCAPTCHA Secret, Stripe Secret Keys, Webhook Secret) werden nicht mehr ins HTML ausgegeben (nur „•••• 1a2b“), leeres Feld = unverändert, „Schlüssel entfernen“ zum Löschen; Speicherung ohne Autoload.
* Sicherheit: Admin-Hinweise werden pro Benutzer gespeichert und nur noch bei der Ausgabe escaped (kein doppeltes Escaping mehr).
* Fix: Mittagspause wurde beim Slot-Generieren immer angewendet (12:00–13:00), auch ohne Häkchen.
* Fix: Filter, Reset und Aktions-Links der Buchungsübersicht sowie Buchungs-Links im E-Mail-Log zeigten auf das Dashboard statt auf die Buchungsliste.
* Fix: Flatpickr wird lokal (4.6.13) statt unversioniert vom CDN geladen – und nur noch im Slot-Manager.
* Fix: Button-Farbe lässt sich wieder auf „wie Akzentfarbe“ (leer) speichern.
* Fix: Radio-Karten in den Einstellungen beeinflussen nur noch die eigene Gruppe.
* Fix: „Log leeren“ im E-Mail-Log per Redirect (kein erneutes Absenden beim Neuladen).
* Fix: Doppelte JavaScript-Handler im Slot-Manager entfernt; Pflichtfeld „Datum“ wird beim Absenden geprüft.
* Fix: Musterrechnung verwendet Präfix und Jahr gemäß WordPress-Zeitzone.
* Barrierefreiheit: Einstellungs-Tabs mit ARIA-Rollen und Pfeiltasten-Navigation; ausgegraute Bereiche bleiben per Tastatur und Maus bedienbar; Labels für alle Rechnungsfelder; Shortcodes per Tastatur kopierbar.
* Fix: Shortcode kopieren funktioniert auch ohne HTTPS (Fallback).
* Doku: README und Handbuch aktualisiert (Menü „SlotPress“, Zahlungswege, Statusliste, Webhook-Events, Rechnungsarchiv/Nginx, DOI-Bestätigung per Button).

= 2.0.0 =
* Initial release of Pro
