Vai al contenuto principale

Panoramica

Gli abbonamenti on-demand ti consentono di autorizzare il metodo di pagamento di un cliente una sola volta e poi addebitare importi variabili ogni volta che ne hai bisogno, invece di seguire un programma fisso.
Gli abbonamenti on-demand sono ora disponibili per tutte le aziende. Questa funzionalità consente un controllo di fatturazione flessibile per servizi basati sull’uso e misurati.
Usa questa guida per:
  • Creare un abbonamento on-demand (autorizzare un mandato con prezzo iniziale opzionale)
  • Attivare addebiti successivi con importi personalizzati
  • Monitorare i risultati utilizzando webhook
Per una configurazione generale dell’abbonamento, vedere la Guida all’integrazione degli abbonamenti.

Requisiti

  • Account commerciante Dodo Payments e chiave API
  • Segreto del webhook configurato e un endpoint per ricevere eventi
  • Un prodotto in abbonamento nel tuo catalogo
Se desideri che il cliente approvi il mandato tramite checkout ospitato, imposta payment_link: true e fornisci un return_url.

Come funziona l’on-demand

  1. Crei un abbonamento con l’oggetto on_demand per autorizzare un metodo di pagamento e, facoltativamente, raccogliere un addebito iniziale.
  2. In seguito, crei addebiti contro quell’abbonamento con importi personalizzati utilizzando l’endpoint di addebito dedicato.
  3. Ascolti i webhook (ad es., payment.succeeded, payment.failed) per aggiornare il tuo sistema.

Crea un abbonamento on-demand

Endpoint: POST /subscriptions Campi chiave della richiesta (corpo):
product_id
string
obbligatorio
ID del prodotto per l’abbonamento.
quantity
integer
obbligatorio
Numero di unità. Minimo 1.
billing
object
obbligatorio
Indirizzo di fatturazione per il cliente.
customer
object
obbligatorio
Allegare un cliente esistente o fornire i dettagli del cliente.
Se vero, crea un link di checkout ospitato per l’autorizzazione del mandato e il pagamento iniziale opzionale.
return_url
string
Dove reindirizzare il cliente dopo aver completato il checkout ospitato.
on_demand.mandate_only
boolean
obbligatorio
Se vero, autorizza il metodo di pagamento senza addebitare il cliente durante la creazione.
on_demand.product_price
integer
Importo dell’addebito iniziale (nell’unità monetaria più piccola). Se specificato, questo valore sovrascrive il prezzo originale del prodotto impostato durante la creazione del prodotto. Se omesso, viene utilizzato il prezzo memorizzato del prodotto. Esempio: per addebitare $1.00, passare 100.
on_demand.product_currency
string
Sovrascrittura della valuta opzionale per l’addebito iniziale. Predefinito alla valuta del prodotto.
on_demand.product_description
string
Sovrascrittura della descrizione opzionale per la fatturazione e gli articoli di linea.
on_demand.adaptive_currency_fees_inclusive
boolean
Se vero, include le spese di valuta adattiva all’interno di product_price. Se falso, le spese vengono aggiunte sopra. Ignorato quando la tariffazione adattiva è disabilitata.

Crea un abbonamento on-demand

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);
Imposta payment_link: true, reindirizza il cliente a payment_link per completare l’autorizzazione del mandato.
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": []
}

Addebita un abbonamento on-demand

Dopo che il mandato è stato autorizzato, crea addebiti secondo necessità. Endpoint: POST /subscriptions/{subscription_id}/charge Campi chiave della richiesta (corpo):
product_price
integer
obbligatorio
Importo da addebitare (nell’unità monetaria più piccola). Esempio: per addebitare $25.00, passare 2500.
product_currency
string
Sovrascrittura della valuta opzionale per l’addebito.
product_description
string
Sovrascrittura della descrizione opzionale per questo addebito.
adaptive_currency_fees_inclusive
boolean
Se vero, include le spese di valuta adattiva all’interno di product_price. Se falso, le spese vengono aggiunte sopra.
metadata
object
Metadati aggiuntivi per il pagamento. Se omesso, vengono utilizzati i metadati dell’abbonamento.
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" }
Addebitare un abbonamento che non è on-demand potrebbe fallire. Assicurati che l’abbonamento abbia on_demand: true nei suoi dettagli prima di addebitare.

Riprova ai pagamenti

Il nostro sistema di rilevamento delle frodi potrebbe bloccare schemi di ripetizione aggressivi (e può contrassegnarli come potenziale test di carte). Segui una politica di ripetizione sicura.
Schemi di ripetizione a raffica possono essere contrassegnati come fraudolenti o sospetti test di carte dai nostri sistemi di rischio e dai processori. Evita ripetizioni raggruppate; segui il programma di backoff e le linee guida di allineamento temporale di seguito.

