Mit dem Abo-Modul lassen sich Produkte als Abonnement ohne feste Laufzeit anbieten. Kunden erhalten das abonnierte Produkt in vordefinierten Intervallen automatisch wiederkehrend.
Inhalt
Schritt 1: Abo-Produkte definieren
Schritt 2: Freischaltung/Aktivierung
Schritt 3: Fehlermeldung ergänzen
Schritt 4: Konfigurieren des Abo-Moduls in der Shopkonfiguration shop.config
Schritt 5: Konfigurieren der E-Mail-Benachrichtigungen
Schritt 6: Versandart für Abo-Bestellungen (optional)
Schritt 7: Template für die Abo-Verwaltung/Abo-Übersicht im Kundenkonto
Schritt 8: E-Mail-Templates für die konfigurierten E-Mail-Benachrichtigungen anlegen
Schritt 9: Abo-Modul Bestellablauf in das Template Produktdetailansicht (ws_product.htm) integrieren
Schritt 10: Template der Anmeldeseite (ws_login.htm) anpassen
Schritt 13: Template für die Verwaltung der Bankdaten (ws_bank_manage.htm) anpassen (optional)
Schritt 14: AGB abfragen (optional)
Schritt 15: Abo-Modul mit PayPal bezahlen (optional)
Das Abo-Modul ermöglicht Abonnements ohne feste Laufzeit: Ein Produkt wird in einem definierten Intervall wiederholt geliefert und jeweils zum Versand abgerechnet.
Abschluss eines Abos (Produktdetailseite)
Ein Abo wird direkt auf der Produktdetailseite abgeschlossen.
Der klassische Bestellablauf (Warenkorb/Checkout) wird dabei nicht durchlaufen.
Beim Abschluss werden – je nach Shopkonfiguration – die Abo-Einstellungen festgelegt, z. B.:
•Lieferintervall
•Lieferadresse (z. B. Rechnungsadresse oder abweichende Lieferadresse aus dem Adressbuch)
•Zahlungsart (z. B. Lastschrift, Rechnung, ggf. weitere wie PayPal – abhängig von der Konfiguration)
Da die Abo-Einstellungen produktbezogen auf der Produktdetailseite gewählt werden, bezieht sich ein Abo technisch immer auf genau ein Produkt (Menge kann > 1 sein). Weitere Produkte werden über separate Abos abgebildet.
Auslösung beim Abschluss des Abos
Beim erstmaligen Abschluss eines Abos gibt es zwei mögliche Varianten, die ein Händler anbieten kann:
•Nur abonnieren (zeitversetzte Auslösung)
Es wird zunächst nur der Abo-Eintrag angelegt. Die erste Bestellung aus diesem Abo wird erst zum nächsten konfigurierten Sammelzeitpunkt erzeugt und an das ERP übergeben (z. B. täglich um 12:00 Uhr).
Beispiel: Sammelzeitpunkt 12:00 Uhr, Abschluss um 13:00 Uhr → erste Bestellung erst am Folgetag zum Sammellauf. Die Bestelleingangsbestätigung erhält der Kunde entsprechend erst dann.
•Abonnieren und sofort auslösen (Sofort-Trigger)
Optional kann die erste Bestellung beim Abschluss sofort erzeugt und unmittelbar an das ERP übergeben werden (z. B. über BT-SubscriptionAndTrigger). Der Kunde erhält die Bestelleingangsbestätigung direkt nach Abschluss.
Wiederkehrende Bestellungen
Nach dem Start erzeugt das Abo-Modul weitere Bestellungen gemäß dem gewählten Lieferintervall.
Die Übergabe an das ERP erfolgt standardmäßig über den konfigurierten Sammelmechanismus (sofern kein Sofort-Trigger verwendet wird).
Verwaltung im Kundenkonto
Abos werden im Kundenkonto verwaltet. Typische Aktionen sind:
•Lieferintervall ändern
•Menge ändern
•Lieferadresse ändern
•Zahlungsart ändern (bei Lastschrift ggf. Bankverbindung/BankIndex wählen)
•Pausieren und Pause beenden (Abos können unbegrenzt pausiert werden)
•Kündigen/Löschen des Abos
Benachrichtigungen
Der Shop informiert den Kunden per E-Mail über Abo-Bestellungen und anstehende Lieferungen. Der Händler wird ebenfalls über anstehende Lieferungen und Fehlerfälle informiert.
Schritt 1: Abo-Produkte definieren
Produkte, die im Abo verkauft werden, müssen im Warenwirtschaftssystem speziell gekennzeichnet werden. Die Kennzeichnung erfolgt über das technische Produktdatenfeld "SubscriptionProduct", welches vom Warenwirtschaftssystem unterstützt werden muss. Erfolgt keine Unterstützung durch das Warenwirtschaftssystem, kann alternativ beim Import ein Mapping eines freien Datenfeldes auf das benötigte technische Feld erfolgen.
Produkte können so gekennzeichnet werden, dass sie
▪im Abo (SubscriptionProduct yes = y) oder
▪nicht im Abo (SubscriptionProduct no = n) oder
▪sowohl im Abo, als auch als "normales" Kaufprodukt (SubscriptionProduct both = b)
erhältlich sind.
Dem Abo-Produkt kann - wie allen anderen Produkten im Shop auch - ein Rabatt zugewiesen werden. Die Angabe eines Rabattes beim Produkt ist keine Pflicht für das Abo-Modul, sondern nur eine Option.
Beim Produkt können alle produktspezifischen Rabatte genutzt werden, die in der WEBSALE V8s zur Verfügung stehen.
Wegweiser: Rabatte festlegen
Weitere Hinweise zum Anlegen/Flaggen eines Abo-Produkts entnehmen Sie bitte der separaten Schnittstellen-Dokumentation unter
https://doku.websale.de/schnittstellen.
Hinweis: |
|
|
Die folgenden Schritte und Code-Beispiele zeigen die grundlegende Integration des Abo-Moduls. |
Schritt 2: Freischaltung/Aktivierung
Das Abo-Modul muss technisch freigeschaltet/aktiviert werden. Bitte wenden Sie sich an Ihren WEBSALE-Ansprechpartner und teilen Sie diesem mit, welche Zahlungsart für das Abo-Modul genutzt werden soll.
Teilen Sie uns bei der Freischaltung mit, welche Zahlungsarten, dem Käufer zur Auswahl gestellt werden, z.B. Rechnung, Lastschrift, PayPal etc.
Schritt 3: Fehlermeldung ergänzen
Ergänzen Sie in Ihrer Shopkonfiguration shop.config im Abschnitt NotifyMessages-Txt die folgende Fehlermeldung:
<NotifyMessages-Txt>
...
ProductSubscriptionProductNotOrderable = Um das Abo-Produkt ~PR-Name~ bestellen zu können, müssen Sie sich anmelden. Klicken Sie <a href="~WS-LoginLink~&type=LoginUser">hier</a>.
...
</NotifyMessages-Txt>
Referenz: NotifyMessages-Txt
Schritt 4: Konfigurieren des Abo-Moduls in der Shopkonfiguration shop.config
Ergänzen Sie in Ihrer Shopkonfiguration shop.config den Abschnitt Subscription und fügen Sie die jeweiligen Parameter und Unterabschnitte ein:
Lieferintervalle (Cycles)
Legen Sie hier die gewünschten Intervalle fest, die dann bei allen Produkten verwendet werden, z. B.:
▪1 Woche
▪14 Tage
▪1 Monat
▪3 Monate
▪1 Jahr etc.
Bis zu 15 Lieferintervalle können definiert werden. Die Intervalle sind jederzeit änderbar.
Ändert/löscht ein Händler ein Lieferintervall, welches bereits für Abos genutzt wird, wird der Käufer darüber nicht informiert. Das Lieferintervall beim Käufer wird erst verändert, wenn der Käufer in seiner Abo-Verwaltung davon Kenntnis genommen hat, d. h. der Kunde öffnet die Abo-Verwaltung über sei Kundenkonto aktiv im Shop und erhält dann eine Meldung.
Lieferintervall-Einträge sollten also nach Liveschaltung des Abo-Moduls nicht gelöscht oder geändert werden, da dies nachteilig für den Käufer sein kann.
<Subscription>
...
<Cycles>
<+Entry>
Description = einmal pro Woche
count = 1
unit = week
</+Entry>
<+Entry>
Description = alle 14 Tage
count = 14
unit = day
</+Entry>
<+Entry>
Description = einmal pro Monat
count = 1
unit = month
</+Entry>
<+Entry>
Description = alle 3 Monate
count = 3
unit = month
</+Entry>
<+Entry>
Description = einmal im Jahr
count = 1
unit = year
</+Entry>
</Cycles>
...
</Subscription>
Referenz: Subscription
Mehrere Abos für eine Lieferung zusammenfassen (ConsiderNextDays)
Hat ein Kunde mehrere Abos abgeschlossen und liegen die Lieferintervalle zeitlich sehr nah beieinander, kann die Lieferung zusammengefasst werden.
Die Zeitspanne, in welcher Bestellungen zusammengefasst werden sollen, kann mit diesem Parameter konfiguriert werden:
<Subscription>
...
ConsiderNextDays = 3
...
</Subscription>
Referenz: Subscription
Erneuter Bestellversuch für Abos nach aufgetretenen Fehlern (DaysRetry)
Tritt bei einer Bestellung ein Fehler auf, wird die Bestellung nicht ausgeführt und der Händler wird per E-Mail informiert.
Der XML-Bestellgenerator versucht nach x Tagen einen weiteren Bestellversuch. Dieser Zeitraum wird mit diesem Parameter konfiguriert.
Wird der Fehler nicht innerhalb von x Tagen behoben, erfolgt danach kein weiterer Bestellversuch durch den XML-Bestellgenerator. Stattdessen erhält der Händler per E-Mail eine Übersicht aller Abo-Produkte, bei denen ein Fehler vorliegt, der die Bestellung verhindert.
<Subscription>
...
DaysRetry = 2
...
</Subscription>
Referenz: Subscription
Begrenzung der Abonnements pro Kunde
Legt fest, wie viele Abonnements ein Benutzerkonto gleichzeitig besitzen darf.
Wird der Wert auf > 0 gesetzt, begrenzt das Abo-Modul die Anzahl der Abonnements pro Benutzerkonto auf diesen Wert.
Ist der Wert 0 (oder nicht gesetzt), können beliebig viele Abonnements angelegt werden.
<Subscription>
...
MaxSubscriptionsPerUser = 0
...
</Subscription>
Referenz: Subscription
Schritt 5: Konfigurieren der E-Mail-Benachrichtigungen
In der Shopkonfiguration shop.config im Abschnitt Subscription können Sie auch die Einstellungen der E-Mail-Benachrichtigungen vornehmen:
Informations-E-Mail an den Käufer über seine bevorstehenden Abos (SubscriberNotificationMail)
Diese E-Mail wird an den Käufer verschickt, um seine nächste Abo-Bestellung anzukündigen. Der Versand der E-Mail erfolgt so viele Tage im Voraus der Bestellung wie unter Days angegeben.
Fügen Sie den Unterabschnitt <SubscriberNotificationMail> innerhalb von <Subscription> ein und konfigurieren Sie die folgenden Parameter:
<Subscription>
...
<SubscriberNotificationMail> # E-Mail an Kunden mit Übersicht seiner Abo-Produkte, die in n Tagen versendet werden
Allow = yes
SenderAddress = versender@adresse.de
SenderName = Versendername
Subject-Txt = Demnächst wird mindestens ein Aboprodukt bestellt
ReplyTo = antwort@adresse.de
Template = mail_subscription_customer_notification.htm
Days = 4
</SubscriberNotificationMail>
...
</Subscription>
Referenz: Subscription
Informations-E-Mail an den Händler mit einer Übersicht der bevorstehenden Abos (MerchantNotificationMail)
Diese E-Mail wird an den Händler verschickt, um die nächste Abo-Bestellung anzukündigen. Der Versand der E-Mail erfolgt so viele Tage im Voraus der Bestellung wie unter Days angegeben.
Fügen Sie den Unterabschnitt <MerchantNotificationMail> innerhalb von <Subscription> ein und konfigurieren Sie die folgenden Parameter:
<Subscription>
...
<MerchantNotificationMail> # E-Mail an den Händler mit Übersicht aller Abo-Produkte, die in n Tagen anstehen
Allow = yes
SenderAddress = versender@adresse.de
SenderName = Versendername
Subject-Txt = Demnächst wird mindestens ein Aboprodukt bestellt
ReplyTo = antwort@adresse.de
Template = mail_subscription_merchant_notification.htm
Days = 4
</MerchantNotificationMail>
...
</Subscription>
Referenz: Subscription
Informations-E-Mail an den Händler bei fehlerhaften Abo-Bestellungen (OrderErrorMail)
Kann eine Bestellung durch den WEBSALE XML-Bestellgenerator nicht ausgeführt werden, wird der Händler per E-Mail informiert und kann dann mit dem Käufer in Kontakt treten.
Die E-Mail enthält eine Auflistung aller Abo-Produkte, die auf Grund eines Fehlers aktuell nicht bestellbar sind.
Fügen Sie den Unterabschnitt <OrderErrorMail> innerhalb von <Subscription> ein und konfigurieren Sie die folgenden Parameter:
<Subscription>
...
<OrderErrorMail> # E-Mail an Shopbetreiber, wenn eine Bestellung nicht generiert werden konnte.
Allow = yes
ReceiverAddress = empfaenger@adresse.de
SenderAddress = versender@adresse.de
SenderName = Versendername
Subject-Txt = Abobestellung konnte nicht erstellt werden
ReplyTo = antwort@adresse.de
Template = mail_subscription_order_error.htm
</OrderErrorMail>
...
</Subscription>
Referenz: Subscription
Informations-E-Mail an den Händler nach 2 fehlerhaften Bestellversuchen (DisabledNotificationMail)
Tritt auch nach dem zweiten Bestellversuch ein Fehler auf, erhält der Händler eine E-Mail mit allen Abos, die nicht mehr bestellt werden konnten.
Fügen Sie den Unterabschnitt <DisabledNotificationMail> innerhalb von <Subscription> ein und konfigurieren Sie die folgenden Parameter:
<Subscription>
...
<DisabledNotificationMail> # E-Mail mit allen Abos, die nicht mehr bestellt werden konnten.
Allow = yes
SenderAddress = versender@adresse.de
ReceiverAddress = empfaenger@adresse.de
SenderName = Versendername
Subject-Txt = Es gibt Abos, die nicht mehr bestellt werden konnten.
ReplyTo = antwort@adresse.de
Template = mail_subscription_disabled_notification.htm
</DisabledNotificationMail>
...
</Subscription>
Referenz: Subscription
Schritt 6: Versandart für Abo-Bestellungen (optional)
Legen Sie optional bei Ihren Versandarten fest, ob diese für Abo-Bestellungen zur Verfügung stehen sollen. Fügen Sie den Parameter AllowForSubscriptionOrder-Qualification in die <+Deliverer>-Abschnitte der Shopkonfiguration shop.config ein. Im Standard erhalten Versandarten den Wert use-for-all und sind somit sowohl für Abo-Bestellungen als auch für "normale" Bestellungen zulässig. Ändern Sie bei Bedarf den Wert auf not-for-subscriptionorder, um Versandarten für Abo-Bestellungen auszuschließen, oder auf only-for-subscriptionorder für Versandarten
<+Deliverer>
...
AllowForSubscriptionOrder-Qualification = # [use-for-all|only-for-subscriptionorder|not-for-subscriptionorder]
...
</+Deliverer>
Referenz: +Deliverer
WEBSALE empfiehlt kostenlosen Versand, um bestmögliche Preistransparenz für den Käufer zu gewährleisten.
Ablehnungsgründe für Versandarten ergänzen (optional)
Sie können dem Käufer bei der Auswahl der Versandarten optional auch die ausgeschlossenen Versandarten anzeigen lassen mit einem Hinweis, warum diese für das gewünschte Abo nicht zur Verfügung stehen.
Erstellen Sie dafür eine entsprechende Regel in der Shopkonfiguration. Weitere Informationen hierzu finden Sie unter
Wegweiser: Versandarten anlegen: Nicht verfügbare Versandarten ausgegraut darstellen.
Verwenden Sie dabei die folgenden ShowDisabled-Txt-Meldungen:
<DelivererShowDisabled-Definitions>
<+ShowDisabled-Rule>
ShowDisabled-GroupID = # z. B. VersandartNichtVerfuegbar
<ShowDisabled-Txt>
29 = Versandart ist nur für Abobestellungen verfügbar (aktuelle Bestellung ist keine Abobestellung)
30 = Versandart nur für Nicht-Abobestellungen verfügbar (aktuelle Bestellung ist eine Abobestellung)
</ShowDisabled-Txt>
...
</+ShowDisabled-Rule>
</DelivererShowDisabled-Definitions>
Referenz: Abschnitt DelivererShowDisabled-Definitions
Hinweis: |
|
|
Achten Sie darauf, bei jedem +Deliverer-Abschnitt die UseShowDisabled-GroupID zu hinterlegen. |
Schritt 7: Template für die Abo-Verwaltung/Abo-Übersicht im Kundenkonto
Der Käufer kommt auf diese Abo-Übersicht, wenn auf der Produktseite ein Abonnement abgeschlossen oder wenn die Seite direkt vom Kundenkonto aufgerufen wurde.
Geben Sie in Ihrer Shopkonfiguration shop.config im Abschnitt Templates bei dem Parameter Subscription den Namen des neuen Templates an.
<Templates>
...
Subscription = ws_subscription_manage.htm
...
</Templates>
Referenz: Templates
Legen Sie ein neues Template an und speichern Sie dieses unter dem soeben gewählten Namen in Ihrem Template-Verzeichnis, z. B. benutzer/templates/translation.
Fügen Sie folgenden Inhalt auf dem Template ein - der Code beinhaltet folgende Funktionen:
•Ajax-fähiger Bereich für die Abo-Verwaltung (optional als Ajax-Fragment nutzbar)
•Ausgabe von Status-, Erfolgs- und Fehlermeldungen
•Übersicht über vorhandene Abonnements (inkl. „keine Abos vorhanden“)
•Optionaler Rücksprung zum ursprünglich ausgewählten Abo-Produkt (OTP-Parameter)
•Pro Abo: Anzeige der wichtigsten Produktinformationen
•Pro Abo: Anzeige des aktuellen Abo-Status und des nächsten Lieferdatums
•Pro Abo: Änderungsmöglichkeiten für die zentralen Abo-Einstellungen (z. B. Menge, Intervall, Zahlungsart, Adresse)
•Zahlungsart-spezifische Bereiche (z. B. Lastschrift mit Bankauswahl, PayPal mit Konto-Verknüpfung)
•Aktionen zur Abo-Verwaltung (z. B. pausieren, reaktivieren, löschen) inklusive Ajax-Übermittlung
...
<div id="subscriptionContent">
{ST-Ajax}<WS-Ajax-subscriptionContent>{/ST-Ajax}
<h5>Abonnementen-Verwaltung</h5>
<!-- ========================================================= -->
<!-- Erfolgsmeldungen (z. B. nach Speichern, Pausieren, Löschen) -->
<!-- ========================================================= -->
{MSG-Subscription_success}
<p>Erfolgscode: ~MSG-Subscription_success~</p>
{MSG-Subscription_success(1)}<p>Ihr Abonnement wurde erfolgreich abgeschlossen.</p>{/MSG-Subscription_success(1)}
{MSG-Subscription_success(2)}<p>Ihr Abonnement wurde pausiert. Sie können das Abo jederzeit reaktivieren.</p>{/MSG-Subscription_success(2)}
{MSG-Subscription_success(3)}<p>Ihr Abonnement ist wieder aktiv. Das nächste Lieferdatum entnehmen Sie bitte der Übersicht.</p>{/MSG-Subscription_success(3)}
{MSG-Subscription_success(4)}<p>Ihr Abonnement wurde erfolgreich an Ihre Wünsche angepasst.</p>{/MSG-Subscription_success(4)}
{MSG-Subscription_success(5)}<p>Sie haben Ihr Abonnement gelöscht.</p>{/MSG-Subscription_success(5)}
{MSG-Subscription_success(6)}<p>Ihre erste Abo-Bestellung wird bald durchgeführt.</p>{/MSG-Subscription_success(6)}
{MSG-Subscription_success(7)}<p>Es wurde eine neue Bankverbindung für Ihre Abonnements festgelegt.</p>{/MSG-Subscription_success(7)}
{/MSG-Subscription_success}
<!-- ===================== -->
<!-- Fehlermeldungen (Codes) -->
<!-- ===================== -->
{MSG-Subscription_error}
<p>Fehlercode: ~MSG-Subscription_error~</p>
{MSG-Subscription_error(1)}<p>Sie sind nicht angemeldet. Um ein Abo abschließen zu können, müssen Sie angemeldet sein.</p>{/MSG-Subscription_error(1)}
{MSG-Subscription_error(2)}<p>Bitte prüfen Sie Ihre Eingaben. Die eingegebene Menge oder der Zeitraum Ihres Abos könnten fehlerhaft sein.</p>{/MSG-Subscription_error(2)}
{MSG-Subscription_error(3)}<p>Bitte reaktivieren Sie Ihr Abonnement, bevor Sie Änderungen daran vornehmen.</p>{/MSG-Subscription_error(3)}
{MSG-Subscription_error(4)}<p>Das ausgewählte Produkt ist kein Aboprodukt.</p>{/MSG-Subscription_error(4)}
{MSG-Subscription_error(5)}<p>Das ausgewählte Produkt ist kein Aboprodukt, da es aus einem Set von Produkten besteht.</p>{/MSG-Subscription_error(5)}
{MSG-Subscription_error(6)}<p>Bitte wählen Sie eine spezifische Produktvariante, um das Abo abzuschließen.</p>{/MSG-Subscription_error(6)}
{MSG-Subscription_error(7)}<p>Das ausgewählte Produkt kann nicht gefunden werden.</p>{/MSG-Subscription_error(7)}
{MSG-Subscription_error(8)}<p>Ihre Abobestellung konnte nicht ausgeführt werden.</p>{/MSG-Subscription_error(8)}
{MSG-Subscription_error(9)}<p>Ihre Abobestellung konnte nicht ausgeführt werden.</p>{/MSG-Subscription_error(9)}
{MSG-Subscription_error(10)}<p>Ihre Abobestellung konnte nicht ausgeführt werden.</p>{/MSG-Subscription_error(10)}
{MSG-Subscription_error(11)}<p>Ihre Abobestellung konnte nicht ausgeführt werden.</p>{/MSG-Subscription_error(11)}
{/MSG-Subscription_error}
<!-- ========================================================= -->
<!-- Statusmeldung: Anzahl Abos / keine Abos -->
<!-- ========================================================= -->
{SUBS-Data}
<p>Sie haben ~SUBS-Data~ Abonnements. Hier können Sie Ihre Abonnements ändern, pausieren und löschen.</p>
<p>Hier finden Sie eine Übersicht Ihrer Abonnements. Sie können Ihr Abo jederzeit beenden, pausieren und wieder aktivieren.</p>
{/SUBS-Data}
{!SUBS-Data}
<p>Es befinden sich derzeit noch keine Produkte auf Ihrer Aboliste.</p>
{/!SUBS-Data}
<!-- ========================================================= -->
<!-- Optionaler Button: Zurück zum Abo-Produkt (OTP-Rücksprung) -->
<!-- ========================================================= -->
{WS-OTPSubscriptionProdindex}
{PR-LoadData($WS-OTPSubscriptionProdindex$,0)}
<a href="~PR-Link~" class="btn btn-secondary btn-block-sm btn-block-xs">Zurück zum Abo-Produkt "~PR-Name~"</a>
{/PR-LoadData($WS-OTPSubscriptionProdindex$,0)}
{/WS-OTPSubscriptionProdindex}
<!-- ========================================================= -->
<!-- Abo-Übersicht: Formular + Schleife über alle Abos -->
<!-- ========================================================= -->
{SUBS-Data}
<form action="~FORM-Subscription~" method="POST" id="subscription">
{@SUBS-Data}
<!-- Produktdaten zum Abo laden -->
{PR-LoadData($SUBS-Data_PR_Number$,1)}
{PR-Name}<h5>~PR-Name~</h5>{/PR-Name}
{PR-Descr}<p>~PR-Descr~</p>{/PR-Descr}
{PR-LargeImage}<a href="~PR-DepVarLink~"><img src="~PR-LargeImage~" alt="~PR-Name_StripHtml~" width="100"/></a>{/PR-LargeImage}
<p>~DC-FPCurrentPrice_set($PR-Price$)~</p>
<!-- Preisänderung: gespeicherten Abo-Preis mit aktuellem Produktpreis vergleichen -->
{!DC-FPCurrentPrice($SUBS-Data_PR_Price$)}
<p>Für dieses Produkt gab es eine Preisänderung. Der aktuelle Preis beträgt jetzt ~DC-FPCurrentPrice~ ~WS-CurrencySymbol~</p>
{/!DC-FPCurrentPrice($SUBS-Data_PR_Price$)}
{/PR-LoadData($SUBS-Data_PR_Number$,1)}
<!-- Preis * Menge (Hinweis: hier wird nicht gerechnet, nur textlich ausgegeben) -->
<p>Gesamtpreis: ~SUBS-Data_PR_Price~ ~WS-CurrencySymbol~ * ~SUBS-Data_PR_Quantity~</p>
<!-- ================= -->
<!-- Menge ändern -->
<!-- ================= -->
<h5>Menge</h5>
<input name="~SUBS-Data_PR_Quantity_input~" value="~SUBS-Data_PR_Quantity~" onblur="return ws_AJAXsendForm('subscription','~WS-Charset~', ws_AJAXSubscriptionStart(), ws_AJAXSubscriptionError(),'ws_AJAXSubscriptionResponseSuccess()', 'ws_AJAXSubscriptionResponseError()')">
<hr>
<!-- ================= -->
<!-- Status & nächste Lieferung -->
<!-- ================= -->
{SUBS-Data_state_ispaused}<p>Sie haben das Abonnement pausiert.</p>{/SUBS-Data_state_ispaused}
{SUBS-Data_state_isactive}
<p>Das Abonnement ist aktiv.</p>
<p>Nächste Lieferung: ~DC-DateTime_setunixtimestamp($SUBS-Data_nextorder_unixtimestamp$)~ ~DC-DateTime_day~. ~DC-DateTime_month~. ~DC-DateTime_year~</p>
{/SUBS-Data_state_isactive}
{SUBS-Data_state_isnew}
<p>Das Abonnement ist neu.</p>
<p>Erste Lieferung: ~DC-DateTime_setunixtimestamp($SUBS-Data_nextorder_unixtimestamp$)~ ~DC-DateTime_day~. ~DC-DateTime_month~. ~DC-DateTime_year~</p>
{/SUBS-Data_state_isnew}
{SUBS-Data_state_istriggered}
<p>Das Abonnement ist aktiv.</p>
<p>Erste Lieferung: ~DC-DateTime_setunixtimestamp($SUBS-Data_nextorder_unixtimestamp$)~ ~DC-DateTime_day~. ~DC-DateTime_month~. ~DC-DateTime_year~</p>
{/SUBS-Data_state_istriggered}
<hr>
<!-- ================= -->
<!-- Lieferintervall ändern -->
<!-- ================= -->
<h5>Lieferintervall</h5>
<select class="form-control" name="~SUBS-CycleSelection_input~" onchange="return ws_AJAXsendForm('subscription','~WS-Charset~',ws_AJAXSubscriptionStart(), ws_AJAXSubscriptionError(),'ws_AJAXSubscriptionResponseSuccess()', 'ws_AJAXSubscriptionResponseError()')">
{@SUBS-CycleSelection_data}
<option value="~SUBS-CycleSelection_data_value~" ~SUBS-CycleSelection_data_selected~>~SUBS-CycleSelection_data_descr~</option>
{/@SUBS-CycleSelection_data}
</select>
<hr>
<!-- ================= -->
<!-- Zahlungsart ändern -->
<!-- ================= -->
<h5>Zahlungsart</h5>
<select class="form-control" name="~SUBS-PaymentMethod_input~" onchange="return ws_AJAXsendForm('subscription','~WS-Charset~',ws_AJAXSubscriptionStart(), ws_AJAXSubscriptionError(),'ws_AJAXSubscriptionResponseSuccess()', 'ws_AJAXSubscriptionResponseError()')">
{@SUBS-AllowedPayments}
<!-- Mapping auf lesbaren Namen -->
~DC-FP1_Set($SUBS-AllowedPayments$)~
{@PAY-Data}
{DC-CompareStringInList($PAY-Data_index$,$SUBS-AllowedPayments$)}~DC-FP1_Set($PAY-Data_name$)~{/DC-CompareStringInList($PAY-Data_index$,$SUBS-AllowedPayments$)}
{/@PAY-Data}
<!-- gespeicherter Paymentcode aus Abo-Eintrag -->
<option value="~SUBS-AllowedPayments~" {SUBS-Data_PaymentCode($SUBS-AllowedPayments$)}selected{/SUBS-Data_PaymentCode($SUBS-AllowedPayments$)}>
~DC-FP1~
</option>
{/@SUBS-AllowedPayments}
</select>
<!-- ===================================================== -->
<!-- Workaround: BankIndex setzen, damit Wechsel auf Lastschrift möglich ist -->
<!-- Hintergrund: PAY_DEBIT erfordert BankIndex -->
<!-- ===================================================== -->
{!SUBS-Data_PaymentCode(4)}{BANK-Data}{BANK-BankSelection}
~DC-FPFirstBankIndex_set(0)~
{@BANK-Data}
{DC-FPFirstBankindex(0)}
~DC-FPFirstBankIndex_set($BANK-BankSelection_code$)~
<input type="hidden" name="~SUBS-BankIndex_input~" value="~BANK-BankSelection_code~">
{/DC-FPFirstBankindex(0)}
{/@BANK-Data}
{/BANK-BankSelection}{/BANK-Data}{/!SUBS-Data_PaymentCode(4)}
<!-- ================= -->
<!-- Sonderfall: PayPal (PaymentCode 37) -->
<!-- ================= -->
{SUBS-Data_PaymentCode(37)}
<p>Dieses Abonnement wird mit PayPal bezahlt.</p>
{!PPC-Vaulted}
<p>Bitte verbinden Sie für diese Zahlungsart einmal Ihr PayPal-Konto.</p>
<a href="~WS-PPCVaultManageLink~">Jetzt mit Ihrem PayPal-Konto verbinden</a>
{/!PPC-Vaulted}
{PPC-Vaulted}
<p>Sie nutzen für die Zahlung das PayPal-Konto mit der E-Mail-Adresse: ~PPC-VaultedEmailAddress~</p>
{/PPC-Vaulted}
{/SUBS-Data_PaymentCode(37)}
<!-- ================= -->
<!-- Sonderfall: Lastschrift (PaymentCode 4) -> Bankauswahl -->
<!-- ================= -->
{SUBS-Data_PaymentCode(4)}
{BANK-Data}
{BANK-BankSelection}
<select class="form-control" name="~SUBS-BankIndex_input~" onchange="return ws_AJAXsendForm('subscription','~WS-Charset~', ws_AJAXSubscriptionStart(), ws_AJAXSubscriptionError(),'ws_AJAXSubscriptionResponseSuccess()', 'ws_AJAXSubscriptionResponseError()')">
{@BANK-Data}
<option value="~BANK-BankSelection_code~" {SUBS-Data_BankIndex($BANK-BankSelection_code$)}selected{/SUBS-Data_BankIndex($BANK-BankSelection_code$)}>~BANK-Bank~</option>
{/@BANK-Data}
</select>
{/BANK-BankSelection}
{/BANK-Data}
{/SUBS-Data_PaymentCode(4)}
<hr>
<!-- ================= -->
<!-- Lieferadresse ändern -->
<!-- ================= -->
~D-LoadData~
<h5>Lieferadresse</h5>
<select class="form-control" name="~SUBS-DelivAddress_input~" onchange="return ws_AJAXsendForm('subscription','~WS-Charset~',ws_AJAXSubscriptionStart(), ws_AJAXSubscriptionError(),'ws_AJAXSubscriptionResponseSuccess()', 'ws_AJAXSubscriptionResponseError()')">
<option value="0" {SUBS-Data_DelivAddress(0)}selected{/SUBS-Data_DelivAddress(0)}>Rechnungsadresse verwenden</option>
{D-DeliverySelection}
{@D-Data}
<option value="~D-DeliverySelection_value~" {SUBS-Data_DelivAddress($D-DeliverySelection_value$)}selected{/SUBS-Data_DelivAddress($D-DeliverySelection_value$)}>
{D-UserDescr}~D-UserDescr~{/D-UserDescr}{!D-UserDescr}~D-FirstName~, ~D-LastName~, ~D-Zip~ ~D-City~{/!D-UserDescr}
</option>
{/@D-Data}
{/D-DeliverySelection}
</select>
<hr>
<!-- ================= -->
<!-- Aktionen: löschen / pausieren / aktivieren -->
<!-- ================= -->
<button type="submit" name="~SUBS-Data_Buttonname~" value="~SUBS-Data_Buttonvalue_delete~" onClick="return ws_AJAXsendForm('subscription','~WS-Charset~',ws_AJAXSubscriptionStart(), ws_AJAXSubscriptionError(),'ws_AJAXSubscriptionResponseSuccess()', 'ws_AJAXSubscriptionResponseError()','~SUBS-Data_Buttonname~=~SUBS-Data_Buttonvalue_delete~')">
löschen
</button>
{SUBS-Data_Buttonvalue_pause}
<button type="submit" name="~SUBS-Data_Buttonname~" value="~SUBS-Data_Buttonvalue_pause~" onClick="return ws_AJAXsendForm('subscription','~WS-Charset~',ws_AJAXSubscriptionStart(), ws_AJAXSubscriptionError(),'ws_AJAXSubscriptionResponseSuccess()', 'ws_AJAXSubscriptionResponseError()','~SUBS-Data_Buttonname~=~SUBS-Data_Buttonvalue_pause~')">
pausieren
</button>
{/SUBS-Data_Buttonvalue_pause}
{SUBS-Data_Buttonvalue_resume}
<button type="submit" name="~SUBS-Data_Buttonname~" value="~SUBS-Data_Buttonvalue_resume~" onClick="return ws_AJAXsendForm('subscription','~WS-Charset~',ws_AJAXSubscriptionStart(), ws_AJAXSubscriptionError(),'ws_AJAXSubscriptionResponseSuccess()', 'ws_AJAXSubscriptionResponseError()','~SUBS-Data_Buttonname~=~SUBS-Data_Buttonvalue_resume~')">
aktivieren
</button>
{/SUBS-Data_Buttonvalue_resume}
{/@SUBS-Data}
</form>
{/SUBS-Data}
{ST-Ajax}</WS-Ajax-subscriptionContent>{/ST-Ajax}
</div>
<!-- ========================================================= -->
<!-- AJAX-Callbacks (Beispiel / Platzhalter) -->
<!-- ========================================================= -->
<script>
function ws_AJAXSubscriptionStart() {}
function ws_AJAXSubscriptionError() {}
function ws_AJAXSubscriptionResponseSuccess() {}
function ws_AJAXSubscriptionResponseError() {}
</script>
Referenz: SUBS-Tags
Schritt 8: E-Mail-Templates für die konfigurierten E-Mail-Benachrichtigungen anlegen
Legen Sie für die gewünschten E-Mail-Benachrichtigungen neue Templates an und speichern Sie diese in Ihrem Template-Verzeichnis, z. B. benutzer/templates/translation.
Der jeweilige Dateiname muss mit den Angaben in der Shopkonfiguration shop.config, Abschnitt Subscription, Unterabschnitt der entsprechenden E-Mail, Parameter Template übereinstimmen (siehe Schritt 3).
Informations-E-Mail an den Händler bei fehlerhaften Abo-Bestellungen (OrderErrorMail)
Kann eine Bestellung durch den WEBSALE XML-Bestellgenerator nicht ausgeführt werden, wird der Händler per E-Mail informiert und kann dann mit dem Käufer in Kontakt treten.
Fügen Sie folgenden Inhalt ein:
{E-SUBS_ErrorMsg}~E-SUBS_ErrorMsg~{/E-SUBS_ErrorMsg}
{E-SUBS_ErrorCode}~E-SUBS_ErrorCode~{/E-SUBS_ErrorCode}
{@E-SUBS_Data}
Abo-Index: ~E-SUBS_DATA_Index~
UserIndex: ~E-SUBS_DATA_UserIndex~
Abo-Preis: ~E-SUBS_DATA_PR_Price~ ~E-SUBS_DATA_PR_CurrencyCode~
Produktindex: ~E-SUBS_DATA_PR_Index~
Produktnummer: ~E-SUBS_DATA_PR_number~
Produktname: ~E-SUBS_DATA_PR_Name~
Menge: ~E-SUBS_DATA_PR_Quantity~
Abo erstellt: ~E-SUBS_DATA_Created~
Abo zuletzt bearbeitet: ~E-SUBS_DATA_LastChange~
Datum der letzten Bestellung: ~E-SUBS_DATA_LastOrder~
Datum der nächsten Bestellung: ~E-SUBS_DATA_NextOrder~
Laden der aktuellen Produktdaten:
{PR-LoadData({NO_PARSING}~E-SUBS_DATA_PR_Index~,0)}
~PR-Name~
~PR-Price~ ~WS-Currency~
{/PR-LoadData({/NO_PARSING}~E-SUBS_DATA_PR_Index~,0)}
{/@E-SUBS_Data}
Referenz: E-SUBS-Tags
Informations-E-Mail an den Käufer über seine bevorstehenden Abos (SubscriberNotificationMail)
Diese E-Mail wird an den Käufer verschickt, um seine nächste Abo-Bestellung anzukündigen.
Fügen Sie folgenden Inhalt ein:
Auflistung aller anstehenden Abos:
{@E-SUBS_Data}
ID: ~E-SUBS_DATA_Index~
UserIndex: ~E-SUBS_DATA_UserIndex~
Price: ~E-SUBS_DATA_PR_Price~
Currency: ~E-SUBS_DATA_PR_CurrencyCode~
Produktindex: ~E-SUBS_DATA_PR_Index~
Produktnummer: ~E-SUBS_DATA_PR_number~
Produktname: ~E-SUBS_DATA_PR_Name~
Quantity: ~E-SUBS_DATA_PR_Quantity~
Abo erstellt: ~E-SUBS_DATA_Created~
Abo zuletzt bearbeitet: ~E-SUBS_DATA_LastChange~
Datum der letzten Bestellung: ~E-SUBS_DATA_LastOrder~
Datum der nächsten Bestellung: ~E-SUBS_DATA_NextOrder~
{/@E-SUBS_Data}
Referenz: E-SUBS-Tags
Informations-E-Mail an den Händler mit einer Übersicht der bevorstehenden Abos (MerchantNotificationMail)
Diese E-Mail wird an den Händler verschickt, um die nächste Abo-Bestellung anzukündigen.
Fügen Sie folgenden Inhalt ein:
Auflistung aller anstehenden Abos:
{@E-SUBS_Data}
ID: ~E-SUBS_DATA_Index~
UserIndex: ~E-SUBS_DATA_UserIndex~
Price: ~E-SUBS_DATA_PR_Price~
Currency: ~E-SUBS_DATA_PR_CurrencyCode~
Produktindex: ~E-SUBS_DATA_PR_Index~
Produktnummer: ~E-SUBS_DATA_PR_number~
Produktname: ~E-SUBS_DATA_PR_Name~
Quantity: ~E-SUBS_DATA_PR_Quantity~
Abo erstellt: ~E-SUBS_DATA_Created~
Abo zuletzt bearbeitet: ~E-SUBS_DATA_LastChange~
Datum der letzten Bestellung: ~E-SUBS_DATA_LastOrder~
Datum der nächsten Bestellung: ~E-SUBS_DATA_NextOrder~
{/@E-SUBS_Data}
Auflistung aller Abos gruppiert nach Produkt:
{@E-SUBS_DataByProduct}
Price: ~E-SUBS_DATA_PR_Price~
Currency: ~E-SUBS_DATA_PR_CurrencyCode~
Produktindex: ~E-SUBS_DATA_PR_Index~
Produktnummer: ~E-SUBS_DATA_PR_number~
Produktname: ~E-SUBS_DATA_PR_Name~
Quantity: ~E-SUBS_DATA_PR_Quantity~
{/@E-SUBS_DataByProduct}
Referenz: E-SUBS-Tags
Informations-E-Mail an den Händler nach 2 fehlerhaften Bestellversuchen (DisabledNotificationMail)
Tritt auch nach dem zweiten Bestellversuch ein Fehler auf, erhält der Händler eine E-Mail mit allen Abos, die nicht mehr bestellt werden konnten.
Fügen Sie folgenden Inhalt ein:
{@E-SUBS_Data}
ID: ~E-SUBS_DATA_Index~
UserIndex: ~E-SUBS_DATA_UserIndex~
Price: ~E-SUBS_DATA_PR_Price~
Currency: ~E-SUBS_DATA_PR_CurrencyCode~
Produktindex: ~E-SUBS_DATA_PR_Index~
Produktnummer: ~E-SUBS_DATA_PR_number~
Produktname: ~E-SUBS_DATA_PR_Name~
Quantity: ~E-SUBS_DATA_PR_Quantity~
Abo erstellt: ~E-SUBS_DATA_Created~
Abo zuletzt bearbeitet: ~E-SUBS_DATA_LastChange~
Datum der letzten Bestellung: ~E-SUBS_DATA_LastOrder~
Datum der nächsten Bestellung: ~E-SUBS_DATA_NextOrder~
{/@E-SUBS_Data}
Referenz: E-SUBS-Tags
Schritt 9: Abo-Modul Bestellablauf in das Template Produktdetailansicht (ws_product.htm) integrieren
Das Abo-Modul wird auf dem Template ws_product.htm integriert.
Nehmen Sie folgende Erweiterungen vor:
Um die Anzeige für abonnementfähige und nicht abonnementfähige Produkte zu unterscheiden wird das Tag PR-SubscriptionProduct verwendet.
{PR-Data}
...
{!PR-SubscriptionProduct}
<!-- Produkt unterstützt keine Abos -->
<p>Dieses Produkt steht nicht als Abonnement zur Verfügung</p>
{/!PR-SubscriptionProduct}
{PR-SubscriptionProduct}
<!-- Produkt ist als Abo-Produkt konfiguriert -->
<p>Für dieses Produkt ist eine Abo-Lieferung möglich.</p>
{/PR-SubscriptionProduct}
...
{/PR-Data}
Referenz: PR-SubscriptionProduct
Um ein Abonnement abschließen zu können, muss man ein Kundenkonto besitzen und eingeloggt sein. Dazu bieten Sie auf der Produktdetailansicht eine Weiterleitung auf die Seite ws_login.htm an. Dort kann sich der Bestandskunde anmelden oder der Neukunde eine neues Kundenkonto eröffnen.
Um nach der Anmeldung von der Seite ws_login.htm zurück zum Produkt navigieren zu können, werden OTP-Parameter in der URL mitgegeben.
{!ST-LoggedIn}
Sie benötigen ein Kundenkonto, um ein Abonnement abschließen zu können. Melden Sie sich an oder eröffnen Sie ein neues Kundenkonto<br>
<a href='~WS-LoginLink~&type=loginUser&otplogintype=newuser&act=subscription&otpsubscriptionprodindex=~PR-ProdIndex~'>Anmelden</a>
{/!ST-LoggedIn}
Referenz: ST-LoggedIn
Auf der Seite ws_product.htm wird man benachrichtigt, dass eine Bankverbindung und Rechnungsadresse hinterlegt sein müssen.
Wenn diese Infos hinterlegt sind, dann hat man die Option, diese zu bearbeiten.
{PR-Data}
...
{PR-SubscriptionProduct}
<form action="~FORM-Product~" method="Post" id="productform">
<!-- Produkt ist als Abo-Produkt konfiguriert -->
<p>Für dieses Produkt ist eine Abo-Lieferung möglich.</p>
{!ST-LoggedIn}
<!-- Abo-Abschluss nur mit Kundenkonto/Login -->
Sie benötigen ein Kundenkonto, um ein Abonnement abschließen zu können.
Melden Sie sich an oder eröffnen Sie ein neues Kundenkonto
<!-- Login-Link inkl. Rücksprung/Parameter, damit danach wieder die Abo-PDP geöffnet werden kann -->
<a href="~WS-LoginLink~&type=loginUser&act=subscription&otpsubscriptionprodindex=~PR-ProdIndex~">Anmelden</a>
{/!ST-LoggedIn}
{ST-LoggedIn}
<!-- ========================================================= -->
<!-- 1) Lieferintervall-Auswahl (shop.config / Abo-Konfiguration) -->
<!-- ========================================================= -->
<hr>
{SUBS-CycleSelection}
<h5>Wählen Sie Ihr gewünschtes Lieferintervall aus</h5>
<!-- onchange triggert Ajax-Refresh der Produktform (PDP), damit abhängige Bereiche nachladen -->
<select class="form-control" name="~SUBS-CycleSelection_input~" onchange="ws_AJAXPR('productform', '~WS-Charset~');">
<option value="">Bitte wählen Sie</option>
{@SUBS-CycleSelection_data}
<!-- value = Intervall-Key, *_selected setzt selected-Attribut -->
<option value="~SUBS-CycleSelection_data_value~" ~SUBS-CycleSelection_data_selected~>~SUBS-CycleSelection_data_descr~</option>
{/@SUBS-CycleSelection_data}
</select>
{/SUBS-CycleSelection}
<!-- Optional: Anzeige des gewählten Intervalls (funktioniert nur, wenn Ajax-Refresh aktiv ist) -->
{SUBS-CycleSelection_data_selected}
<div>
Gewähltes Lieferintervall:
{@SUBS-CycleSelection_data}
{SUBS-CycleSelection_data_selected}~SUBS-CycleSelection_data_descr~{/SUBS-CycleSelection_data_selected}
{/@SUBS-CycleSelection_data}
</div>
{/SUBS-CycleSelection_data_selected}
<!-- ========================================================= -->
<!-- 2) Lieferadresse-Auswahl -->
<!-- 0 = Rechnungsadresse, >0 = Lieferadresse aus Adressbuch -->
<!-- ========================================================= -->
<hr>
~D-LoadData~
<h5>Wohin sollen wir das Produkt zukünftig immer liefern?</h5>
<!-- onchange triggert Ajax-Refresh der Produktform (PDP), damit abhängige Bereiche nachladen -->
<select class="form-control" name="~SUBS-DelivAddress_input~" onchange="ws_AJAXPR('productform', '~WS-Charset~');">
<option value="">Bitte wählen Sie</option>
<!-- Rechnungsadresse -->
<option value="0" {SUBS-DelivAddress_selected(0)}selected{/SUBS-DelivAddress_selected(0)}>An meine Rechnungsadresse</option>
{D-DeliverySelection}
<!-- Adressbuch-Lieferadressen -->
{@D-Data}
<option value="~D-DeliverySelection_value~" {SUBS-DelivAddress_selected($D-DeliverySelection_value$)}selected{/SUBS-DelivAddress_selected($D-DeliverySelection_value$)}>
Lieferadresse: ~D-FirstName~, ~D-LastName~, ~D-Zip~ ~D-City~
</option>
{/@D-Data}
{/D-DeliverySelection}
</select>
<!-- Link: neue Lieferadresse anlegen -->
<!-- Hinweis: besser per Ajax/Modal, damit ausgewählte Abo-Parameter nicht verloren gehen -->
{D-NewDelivAddressLink}
<a href="~D-NewDelivAddressLink~&otpsubscriptionprodindex=~PR-ProdIndex~">An eine neue Lieferadresse</a>
{/D-NewDelivAddressLink}
<!-- Optional: Anzeige der aktuell gewählten Adresse (setzt Ajax-Refresh voraus) -->
{SUBS-DelivAddress_selected}
<!-- 2a) Rechnungsadresse gewählt -->
{SUBS-DelivAddress_selected(0)}
<div>
{A-Salutation}~A-Salutation~<br>{/A-Salutation}
{A-FirstName}~A-FirstName~<br>{/A-FirstName}
{A-LastName}~A-LastName~<br>{/A-LastName}
{A-Street1}~A-Street1~<br>{/A-Street1}
{A-Zip}~A-Zip~{/A-Zip}{A-City} ~A-City~<br><br>{/A-City}
<!-- Hinweis zum Ändern: besser per Ajax/Modal, damit ausgewählte Abo-Parameter nicht verloren gehen -->
<a href="~WS-EnsureNextLinkContainsURLParams~~WS-AddrManageLink~&otpsubscriptionprodindex=~PR-ProdIndex~">Rechnungsadresse ändern</a>
</div>
{/SUBS-DelivAddress_selected(0)}
<!-- 2b) Abweichende Lieferadresse gewählt -->
{!SUBS-DelivAddress_selected(0)}
<div>
{D-DeliverySelection}
{@D-Data}
{SUBS-DelivAddress_selected($D-DeliverySelection_value$)}
{D-Salutation}~D-Salutation~<br>{/D-Salutation}
{D-FirstName}~D-FirstName~{/D-FirstName}{D-LastName} ~D-LastName~<br>{/D-LastName}
{D-Street1}~D-Street1~<br>{/D-Street1}
{D-Zip}~D-Zip~{/D-Zip}{D-City} ~D-City~<br><br>{/D-City}
<!-- Hinweis zum Ändern: besser per Ajax/Modal, damit ausgewählte Abo-Parameter nicht verloren gehen -->
{D-EditLink}
<a href="~WS-EnsureNextLinkContainsURLParams~~D-EditLink~&otpsubscriptionprodindex=~PR-ProdIndex~">Lieferadresse ändern</a>
{/D-EditLink}
{/SUBS-DelivAddress_selected($D-DeliverySelection_value$)}
{/@D-Data}
{/D-DeliverySelection}
</div>
{/!SUBS-DelivAddress_selected(0)}
{/SUBS-DelivAddress_selected}
<!-- ========================================================= -->
<!-- 3) Zahlungsart-Auswahl (AllowedPayments + PAY-Data für Namen) -->
<!-- ========================================================= -->
<hr>
<h5>Wählen Sie Ihre Zahlungsart aus</h5>
<!-- onchange triggert Ajax-Refresh der Produktform (PDP), damit abhängige Bereiche nachladen -->
<select class="form-control" name="~SUBS-PaymentMethod_input~" onchange="ws_AJAXPR('productform', '~WS-Charset~');">
<option value="">Bitte wählen Sie</option>
{@SUBS-AllowedPayments}
<!-- Default: Code als Fallback anzeigen -->
~DC-FPPaymentName_set($SUBS-AllowedPayments$)~
<!-- Mapping: Payment-Index -> Payment-Name -->
{@PAY-Data}
{DC-CompareStringInList($PAY-Data_index$,$SUBS-AllowedPayments$)}
~DC-FPPaymentName_set($PAY-Data_name$)~
{/DC-CompareStringInList($PAY-Data_index$,$SUBS-AllowedPayments$)}
{/@PAY-Data}
<!-- selected, wenn dieser Paymentcode aktuell gewählt ist -->
<option value="~SUBS-AllowedPayments~" {SUBS-PaymentMethod_selected($SUBS-AllowedPayments$)}selected{/SUBS-PaymentMethod_selected($SUBS-AllowedPayments$)}>
~DC-FPPaymentName~
</option>
{/@SUBS-AllowedPayments}
</select>
<!-- Optional: Anzeige der gewählten Zahlungsart (setzt Ajax-Refresh voraus) -->
{SUBS-PaymentMethod_selected}
<div>
Gewählte Zahlungsart:
{@SUBS-AllowedPayments}
~DC-FPPaymentName_set($SUBS-AllowedPayments$)~
{@PAY-Data}
{DC-CompareStringInList($PAY-Data_index$,$SUBS-AllowedPayments$)}
~DC-FPPaymentName_set($PAY-Data_name$)~
{/DC-CompareStringInList($PAY-Data_index$,$SUBS-AllowedPayments$)}
{/@PAY-Data}
{SUBS-PaymentMethod_selected($SUBS-AllowedPayments$)}
~DC-FPPaymentName~
{/SUBS-PaymentMethod_selected($SUBS-AllowedPayments$)}
{/@SUBS-AllowedPayments}
<!-- ===================================================== -->
<!-- 3a) Zusatz: Bankauswahl bei Lastschrift -->
<!-- Hinweis: hier wird Paymentcode "4" als Lastschrift angenommen -->
<!-- ===================================================== -->
{SUBS-PaymentMethod_selected(4)}
<!-- Bankdaten vorhanden? dann Auswahl anzeigen -->
{BANK-Data}{BANK-BankSelection}
<!-- onchange triggert Ajax-Refresh der Produktform (PDP), damit abhängige Bereiche nachladen -->
<select class="form-control" name="~SUBS-BankIndex_input~" onchange="ws_AJAXPR('productform', '~WS-Charset~');">
<option value="">Bitte wählen</option>
{@BANK-Data}
<option value="~BANK-BankSelection_code~"{SUBS-BankIndex_selected($BANK-BankSelection_code$)} selected{/SUBS-BankIndex_selected($BANK-BankSelection_code$)}>
~BANK-Bank~
</option>
{/@BANK-Data}
</select>
{/BANK-BankSelection}{/BANK-Data}
<!-- Hinweis zum Ändern: besser per Ajax/Modal, damit ausgewählte Abo-Parameter nicht verloren gehen -->
{Bank-NewBankLink}
<a href="~WS-EnsureNextLinkContainsURLParams~~Bank-NewBankLink~&otpsubscriptionprodindex=~PR-ProdIndex~">
Neue Bankverbindung
</a>
{/Bank-NewBankLink}
<!-- Anzeige der ausgewählten Bankverbindung (setzt Ajax-Refresh voraus) -->
{BANK-Data}{BANK-BankSelection}
<div>
{@BANK-Data}
{SUBS-BankIndex_selected($BANK-BankSelection_code$)}
Gewählte Bankverbindung:<br>
{BANK-Owner}Kontoinhaber: ~BANK-Owner~<br>{/BANK-Owner}
{BANK-IBAN}IBAN-Nummer: ~BANK-IBAN~<br>{/BANK-IBAN}
{BANK-Bank}Kreditinstitut: ~BANK-Bank~<br><br>{/BANK-Bank}
<!-- Hinweis zum Ändern: besser per Ajax/Modal, damit ausgewählte Abo-Parameter nicht verloren gehen -->
{BANK-EditLink}
<a href="~WS-EnsureNextLinkContainsURLParams~~Bank-EditLink~&otpsubscriptionprodindex=~PR-ProdIndex~">
Bankverbindung ändern
</a>
{/BANK-EditLink}
{/SUBS-BankIndex_selected($BANK-BankSelection_code$)}
{/@BANK-Data}
</div>
{/BANK-BankSelection}{/BANK-Data}
{/SUBS-PaymentMethod_selected(4)}
</div>
{/SUBS-PaymentMethod_selected}
<!-- ========================================================= -->
<!-- 4) AGB / Widerruf -->
<!-- ========================================================= -->
<hr>
<h5>Bitte akzeptieren Sie die AGB</h5>
<!-- value="1" ist wichtig, damit serverseitig eindeutig ausgewertet werden kann -->
<!-- onchange triggert Ajax-Refresh der Produktform (PDP), damit abhängige Bereiche nachladen -->
<input type="checkbox" name="~WS-AcceptTermsAndConditions_input~" value="1" ~WS-AcceptTermsAndConditions_checked~ onchange="ws_AJAXPR('productform', '~WS-Charset~');">
Ja, ich akzeptiere Ihre Allgemeinen Geschäftsbedingungen und habe von meinem Widerrufsrecht Kenntnis genommen.
<!-- ========================================================= -->
<!-- 5) Buttons: nur Abo anlegen oder Abo + sofort triggern -->
<!-- ========================================================= -->
<!-- disabled wenn Bedingungen nicht erfüllt, z. B. AGB nicht akzeptiert -->
<input name="~BT-Subscription~" value="Abonnieren" type="submit" {!ST-Conditions_OK}disabled{/!ST-Conditions_OK}>
ODER
<input name="~BT-SubscriptionAndTrigger~" value="Abonnieren und direkt bestellen" type="submit" {!ST-Conditions_OK}disabled{/!ST-Conditions_OK}>
{/ST-LoggedIn}
</form>
{/PR-SubscriptionProduct}
...
{/PR-Data}
Referenz: SUBS-Data
Für Ändern- und Bearbeiten-Funktionen, müssen mittels OTP-Parametern entsprechende Verlinkung auf den Manage-Templates, z.B. ws_address_manage.htm, hinzugefügt werden.
Schritt 10: Template der Anmeldeseite (ws_login.htm) anpassen
Der gezeigte Code dient dazu, den Abo-Abschluss für nicht eingeloggte Kunden sauber zu unterstützen.
Wenn ein Kunde ein Abo-Produkt aufruft und noch nicht angemeldet ist, muss er zunächst zum Login weitergeleitet werden.
Damit nach dem Login der Bezug zum ursprünglich ausgewählten Abo-Produkt nicht verloren geht, wird der Produktindex über einen OTP-Parameter (otpsubscriptionprodindex) mitgeführt.
Dadurch bleibt die Information über das Abo-Produkt über den Login hinweg erhalten.
...
{Type-LoginUser}
...
<!-- Neukunden-Anmeldung -->
<form action="~FORM-LoginNewUser~" method="Post">
...
{WS-OTPSubscriptionProdindex}<input type="hidden" name="otpsubscriptionprodindex" value="~WS-OTPSubscriptionProdindex~">{/WS-OTPSubscriptionProdindex}
...
</form>
UND / ODER
<!-- Bestandskunden-Anmeldung -->
<form action="~FORM-LoginKnownUser~" method="Post">
...
{WS-OTPSubscriptionProdindex}<input type="hidden" name="otpsubscriptionprodindex" value="~WS-OTPSubscriptionProdindex~">{/WS-OTPSubscriptionProdindex}
...
</form>
ODER
<!-- Kombinierte Anmeldung für Neu- und Bestandskunden -->
<form action="~FORM-CombinedLogin~" method="Post">
...
{WS-OTPSubscriptionProdindex}<input type="hidden" name="otpsubscriptionprodindex" value="~WS-OTPSubscriptionProdindex~">{/WS-OTPSubscriptionProdindex}
...
</form>
{WS-OTPSubscriptionProdindex}
{PR-LoadData($WS-OTPSubscriptionProdindex$,0)}
<a href="~PR-Link~">Zurück zum Abo-Produkt "~PR-Name~"</a>
{/PR-LoadData($WS-OTPSubscriptionProdindex$,0)}
{/WS-OTPSubscriptionProdindex}
...
{/Type-LoginUser}
...
Referenz: FORM-CombinedLogin
Referenz: FORM-LoginNewUser
Nach erfolgreichem Login wird der Kunde standardmäßig auf die Kundenkonto-Seite (ws_user_account.htm) geleitet.
Um einen unnötigen Seitenwechsel zu vermeiden und den Abo-Abschluss nahtlos fortzusetzen, wird empfohlen, den Login per Ajax im Modul/Layer (Modal) zu realisieren.
So kann der Kunde nach dem Login direkt auf der Produktdetailseite bleiben und das Abo ohne Unterbrechung abschließen.
..
{WS-OTPSubscriptionProdindex}
{PR-LoadData($WS-OTPSubscriptionProdindex$,0)}
<a href="~PR-Link~">Zurück zum Abo-Produkt "~PR-Name~"</a>
{/PR-LoadData($WS-OTPSubscriptionProdindex$,0)}
{/WS-OTPSubscriptionProdindex}
...
Schritt 11: Template der Verwaltungsseite der Rechnungsadresse im Kundenkonto (ws_address_manage.htm) anpassen
Ergänzen Sie das Template ws_address_manage.htm innerhalb des {A-Edit}-Bereichs mit den versteckten OTP-Parametern und den Links zurück auf die Abo-Produktseite.
{A-Edit}
...
<form action="~FORM-AddrManage~" method="post">
...
{WS-OTPSubscriptionProdindex}<input type="hidden" name="otpsubscriptionprodindex" value="~WS-OTPSubscriptionProdindex~">{/WS-OTPSubscriptionProdindex}
...
{WS-OTPSubscriptionProdindex}
{PR-LoadData($WS-OTPSubscriptionProdindex$,0)}
<a href="~PR-Link~" class="btn btn-secondary btn-block-sm btn-block-xs">Zurück zum Abo-Produkt "~PR-Name~"</a>
{/PR-LoadData($WS-OTPSubscriptionProdindex$,0)}
{/WS-OTPSubscriptionProdindex}
</form>
...
{/A-Edit}
Schritt 12: Template für die Verwaltung der Lieferadresse (ws_deliv_address_manage.htm) anpassen (optional)
Ergänzen Sie auf dem Template ws_deliv_address_manage.htm innerhalb des {D-Edit}-Bereichs mit den versteckten OTP-Parametern und den Links zurück auf die Abo-Produktseite.
{D-Edit}
...
<form action="~FORM-DelivAddrManage~" method="POST">
...
{WS-OTPSubscriptionProdindex}<input type="hidden" name="otpsubscriptionprodindex" value="~WS-OTPSubscriptionProdindex~">{/WS-OTPSubscriptionProdindex}
...
{WS-OTPSubscriptionProdindex}
{PR-LoadData($WS-OTPSubscriptionProdindex$,0)}
<a href="~PR-Link~" class="btn btn-secondary btn-block-sm btn-block-xs">Zurück zum Abo-Produkt "~PR-Name~"</a>
{/PR-LoadData($WS-OTPSubscriptionProdindex$,0)}
{/WS-OTPSubscriptionProdindex}
</form>
...
{/D-Edit}
Referenz: D-Tags
Schritt 13: Template für die Verwaltung der Bankdaten (ws_bank_manage.htm) anpassen (optional)
Ergänzen Sie auf dem Template ws_bank_manage.htm innerhalb des {BANK-Edit}-Bereichs mit den versteckten OTP-Parametern und den Links zurück auf die Abo-Produktseite.
{BANK-Edit}
...
<form action="~FORM-BankManage~" method="POST">
...
{WS-OTPSubscriptionProdindex}<input type="hidden" name="otpsubscriptionprodindex" value="~WS-OTPSubscriptionProdindex~">{/WS-OTPSubscriptionProdindex}
...
{WS-OTPSubscriptionProdindex}
{PR-LoadData($WS-OTPSubscriptionProdindex$,0)}
<a href="~PR-Link~" class="btn btn-secondary btn-block-sm btn-block-xs">Zurück zum Abo-Produkt "~PR-Name~"</a>
{/PR-LoadData($WS-OTPSubscriptionProdindex$,0)}
{/WS-OTPSubscriptionProdindex}
</form>
...
{/BANK-Edit}
Referenz: BANK-Tags
Schritt 14: AGB abfragen (optional)
Wenn Sie auf der Produktdetailansicht bei einer Abo-Bestellung auch die AGBs abfragen wollen, dann passen Sie bitte in der Shopkonfiguration shop.config den Abschnitt <AcceptTermsAndConditions> wie folgt an:
<AcceptTermsAndConditions>
...
Allow = yes
UserMustAcceptTermsAndConditions = yes
...
RequiredForNewSubscriptions = yes
...
</AcceptTermsAndConditions>
Referenz: AcceptTermsAndConditions
Referenz: AGB akzeptieren
Schritt 15: Abo-Modul mit PayPal bezahlen (optional)
Möchten Sie für das Abo-Moduk PayPal anbieten, benötigen Sie explizit PayPal Vault
Die notwendigen Schritte finden Sie hier:
Referenz: PayPal Checkout
Haben Sie alle Schritte durchgeführt, ist die Funktion "Abo-Modul" vollständig integriert und kann getestet/eingesetzt werden.
Rabatt gewähren auf Abo-Bestellung (optional)
Optional können Sie jedem Produkt einen Rabatt zuordnen, wenn es im Abonnement bestellt wird.
Voraussetzung
Der Rabattsatz in Prozent muss im Produktdatenfeld SubscriptionDiscount des Abo-Produkts hinterlegt sein.
Rabatt im Shop anzeigen
Die Klammerung PR-SubscriptionProductType() prüft, ob das Produkt im Abo bestellbar ist. Dabei steht im Argument y für abo-fähig, n für nicht abo-fähig und das b für sowohl als auch.
{PR-SubscriptionProductType(b)}
Dieses Produkt ist auch im Abonnement bestellbar.
{PR-SubscriptionDiscount}
Bei Bestellung per Abonnement gewähren wir ~PR-SubscriptionDiscount~ % Rabatt.
Der Rabatt beträgt absolut: ~PR-SubscriptionDiscountPrice~ ~WS-Currency~
Der reduzierte Produktpreis im Abo beträgt: ~PR-SubscriptionPrice~ ~WS-Currency~
{PR-SubscriptionDiscountPrice_prec}
~WS-SetPrecTagOutput(3)~
~PR-SubscriptionDiscountPrice_prec~ <!-- der reduzierte Preis wird mit höherer Präzision ausgegeben -->
{/PR-SubscriptionDiscountPrice_prec}
{/PR-SubscriptionDiscount}
{/PR-SubscriptionProductType(b)}
Referenz: PR-SubscriptionProductType()
Referenz: PR-SubscriptionDiscount
Referenz: PR-SubscriptionDiscountPrice
Referenz: PR-SubscriptionPrice
Referenz: PR-SubscriptionDiscountPrice_prec
PayPal Vault für das Abo-Modul
Die Integration von PayPal Vault finden sie hier