> ## 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.

# v1.97.6 (7. Mai 2026)

> Entitlements starten mit fünf neuen Fulfillment-Integrationen (Discord, GitHub, Telegram, Framer, Notion), Kündigungsgründe für Abonnements im Kundenportal, konfigurierbare INR E-Mandat-Schwelle, adaptive Währungsgebühren inklusive Einstellung, Dodo Payments Desktop-App für macOS/Windows/Linux, Stablecoin-Zahlungen (USDC/USDP/USDG), Import bestehender Lizenzschlüssel, require_phone_number für Checkout-Sitzungen und Fehlerbehebungen

## Neue Funktionen

### 1. **Entitlements**

Dodo Payments bietet nun einheitliche **Entitlements** — eine einzelne Ebene, die die automatische Lieferung für jede Fulfillment-Integration ermöglicht. Ein einzelnes Produkt kann mehrere Entitlements bei jedem erfolgreichen Kauf oder aktivem Abonnement liefern.

<Frame>
  <img src="https://mintcdn.com/dodopayments/do-W-dMDGVB_xzr_/images/entitlements/list.png?fit=max&auto=format&n=do-W-dMDGVB_xzr_&q=85&s=12a326205f64d1e71485bce46114d296" alt="Entitlements-Dashboard mit der Liste der Entitlements links und der Grant-Aktivität rechts" style={{ maxHeight: '500px', width: 'auto' }} width="2000" height="1195" data-path="images/entitlements/list.png" />
</Frame>

**Fünf neue Plattform-Integrationen**

Bisher lieferte Dodo Payments **Lizenzschlüssel** und **digitale Dateien** automatisch beim Kauf. Entitlements erweitern diesen Umfang auf fünf zusätzliche Plattformen — sodass zahlenden Kunden der Zugang zu Ihrer Community, Ihrem Code oder Ihrem Inhalt gewährt werden kann, sobald die Zahlung erfolgreich ist, ohne manuelle Erfüllung auf Ihrer Seite:

| Integration  | Was es liefert                                                                                                      | Widerrufsverhalten                                              |
| ------------ | ------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- |
| **Discord**  | Weist eine ausgewählte Rolle auf Ihrem Discord-Server nach Abschluss der OAuth des Kunden zu                        | Rolle wird bei Stornierung/Rückerstattung entfernt              |
| **GitHub**   | Fügt den Kunden als Mitarbeiter zu einem privaten Repository auf dem von Ihnen gewählten Berechtigungsniveau hinzu  | Mitarbeiter wird bei Stornierung/Rückerstattung entfernt        |
| **Telegram** | Erstellt einen einmaligen Beitrittsanfrage-Link für einen privaten Chat oder Kanal über Ihren Telegram-Bot          | Kunde wird bei Stornierung/Rückerstattung aus dem Chat entfernt |
| **Framer**   | Schaltet einen Framer-Template-Remix-Link frei, der durch einen Zugangscode gesperrt ist                            | Zugangscode wird bei Stornierung/Rückerstattung deaktiviert     |
| **Notion**   | Dupliziert eine Notion-Template-Seite in den Arbeitsbereich des Kunden, nachdem dieser über OAuth autorisiert wurde | Gelieferte Seite wird bei Stornierung/Rückerstattung archiviert |

Diese schließen sich den bestehenden **Lizenzschlüsseln** (einzigartige Schlüssel mit Aktivierungslimits und Ablauf) und **Digitalen Dateien** (vorgesignierte Download-URLs für E-Books, Vorlagen, Medien) an, die jetzt alle im selben Grant-Lebenszyklus verwaltet werden.

**Was Sie direkt erhalten**

| Fähigkeit                             | Beschreibung                                                                                                                                                                                                                 |
| ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Wiederverwendbare Vorlagen**        | Definieren Sie ein Entitlement einmal (Aktivierungslimits, Dateibundles, Discord-Rolle, Repo-Berechtigung usw.) und fügen Sie es zu jedem Produkt hinzu                                                                      |
| **Automatische Grants**               | Ausgegeben bei `payment.succeeded` und `subscription.active`, idempotent über Erneuerungen und Reaktivierungen hinweg                                                                                                        |
| **Lebenszyklus-bewusste Widerrufung** | Widerrufen bei `subscription.cancelled`, `subscription.on_hold`, `subscription.expired`, `refund.succeeded`, `subscription.plan_changed` oder manueller API-/Dashboard-Widerruf — mit einem ausgefüllten `revocation_reason` |
| **OAuth + direkt Plattform-Flow**     | OAuth für Discord-, GitHub- und Notion-Abonnenten-Zustimmung; direkte Plattformaufrufe für Telegram, Framer und Digitale Dateien                                                                                             |
| **Drift-Erkennung**                   | Erkennt, wenn eine Discord-Rolle, ein GitHub-Mitarbeiter oder eine Notion-Seite auf der Plattform-Ebene nicht synchron ist und widerruft mit `revocation_reason: platform_external`                                          |
| **Verschlüsselung im Ruhezustand**    | Alle Plattform-Tokens (OAuth, Bot, App-Installationen) werden mit AES-256-GCM gespeichert                                                                                                                                    |

