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. Diese Funktion ist für alle Konten verfügbar – keine Genehmigung erforderlich. Verwenden Sie diesen Leitfaden, um:
  • Ein On-Demand-Abonnement zu erstellen (ein Mandat mit optionalem Anfangspreis zu autorisieren)
  • Nachfolgende Zahlungen mit benutzerdefinierten Beträgen auszulösen
  • Ergebnisse mithilfe von Webhooks zu verfolgen
Für eine allgemeine Abonnementeinrichtung siehe den Leitfaden zur Abonnementintegration.

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 stellen Sie return_url bereit.

So funktioniert On-Demand

  1. Sie erstellen ein Abonnement mit dem on_demand-Objekt, um eine Zahlungsmethode zu autorisieren und optional eine Anfangsbelastung einzuziehen.
  2. Später lösen Sie Belastungen gegen dieses Abonnement mit benutzerdefinierten Beträgen über den dedizierten Charge-Endpunkt aus.
  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 /checkouts Wichtige Anforderungsfelder (Body):
Bitte finden Sie diese in Checkout-Session erstellen

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.checkoutSessions.create({
    product_cart: [{ product_id: 'pdt_123', quantity: 1 }],
    billing_address:  { city: 'SF', country: 'US', state: 'CA', street: '1 Market St', zipcode: '94105' },
    customer: { customer_id: 'cus_123' },
    return_url: 'https://example.com/billing/success',
    subscription_data: {
        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,
        }
    }
  });

  console.log(subscription.checkout_url);
}

main().catch(console.error);
Success
{
  "session_id": "cks_123",
  "checkout_url": "https://test.checkout.dodopayments.com/session/cks123"
}

Berechnen Sie ein On-Demand-Abonnement

Nachdem das Mandat autorisiert wurde, erstellen Sie nach Bedarf Zahlungen. Endpunkt: POST /subscriptions/{subscription_id}/charge Wichtige Anforderungsfelder (Body):
product_price
integer
erforderlich
Betrag, der berechnet 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 Belastung.
product_description
string
Optionale Beschreibung für diese Belastung.
adaptive_currency_fees_inclusive
boolean
Ist dies auf true gesetzt, werden adaptive Währungsgebühren innerhalb von product_price eingeschlossen. Andernfalls werden die Gebühren oben drauf gerechnet.
metadata
object
Zusätzliche Metadaten für die Zahlung. Wenn weggelassen, werden die Abonnement-Metadaten verwendet.
import DodoPayments from 'dodopayments';

const client = new DodoPayments({ bearerToken: process.env.DODO_PAYMENTS_API_KEY });

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 Laden eines Abonnements, das nicht “on-demand” ist, kann fehlschlagen. Stellen Sie sicher, dass das Abonnement on_demand: true in seinen Details enthält, bevor Sie es belasten.

Zahlungswiederholungen

Unser Betrugserkennungssystem kann aggressive Wiederholungsmuster blockieren (und kann sie als potenzielles Kartentesten kennzeichnen). Befolgen Sie eine sichere Wiederholungsrichtlinie.
Burst-Retry-Muster können von unseren Risikosystemen und Prozessoren als betrügerisch oder verdächtige Kartentests eingestuft werden. Vermeiden Sie gebündelte Wiederholungen; befolgen Sie den Backoff-Plan und die Zeit-Ausrichtungsrichtlinien unten.

Grundsätze für sichere Wiederholungsrichtlinien

  • Backoff-Mechanismus: Verwenden Sie exponentielles Backoff zwischen Wiederholungen.
  • Retry-Begrenzung: Beschränken Sie die Gesamtanzahl der Wiederholungen (max. 3–4 Versuche).
  • Intelligente Filterung: Wiederholen Sie nur bei retryfähigen Fehlern (z. B. Netzwerk-/Issuer-Fehler, 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 ein eigenes Retry-System pflegen, unterscheiden Sie Wiederholungen über Metadaten (z. B. retry_attempt).

Vorgeschlagener Wiederholungszeitplan (Abonnements)

  • 1. Versuch: Sofort, wenn Sie die Zahlung 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 gebündelte Wiederholungen; richten Sie sich nach der Autorisierungszeit

  • Verankern Sie Wiederholungen am ursprünglichen Autorisierungszeitpunkt, um “Burst”-Verhalten in Ihrem Portfolio zu vermeiden.
  • Beispiel: Wenn der Kunde heute um 13:10 Uhr eine Testphase oder ein Mandat startet, planen Sie nachfolgende Wiederholungen für 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 den Zeitpunkt der letzten erfolgreichen Zahlung T speichern, planen Sie den nächsten Versuch um T + X days, um die Time-of-Day-Ausrichtung beizubehalten.
Zeitzone und DST: Verwenden Sie einen konsistenten Zeitstandard für die Planung und konvertieren Sie nur zur Anzeige, um Intervalle beizubehalten.

Ablehnungscodes, die Sie nicht wiederholen sollten

  • STOLEN_CARD
  • DO_NOT_HONOR
  • FRAUDULENT
  • PICKUP_CARD
  • AUTHENTICATION_FAILURE
  • LOST_CARD
Für eine vollständige Liste von Ablehnungsgründen und der Frage, ob sie vom Nutzer korrigierbar sind, siehe die Transaction Failures-Dokumentation.
Wiederholen Sie nur bei weichen/temporären Problemen (z. B. insufficient_funds, issuer_unavailable, processing_error, Netzwerk-Timeouts). Wenn dieselbe Ablehnung erneut auftritt, setzen Sie weitere Wiederholungen aus.

Implementierungsrichtlinien (kein Code)

  • Verwenden Sie einen Scheduler/Queue, der präzise Zeitstempel speichert; berechnen Sie den nächsten Versuch genau zum gleichen Tageszeiten-Offset (z. B. T + 3 days zur gleichen HH:MM).
  • Pflegen und verwenden Sie den Zeitstempel der letzten erfolgreichen Zahlung T zur Berechnung des nächsten Versuchs; bündeln Sie nicht mehrere Abonnements zum selben Zeitpunkt.
  • Bewerten Sie immer den letzten Ablehnungsgrund; stoppen Sie Wiederholungen bei harten Ablehnungen aus der oben genannten Ausnahmeliste.
  • Begrenzen Sie gleichzeitige Wiederholungen pro Kunde und pro Konto, um unbeabsichtigte Spitzen zu vermeiden.
  • Kommunizieren Sie proaktiv: Informieren Sie den Kunden per E-Mail/SMS, dass er seine Zahlungsmethode vor dem nächsten geplanten Versuch aktualisieren soll.
  • Verwenden Sie Metadaten nur zur Beobachtbarkeit (z. B. retry_attempt); versuchen Sie niemals, Betrugs-/Risikosysteme zu “umgehen”, indem Sie belanglose Felder rotieren.

Ergebnisse mit Webhooks verfolgen

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

Testen und nächste Schritte

1

Create in test mode

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

Trigger a charge

Rufen Sie den Charge-Endpunkt mit einem kleinen product_price auf (z. B. 100) und vergewissern Sie sich, dass Sie payment.succeeded erhalten.
3

Go live

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

Fehlersuche

  • 422 Invalid Request: Stellen Sie sicher, dass on_demand.mandate_only bei der Erstellung und product_price bei Belastungen bereitgestellt wird.
  • Währungsfehler: Wenn Sie product_currency überschreiben, bestätigen Sie, dass diese Währung für Ihr Konto und Ihren Kunden unterstützt wird.
  • Keine empfangenen Webhooks: Überprüfen Sie Ihre Webhook-URL und die Konfiguration des Signatur-Geheimnisses.