Zum Hauptinhalt springen

Übersicht

On-Demand-Abonnements ermöglichen es Ihnen, die Zahlungsmethode eines Kunden einmal zu autorisieren und dann variable Beträge zu berechnen, wann immer Sie es benötigen, anstatt nach einem festen Zeitplan.
On-Demand-Abonnements sind jetzt für alle Unternehmen verfügbar. Diese Funktion ermöglicht eine flexible Abrechnungskontrolle für nutzungsbasierte und gemessene Dienste.
Verwenden Sie diesen Leitfaden, um:
  • Ein On-Demand-Abonnement zu erstellen (ein Mandat mit optionalem Anfangspreis zu autorisieren)
  • Nachfolgende Gebühren mit benutzerdefinierten Beträgen auszulösen
  • Ergebnisse mithilfe von Webhooks zu verfolgen
Für eine allgemeine Abonnementeinrichtung siehe den Subscription Integration Guide.

Voraussetzungen

  • Dodo Payments-Händlerkonto und API-Schlüssel
  • Webhook-Geheimnis konfiguriert und einen Endpunkt zum Empfangen von Ereignissen
  • Ein Abonnementprodukt in Ihrem Katalog
Wenn Sie möchten, dass der Kunde das Mandat über den gehosteten Checkout genehmigt, setzen Sie payment_link: true und geben Sie einen return_url an.

Wie On-Demand funktioniert

  1. Sie erstellen ein Abonnement mit dem on_demand Objekt, um eine Zahlungsmethode zu autorisieren und optional eine Anfangsgebühr zu erheben.
  2. Später erstellen Sie Gebühren für dieses Abonnement mit benutzerdefinierten Beträgen über den speziellen Gebührenendpunkt.
  3. Sie hören auf Webhooks (z. B. payment.succeeded, payment.failed), um Ihr System zu aktualisieren.

Erstellen Sie ein On-Demand-Abonnement

Endpunkt: POST /subscriptions Wichtige Anforderungsfelder (Body):
product_id
string
erforderlich
Produkt-ID für das Abonnement.
quantity
integer
erforderlich
Anzahl der Einheiten. Mindestens 1.
billing
object
erforderlich
Rechnungsadresse des Kunden.
customer
object
erforderlich
Entweder einen bestehenden Kunden anhängen oder Kundendetails angeben.
Wenn wahr, wird ein gehosteter Checkout-Link zur Genehmigung des Mandats und optionalen Anfangszahlung erstellt.
return_url
string
Wohin der Kunde nach Abschluss des gehosteten Checkouts umgeleitet werden soll.
on_demand.mandate_only
boolean
erforderlich
Wenn wahr, autorisiert die Zahlungsmethode, ohne den Kunden während der Erstellung zu belasten.
on_demand.product_price
integer
Betrag der Anfangsgebühr (in der kleinsten Währungseinheit). Wenn angegeben, überschreibt dieser Wert den ursprünglichen Preis des Produkts, der während der Produktcreation festgelegt wurde. Wenn weggelassen, wird der gespeicherte Preis des Produkts verwendet. Beispiel: Um $1,00 zu berechnen, übergeben Sie 100.
on_demand.product_currency
string
Optionale Währungsüberschreibung für die Anfangsgebühr. Standardmäßig die Produktwährung.
on_demand.product_description
string
Optionale Beschreibung für Abrechnung und Positionen.
on_demand.adaptive_currency_fees_inclusive
boolean
Wenn wahr, werden adaptive Währungsgebühren innerhalb von product_price einbezogen. Wenn falsch, werden Gebühren zusätzlich hinzugefügt. Wird ignoriert, wenn adaptive Preisgestaltung deaktiviert ist.

Erstellen Sie ein On-Demand-Abonnement

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 subscription = await client.subscriptions.create({
    billing: { city: 'SF', country: 'US', state: 'CA', street: '1 Market St', zipcode: '94105' },
    customer: { customer_id: 'customer_123' },
    product_id: 'prod_sub_123',
    quantity: 1,
    payment_link: true,
    return_url: 'https://example.com/billing/success',
    on_demand: {
      mandate_only: true, // set false to collect an initial charge
      // product_price: 1000, // optional: charge $10.00 now if mandate_only is false
      // product_currency: 'USD',
      // product_description: 'Custom initial charge',
      // adaptive_currency_fees_inclusive: false,
    },
  });

  // If payment_link was true, redirect the customer to authorize the mandate
  console.log(subscription.payment_link);
}

