> ## Documentation Index
> Fetch the complete documentation index at: https://dokumentation.websale.de/llms.txt
> Use this file to discover all available pages before exploring further.

# Abo-Modul

> Produkte als Abonnement ohne feste Laufzeit anbieten, mit Lieferintervallen, Verwaltung im Kundenkonto und automatisch wiederkehrenden Bestellungen.

Wer Kaffee, Tierfutter oder Kontaktlinsen verkauft, verkauft etwas, das regelmäßig nachgekauft wird. Das Abo-Modul nimmt dem Käufer diesen wiederkehrenden Bestellvorgang ab: Er abonniert das Produkt einmal und bekommt es danach im gewählten Intervall automatisch geliefert und abgerechnet.

Abos haben **keine feste Laufzeit**. Der Käufer kann sie jederzeit pausieren, ändern oder beenden.

## Wie es funktioniert

### Der Abschluss läuft nicht über den Warenkorb

Ein Abo wird direkt auf der Produktdetailseite abgeschlossen. Der klassische Bestellablauf mit Warenkorb und Kasse wird nicht durchlaufen.

Daraus folgt eine Einschränkung, die auf den ersten Blick überrascht: **Ein Abo bezieht sich immer auf genau ein Produkt.** Die Menge kann größer als eins sein, aber zwei verschiedene Produkte ergeben zwei Abos. Der Grund liegt in der Konstruktion: Intervall, Lieferadresse und Zahlungsart werden am Produkt gewählt, nicht an einem Warenkorb.

Beim Abschluss legt der Käufer fest, was zum Abo gehört.

| Einstellung | |
| - | - |
| Lieferintervall | aus den von Ihnen definierten Intervallen |
| Lieferadresse | Rechnungsadresse oder eine Adresse aus dem Adressbuch |
| Zahlungsart | aus den für das Abo freigeschalteten Zahlungsarten |

### Zwei Varianten beim ersten Mal

| Variante | Was geschieht |
| - | - |
| Nur abonnieren | Es entsteht zunächst nur der Abo-Eintrag. Die erste Bestellung erzeugt der Sammellauf zum nächsten konfigurierten Zeitpunkt |
| Abonnieren und sofort auslösen | Die erste Bestellung entsteht sofort und geht unmittelbar an das ERP |

> [!WARNING]
>
> Der Unterschied ist für den Käufer deutlich spürbar. Beim Sammellauf um 12 Uhr und einem Abschluss um 13 Uhr entsteht die erste Bestellung erst am Folgetag, und erst dann bekommt der Käufer seine Bestelleingangsbestätigung. Wer nichts davon weiß, hält das Abo für gescheitert. Weisen Sie im Template darauf hin, oder bieten Sie die sofortige Auslösung an.

### Was der Käufer im Kundenkonto ändern kann

Lieferintervall, Menge, Lieferadresse und Zahlungsart, dazu pausieren, wieder aktivieren und kündigen. Pausieren ist zeitlich unbegrenzt.

### Zustände eines Abos

| Zustand | Bedeutung |
| - | - |
| neu | angelegt, die erste Bestellung steht noch aus |
| ausgelöst | die erste Bestellung wurde sofort erzeugt |
| aktiv | läuft im Intervall |
| pausiert | vom Käufer angehalten |

## Schritt 1: Abo-Produkte kennzeichnen

Die Kennzeichnung erfolgt über das Produktdatenfeld `SubscriptionProduct`.

| Wert | Bedeutung |
| - | - |
| `y` | nur im Abo erhältlich |
| `n` | nicht im Abo erhältlich |
| `b` | sowohl im Abo als auch als normales Kaufprodukt |

Unterstützt Ihr Warenwirtschaftssystem dieses Feld nicht, lässt sich beim Import ein freies Datenfeld darauf abbilden.

