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

# Subscription Integration Guide

> This guide will help you integrate the Dodo Payments Subscription Product into your website.

## Prerequisites

To integrate the Dodo Payments API, you'll need:

* A Dodo Payments merchant account
* API credentials (API key and webhook secret key) from the dashboard

For a more detailed guide on the prerequisites, check this [section](/developer-resources/integration-guide#dashboard-setup).

## API Integration

### Checkout Sessions

Use Checkout Sessions to sell subscription products with a secure, hosted checkout. Pass your subscription product in `product_cart` and redirect customers to the returned `checkout_url`.

<Tip>
  **Mixed Checkout**: You can combine subscription products with one-time products in the same checkout session. This enables use cases like setup fees with subscriptions, hardware bundles with SaaS, and more. See the [Checkout Sessions guide](/developer-resources/checkout-session) for examples.
</Tip>

<Tabs>
  <Tab title="Node.js SDK">
    ```javascript theme={null}
    import DodoPayments from 'dodopayments';

    const client = new DodoPayments({
      bearerToken: process.env.DODO_PAYMENTS_API_KEY,
      environment: 'test_mode', // defaults to 'live_mode'
    });

    async function main() {
      const session = await client.checkoutSessions.create({
        product_cart: [
          { product_id: 'prod_subscription_monthly', quantity: 1 }
        ],
        // Optional: configure trials for subscription products
        subscription_data: { trial_period_days: 14 },
        customer: {
          email: 'subscriber@example.com',
          name: 'Jane Doe',
        },
        return_url: 'https://example.com/success',
      });

      console.log(session.checkout_url);
    }

    main();
    ```
  </Tab>

  <Tab title="Python SDK">
    ```python theme={null}
    import os
    from dodopayments import DodoPayments

    client = DodoPayments(
        bearer_token=os.environ.get("DODO_PAYMENTS_API_KEY"),
        environment="test_mode",  # defaults to "live_mode"
    )

    session = client.checkout_sessions.create(
        product_cart=[
            {"product_id": "prod_subscription_monthly", "quantity": 1}
        ],
        subscription_data={"trial_period_days": 14},  # optional
        customer={
            "email": "subscriber@example.com",
            "name": "Jane Doe",
        },
        return_url="https://example.com/success",
    )

    print(session.checkout_url)
    ```
  </Tab>

  <Tab title="REST API">
    ```javascript theme={null}
    const response = await fetch('https://test.dodopayments.com/checkouts', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${process.env.DODO_PAYMENTS_API_KEY}`
      },
      body: JSON.stringify({
        product_cart: [
          { product_id: 'prod_subscription_monthly', quantity: 1 }
        ],
        subscription_data: { trial_period_days: 14 }, // optional
        customer: {
          email: 'subscriber@example.com',
          name: 'Jane Doe'
        },
        return_url: 'https://example.com/success'
      })
    });

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    const session = await response.json();
    console.log(session.checkout_url);
    ```
  </Tab>
</Tabs>

### API Response

The following is an example of the response:

```json theme={null}
{
  "session_id": "cks_Gi6KGJ2zFJo9rq9Ukifwa",
  "checkout_url": "https://test.checkout.dodopayments.com/session/cks_Gi6KGJ2zFJo9rq9Ukifwa"
}
```

Leiten Sie den Kunden zu `checkout_url`.

### Webhooks

Bei der Integration von Abonnements erhalten Sie Webhooks, um den Lebenszyklus der Abonnements zu verfolgen. Diese Webhooks helfen Ihnen, den Abonnementstatus und Zahlungsszenarien effektiv zu verwalten.

Um Ihren Webhook-Endpunkt einzurichten, folgen Sie bitte unserem [Detaillierten Integrationshandbuch](/developer-resources/integration-guide#implementing-webhooks).

#### Abonnement-Ereignistypen

Die folgenden Webhook-Ereignisse verfolgen Änderungen des Abonnementstatus:

1. **`subscription.active`** - Abonnement wurde erfolgreich aktiviert.
2. **`subscription.updated`** - Abonnementobjekt wurde aktualisiert (wird bei jeder Feldänderung ausgelöst).
3. **`subscription.on_hold`** - Abonnement wird wegen fehlgeschlagener Verlängerung pausiert.
4. **`subscription.failed`** - Abonnementerstellung schlug bei der Erstellung des Mandats fehl.
5. **`subscription.renewed`** - Abonnement wird für den nächsten Abrechnungszeitraum erneuert.

Für ein zuverlässiges Abonnement-Lebenszyklusmanagement empfehlen wir, diese Abonnementereignisse zu verfolgen.

<Tip>
  Verwenden Sie `subscription.updated`, um Echtzeitbenachrichtigungen über Abonnementänderungen zu erhalten, und halten Sie den Zustand Ihrer Anwendung ohne Abfrage des APIs synchron.
</Tip>

#### Zahlungsszenarien

**Erfolgreicher Zahlungsablauf**

Wenn eine Zahlung erfolgreich ist, erhalten Sie die folgenden Webhooks:

1. `subscription.active` - Zeigt die Aktivierung des Abonnements an
2. `payment.succeeded` - Bestätigt die Erstzahlung:
   * Bei sofortiger Abrechnung (0 Testtage): Erwartet innerhalb von 2-10 Minuten
   * Bei Testtagen: immer wenn diese enden
3. `subscription.renewed` - Zeigt den Zahlungsabzug und die Erneuerung für den nächsten Zyklus an. (Grundsätzlich erhalten Sie immer, wenn eine Zahlung für Abonnementprodukte abgezogen wird, den `subscription.renewed` Webhook zusammen mit `payment.succeeded`)

**Zahlungsausfall-Szenarien**

1. Abonnementausfall

* `subscription.failed` - Abonnementerstellung fehlgeschlagen aufgrund eines fehlgeschlagenen Mandats.
* `payment.failed` - Zeigt fehlgeschlagene Zahlung an.

2. Abonnement pausiert

* `subscription.on_hold` - Abonnement wird aufgrund einer fehlgeschlagenen Verlängerungszahlung oder einer fehlgeschlagenen Planänderungsgebühr pausiert.
* Wenn ein Abonnement pausiert, wird es nicht automatisch erneuert, bis die Zahlungsmethode aktualisiert wird.

<Info>**Best Practice**: Um die Implementierung zu vereinfachen, empfehlen wir vor allem, Abonnementereignisse zur Verwaltung des Abonnement-Lebenszyklus zu verfolgen.</Info>

<Tip>
  Für eine vollständige Anleitung zum Lesen von `error_code`/`error_message`, zur Entscheidung, wann ein erneuter Versuch stattfinden soll, und zum Anzeigen von Fehlern für Kunden, siehe [Zahlungsausfälle behandeln](/developer-resources/handle-payment-failures).
</Tip>

#### `subscription.failed` vs. `subscription.on_hold`

Diese beiden Ereignisse sind leicht zu verwechseln, erfordern jedoch eine sehr unterschiedliche Handhabung:

| Ereignis               | Wann es ausgelöst wird                                                                                     | Status    | Wiederherstellbar?  | Was zu tun ist                                                                                                                              |
| ---------------------- | ---------------------------------------------------------------------------------------------------------- | --------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `subscription.failed`  | Das **erste** Mandat konnte bei der Abonnement**erstellung** nicht erstellt werden                         | `failed`  | **Nein — terminal** | Keinen Zugriff gewähren. Bitten Sie den Kunden, ein **neues** Abonnement mit einer anderen Zahlungsmethode zu starten.                      |
| `subscription.on_hold` | Eine **Verlängerungs**zahlung (oder Planänderungsgebühr) schlägt bei einem bereits aktiven Abonnement fehl | `on_hold` | **Ja**              | Wiederherstellen durch Aktualisierung der Zahlungsmethode; siehe [Abonnement auf Pausiert behandeln](#handling-subscription-on-hold) unten. |

<Warning>
  `subscription.failed` ist endgültig — das Abonnement kann nicht reaktiviert werden. Der Kunde muss ein neues Abonnement erstellen. Gewähren Sie niemals Ansprüche, wenn dieses Ereignis ausgelöst wird.
</Warning>

### Abonnement auf Pausiert behandeln

Wenn ein Abonnement in den `on_hold` Zustand wechselt, müssen Sie die Zahlungsmethode aktualisieren, um es zu reaktivieren. Dieser Abschnitt erklärt, wann Abonnements auf Pausiert gestellt werden und wie man sie behandelt.

#### Wann Abonnements auf Pausiert gestellt werden

Ein Abonnement wird pausiert, wenn:

* **Verlängerungszahlung fehlschlägt**: Die automatische Verlängerungsgebühr schlägt aufgrund unzureichender Mittel, abgelaufener Karte oder Bankablehnung fehl
* **Planänderungsgebühr fehlschlägt**: Eine sofortige Gebühr während eines Plan-Upgrades/Downgrades schlägt fehl
* **Zahlungsmethode-Autorisierung fehlschlägt**: Die Zahlungsmethode kann nicht für wiederkehrende Gebühren autorisiert werden

<Warning>
  Abonnements im `on_hold` Zustand werden nicht automatisch erneuert. Sie müssen die Zahlungsmethode aktualisieren, um das Abonnement zu reaktivieren.
</Warning>

#### Reaktivierung von Abonnements von Pausiert

Um ein Abonnement aus dem `on_hold` Zustand zu reaktivieren, verwenden Sie die Update Payment Method API. Dies bewirkt automatisch:

1. Erstellung einer Gebühr für ausstehende Beträge
2. Erstellung einer Rechnung für die Gebühr
3. Verarbeitung der Zahlung mit der neuen Zahlungsmethode
4. Reaktivierung des Abonnements in den `active` Zustand nach erfolgreicher Zahlung

<Steps>
  <Step title="Handle subscription.on_hold webhook">
    Wenn Sie einen `subscription.on_hold` Webhook erhalten, aktualisieren Sie den Zustand Ihrer Anwendung und benachrichtigen Sie den Kunden:

    ```javascript theme={null}
    // Webhook handler
    app.post('/webhooks/dodo', async (req, res) => {
      const event = req.body;
      
      if (event.type === 'subscription.on_hold') {
        const subscription = event.data;
        
        // Update subscription status in your database
        await updateSubscriptionStatus(subscription.subscription_id, 'on_hold');
        
        // Notify customer to update payment method
        await sendEmailToCustomer(subscription.customer_id, {
          subject: 'Payment Required - Subscription On Hold',
          message: 'Your subscription is on hold. Please update your payment method to continue service.'
        });
      }
      
      res.json({ received: true });
    });
    ```
  </Step>

  <Step title="Update payment method">
    Wenn der Kunde bereit ist, seine Zahlungsmethode zu aktualisieren, rufen Sie die Update Payment Method API auf:

    <CodeGroup>
      ```javascript Node.js theme={null}
      // Update with new payment method
      const response = await client.subscriptions.updatePaymentMethod(subscriptionId, {
        type: 'new',
        return_url: 'https://example.com/return'
      });

      // For on_hold subscriptions, a charge is automatically created
      if (response.payment_id) {
        console.log('Charge created for remaining dues:', response.payment_id);
        // Redirect customer to response.payment_link to complete payment
      }
      ```

      ```python Python theme={null}
      # Update with new payment method
      response = client.subscriptions.update_payment_method(
          subscription_id=subscription_id,
          type="new",
          return_url="https://example.com/return"
      )

      # For on_hold subscriptions, a charge is automatically created
      if response.payment_id:
          print("Charge created for remaining dues:", response.payment_id)
          # Redirect customer to response.payment_link to complete payment
      ```
    </CodeGroup>

    <Info>
      Sie können auch eine bestehende Zahlungsmethoden-ID verwenden, wenn der Kunde Zahlungsinformationen gespeichert hat:

      ```javascript theme={null}
      await client.subscriptions.updatePaymentMethod(subscriptionId, {
        type: 'existing',
        payment_method_id: 'pm_abc123'
      });
      ```
    </Info>
  </Step>

  <Step title="Monitor webhook events">
    Nach der Aktualisierung der Zahlungsmethode sollten Sie auf diese Webhook-Ereignisse achten:

    1. **`payment.succeeded`** - Die Gebühr für ausstehende Beträge war erfolgreich
    2. **`subscription.active`** - Das Abonnement wurde reaktiviert

    ```javascript theme={null}
    if (event.type === 'payment.succeeded') {
      const payment = event.data;
      
      // Check if this payment is for an on_hold subscription
      if (payment.subscription_id) {
        // Wait for subscription.active webhook to confirm reactivation
      }
    }

    if (event.type === 'subscription.active') {
      const subscription = event.data;
      
      // Update subscription status in your database
      await updateSubscriptionStatus(subscription.subscription_id, 'active');
      
      // Restore customer access
      await restoreCustomerAccess(subscription.customer_id);
      
      // Notify customer of successful reactivation
      await sendEmailToCustomer(subscription.customer_id, {
        subject: 'Subscription Reactivated',
        message: 'Your subscription has been reactivated successfully.'
      });
    }
    ```
  </Step>
</Steps>

### Beispieldaten für Abonnementereignisse

***

| Eigenschaft   | Typ    | Erforderlich | Beschreibung                                                                             |
| ------------- | ------ | ------------ | ---------------------------------------------------------------------------------------- |
| `business_id` | string | Ja           | Der eindeutige Bezeichner für das Unternehmen                                            |
| `timestamp`   | string | Ja           | Der Zeitstempel, wann das Ereignis eintrat (nicht unbedingt dasselbe wie die Zustellung) |
| `type`        | string | Ja           | Der Ereignistyp. Siehe [Ereignistypen](#event-types)                                     |
| `data`        | object | Ja           | Die Hauptdatennutzlast. Siehe [Datenobjekt](#data-object)                                |

## Abonnementpläne ändern

Sie können einen Abonnementplan mit dem API-Endpunkt zum Planwechsel upgraden oder downgraden. Dies ermöglicht Ihnen die Änderung des Produkts des Abonnements, die Menge und die Handhabung der anteiligen Abrechnung.

<Card title="Change Plan API Reference" icon="arrows-rotate" href="/api-reference/subscriptions/change-plan">
  Für detaillierte Informationen über den Wechsel von Abonnementplänen konsultieren Sie bitte unsere Change Plan API-Dokumentation.
</Card>

### Optionen für anteilige Abrechnung

Beim Wechsel von Abonnementplänen haben Sie zwei Optionen zur Handhabung der sofortigen Gebühr:

#### 1. `prorated_immediately`

* Berechnet den anteiligen Betrag basierend auf der verbleibenden Zeit im aktuellen Abrechnungszyklus
* Belastet den Kunden nur für die Differenz zwischen dem alten und dem neuen Plan
* Während einer Testphase wird der Benutzer sofort auf den neuen Plan umgestellt, der Kunde wird sofort belastet

#### 2. `full_immediately`

* Belastet den Kunden den vollen Abonnementbetrag für den neuen Plan
* Ignoriert verbleibende Zeit oder Guthaben vom vorherigen Plan
* Nützlich, wenn Sie den Abrechnungszyklus zurücksetzen oder den vollen Betrag unabhängig von der anteiligen Abrechnung verlangen möchten

#### 3. `difference_immediately`

* Beim Upgrade wird der Kunde sofort mit dem Unterschied zwischen den beiden Planbeträgen belastet.
* Beispielsweise, wenn der aktuelle Plan 30 Dollar kostet und der Kunde auf 80 Dollar wechselt, werden ihm sofort 50 Dollar berechnet.
* Bei einem Downgrade wird der ungenutzte Betrag des aktuellen Plans als internes Guthaben hinzugefügt und automatisch auf zukünftige Abonnementverlängerungen angerechnet.
* Beispielsweise, wenn der aktuelle Plan 50 Dollar beträgt und der Kunde auf einen 20 Dollar-Plan wechselt, werden die verbleibenden 30 Dollar gutgeschrieben und für den nächsten Abrechnungszyklus verwendet.

### Verhalten

* Wenn Sie diese API aufrufen, initiiert Dodo Payments sofort eine Gebühr basierend auf der von Ihnen gewählten Option für anteilige Abrechnung
* Wenn die Planänderung ein Downgrade ist und Sie `prorated_immediately` verwenden, werden Guthaben automatisch berechnet und dem Guthaben des Abonnements hinzugefügt. Diese Guthaben sind spezifisch für dieses Abonnement und werden nur zur Verrechnung zukünftiger wiederkehrender Zahlungen desselben Abonnements verwendet
* Die `full_immediately` Option umgeht die Guthabenberechnung und belastet den vollen Betrag des neuen Plans

<Tip>
  **Wählen Sie Ihre Abrechnungsoption sorgfältig**: Verwenden Sie `prorated_immediately` für faire Abrechnung, die ungenutzte Zeit berücksichtigt, oder `full_immediately`, wenn Sie den vollen Betrag des neuen Plans unabhängig von den aktuellen Abrechnungszyklen verlangen möchten.
</Tip>

### Gebührenverarbeitung

* Die sofortige Gebühr, die bei der Planänderung initiiert wird, wird normalerweise in weniger als 2 Minuten abgeschlossen
* Wenn diese sofortige Gebühr aus irgendeinem Grund fehlschlägt, wird das Abonnement automatisch pausiert, bis das Problem behoben ist

## On-Demand-Abonnements

<Info>
  On-Demand-Abonnements erlauben es Ihnen, Kunden flexibel zu belasten, nicht nur nach einem festen Zeitplan. Diese Funktion ist für alle Konten verfügbar.
</Info>

**Um ein On-Demand-Abonnement zu erstellen:**

Um ein On-Demand-Abonnement zu erstellen, verwenden Sie den [POST /subscriptions](/api-reference/subscriptions/post-subscriptions) API-Endpunkt und fügen Sie das `on_demand` Feld in Ihren Anfragekörper ein. Dies ermöglicht es Ihnen, eine Zahlungsmethode ohne sofortige Belastung zu autorisieren oder einen benutzerdefinierten Anfangspreis festzulegen.

**Um ein On-Demand-Abonnement zu belasten:**

Für nachfolgende Gebühren verwenden Sie den [POST /subscriptions/{subscription_id}/charge](/api-reference/subscriptions/create-charge) Endpunkt und geben Sie den Betrag an, den Sie dem Kunden für diese Transaktion berechnen möchten.

<Note>
  Für eine vollständige, schrittweise Anleitung — einschließlich Anfrage-/Antwortbeispielen, sicheren Wiederholungsrichtlinien und Webhook-Bearbeitung — siehe den <a href="/developer-resources/ondemand-subscriptions">On-Demand-Abonnements-Leitfaden</a>.
</Note>

## Verwandte API-Referenz

<CardGroup cols={2}>
  <Card title="Create Subscription" icon="code" href="/api-reference/subscriptions/post-subscriptions">
    API-Referenz zur Erstellung von Abonnementprodukten und Verwaltung des Abonnement-Lebenszyklus
  </Card>

  <Card title="Change Subscription Plan" icon="arrows-rotate" href="/api-reference/subscriptions/change-plan">
    API-Referenz zum Upgrade, Downgrade oder Wechsel von Abonnementplänen mit Optionen für anteilige Abrechnung
  </Card>

  <Card title="Update Payment Method" icon="credit-card" href="/api-reference/subscriptions/update-payment-method">
    API-Referenz zur Aktualisierung von Zahlungsmethoden und Reaktivierung pausierter Abonnements
  </Card>

  <Card title="Patch Subscription" icon="pen" href="/api-reference/subscriptions/patch-subscriptions">
    API-Referenz zur Aktualisierung von Abonnementdetails und Konfiguration
  </Card>
</CardGroup>