main().catch(console.error);
Setzen Sie payment_link: true, leiten Sie den Kunden zu payment_link weiter, um die Genehmigung des Mandats abzuschließen.
Success
{
  "subscription_id": "sub_123",
  "payment_link": "https://pay.dodopayments.com/checkout/...",
  "customer": { "customer_id": "customer_123", "email": "[email protected]", "name": "Alex Doe" },
  "metadata": {},
  "recurring_pre_tax_amount": 0,
  "addons": []
}

Belasten Sie ein On-Demand-Abonnement

Nachdem das Mandat genehmigt wurde, erstellen Sie nach Bedarf Gebühren. Endpunkt: POST /subscriptions/{subscription_id}/charge Wichtige Anforderungsfelder (Body):
product_price
integer
erforderlich
Betrag, der belastet werden soll (in der kleinsten Währungseinheit). Beispiel: Um $25,00 zu berechnen, übergeben Sie 2500.
product_currency
string
Optionale Währungsüberschreibung für die Gebühr.
product_description
string
Optionale Beschreibung für diese Gebühr.
adaptive_currency_fees_inclusive
boolean
Wenn wahr, werden adaptive Währungsgebühren innerhalb von product_price einbezogen. Wenn falsch, werden Gebühren zusätzlich hinzugefügt.
metadata
object
Zusätzliche Metadaten für die Zahlung. Wenn weggelassen, werden die Abonnementmetadaten verwendet.
import DodoPayments from 'dodopayments';

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

async function chargeNow(subscriptionId) {
  const res = await client.subscriptions.charge(subscriptionId, { product_price: 2500 });
  console.log(res.payment_id);
}

chargeNow('sub_123').catch(console.error);
Success
{ "payment_id": "pay_abc123" }
Das Belasten eines Abonnements, das nicht On-Demand ist, kann fehlschlagen. Stellen Sie sicher, dass das Abonnement on_demand: true in seinen Details hat, bevor Sie es belasten.

Zahlungswiederholungen

Unser Betrugserkennungssystem kann aggressive Wiederholungsmuster blockieren (und sie als potenzielles Kartentesting kennzeichnen). Befolgen Sie eine sichere Wiederholungsrichtlinie.
Burst-Wiederholungsmuster können von unseren Risikosystemen und Prozessoren als betrügerisch oder verdächtiges Kartentesting gekennzeichnet werden. Vermeiden Sie gruppierte Wiederholungen; befolgen Sie den Backoff-Zeitplan und die Zeitabgleichrichtlinien unten.

Grundsätze für sichere Wiederholungsrichtlinien

  • Backoff-Mechanismus: Verwenden Sie exponentielles Backoff zwischen den Wiederholungen.
  • Wiederholungsgrenzen: Begrenzen Sie die Gesamtzahl der Wiederholungen (maximal 3–4 Versuche).
  • Intelligente Filterung: Wiederholen Sie nur bei wiederholbaren Fehlern (z. B. Netzwerk-/Ausstellerfehler, unzureichende Mittel); wiederholen Sie niemals bei harten Ablehnungen.
  • Verhinderung von Kartentests: Wiederholen Sie keine Fehler wie DO_NOT_HONOR, STOLEN_CARD, LOST_CARD, PICKUP_CARD, FRAUDULENT, AUTHENTICATION_FAILURE.
  • Metadaten variieren (optional): Wenn Sie Ihr eigenes Wiederholungssystem pflegen, unterscheiden Sie Wiederholungen über Metadaten (z. B. retry_attempt).

Vorgeschlagener Wiederholungszeitplan (Abonnements)

  • 1. Versuch: Sofort, wenn Sie die Gebühr erstellen
  • 2. Versuch: Nach 3 Tagen
  • 3. Versuch: Nach weiteren 7 Tagen (insgesamt 10 Tage)
  • 4. Versuch (final): Nach weiteren 7 Tagen (insgesamt 17 Tage)
Letzter Schritt: Wenn weiterhin unbezahlte Beträge bestehen, markieren Sie das Abonnement als unbezahlte oder stornieren Sie es, basierend auf Ihrer Richtlinie. Benachrichtigen Sie den Kunden während des Zeitraums, um seine Zahlungsmethode zu aktualisieren.