**Webhooks**

Vier neue Lebenszyklus-Ereignisse werden für jeden Grant ausgelöst:

| Ereignis                      | Wird ausgelöst, wenn                                                                         |
| ----------------------------- | -------------------------------------------------------------------------------------------- |
| `entitlement_grant.created`   | Ein neuer Grant für einen Kunden erstellt wird                                               |
| `entitlement_grant.delivered` | Kunden-Zugang bereitgestellt                                                                 |
| `entitlement_grant.failed`    | Lieferung konnte nicht abgeschlossen werden; überprüfen Sie `error_code` und `error_message` |
| `entitlement_grant.revoked`   | Zugang zurückgezogen; überprüfen Sie `revocation_reason`                                     |

<Tip>
  Für neue Integrationen lauschen Sie `entitlement_grant.delivered` anstelle von `payment.succeeded`. Zahlungserfolg bedeutet nicht, dass die Lieferung abgeschlossen ist, insbesondere bei OAuth-basierten Integrationen.
</Tip>

Erfahren Sie mehr: [Entitlements](/features/entitlements/introduction) | [Entitlement Grant Webhooks](/developer-resources/webhooks/intents/entitlement-grant)

### 2. **Abonnement-Kündigungsgründe im Kundenportal**

Wenn Kunden ein Abonnement im Kundenportal kündigen, werden sie jetzt aufgefordert zu teilen, **warum sie kündigen**, bevor sie bestätigen. Der erfasste Grund wird beim Abonnement als `cancellation_feedback` gespeichert, in der API- und Webhook-Nutzlast angezeigt und im Dashboard verfügbar, damit Sie Churn-Muster auf einen Blick erkennen können.

<Frame>
  <img src="https://mintcdn.com/dodopayments/RlXcM7JO-E_w40Np/images/customer-portal/cancellation-reasons.png?fit=max&auto=format&n=RlXcM7JO-E_w40Np&q=85&s=979394da2a9aa3907cbf9f4e225f9a4b" alt="Kundenportal-Kündigungs-Modal mit dem Dropdown 'Warum kündigen Sie?' mit Gründen wie Zu teuer, Fehlende Funktionen und Andere" style={{ maxHeight: '500px', width: 'auto' }} width="2880" height="1564" data-path="images/customer-portal/cancellation-reasons.png" />
</Frame>

**Optionsgründe**

| Wert               | Kundenorientiertes Etikett          |
| ------------------ | ----------------------------------- |
| `too_expensive`    | Zu teuer                            |
| `missing_features` | Fehlende Funktionen                 |
| `switched_service` | Zu einem anderen Service gewechselt |
| `unused`           | Nicht genügend Nutzung              |
| `customer_service` | Schlechter Kundenservice            |
| `low_quality`      | Niedrige Qualität                   |
| `too_complex`      | Zu komplex                          |
| `other`            | Andere                              |

**Wo es erscheint**

* **Subscription object**: Neues Feld `cancellation_feedback` (einer der oben genannten Werte) und `cancellation_comment` (optionaler Freitext), ausgefüllt, wenn der Kunde kündigt
* **`subscription.cancelled` webhook**: Beide Felder sind in der Payload enthalten
* **API**: Übergebe `cancellation_feedback` und `cancellation_comment` an `PATCH /subscriptions/{subscription_id}`, wenn du eine Kündigung programmgesteuert planst oder ausführst

```typescript theme={null}
// Reading the captured feedback
const subscription = await client.subscriptions.retrieve('sub_123');
console.log(subscription.cancellation_feedback); // e.g., "too_expensive"
console.log(subscription.cancellation_comment);  // e.g., "Switching to a competitor"
```

<Tip>
  Kombinieren Sie `cancellation_feedback` mit [Abonnement-Dunning](/features/recovery/subscription-dunning), um Ihre Rückgewinnungs-E-Mails gezielt zu richten — z.B. senden Sie einen Rabattcode an `too_expensive`-Kündiger und eine „Was fehlt?“ Umfrage an `missing_features`-Kündiger.
