Bitte beachte, dass sich diese Dokumentation auf die neuste Version dieser Erweiterung bezieht. Wenn eine ältere Version eingesetzt wird, kann diese abweichen. Die jeweils passende Dokumentation befindet sich im Dokumentation-Verzeichnis der Erweiterung.
Abonnements
Mit dem Shop kannst Du ein Abonnementsystem für Frontend-Nutzer über Stripe bereitstellen. Dazu musst Du das Plugin „Subscription-Table“ auf Deiner Website integrieren. Es bietet Ihnen eine Liste der verfügbaren Abonnementprodukte, die in Stripe konfiguriert werden muss, und übernimmt die Weiterleitung, wenn der Nutzer ein neues Abonnement startet.
Optional kannst Du die Stripe-Abonnementpreise in die regulären Produktdatensätze einfügen, sodass diese Produkte mit einem Abonnement-Button versehen werden.
Abonnements Konfigurieren
- Loggen Sie sich auf dashboard.stripe.com ein und wechseln Sie zum Abschnitt Products. Hier müssen Sie für jedes Abonnement, das Sie anbieten, ein Produkt erstellen - zum Beispiel Basic-Plan und Premium-Plan. Produkte müssen separat in der Sandbox und im Live-Modus erstellt werden, wobei man Produkte aus der Sandbox in den Live-Modus kopieren kann. Diese Produkte benötigen die folgenden Daten:
- Name: Produktnamen sind für Kunden an der Kasse, auf Quittungen, Rechnungen und im Kundenportal sichtbar.
- Beschreibung: Produktbeschreibungen erscheinen an der Kasse und im Kundenportal.
- Fügen Sie einen Preis ein und stellen Sie sicher, dass wiederkehrende Zahlung ausgewählt ist.
- Fügen Sie dem Produkt ein Meta-Tag mit dem Schlüssel
category
hinzu. Produkte können nach dem Wert dieses Tags im PluginSubscriptionTable
gefiltert werden (siehe Abschnitt "Tabelle der Abonnementprodukte anzeigen"). - Fügen Sie dem Produkt ein Meta-Tag mit dem Schlüssel
usergroups
hinzu. Setzen Sie den Wert dieses Tags auf eine durch Kommata getrennte Liste von Frontends-Nutzergruppen. Diese Nutzergruppen werden automatisch zu den Frontendnutzern hinzugefügt, die ein Abonnement erwerben, das dieses Produkt enthält. Wenn ein Abonnement endet, werden diese Benutzergruppen automatisch aus dem Frontendbenutzer-Datensatz entfernt. Die Frontend-Benutzer und Frontend-Benutzergruppen müssen im gleichen Datensatz-Container sein. - Füge einen optionalen Meta-Tag mit dem Schlüssel
trial_period_days
hinzu, der die Anzahl der Tage für die Testphase des ersten Abonnements eines Benutzers definiert. Dies wird nur verwendet, wenn das Felde_users.tx_shop_stripe_trial_period_end
leer ist. Es müssen mindestens 2 Tage verwendet werden. - Füge einen optionalen Meta-Tag mit dem Schlüssel
sorting_index
hinzu, der die Sortierung der Produkte in der Anzeige ändert. - Konfigurieren Sie Webhooks (siehe Abschnitt "Konfiguration der Stripe-Webhooks").
Attention:
Bei der Verwendung von Stripe-Kunden benötigt der Frontend-Benutzer in seinem Benutzerdatensatz den kurzen Iso-Code seines Landes (z.B.: DE)!
Einrichtungsgebühr
Wenn für Dein Abonnement eine Einrichtungsgebühr anfällt, erstelle hierfür einfach ein separates Stripe-Produkt. Dieses Produkt enthält lediglich den Namen, der im Checkout und auf der Rechnung angezeigt wird, sowie einen einmaligen Preis. Kopiere die Preis-ID (price_xyz…
) und füge diese in den Metadaten des Abonnementprodukts mit dem Schlüssel setup_fee
ein.
Durch diese Verknüpfung fügt die Shop-Erweiterung diesen Preis bei einem neuen Abonnement im Checkout hinzu. Wenn Du in der Abonnementtabelle einen zusätzlichen Hinweis zur Einrichtungsgebühr benötigst, verwende einfach den Metadatenschlüssel setup_fee_description
mit dem ensprechenden Text.
Meta-Feld Übersicht
Feld | Typ | Beschreibung |
---|---|---|
category | string | Kategorisierungs Identifier. |
usergroups | int, comma-separated | Eine oder mehrere Frontend-Benutzergruppen-UIDs. Diese werden beim Abonnement dem Frontend-Benutzer zugeordnet. |
trial_period_days | int | Anzahl der Tage in der Testphase. 0 bedeutet, dass keine Testphase verfügbar ist. |
sorting_index | int | Sortierindexnummer zum Ändern der Anzeigereihenfolge der Produkte im Frontend. |
css_class | string | Eine oder mehrere CSS-Klassen getrennt durch ein Leerzeichen für die Frontend-Darstellung. |
setup_fee | string | Dies ist eine Stripe-Preis-ID, die die Bezeichnung und den Wert der Einrichtungsgebühr enthält. |
setup_fe_description | string | Dies ist ein optionaler Hinweistext für die Einrichtungsgebühr in der Abonnementtabelle. |
Steuern
Wenn du Steuern verwenden möchtest, kannst du das „Stripe Tax“-Add-on nutzen oder Steuerdatensätze mit dieser Shop-Erweiterung anlegen. Wenn du Steuerdatensätze einsetzt, musst du eine Stripe-Tax-ID zuweisen und die Checkbox Standard-Stripe-Steuersatz aktivieren. Ist das erledigt, prüft der Abonnement-Link den Ländercode des Nutzers (dazu muss fe_users.country
ausschließlich den zweistelligen ISO-Ländercode enthalten – EXT:modules stellt ein Frontend-Benutzermanagement mit diesen Codes bereit) und lädt das entsprechende Steuerdatensatz-Overlay sowie die zugewiesene Stripe-Tax-ID. Wenn du keine Steuerkonfiguration benötigst, weil du Stripe Tax nutzt, markiere einfach keinen Datensatz als Standard-Stripe-Steuersatz.
Hinweis:
Beim Anlegen einer Steuer in Stripe musst du entscheiden, ob die Steuer bereits in deinen Produktpreisen enthalten ist oder nicht – das bedeutet zum Beispiel: Arbeitest du mit Nettopreisen in deinen Produkten, musst du in deiner Steuerdefinition bei Stripe exclusive auswählen!
Konfiguration der Stripe-Webhooks
Ein Webhook für den Empfang von Stripe-Events ist grundsätzlich erforderlich, um die mit einem Stripe-Produkt verknüpften Benutzergruppen automatisch zuzuweisen oder zu entfernen und beispielsweise Abowechsel korrekt abzuwickeln.
Um die Konfiguration zu vereinfachen, kann eine Kurz-URL für die Seite mit einem SubscriptionTable
- oder Subscriptions
-Plugin eingerichtet werden.
ShopSubscriptionsPlugin:
type: Extbase
limitToPages:
- {page uid with the Subscriptions plugin}
extension: ShopPro
plugin: Subscriptions
routes:
- routePath: '/stripe-subscription-callback'
_controller: 'Subscription::stripeSubscriptionCallback'
defaultController: 'Subscription::list'
or
ShopSubscriptionsPlugin:
type: Extbase
limitToPages:
- {page uid with the SubscriptionTable plugin}
extension: ShopPro
plugin: SubscriptionTable
routes:
- routePath: '/stripe-subscription-callback'
_controller: 'Subscription::stripeSubscriptionCallback'
defaultController: 'Subscription::list'
Konfiguration des Webhooks im Stripe Dashboard
- Gehen Sie auf die Seite https://dashboard.stripe.com/webhooks und klicken Sie auf Endpunkt hinzufügen.
- Geben Sie die URL der Seite ein, die im Schritt "Einrichten der Webhook-Seite" eingerichtet wurde.
- Wählen Sie "Select Events" und wählen Sie
checkout.session.completed
,customer.subscription.created
,customer.subscription.updated
undcustomer.subscription.deleted
. - klicken Sie auf "Endpunkt hinzufügen".
- Klicken Sie auf den neu erstellten Webhook-Eintrag und kopieren Sie das Endpoint Secret.
- Fügen Sie das Endpoint Secret in die
subscriptionEndpointSecret
TypoScript Konstante ein.
Lokale Verwendung des Stripe-Webhooks
Stripe CLI installieren Lade das offizielle Debian-Package herunter und installiere es:
# Beispiel für Debian/Ubuntu wget https://stripe.jfrog.io/artifactory/deb-local/pool/main/s/stripe-cli/stripe-cli_<version>_amd64.deb sudo dpkg -i stripe-cli_<version>_amd64.deb
Ersetze
<version>
durch die aktuellste Version, die Du auf der Stripe-Repository-Seite findest.Mit Deinem Stripe-Account verbinden
stripe login
– Dadurch öffnet sich ein Browserfenster, in dem Du Dich bei Stripe anmeldest und den Zugriff verifizierst.
Webhooks weiterleiten Wechsle zurück in Dein Terminal und starte den Listener mit Weiterleitung auf Deine DDEV-URL:
stripe listen \ --forward-to https://typo3-12-13.shop13.ddev.site/subscription/your-subscriptions/stripe-subscription-callback
– Der Listener hängt sich an Stripe-Events (z. B.
invoice.paid
,customer.subscription.updated
) und schickt sie an Deinen lokalen Callback-Endpoint. Achte dabei darauf, dass die lokale Nutzung einen eigenen Webhook-Secret bekommt, welcher beim Start auf der CLI ausgegeben wird:Your webhook signing secret is whsec_03b75a…
Callback-Endpoint in TYPO3 prüfen – Stelle sicher, dass Dein TYPO3-Projekt unter der DDEV-URL erreichbar ist und der Callback-Controller die übertragenen JSON-Daten korrekt verarbeitet. – Falls nötig, aktiviere in DDEV HTTPS (standardmäßig an) und passe ggf.
config.yaml
an.
PSR-14 Events
Wenn
- der Webhook korrekt eingerichtet ist
- trifft eines der unterstützten Ereignisse beim Webhook ein
- es existiert ein Benutzer in der Datenbank mit der entsprechenden Stripe-Kunden-ID
wird ein PSR-14-Event ausgelöst.
Fügen Sie Folgendes zu Configuration/Services.yaml
hinzu, um auf die Events zu reagieren:
services:
CodingMs\ShopPro\EventListener\Stripe\Subscriptions\StripeSubscriptionCreatedMailEventListener:
tags:
- name: event.listener
identifier: 'shop.stripe.subscriptionCreatedDecreaseStockAmounts'
event: CodingMs\ShopPro\Event\Stripe\Subscriptions\StripeSubscriptionCreatedEvent
CodingMs\ShopPro\EventListener\Stripe\Subscriptions\StripeSubscriptionCreatedDecreaseStockAmountsEventListener:
tags:
- name: event.listener
identifier: 'shop.stripe.subscriptionCreatedMail'
event: CodingMs\ShopPro\Event\Stripe\Subscriptions\StripeSubscriptionCreatedEvent
CodingMs\ShopPro\EventListener\Stripe\Subscriptions\StripeSubscriptionDeletedMailEventListener:
tags:
- name: event.listener
identifier: 'shop.stripe.subscriptionDeletedMail'
event: CodingMs\ShopPro\Event\Stripe\Subscriptions\StripeSubscriptionDeletedEvent
CodingMs\ShopPro\EventListener\Stripe\Subscriptions\StripeSubscriptionUpdatedMailEventListener:
tags:
- name: event.listener
identifier: 'shop.stripe.subscriptionUpdatedMail'
event: CodingMs\ShopPro\Event\Stripe\Subscriptions\StripeSubscriptionUpdatedEvent
CodingMs\ShopPro\EventListener\Stripe\Subscriptions\StripeSubscriptionTrailWillEndMailEventListener:
tags:
- name: event.listener
identifier: 'shop.stripe.subscriptionTrailWillEndMail'
event: CodingMs\ShopPro\Event\Stripe\Subscriptions\StripeSubscriptionTrailWillEndEvent
Hinweis:
Wenn der Nutzer ein Abonnement kündigt, das noch eine Restlaufzeit hat, sendet Stripe zunächst ein Update-Event und nach Ablauf der Restlaufzeit ein zusätzliches Delete-Event!
Diese Ereignisse enthalten das Stripe-Subscription-Objekt, den zugehörigen Frontend-Benutzer und den Settings-Knoten.
Weitere Informationen zur Registrierung eines Event-Listeners finden Sie hier: https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/ApiOverview/Events/EventDispatcher/Index.html#registering-the-event-listener
E-Mails
Die zuvor beschriebenen Events können verwendet werden, um E-Mails an den Admin oder Kunden zu senden, wenn ein Abonnement erstellt, aktualisiert oder gelöscht wird bzw. wenn die Testphase endet.
Hinweis:
Ein Beispiel für die Abonnement-Objekte, die in den Fluid-Mail-Templates verfügbar sind, findest du im Ordner
EXT:shop_pro/Development/Stripe/Subscription
.
Tabelle der Abonnementprodukte anzeigen
- verwenden Sie das Plugin
SubscriptionTable
- fügen Sie bei der Produkterstellung dem Produkt ein Meta-Tag mit dem Schlüssel
category
hinzu und setzen Sie einen benutzerdefinierten Bezeichner (z.B.: subscription). Dies ermöglicht Ihnen, bestimmte Produkte in Abonnement-Tabellen anzuzeigen.
Liste der Abonnements anzeigen
- Verwenden Sie das Plugin
Subscriptions
Der Nutzer hat die Möglichkeit, die Liste seiner aktiven und bereits abgelaufenen Abonnements einzusehen und die Abonnements sofort oder zum Ende der Laufzeit zu kündigen. Für jedes Abonnement hat der Benutzer die Möglichkeit, die Liste der Rechnungen einzusehen und diese herunterzuladen.
Nebenbemerkung: Benutzer-Synchronisation
Stripe benötigt einen Stripe-Kundendatensatz für jeden unserer Frontend-Benutzer. Um diese Anforderung zu erfüllen, hat jeder Frontend-Benutzer ein Feld Stripe-Customer ID. Wenn ein Frontend-Benutzer eingeloggt ist und die Stripe-Customer ID leer ist, wird ein Versuch unternommen, einen neuen Stripe-Kunden anzulegen. Die neue Stipe-Kunden-ID wird dem Benutzerdatensatz zugeordnet. Wenn die Adressdaten des Frontend-Benutzers geändert werden, werden die geänderten Daten automatisch mit Stripe synchronisiert.
Es ist sehr wichtig, den Stripe-Kunden-Datensatz auf dem neuesten Stand zu halten, wenn Tools oder Skripte von Drittanbietern zum Ändern von Benutzerdaten im Frontend verwendet werden. Falls erforderlich, kann die Benutzersynchronisation manuell aufgerufen werden. Ein Beispiel finden Sie in EXT:shop_pro/Classes/EventListener/AfterProfileUpdateEventListener.php
public function __invoke(AfterProfileUpdatedEvent $event): void
{
$frontendUserRepository = GeneralUtility::makeInstance(FrontendUserRepository::class);
$frontendUser = $frontendUserRepository->findOneByUid($event->getFrontendUser()->getUid() ?? 0);
if(!isset($frontendUser)) {
return;
}
$routing = $GLOBALS['TYPO3_REQUEST']->getAttribute('routing');
$pageId = $routing->getPageId();
$subscriptionServiceSettings = TypoScriptService::getTypoScript(
$pageId
)['plugin']['tx_shop']['settings']['basketOrder']['orderOptions']['stripe'];
$subscriptionService = GeneralUtility::makeInstance(SubscriptionService::class, $subscriptionServiceSettings);
$subscriptionService->updateStripeCustomer($frontendUser);
}
Hinweis:
Alle Stripe-Elemente werden in der Sprache verwendet, die der Benutzer gerade auf der Website verwendet. Diese wird aus der Site-Configuration ausgelesen.
Fehlersuche
Sollte die Weiterleitung zu Stripe zum Abo-Abhschluss nicht funktionieren, aktiviere bitte das Logging (siehe How-To debugging). Hier werden hilfreiche Informationen geloggt, welche bei der Fehlerkorrektur helfen.
Checkliste für die Livegang
Achtung:
Diese Liste ist ggf. nicht vollständig!
API Keys umstellen
Wichtigster Punkt - Test-Keys funktionieren nicht im Live-Modus und umgekehrt.
sk_test_xxx
→ ersetzen durchsk_live_xxx
pk_test_xxx
→ ersetzen durchpk_live_xxx
Webhooks neu einrichten (und Secret anpassen)
Stripe trennt Test- und Live-Events strikt.
- Du musst im Live-Modus neue Webhook-Endpunkte im Stripe Dashboard einrichten.
- Den neuen Webhook Secret (
whsec_...
) speichern und in deinem PHP-Handler verwenden.
Payment Methods prüfen
Im Test-Modus stehen viele Zahlungsmethoden zur Verfügung, die im Live-Modus evtl. nicht aktiviert oder freigeschaltet sind.
- Prüfe unter Einstellungen > Zahlungen, welche Zahlungsmethoden aktiv sind.
- Aktivieren ggf. SEPA, SOFORT, Apple Pay, giropay, etc.
- Testkarten funktionieren natürlich nicht mehr – es müssen echte Zahlungen erfolgen.
Steuerlogik prüfen (falls aktiviert)
Wenn Du Stripe Tax oder manuelle Steuerberechnung nutzt, prüfe die Live-Konfiguration.
- Hast Du die richtigen Steuersätze im Live-Modus hinterlegt?
- Integrierst Du tax_behavior, automatic_tax, inclusive/exclusive korrekt im Code?
Produkt- und Preis-IDs anpassen
Produkte und Preise im Test-Modus sind nicht identisch mit denen im Live-Modus.
- IDs wie
prod_...
undprice_...
sind test-/live-spezifisch. - Lege die Produkte im Live-Modus im Dashboard an oder automatisiere das via API.
- Passe deine PHP-Konstanten oder Konfigurationsquellen entsprechend an.
- IDs wie
Subscriptions/Abos: Test-Daten ≠ Live-Daten
Bereits erstellte Subscriptions im Test-Modus sind nicht übertragbar.
- Du musst alle Kunden im Live-Modus neu anlegen. -Nutze ggf. customer_metadata zur Zuordnung.
E-Mail Templates & Branding prüfen
Customer-Mails für Rechnungen, Zahlungsfehler usw. anpassen unter Einstellungen > Branding & E-Mail. Hast Du E-Mail-Absender, Logo, Farben etc. für Live konfiguriert?
Live-Zahlung testen (mit kleiner echter Zahlung)
Mache eine eigene Live-Zahlung mit echter Karte und kleinem Betrag.
Prüfe, ob:
- Kunden korrekt angelegt werden
- Webhooks korrekt auslösen
- Abos gebucht werden
- Rechnungen/Steuern korrekt erzeugt werden
- Dein System damit richtig weiterarbeitet
Fehler-Logging & Monitoring aktivieren
- Prüfe Error-Logging in deinem TYPO3 und PHP-Code.
- Aktiviere ggf. Notifications in Stripe (z.B. bei fehlgeschlagenen Zahlungen).
Zeitabhängige Prozesse (z.B. Verlängerung, Kündigung)
- Funktioniert die Kündigungs-Logik?
- Was passiert bei Downgrade / Upgrade?
- Werden Reaktivierungen sauber behandelt?
Datenschutz & Compliance
- Achte auf DSGVO-konforme Speicherung von Kundendaten.
- Dokumentiere, wie Du mit Zahlungsdaten, Rechnungen und Löschpflichten umgehst.
- Stripe ist zwar konform, aber Du musst deine eigene Rolle in der Verarbeitung dokumentieren (AV-Vertrag mit Stripe abschließen).