Vermeiden Sie Burst-Wiederholungen; richten Sie sich nach der Autorisierungszeit

  • Verankern Sie Wiederholungen an dem ursprünglichen Autorisierungszeitstempel, um „Burst“-Verhalten in Ihrem Portfolio zu vermeiden.
  • Beispiel: Wenn der Kunde um 13:10 Uhr heute einen Test oder ein Mandat startet, planen Sie nachfolgende Wiederholungen um 13:10 Uhr an den folgenden Tagen gemäß Ihrem Backoff (z. B. +3 Tage → 13:10 Uhr, +7 Tage → 13:10 Uhr).
  • Alternativ, wenn Sie die letzte erfolgreiche Zahlungszeit T speichern, planen Sie den nächsten Versuch um T + X days, um die Tageszeit-Ausrichtung zu bewahren.
Zeitzone und DST: Verwenden Sie einen konsistenten Zeitstandard für die Planung und konvertieren Sie nur zur Anzeige, um Intervalle aufrechtzuerhalten.

Ablehnungscodes, die Sie nicht wiederholen sollten

  • STOLEN_CARD
  • DO_NOT_HONOR
  • FRAUDULENT
  • PICKUP_CARD
  • AUTHENTICATION_FAILURE
  • LOST_CARD
Für eine umfassende Liste von Ablehnungsgründen und ob sie vom Benutzer korrigierbar sind, siehe die Transaction Failures Dokumentation.
Wiederholen Sie nur bei weichen/temporären Problemen (z. B. insufficient_funds, issuer_unavailable, processing_error, Netzwerkzeitüberschreitungen). Wenn die gleiche Ablehnung wiederholt wird, pausieren Sie weitere Wiederholungen.

Implementierungsrichtlinien (kein Code)

  • Verwenden Sie einen Scheduler/Queue, der präzise Zeitstempel speichert; berechnen Sie den nächsten Versuch zum genauen Tageszeitversatz (z. B. T + 3 days zur gleichen HH:MM).
  • Behalten Sie den letzten erfolgreichen Zahlungszeitstempel T bei und beziehen Sie ihn ein, um den nächsten Versuch zu berechnen; bündeln Sie niemals mehrere Abonnements zur gleichen Zeit.
  • Bewerten Sie immer den letzten Ablehnungsgrund; stoppen Sie Wiederholungen bei harten Ablehnungen in der obigen Ausnahmeliste.
  • Begrenzen Sie gleichzeitige Wiederholungen pro Kunde und pro Konto, um versehentliche Spitzen zu vermeiden.
  • Kommunizieren Sie proaktiv: E-Mail/SMS an den Kunden, um seine Zahlungsmethode vor dem nächsten geplanten Versuch zu aktualisieren.
  • Verwenden Sie Metadaten nur zur Beobachtbarkeit (z. B. retry_attempt); versuchen Sie niemals, Betrugs-/Risikosysteme zu „umgehen“, indem Sie unwesentliche Felder rotieren.

Ergebnisse mit Webhooks verfolgen

Implementieren Sie die Webhook-Verarbeitung, um die Kundenreise zu verfolgen. Siehe Implementing Webhooks.
  • subscription.active: Mandat genehmigt und Abonnement aktiviert
  • subscription.failed: Erstellung fehlgeschlagen (z. B. Mandatsfehler)
  • subscription.on_hold: Abonnement auf Hold gesetzt (z. B. unbezahlter Zustand)
  • payment.succeeded: Gebühr erfolgreich
  • payment.failed: Gebühr fehlgeschlagen
Für On-Demand-Workflows konzentrieren Sie sich auf payment.succeeded und payment.failed, um nutzungsbasierte Gebühren abzugleichen.

Testen und nächste Schritte

1

Im Testmodus erstellen

Verwenden Sie Ihren Test-API-Schlüssel, um das Abonnement mit payment_link: true zu erstellen, und öffnen Sie dann den Link und schließen Sie das Mandat ab.
2

Eine Gebühr auslösen

Rufen Sie den Gebührenendpunkt mit einer kleinen product_price (z. B. 100) auf und überprüfen Sie, ob Sie payment.succeeded erhalten.
3

Live gehen

Wechseln Sie zu Ihrem Live-API-Schlüssel, sobald Sie Ereignisse und interne Statusaktualisierungen validiert haben.

Fehlersuche

  • 422 Ungültige Anfrage: Stellen Sie sicher, dass on_demand.mandate_only bei der Erstellung angegeben ist und product_price für Gebühren angegeben ist.
  • Währungsfehler: Wenn Sie product_currency überschreiben, bestätigen Sie, dass es für Ihr Konto und Ihren Kunden unterstützt wird.
  • Keine Webhooks empfangen: Überprüfen Sie Ihre Webhook-URL und die Konfiguration des Signaturgeheimnisses.