</Tip>

Erfahren Sie mehr: [Kundenportal](/features/customer-portal#cancelling-a-subscription) | [Abonnement-Webhooks](/developer-resources/webhooks/intents/subscription)

### 3. **Konfigurierbare Mandate Mindestbetrag für INR E-Mandate**

Sie können jetzt den **Mandatsschwelle** für INR E-Mandate bei indischen Karten-Abonnements konfigurieren. Bisher verwendete jedes indische Karten-Abonnement unter ₹15.000 ein festes ₹15.000 On-Demand-Mandat. Jetzt können Sie diese Schwelle auf Händlerebene — und pro Checkout-Sitzung oder Abonnement bei Bedarf — überschreiben.

Der mit der Bank des Kunden registrierte Mandatsbetrag ist `max(mandate_min_amount_inr_paise, billing_amount)`, daher fungiert dieser Wert als **Autorisierungsgrenze**, wann immer die Abrechnung unterhalb der Schwelle liegt.

```typescript theme={null}
// Per-subscription override
const subscription = await client.subscriptions.create({
  product_id: 'pdt_inr_monthly',
  customer: { email: 'customer@example.in' },
  billing: { country: 'IN' /* ... */ },
  mandate_min_amount_inr_paise: 2_000_000 // ₹20,000 ceiling for this subscription
});

// Or via a checkout session
const session = await client.checkoutSessions.create({
  product_cart: [{ product_id: 'pdt_inr_monthly', quantity: 1 }],
  mandate_min_amount_inr_paise: 2_000_000,
  return_url: 'https://yoursite.com/return'
});
```

**Auflösungspriorität**

1. Pro-Anfrage-Überschreibung (`mandate_min_amount_inr_paise` für die Checkout-Sitzung, Zahlung oder Abonnement)
2. Händlereinstellungen in den Geschäftseinstellungen
3. Systemstandard von **₹15.000** (1.500.000 Paise)

| Feld                           | Typ                   | Bereich | Gilt für                                                       |
| ------------------------------ | --------------------- | ------- | -------------------------------------------------------------- |
| `mandate_min_amount_inr_paise` | `integer` (INR Paise) | `>= 1`  | Indische Karten INR-Abonnements auf nicht-Airwallex-Connectors |

<Info>
  Diese Einstellung betrifft nur E-Mandate, die für indische Karten (Visa, Mastercard, RuPay) bei INR-Abonnements registriert sind. UPI-Abonnements folgen ihrem eigenen AutoPay-Flow und sind nicht betroffen.
</Info>

Erfahren Sie mehr: [Indien Zahlungsmethoden](/features/payment-methods/india#mandate-types) | [Abonnements mit RBI Mandaten](/features/subscription#subscriptions-with-rbi-compliant-mandates)

### 4. **Adaptive Currency Gebühren inklusive Geschäftseinstellung**

Adaptive Currency ist die Funktion, die es Ihnen ermöglicht, Kunden in ihrer lokalen Währung zu berechnen. Standardmäßig wird die **2–4% Adaptive Currency-Gebühr** vom Kunden getragen und zu Ihrem angezeigten Preis hinzugefügt. Mit der neuen **Gebühren inklusive**-Einstellung können Sie dies umdrehen: Halten Sie den angezeigten Preis für den Kunden unverändert und übernehmen Sie die Gebühr selbst.

**Wo konfigurieren**

Gehen Sie zu **Einstellungen → Geschäft**, stellen Sie sicher, dass **Adaptive Pricing** aktiviert ist, und schalten Sie **Gebühren inklusive** im Adaptive Currency-Bereich um.

**Pro-Anfrage-Überschreibung**

Sie können den Händlerstandard für einzelne Zahlungen, On-Demand-Abonnementgebühren und Planänderungen auch mithilfe des booleschen Werts `adaptive_currency_fees_inclusive` überschreiben:

```typescript theme={null}
const payment = await client.payments.create({
  product_cart: [{ product_id: 'pdt_abc', quantity: 1 }],
  customer: { customer_id: 'cus_123' },
  billing: { country: 'US' },
  adaptive_currency_fees_inclusive: true, // override business default
  return_url: 'https://yoursite.com/return'
});
```

| Modus               | Kunde sieht                               | Händler begleicht                |
| ------------------- | ----------------------------------------- | -------------------------------- |
| Exklusiv (Standard) | Lokaler Preis + 2–4% Gebühr auf den Preis | Voller Basispreis                |
| Inklusive           | Lokaler Preis (unverändert)               | Basispreis minus die 2–4% Gebühr |

<Info>
  INR → INR-Transaktionen werden immer als inklusive behandelt, unabhängig von der Geschäftseinstellung oder der Pro-Anfrage-Überschreibung.
</Info>

Erfahren Sie mehr: [Adaptive Currency](/features/adaptive-currency)

### 5. **Dodo Payments Desktop-App**

Die offizielle **Dodo Payments Desktop**-App ist jetzt allgemein verfügbar für **macOS, Windows und Linux**. Führen Sie Ihr Zahlungs-Dashboard als schnelle, native App aus — es ist kein Browser-Tab erforderlich.

| Plattform                     | Download                                              |
| ----------------------------- | ----------------------------------------------------- |
| macOS (Apple Silicon)         | `Dodo.Payments_<version>_aarch64.dmg`                 |
| macOS (Intel)                 | `Dodo.Payments_<version>_x64.dmg`                     |
| Windows                       | `Dodo.Payments_<version>_x64-setup.exe` (oder `.msi`) |
| Linux (Debian/Ubuntu)         | `Dodo.Payments_<version>_amd64.deb`                   |
| Linux (Fedora/RHEL)           | `Dodo.Payments-<version>-1.x86_64.rpm`                |
| Linux (AppImage, Auto-Update) | `Dodo.Payments_<version>_amd64.AppImage`              |

**Was drin steckt**

* **Kleine native Binärdatei** — gebaut mit Tauri auf dem nativen Webview des Systems, \~5 MB gesamt (keine gebündelte Chromium)
* **Signiert und beglaubigt** — macOS-Builds sind mit einer Apple Developer ID signiert und beglaubigt, sodass keine Gatekeeper-Warnungen auftreten
* **Auto-Update** — überprüft jede 4 Stunden und wendet automatisch signierte Updates von GitHub-Releases an (funktioniert auf macOS, Windows und Linux AppImage)
* **Systemtray + Menüleiste** — Verstecken im Tray auf macOS, vollständige Datei/Bearbeiten/Anzeigen/Hilfe-Menüs mit Tastenkombinationen (`⌘⇧H` gehe zum Dashboard, `⌘L` aktuelle URL kopieren, `⌘⌥I` Entwicklerwerkzeuge)
* **Deep-Link-Support** — Magic-Link-Authentifizierungslinks öffnen sich direkt in der App
* **Mehrfachfenster** — Öffnen Sie mehrere Dashboards nebeneinander

<Tip>
  Holen Sie sich den neuesten Installer für Ihre Plattform von der [Desktop-App-Releases-Seite](https://github.com/dodopayments/dodo-desktop/releases/latest). Das Repo ist vollständig Open Source.
</Tip>

### 6. **Stablecoin-Zahlungen (USDC, USDP, USDG)**

Akzeptieren Sie **Stablecoin-Zahlungen weltweit** mit USD-Abrechnung. Kunden zahlen aus ihrer bevorzugten Stablecoin-Wallet im Netzwerk ihrer Wahl; Sie erhalten Fiat-USD ohne Krypto-Volatilität, keine Rückbuchungen und ohne erforderliche Bankinfrastruktur auf der Kundenseite.

**Unterstützte Währungen und Netzwerke**

| Stablecoin | Netzwerke                       |
| ---------- | ------------------------------- |
| **USDC**   | Ethereum, Solana, Polygon, Base |
| **USDP**   | Ethereum, Solana                |
| **USDG**   | Ethereum                        |

**Abdeckung**

| Detail              | Wert                                    |
| ------------------- | --------------------------------------- |
| Rechnungswährung    | USD                                     |
| Unterstützte Länder | Weltweit (außer Indien)                 |
| Abonnements         | Nicht unterstützt (nur Einmalzahlungen) |
| Mindestbetrag       | \$0,50                                  |
| Abrechnung          | USD                                     |

**Konfiguration**

Übergeben Sie `crypto_currency` in `allowed_payment_method_types` beim Erstellen einer Checkout-Session:

```javascript theme={null}
const session = await client.checkoutSessions.create({
  product_cart: [{ product_id: 'pdt_123', quantity: 1 }],
  allowed_payment_method_types: ['crypto_currency', 'credit', 'debit'],
  return_url: 'https://example.com/success'
});
```

Dem Kunden wird eine Wallet-Adresse und ein QR-Code mit dem in Echtzeit berechneten Stablecoin-Betrag angezeigt; sobald die Blockchain die Transaktion bestätigt, feuert Ihr `payment.succeeded`-Webhook und der Kunde wird auf Ihre Erfolgseite umgeleitet.

<Info>
  Stablecoin-Zahlungen sind von Natur aus unumkehrbar — es gibt keine Rückbuchungen. Wir empfehlen, immer `credit` und `debit` als Fallback-Methoden für Kunden ohne Stablecoin-Wallet anzubieten.
</Info>

Erfahren Sie mehr: [Stablecoin-Zahlungen](/features/payment-methods/stablecoins)

### 7. **Bestehende Lizenzschlüssel importieren**

Sie können jetzt **Lizenzschlüssel aus einem anderen System** in Dodo Payments importieren, mithilfe der [Erstellen Lizenzschlüssel API](/api-reference/licenses/create-license-key). Dies ermöglicht eine störungsfreie Migration von jedem externen Lizenzschlüsselanbieter, sodass Ihre bestehenden Kunden ihre Schlüssel weiterhin gegen Dodo Payments aktivieren, validieren und deaktivieren können, ohne dass eine Neuvergabe erforderlich ist.

```typescript theme={null}
const licenseKey = await client.licenseKeys.create({
  customer_id: 'cus_abc123',
  product_id: 'pdt_456',
  key: 'YOUR-EXISTING-LICENSE-KEY',
  activations_limit: 5,
  expires_at: '2026-12-31T23:59:59Z',
});
```

Importierte Schlüssel sind mit `source: "import"` versehen (vs. `source: "auto"` für automatisch bei Zahlung generierte Schlüssel), sodass Sie migrierte Bestände von organisch ausgegebenen Schlüsseln unterscheiden können, wenn Sie `GET /license_keys` abfragen. Der `payment_id` bei importierten Schlüsseln ist `null`, da sie nicht mit einer Dodo Payments-Transaktion verknüpft sind.

<Warning>
  Lizenzschlüssel, die über die API erstellt oder aktualisiert werden, lösen keine E-Mail-Benachrichtigungen an Kunden aus. Wenn Sie Kunden über einen importierten Schlüssel informieren müssen, bearbeiten Sie dies separat in Ihrer Anwendung.
</Warning>

<Tip>
  Migrieren Sie von Polar.sh oder Lemon Squeezy? Das [`dodo-migrate` CLI](/migrate-to-dodo) automatisiert Massenimporte von Produkten, Kunden, Rabatten und Lizenzschlüsseln mit einem einzigen Befehl.
</Tip>

Erfahren Sie mehr: [Lizenzschlüssel](/features/license-keys#import-existing-license-keys-via-api) | [Erstellen Lizenzschlüssel API](/api-reference/licenses/create-license-key)

### 8. **`require_phone_number` für Checkout-Sitzungen**

Zwingen Sie Kunden, eine Telefonnummer beim Checkout anzugeben, indem Sie `feature_flags.require_phone_number: true` bei der Erstellung einer Checkout-Sitzung setzen. Die Telefonnummer wird zu einem Pflichtfeld im Checkout-Formular, mit Formularvalidierung, die "Telefonnummer ist erforderlich" anzeigt, wenn der Kunde das Feld leer lässt.

```typescript theme={null}
const session = await client.checkoutSessions.create({
  product_cart: [{ product_id: 'pdt_abc', quantity: 1 }],
  feature_flags: {
    allow_phone_number_collection: true,
    require_phone_number: true
  },
  return_url: 'https://yoursite.com/return'
});
```

| Flag                            | Standard | Verhalten                                     |
| ------------------------------- | -------- | --------------------------------------------- |
| `allow_phone_number_collection` | `true`   | Zeigt das Telefonnummernfeld beim Checkout an |
| `require_phone_number`          | `false`  | Macht das Telefonnummernfeld erforderlich     |

<Warning>
  `require_phone_number: true` erfordert `allow_phone_number_collection: true`. Die API lehnt Sitzungen ab, bei denen `require_phone_number` wahr ist, während die Telefonsammlung deaktiviert ist.
</Warning>

<Tip>
  Nützlich für B2B SaaS, regulierte Branchen oder jeden Ablauf, in dem Sie einen verifizierten Kontaktkanal für Support, Betrugsüberprüfung oder Compliance benötigen.
</Tip>

Erfahren Sie mehr: [Checkout-Funktionen](/features/checkout) | [Erstellen Checkout-Sitzung API](/api-reference/checkout-sessions/create)

## Fehlerkorrekturen & Verbesserungen

* Kleinere Fehlerkorrekturen und Stabilitätsverbesserungen auf der ganzen Plattform