Principi per politiche di ripetizione sicure

  • Meccanismo di backoff: Usa il backoff esponenziale tra le ripetizioni.
  • Limiti di ripetizione: Limita il totale delle ripetizioni (massimo 3-4 tentativi).
  • Filtraggio intelligente: Ripeti solo in caso di errori ripetibili (ad es., errori di rete/emittente, fondi insufficienti); non ripetere mai i rifiuti definitivi.
  • Prevenzione dei test di carte: Non ripetere i rifiuti come DO_NOT_HONOR, STOLEN_CARD, LOST_CARD, PICKUP_CARD, FRAUDULENT, AUTHENTICATION_FAILURE.
  • Variazione dei metadati (opzionale): Se mantieni il tuo sistema di ripetizione, differenzia le ripetizioni tramite metadati (ad es., retry_attempt).

Programma di ripetizione suggerito (abbonamenti)

  • 1° tentativo: Immediato quando crei l’addebito
  • 2° tentativo: Dopo 3 giorni
  • 3° tentativo: Dopo altri 7 giorni (10 giorni totali)
  • 4° tentativo (finale): Dopo altri 7 giorni (17 giorni totali)
Passo finale: se ancora non pagato, contrassegna l’abbonamento come non pagato o annullalo, in base alla tua politica. Notifica il cliente durante il periodo per aggiornare il proprio metodo di pagamento.

Evita ripetizioni a raffica; allineati all’orario di autorizzazione

  • Ancorare le ripetizioni al timestamp di autorizzazione originale per evitare comportamenti a “raffica” nel tuo portafoglio.
  • Esempio: Se il cliente inizia una prova o un mandato alle 13:10 di oggi, pianifica le ripetizioni successive alle 13:10 nei giorni successivi secondo il tuo backoff (ad es., +3 giorni → 13:10, +7 giorni → 13:10).
  • In alternativa, se memorizzi l’ora dell’ultimo pagamento riuscito T, pianifica il prossimo tentativo a T + X days per preservare l’allineamento dell’ora del giorno.
Fuso orario e ora legale: utilizza uno standard di tempo coerente per la pianificazione e converti solo per la visualizzazione per mantenere gli intervalli.

Codici di rifiuto che non dovresti ripetere

  • STOLEN_CARD
  • DO_NOT_HONOR
  • FRAUDULENT
  • PICKUP_CARD
  • AUTHENTICATION_FAILURE
  • LOST_CARD
Per un elenco completo delle motivazioni di rifiuto e se sono correggibili dall’utente, vedere la Documentazione sui fallimenti delle transazioni.
Ripeti solo in caso di problemi soft/temporanei (ad es., insufficient_funds, issuer_unavailable, processing_error, timeout di rete). Se lo stesso rifiuto si ripete, interrompi ulteriori ripetizioni.

Linee guida per l’implementazione (senza codice)

  • Usa un pianificatore/coda che persiste timestamp precisi; calcola il prossimo tentativo all’esatto offset dell’ora del giorno (ad es., T + 3 days alla stessa HH:MM).
  • Mantieni e fai riferimento all’ora dell’ultimo pagamento riuscito T per calcolare il prossimo tentativo; non raggruppare più abbonamenti nello stesso istante.
  • Valuta sempre l’ultima motivazione di rifiuto; interrompi le ripetizioni per i rifiuti definitivi nell’elenco di esclusione sopra.
  • Limita le ripetizioni concorrenti per cliente e per account per prevenire picchi accidentali.
  • Comunica proattivamente: invia un’email/SMS al cliente per aggiornare il proprio metodo di pagamento prima del prossimo tentativo programmato.
  • Usa i metadati solo per l’osservabilità (ad es., retry_attempt); non cercare mai di “evadere” i sistemi di frode/rischio ruotando campi insignificanti.

Monitora i risultati con i webhook

Implementa la gestione dei webhook per monitorare il percorso del cliente. Vedi Implementazione dei Webhook.
  • subscription.active: Mandato autorizzato e abbonamento attivato
  • subscription.failed: Creazione fallita (ad es., fallimento del mandato)
  • subscription.on_hold: Abbonamento messo in attesa (ad es., stato non pagato)
  • payment.succeeded: Addebito riuscito
  • payment.failed: Addebito fallito
Per i flussi on-demand, concentrati su payment.succeeded e payment.failed per riconciliare gli addebiti basati sull’uso.

Test e prossimi passi

1

Crea in modalità test

Usa la tua chiave API di test per creare l’abbonamento con payment_link: true, quindi apri il link e completa il mandato.
2

Attiva un addebito

Chiama l’endpoint di addebito con un piccolo product_price (ad es., 100) e verifica di ricevere payment.succeeded.
3

Vai in produzione

Passa alla tua chiave API live una volta che hai convalidato eventi e aggiornamenti dello stato interno.

Risoluzione dei problemi

  • 422 Richiesta non valida: Assicurati che on_demand.mandate_only sia fornito alla creazione e che product_price sia fornito per gli addebiti.
  • Errori di valuta: Se sovrascrivi product_currency, conferma che sia supportato per il tuo account e cliente.
  • Nessun webhook ricevuto: Verifica l’URL del tuo webhook e la configurazione del segreto della firma.