Wegweiser: [Rabatte festlegen](https://dokumentation.websale.de/v8s/weitere-funktionen-im-bestellprozess-kontext/rabatte-festlegen.md)

Die folgenden Schritte zeigen die Grundintegration. Ausführlichere Beispiele mit CSS, Modal-Dialogen und JavaScript stehen in den Materialien.

Materialien: [Materialien Abo-Modul](https://dokumentation.websale.de/v8s/materialien/materialien-abo-modul.md)

## Schritt 2: Freischaltung

Lassen Sie das Abo-Modul freischalten und teilen Sie dabei mit, **welche Zahlungsarten** dem Käufer im Abo zur Auswahl stehen sollen, beispielsweise Rechnung, Lastschrift oder PayPal.

## Schritt 3: Die Fehlermeldung für nicht angemeldete Käufer

Ein Abo setzt ein Kundenkonto voraus. Für den Fall, dass ein nicht angemeldeter Besucher es trotzdem versucht, hinterlegen Sie einen Text.

```ini theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<NotifyMessages-Txt>
   ...
   ProductSubscriptionProductNotOrderable = Um das Abo-Produkt ~PR-Name~ zu abonnieren, melden Sie sich bitte an. <a href="~WS-LoginLink~&type=LoginUser">Zur Anmeldung</a>
   ...
</NotifyMessages-Txt>
```

Referenz: [Abschnitt NotifyMessages-Txt](https://dokumentation.websale.de/v8s/referenz/konfigurationen/shopkonfiguration-shop-config/texte-und-meldungen.md#notifymessages-txt)

## Schritt 4: Das Modul konfigurieren

Alle Einstellungen stehen im Abschnitt `<Subscription>` der `shop.config`.

### Die Lieferintervalle

```ini theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<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>
```

| Parameter | |
| - | - |
| `description` | der Text, den der Käufer in der Auswahlliste sieht |
| `count` | die Anzahl |
| `unit` | die Einheit: `day`, `week`, `month` oder `year` |

> [!WARNING]
>
> Ein Eintrag mit einer unbekannten Einheit oder einem `count` von null wird **kommentarlos verworfen**. Er erscheint dann einfach nicht in der Auswahlliste, und es gibt keine Fehlermeldung. Wenn ein Intervall fehlt, prüfen Sie zuerst die Schreibweise der Einheit.
>
> Ändern oder löschen Sie Intervalle nach dem Livegang **nicht mehr**. Bestehende Abos behalten ihr altes Intervall, und der Käufer erfährt von der Änderung erst, wenn er selbst die Abo-Verwaltung öffnet. Bis dahin läuft sein Abo mit einem Intervall, das es offiziell nicht mehr gibt.

Die Zahl der Intervalle ist begrenzt. Legen Sie lieber wenige gut gewählte an als viele ähnliche. Jedes zusätzliche Intervall ist eine Entscheidung mehr, die der Käufer beim Abschluss treffen muss.

### Lieferungen zusammenfassen

Hat ein Käufer mehrere Abos mit ähnlichen Intervallen, lassen sich deren Lieferungen bündeln.

```ini theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<Subscription>
   ...
   ConsiderNextDays = 3
   ...
</Subscription>
```

Der Wert ist die Zeitspanne in Tagen, innerhalb derer anstehende Bestellungen zusammengefasst werden. Das spart Versandkosten und erspart dem Käufer zwei Pakete in derselben Woche.

### Erneute Bestellversuche nach Fehlern

```ini theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<Subscription>
   ...
   DaysRetry = 2
   ...
</Subscription>
```

Schlägt eine Abo-Bestellung fehl, versucht es der Bestellgenerator nach dieser Zahl von Tagen erneut. Bleibt der Fehler bestehen, wird nicht weiter versucht, und Sie erhalten eine Übersicht aller betroffenen Abos per E-Mail.

### Höchstzahl der Abos je Kunde

```ini theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<Subscription>
   ...
   MaxSubscriptionsPerUser = 0
   ...
</Subscription>
```

`0` oder nicht gesetzt bedeutet unbegrenzt. Ein Wert größer null begrenzt die Zahl gleichzeitiger Abos je Benutzerkonto.

Referenz: [Abschnitt Subscription](https://dokumentation.websale.de/v8s/referenz/konfigurationen/shopkonfiguration-shop-config/warenkorb-und-bestellprozess.md#subscription)

## Schritt 5: Die E-Mail-Benachrichtigungen konfigurieren

Vier Benachrichtigungen stehen zur Verfügung, alle als Unterabschnitte von `<Subscription>`.

| Unterabschnitt | Geht an | Wann |
| - | - | - |
| `<SubscriberNotificationMail>` | den Käufer | so viele Tage vor der nächsten Lieferung wie unter `Days` angegeben |
| `<MerchantNotificationMail>` | Sie | dieselbe Vorankündigung, aus Ihrer Sicht |
| `<OrderErrorMail>` | Sie | wenn eine Abo-Bestellung nicht erzeugt werden konnte |
| `<DisabledNotificationMail>` | Sie | wenn ein Abo auch nach dem zweiten Versuch scheitert |

```ini theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<Subscription>
   ...
   <SubscriberNotificationMail>
      Allow         = yes
      SenderAddress = versand@ihrshop.de
      SenderName    = Ihr Shop
      Subject-Txt   = Ihre nächste Abo-Lieferung steht an
      ReplyTo       = service@ihrshop.de
      Template      = mail_subscription_customer_notification.htm
      Days          = 4
   </SubscriberNotificationMail>
   ...
</Subscription>
```

Die beiden Händler-Meldungen brauchen zusätzlich eine Empfängeradresse.

```ini theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<Subscription>
   ...
   <OrderErrorMail>
      Allow           = yes
      ReceiverAddress = bestellungen@ihrshop.de
      SenderAddress   = versand@ihrshop.de
      SenderName      = Ihr Shop
      Subject-Txt     = Eine Abo-Bestellung konnte nicht erstellt werden
      ReplyTo         = service@ihrshop.de
      Template        = mail_subscription_order_error.htm
   </OrderErrorMail>
   ...
</Subscription>
```

`Days` gibt es nur bei den beiden Vorankündigungen. Wählen Sie den Wert so, dass der Käufer noch reagieren kann, beispielsweise um die Menge anzupassen oder das Abo zu pausieren. Vier Tage sind ein brauchbarer Ausgangswert, ein Tag ist zu knapp.

> [!WARNING]
>
> Die Vorankündigung an den Käufer ist keine Höflichkeit, sondern Ihr wirksamster Schutz vor Rücksendungen und Zahlungsrückläufern. Wer vergessen hat, dass er abonniert hat, widerspricht der Abbuchung.

## Schritt 6: Versandarten einschränken (optional)

In den `<+Deliverer>`-Abschnitten legen Sie fest, ob eine Versandart für Abo-Bestellungen gilt.

```ini theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<+Deliverer>
   ...
   AllowForSubscriptionOrder-Qualification = use-for-all
   ...
</+Deliverer>
```

| Wert | Wirkung |
| - | - |
| `use-for-all` | für Abo- und normale Bestellungen. Voreinstellung |
| `only-for-subscriptionorder` | ausschließlich für Abo-Bestellungen |
| `not-for-subscriptionorder` | für Abo-Bestellungen ausgeschlossen |

WEBSALE empfiehlt für Abos kostenlosen Versand. Bei einem wiederkehrenden Betrag ist Preistransparenz besonders wichtig, und Versandkosten, die der Käufer beim Abschluss nicht überblickt, sind ein häufiger Kündigungsgrund.

Ausgeschlossene Versandarten lassen sich dem Käufer ausgegraut mit Begründung anzeigen.

```ini theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<DelivererShowDisabled-Definitions>
   <+ShowDisabled-Rule>
      ShowDisabled-GroupID = VersandartNichtVerfuegbar
      <ShowDisabled-Txt>
         29 = Diese Versandart steht nur für Abo-Bestellungen zur Verfügung.
         30 = Diese Versandart steht für Abo-Bestellungen nicht zur Verfügung.
      </ShowDisabled-Txt>
   </+ShowDisabled-Rule>
</DelivererShowDisabled-Definitions>
```

> [!WARNING]
>
> Hinterlegen Sie in jedem `<+Deliverer>`-Abschnitt die passende `UseShowDisabled-GroupID`. Ohne sie greift die Regel nicht.

Referenz: [Abschnitt +Deliverer](https://dokumentation.websale.de/v8s/referenz/konfigurationen/shopkonfiguration-shop-config/versand-und-lieferung.md#deliverer) · [Abschnitt DelivererShowDisabled-Definitions](https://dokumentation.websale.de/v8s/referenz/konfigurationen/shopkonfiguration-shop-config/versand-und-lieferung.md#deliverershowdisabled-definitions)

Wegweiser: [Versandarten anlegen](https://dokumentation.websale.de/v8s/versandarten-anlegen/versandarten-anlegen.md)

## Schritt 7: Die Abo-Verwaltung im Kundenkonto

```ini theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<Templates>
   ...
   Subscription = ws_subscription_manage.htm
   ...
</Templates>
```

Auf diese Seite kommt der Käufer nach dem Abschluss eines Abos und aus seinem Kundenkonto heraus. Sie enthält:

* Erfolgs- und Fehlermeldungen
* die Übersicht aller Abos, einschließlich des Falls "noch keine Abos"
* je Abo die Produktdaten, den Zustand und das nächste Lieferdatum
* je Abo die Änderungsmöglichkeiten
* die Aktionen löschen, pausieren und aktivieren

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<div id="subscriptionContent">
{ST-Ajax}<WS-Ajax-subscriptionContent>{/ST-Ajax}

   <h2>Ihre Abonnements</h2>

   {MSG-Subscription_success}
      {MSG-Subscription_success(1)}<p>Ihr Abonnement wurde abgeschlossen.</p>{/MSG-Subscription_success(1)}
      {MSG-Subscription_success(2)}<p>Ihr Abonnement ist pausiert. Sie können es jederzeit wieder aktivieren.</p>{/MSG-Subscription_success(2)}
      {MSG-Subscription_success(3)}<p>Ihr Abonnement ist wieder aktiv.</p>{/MSG-Subscription_success(3)}
      {MSG-Subscription_success(4)}<p>Ihre Änderungen wurden übernommen.</p>{/MSG-Subscription_success(4)}
      {MSG-Subscription_success(5)}<p>Ihr Abonnement wurde gelöscht.</p>{/MSG-Subscription_success(5)}
      {MSG-Subscription_success(6)}<p>Ihre erste Abo-Bestellung wird in Kürze ausgeführt.</p>{/MSG-Subscription_success(6)}
      {MSG-Subscription_success(7)}<p>Für Ihre Abonnements gilt jetzt eine neue Bankverbindung.</p>{/MSG-Subscription_success(7)}
   {/MSG-Subscription_success}

   {MSG-Subscription_error}
      {MSG-Subscription_error(1)}<p>Bitte melden Sie sich an, um ein Abo abzuschließen.</p>{/MSG-Subscription_error(1)}
      {MSG-Subscription_error(2)}<p>Bitte prüfen Sie Menge und Lieferintervall.</p>{/MSG-Subscription_error(2)}
      {MSG-Subscription_error(3)}<p>Bitte aktivieren Sie das Abonnement, bevor Sie es ändern.</p>{/MSG-Subscription_error(3)}
      {MSG-Subscription_error(4)}<p>Dieses Produkt ist nicht als Abo erhältlich.</p>{/MSG-Subscription_error(4)}
      {MSG-Subscription_error(5)}<p>Set-Produkte können nicht abonniert werden.</p>{/MSG-Subscription_error(5)}
      {MSG-Subscription_error(6)}<p>Bitte wählen Sie zuerst eine Produktvariante.</p>{/MSG-Subscription_error(6)}
      {MSG-Subscription_error(7)}<p>Das Produkt wurde nicht gefunden.</p>{/MSG-Subscription_error(7)}
   {/MSG-Subscription_error}

   {!SUBS-Data}
      <p>Sie haben derzeit keine Abonnements.</p>
   {/!SUBS-Data}

   {SUBS-Data}

      <p>Sie haben ~SUBS-Data~ Abonnements. Sie können sie jederzeit ändern, pausieren oder beenden.</p>

      <form action="~FORM-Subscription~" method="post" id="subscription">

      {@SUBS-Data}

         {PR-LoadData($SUBS-Data_PR_Number$,1)}
            {PR-Name}<h3>~PR-Name~</h3>{/PR-Name}
            {PR-LargeImage}
               <a href="~PR-DepVarLink~"><img src="~PR-LargeImage~" alt="~PR-Name_StripHtml~" width="100"></a>
            {/PR-LargeImage}

            ~DC-FPCurrentPrice_set($PR-Price$)~

            {!DC-FPCurrentPrice($SUBS-Data_PR_Price$)}
               <p>Der Preis dieses Produkts hat sich geändert und beträgt jetzt ~DC-FPCurrentPrice~ ~WS-CurrencySymbol~.</p>
            {/!DC-FPCurrentPrice($SUBS-Data_PR_Price$)}
         {/PR-LoadData($SUBS-Data_PR_Number$,1)}

         {SUBS-Data_state_ispaused}<p>Dieses Abonnement ist pausiert.</p>{/SUBS-Data_state_ispaused}
         {SUBS-Data_state_isactive}
            <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>Erste Lieferung: ~DC-DateTime_setunixtimestamp($SUBS-Data_nextorder_unixtimestamp$)~ ~DC-DateTime_day~.~DC-DateTime_month~.~DC-DateTime_year~</p>
         {/SUBS-Data_state_isnew}

         <label>Menge</label>
         <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()')">

         <label>Lieferintervall</label>
         <select 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>

         <button type="submit" name="~SUBS-Data_Buttonname~" value="~SUBS-Data_Buttonvalue_delete~">löschen</button>

         {SUBS-Data_Buttonvalue_pause}
            <button type="submit" name="~SUBS-Data_Buttonname~" value="~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~">aktivieren</button>
         {/SUBS-Data_Buttonvalue_resume}

      {/@SUBS-Data}

      </form>

   {/SUBS-Data}

{ST-Ajax}</WS-Ajax-subscriptionContent>{/ST-Ajax}
</div>
```

Die Klammerungen `{SUBS-Data_Buttonvalue_pause}` und `{SUBS-Data_Buttonvalue_resume}` sind das Mittel, um immer nur die passende Schaltfläche zu zeigen. Ein pausiertes Abo bietet "aktivieren", ein laufendes "pausieren". Prüfen Sie den Zustand nicht selbst.

Der Preisvergleich über `DC-FPCurrentPrice` meldet dem Käufer eine Preisänderung seit dem Abschluss seines Abos. Das ist ein freiwilliger, aber sehr sinnvoller Zusatz: Eine stillschweigend teurer gewordene Abbuchung ist der klassische Anlass für Rückfragen.

> [!WARNING]
>
> Das Feld für die Menge sendet beim Verlassen, die Auswahllisten senden beim Ändern. Es gibt keine Schaltfläche "speichern". Weisen Sie den Käufer darauf hin, sonst klickt er suchend umher und glaubt, seine Änderung sei verloren.

Referenz: [SUBS-Tags](https://dokumentation.websale.de/v8s/referenz/tags/subs/abo-abschliessen.md) · [Abschnitt Templates](https://dokumentation.websale.de/v8s/referenz/konfigurationen/shopkonfiguration-shop-config/grundlagen-und-technik.md#templates)

## Schritt 8: Die E-Mail-Templates anlegen

Die Dateinamen müssen zu den `Template`-Angaben aus Schritt 5 passen.

Alle vier Benachrichtigungen bauen auf derselben Schleife `@E-SUBS_Data` auf, die über die betroffenen Abos läuft.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{@E-SUBS_Data}
   Abo-Index:      ~E-SUBS_DATA_Index~
   Kundenindex:    ~E-SUBS_DATA_UserIndex~
   Produktnummer:  ~E-SUBS_DATA_PR_number~
   Produktname:    ~E-SUBS_DATA_PR_Name~
   Menge:          ~E-SUBS_DATA_PR_Quantity~
   Preis:          ~E-SUBS_DATA_PR_Price~ ~E-SUBS_DATA_PR_CurrencyCode~
   Angelegt am:    ~E-SUBS_DATA_Created~
   Zuletzt geändert: ~E-SUBS_DATA_LastChange~
   Letzte Bestellung:  ~E-SUBS_DATA_LastOrder~
   Nächste Bestellung: ~E-SUBS_DATA_NextOrder~
{/@E-SUBS_Data}
```

Die vier Templates unterscheiden sich nur in wenigen Punkten.

| Template | Zusätzlich |
| - | - |
| an den Käufer | nichts, nur die Schleife. Formulieren Sie hier für Menschen, nicht mit technischen Indizes |
| an den Händler, Vorankündigung | zusätzlich `@E-SUBS_DataByProduct`, gruppiert nach Produkt |
| an den Händler, Bestellfehler | zusätzlich `E-SUBS_ErrorMsg` und `E-SUBS_ErrorCode` |
| an den Händler, endgültig gescheitert | nichts, nur die Schleife |

> [!WARNING]
>
> Die Vorlagen geben in der Käufer-E-Mail Abo-Index, Kundenindex und Produktindex aus. Das sind interne Nummern, die für den Käufer bedeutungslos sind. Verwenden Sie in dieser einen E-Mail nur Produktname, Menge, Preis und Datum.

Die Gruppierung nach Produkt zeigt Ihnen, wie viel von welchem Artikel insgesamt ansteht.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{@E-SUBS_DataByProduct}
   Produktnummer: ~E-SUBS_DATA_PR_number~
   Produktname:   ~E-SUBS_DATA_PR_Name~
   Menge:         ~E-SUBS_DATA_PR_Quantity~
{/@E-SUBS_DataByProduct}
```

Genau diese Gruppierung macht die Vorankündigung an Sie nützlich. Sie sehen daran rechtzeitig, ob der Bestand für die anstehenden Abo-Lieferungen reicht.

Aktuelle Produktdaten laden Sie bei Bedarf nach.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{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)}
```

`NO_PARSING` ist hier nötig, weil der Produktindex erst zur Laufzeit feststeht und der Parameter deshalb nicht vorab aufgelöst werden darf.

Referenz: [E-SUBS-Tags](https://dokumentation.websale.de/v8s/referenz/tags/e-pia/galerie.md)

## Schritt 9: Die Produktdetailansicht erweitern

Hier entsteht das Abo. Das ist der umfangreichste Schritt.

### Abo-fähige Produkte unterscheiden

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{PR-Data}
   {PR-SubscriptionProduct}
      <p>Dieses Produkt ist auch im Abonnement erhältlich.</p>
   {/PR-SubscriptionProduct}

   {!PR-SubscriptionProduct}
      <p>Dieses Produkt ist nicht als Abonnement erhältlich.</p>
   {/!PR-SubscriptionProduct}
{/PR-Data}
```

### Nicht angemeldete Besucher zum Login führen

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{!ST-LoggedIn}
   <p>Für ein Abonnement benötigen Sie ein Kundenkonto.</p>
   <a href="~WS-LoginLink~&type=loginUser&act=subscription&otpsubscriptionprodindex=~PR-ProdIndex~">
      Anmelden oder Konto eröffnen
   </a>
{/!ST-LoggedIn}
```

Der Parameter `otpsubscriptionprodindex` merkt sich das Produkt über den Login hinweg. Ohne ihn landet der Käufer nach der Anmeldung im Kundenkonto und muss das Produkt erneut suchen. Dieser Parameter zieht sich durch die Schritte 10 bis 13.

### Die Abo-Einstellungen anbieten

Das Ganze steht im Produktformular.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{PR-SubscriptionProduct}
<form action="~FORM-Product~" method="post" id="productform">
{ST-LoggedIn}

   {SUBS-CycleSelection}
      <label>Lieferintervall</label>
      <select name="~SUBS-CycleSelection_input~" onchange="ws_AJAXPR('productform', '~WS-Charset~');">
         <option value="">Bitte wählen</option>
         {@SUBS-CycleSelection_data}
            <option value="~SUBS-CycleSelection_data_value~" ~SUBS-CycleSelection_data_selected~>~SUBS-CycleSelection_data_descr~</option>
         {/@SUBS-CycleSelection_data}
      </select>
   {/SUBS-CycleSelection}

   ~D-LoadData~
   <label>Lieferadresse</label>
   <select name="~SUBS-DelivAddress_input~" onchange="ws_AJAXPR('productform', '~WS-Charset~');">
      <option value="">Bitte wählen</option>
      <option value="0" {SUBS-DelivAddress_selected(0)}selected{/SUBS-DelivAddress_selected(0)}>An meine Rechnungsadresse</option>
      {D-DeliverySelection}
         {@D-Data}
            <option value="~D-DeliverySelection_value~" {SUBS-DelivAddress_selected($D-DeliverySelection_value$)}selected{/SUBS-DelivAddress_selected($D-DeliverySelection_value$)}>
               ~D-FirstName~ ~D-LastName~, ~D-Zip~ ~D-City~
            </option>
         {/@D-Data}
      {/D-DeliverySelection}
   </select>

   {D-NewDelivAddressLink}
      <a href="~D-NewDelivAddressLink~&otpsubscriptionprodindex=~PR-ProdIndex~">An eine neue Lieferadresse</a>
   {/D-NewDelivAddressLink}

   <label>Zahlungsart</label>
   <select name="~SUBS-PaymentMethod_input~" onchange="ws_AJAXPR('productform', '~WS-Charset~');">
      <option value="">Bitte wählen</option>
      {@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}
         <option value="~SUBS-AllowedPayments~" {SUBS-PaymentMethod_selected($SUBS-AllowedPayments$)}selected{/SUBS-PaymentMethod_selected($SUBS-AllowedPayments$)}>
            ~DC-FPPaymentName~
         </option>
      {/@SUBS-AllowedPayments}
   </select>

   {SUBS-PaymentMethod_selected(4)}
      {BANK-Data}{BANK-BankSelection}
         <label>Bankverbindung</label>
         <select 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}

      {Bank-NewBankLink}
         <a href="~WS-EnsureNextLinkContainsURLParams~~Bank-NewBankLink~&otpsubscriptionprodindex=~PR-ProdIndex~">Neue Bankverbindung</a>
      {/Bank-NewBankLink}
   {/SUBS-PaymentMethod_selected(4)}

   <label>
      <input type="checkbox" name="~WS-AcceptTermsAndConditions_input~" value="1"
             ~WS-AcceptTermsAndConditions_checked~ onchange="ws_AJAXPR('productform', '~WS-Charset~');">
      Ich akzeptiere die AGB und habe das Widerrufsrecht zur Kenntnis genommen.
   </label>

   <input type="submit" name="~BT-Subscription~" value="Abonnieren" {!ST-Conditions_OK}disabled{/!ST-Conditions_OK}>
   <input type="submit" name="~BT-SubscriptionAndTrigger~" value="Abonnieren und sofort liefern" {!ST-Conditions_OK}disabled{/!ST-Conditions_OK}>

{/ST-LoggedIn}
</form>
{/PR-SubscriptionProduct}
```

Jede Auswahl löst über `ws_AJAXPR` einen Neuaufbau des Formulars aus. Das ist nötig, weil abhängige Bereiche nachladen müssen: Die Bankauswahl erscheint erst, wenn Lastschrift gewählt ist, und die Adressanzeige erst, wenn eine Adresse gewählt ist.

> [!WARNING]
>
> Die beiden Schaltflächen entsprechen den beiden Varianten aus dem Abschnitt "Wie es funktioniert". Beschriften Sie sie so, dass der Unterschied erkennbar ist. "Abonnieren" und "Abonnieren und sofort bestellen" sagt mehr als "Abonnieren" und "Jetzt abonnieren".

Die Zahlungsart-Auswahl sieht aufwendig aus, weil `SUBS-AllowedPayments` nur den Zahlungsart-Code liefert. Die Schleife über `@PAY-Data` bildet diesen Code auf den lesbaren Namen ab.

Referenz: [PR-SubscriptionProduct](https://dokumentation.websale.de/v8s/referenz/tags/pr/grundlagen-und-produktdaten.md) · BT-Subscription · BT-SubscriptionAndTrigger · SUBS-Tags

## Schritte 10 bis 13: Den Produktbezug über andere Seiten retten

Der Käufer verlässt die Produktseite mehrfach: zum Anmelden, zum Anlegen einer Adresse, zum Hinterlegen einer Bankverbindung. Damit er zurückfindet, wird der Produktindex überall mitgeführt.

**Das Muster ist auf allen vier Seiten dasselbe.** Es besteht aus zwei Teilen: einem versteckten Feld im Formular und einem Rücksprunglink.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{WS-OTPSubscriptionProdindex}
   <input type="hidden" name="otpsubscriptionprodindex" value="~WS-OTPSubscriptionProdindex~">
{/WS-OTPSubscriptionProdindex}

{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 | Template | Einzubauen in |
| - | - | - |
| 10 | `ws_login.htm` | jedes verwendete Anmeldeformular |
| 11 | `ws_address_manage.htm` | den Bereich `A-Edit` |
| 12 | `ws_deliv_address_manage.htm` | den Bereich `D-Edit`, optional |
| 13 | `ws_bank_manage.htm` | den Bereich `BANK-Edit`, optional |

Auf der Anmeldeseite gehört das versteckte Feld in **alle** Formulare, die Sie verwenden, also gegebenenfalls in das für Neukunden, das für Bestandskunden und das kombinierte.

Besser als der Umweg über eigene Seiten ist es, Anmeldung und Adresspflege per AJAX in einem Dialog auf der Produktseite zu erledigen. Der Käufer bleibt dann, wo er ist, und die bereits gewählten Abo-Einstellungen gehen nicht verloren. Die Beispiele in den Materialien zeigen das.

Referenz: [FORM-CombinedLogin](https://dokumentation.websale.de/v8s/referenz/tags/form-formulare.md#anmeldung-und-passwort) · D-Tags · [BANK-Tags](https://dokumentation.websale.de/v8s/referenz/tags/bank.md)

## Schritt 14: AGB abfragen (optional)

```ini theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<AcceptTermsAndConditions>
   ...
   Allow                            = yes
   UserMustAcceptTermsAndConditions = yes
   RequiredForNewSubscriptions      = yes
   ...
</AcceptTermsAndConditions>
```

Der dritte Parameter ist der entscheidende. Er verlangt die Zustimmung auch beim Abo-Abschluss, der ja nicht über den normalen Bestellprozess läuft und deshalb die dortige AGB-Abfrage nicht durchläuft.

Referenz: [Abschnitt AcceptTermsAndConditions](https://dokumentation.websale.de/v8s/referenz/konfigurationen/shopkonfiguration-shop-config/warenkorb-und-bestellprozess.md#accepttermsandconditions)

Wegweiser: [AGB akzeptieren](https://dokumentation.websale.de/v8s/bestelluebersicht-bestelleingangsbestaetigung/agb-akzeptieren.md)

## Schritt 15: PayPal für Abos (optional)

Für Abos mit PayPal ist **PayPal Vault** erforderlich. Eine einmalige Zahlung genügt nicht, denn der Shop muss später wiederkehrend abbuchen können.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{SUBS-Data_PaymentCode(37)}
   {!PPC-Vaulted}
      <p>Bitte verbinden Sie einmalig Ihr PayPal-Konto.</p>
      <a href="~WS-PPCVaultManageLink~">PayPal-Konto verbinden</a>
   {/!PPC-Vaulted}
   {PPC-Vaulted}
      <p>Zahlung über das PayPal-Konto ~PPC-VaultedEmailAddress~</p>
   {/PPC-Vaulted}
{/SUBS-Data_PaymentCode(37)}
```

> [!WARNING]
>
> Ohne verbundenes Konto scheitert die erste wiederkehrende Abbuchung, nicht der Abschluss. Der Käufer bemerkt das Problem also erst, wenn die Lieferung ausbleibt. Prüfen Sie den Zustand deshalb schon in der Abo-Verwaltung und weisen Sie dort deutlich darauf hin.

Referenz: [PayPal Checkout](https://dokumentation.websale.de/v8s/zahlungsarten-anlegen/paypal-checkout.md)

## Rabatt auf Abo-Bestellungen (optional)

Ein Abo-Rabatt ist das übliche Mittel, um den Käufer von der einmaligen Bestellung zum Abo zu bewegen. Den Satz in Prozent hinterlegen Sie im Produktdatenfeld `SubscriptionDiscount`.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{PR-SubscriptionProductType(b)}
   <p>Dieses Produkt ist auch im Abonnement erhältlich.</p>

   {PR-SubscriptionDiscount}
      <p>Im Abonnement sparen Sie ~PR-SubscriptionDiscount~ %.</p>
      <p>Das sind ~PR-SubscriptionDiscountPrice~ ~WS-Currency~ je Lieferung.</p>
      <p>Ihr Abo-Preis: ~PR-SubscriptionPrice~ ~WS-Currency~</p>
   {/PR-SubscriptionDiscount}

{/PR-SubscriptionProductType(b)}
```

`PR-SubscriptionProductType()` nimmt denselben Wert als Parameter, der auch im Produktdatenfeld steht.

| Parameter | Trifft zu bei |
| - | - |
| `y` | nur im Abo erhältlich |
| `n` | nicht im Abo erhältlich |
| `b` | beides möglich |

Der Rabatt ist optional. Alle übrigen produktbezogenen Rabatte von WEBSALE V8s stehen beim Abo-Produkt ebenfalls zur Verfügung.

Für die Anzeige mit höherer Genauigkeit gibt es `PR-SubscriptionDiscountPrice_prec` in Verbindung mit `WS-SetPrecTagOutput()`. Das ist sinnvoll, wenn der Rabattbetrag je Lieferung klein ist und auf zwei Stellen gerundet null ergäbe.

Referenz: [PR-SubscriptionProductType()](https://dokumentation.websale.de/v8s/referenz/tags/pr/grundlagen-und-produktdaten.md) · [PR-SubscriptionDiscount](https://dokumentation.websale.de/v8s/referenz/tags/pr/grundlagen-und-produktdaten.md) · [PR-SubscriptionDiscountPrice](https://dokumentation.websale.de/v8s/referenz/tags/pr/grundlagen-und-produktdaten.md) · [PR-SubscriptionPrice](https://dokumentation.websale.de/v8s/referenz/tags/pr/grundlagen-und-produktdaten.md)

## Verwandte Themen

* Wegweiser: [Rabatte festlegen](https://dokumentation.websale.de/v8s/weitere-funktionen-im-bestellprozess-kontext/rabatte-festlegen.md)
* Wegweiser: [Versandarten anlegen](https://dokumentation.websale.de/v8s/versandarten-anlegen/versandarten-anlegen.md)
* Wegweiser: [AGB akzeptieren](https://dokumentation.websale.de/v8s/bestelluebersicht-bestelleingangsbestaetigung/agb-akzeptieren.md)
* Referenz: PayPal Checkout


## Related topics

- [Spezielle Online-Dienste](https://dokumentation.websale.de/v8s/online-servicebereich/spezielle-online-dienste.md)
- [MSG- (Meldungen)](https://dokumentation.websale.de/v8s/referenz/tags/msg-meldungen.md)
- [Materialien Abo-Modul](https://dokumentation.websale.de/v8s/materialien/materialien-abo-modul.md)
- [E-SUBS- (Abo-Modul)](https://dokumentation.websale.de/v8s/referenz/tags/e-subs-abo-modul.md)
- [SUBS- (Abos verwalten)](https://dokumentation.websale.de/v8s/referenz/tags/subs/abos-verwalten.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.