> ## 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"
}
```

Reindirizza il cliente a `checkout_url`.

### Webhook

Quando integri gli abbonamenti, riceverai webhook per monitorare il ciclo di vita degli abbonamenti. Questi webhook ti aiutano a gestire efficacemente gli stati degli abbonamenti e gli scenari di pagamento.

Per configurare il tuo endpoint webhook, segui la nostra [Guida dettagliata all'integrazione](/developer-resources/integration-guide#implementing-webhooks).

#### Tipi di eventi di abbonamento

I seguenti eventi webhook monitorano i cambiamenti di stato dell'abbonamento:

1. **`subscription.active`** - L'abbonamento è stato attivato con successo.
2. **`subscription.updated`** - L'oggetto dell'abbonamento è stato aggiornato (si attiva su qualsiasi modifica del campo).
3. **`subscription.on_hold`** - L'abbonamento è messo in attesa a causa di un rinnovo fallito.
4. **`subscription.failed`** - La creazione dell'abbonamento è fallita durante la creazione del mandato.
5. **`subscription.renewed`** - L'abbonamento è rinnovato per il prossimo periodo di fatturazione.

Per una gestione affidabile del ciclo di vita degli abbonamenti, consigliamo di monitorare questi eventi di abbonamento.

<Tip>
  Usa `subscription.updated` per ottenere notifiche in tempo reale su qualsiasi modifica dell'abbonamento, mantenendo lo stato dell'applicazione sincronizzato senza interpellare l'API.
</Tip>

#### Scenari di pagamento

**Flusso di pagamento riuscito**

Quando un pagamento ha successo, riceverai i seguenti webhook:

1. `subscription.active` - Indica l'attivazione dell'abbonamento
2. `payment.succeeded` - Conferma il pagamento iniziale:
   * Per la fatturazione immediata (0 giorni di prova): Aspettati entro 2-10 minuti
   * Per i giorni di prova: ogni volta che termina
3. `subscription.renewed` - Indica la deduzione del pagamento e il rinnovo per il prossimo ciclo. (Fondamentalmente, ogni volta che il pagamento viene dedotto per i prodotti in abbonamento, riceverai il webhook `subscription.renewed` insieme a `payment.succeeded`)

**Scenari di fallimento del pagamento**

1. Fallimento dell'abbonamento

* `subscription.failed` - La creazione dell'abbonamento è fallita a causa del fallimento nella creazione di un mandato.
* `payment.failed` - Indica un pagamento fallito.

2. Abbonamento in attesa

* `subscription.on_hold` - L'abbonamento è messo in attesa a causa di un pagamento di rinnovo fallito o di un addebito per cambio piano fallito.
* Quando un abbonamento è in attesa, non si rinnoverà automaticamente fino a quando il metodo di pagamento non sarà aggiornato.

<Info>**Miglior pratica**: Per semplificare l'implementazione, consigliamo di monitorare principalmente gli eventi di abbonamento per gestire il ciclo di vita degli abbonamenti.</Info>

<Tip>
  Per un walkthrough completo della lettura di `error_code`/`error_message`, decidendo quando riprovare, e facendo emergere i fallimenti ai clienti, vedi [Gestire fallimenti dei pagamenti](/developer-resources/handle-payment-failures).
</Tip>

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

Questi due eventi sono facili da confondere, ma richiedono una gestione molto diversa:

| Evento                 | Quando si attiva                                                                                 | Stato     | Recuperabile?      | Cosa fare                                                                                                                      |
| ---------------------- | ------------------------------------------------------------------------------------------------ | --------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------ |
| `subscription.failed`  | Il **mandato iniziale** non è stato creato alla **creazione** dell'abbonamento                   | `failed`  | **No — terminale** | Non concedere l'accesso. Chiedi al cliente di avviare un **nuovo** abbonamento con un metodo di pagamento diverso.             |
| `subscription.on_hold` | Un pagamento di **rinnovo** (o addebito per cambio piano) è fallito su un abbonamento già attivo | `on_hold` | **Sì**             | Recupera aggiornando il metodo di pagamento; vedi [Gestione abbonamento in attesa](#handling-subscription-on-hold) di seguito. |

<Warning>
  `subscription.failed` è terminale — l'abbonamento non può essere riattivato. Il cliente deve creare un nuovo abbonamento. Non concedere mai diritti quando questo evento si attiva.
</Warning>

### Gestione abbonamento in attesa

Quando un abbonamento entra nello stato `on_hold`, devi aggiornare il metodo di pagamento per riattivarlo. Questa sezione spiega quando gli abbonamenti vengono messi in attesa e come gestirli.

#### Quando gli abbonamenti vengono messi in attesa

Un abbonamento è messo in attesa quando:

* **Il pagamento di rinnovo fallisce**: La carica automatica di rinnovo fallisce a causa di fondi insufficienti, carta scaduta o rifiuto della banca
* **Il cambio di piano fallisce**: Un addebito immediato durante l'upgrade/downgrade del piano fallisce
* **L'autorizzazione del metodo di pagamento fallisce**: Il metodo di pagamento non può essere autorizzato per addebiti ricorrenti

<Warning>
  Gli abbonamenti nello stato `on_hold` non si rinnoveranno automaticamente. È necessario aggiornare il metodo di pagamento per riattivare l'abbonamento.
</Warning>

#### Riattivazione degli abbonamenti in attesa

Per riattivare un abbonamento dallo stato `on_hold`, usa l'API di aggiornamento del metodo di pagamento. Questo automaticamente:

1. Crea un addebito per i restanti debiti
2. Genera una fattura per l'addebito
3. Elabora il pagamento utilizzando il nuovo metodo di pagamento
4. Riattiva l'abbonamento allo stato `active` al pagamento riuscito

<Steps>
  <Step title="Handle subscription.on_hold webhook">
    Quando ricevi un webhook `subscription.on_hold`, aggiorna lo stato della tua applicazione e notifica al cliente:

    ```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">
    Quando il cliente è pronto ad aggiornare il proprio metodo di pagamento, chiama l'API di aggiornamento del metodo di pagamento:

    <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>
      Puoi anche utilizzare un ID di metodo di pagamento esistente se il cliente ha metodi di pagamento salvati:

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

  <Step title="Monitor webhook events">
    Dopo aver aggiornato il metodo di pagamento, monitorare questi eventi webhook:

    1. **`payment.succeeded`** - Il addebito per i debiti rimanenti è riuscito
    2. **`subscription.active`** - L'abbonamento è stato riattivato

    ```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>

### Esempio di payload evento abbonamento

***

| Proprietà     | Tipo    | Richiesto | Descrizione                                                                                                  |
| ------------- | ------- | --------- | ------------------------------------------------------------------------------------------------------------ |
| `business_id` | stringa | Sì        | L'identificatore univoco per l'azienda                                                                       |
| `timestamp`   | stringa | Sì        | Il timestamp di quando l'evento si è verificato (non necessariamente lo stesso di quando è stato consegnato) |
| `type`        | stringa | Sì        | Il tipo di evento. Vedi [Tipi di eventi](#event-types)                                                       |
| `data`        | oggetto | Sì        | Il payload principale dei dati. Vedi [Oggetto dati](#data-object)                                            |

## Modifica dei piani di abbonamento

Puoi aggiornare o ridurre un piano di abbonamento utilizzando l'endpoint API di cambio piano. Questo ti consente di modificare il prodotto dell'abbonamento, la quantità e gestire la ripartizione.

<Card title="Change Plan API Reference" icon="arrows-rotate" href="/api-reference/subscriptions/change-plan">
  Per informazioni dettagliate sul cambio dei piani di abbonamento, fai riferimento alla nostra documentazione API di cambio piano.
</Card>

### Opzioni di ripartizione

Quando cambi i piani di abbonamento, hai due opzioni per gestire l'addebito immediato:

#### 1. `prorated_immediately`

* Calcola l'importo ripartito in base al tempo rimanente nel ciclo di fatturazione attuale
* Addebita al cliente solo la differenza tra il vecchio e il nuovo piano
* Durante un periodo di prova, ciò passerà immediatamente l'utente al nuovo piano, addebitando subito al cliente

#### 2. `full_immediately`

* Addebita al cliente l'intero importo dell'abbonamento per il nuovo piano
* Ignora qualsiasi tempo rimanente o crediti dal piano precedente
* Utile quando si desidera reimpostare il ciclo di fatturazione o addebitare l'intero importo indipendentemente dalla ripartizione

#### 3. `difference_immediately`

* Durante un upgrade, il cliente viene immediatamente addebitato la differenza tra gli importi dei due piani.
* Ad esempio, se il piano attuale è di 30 dollari e il cliente passa a un piano di 80 dollari, vengono addebitati immediatamente 50 dollari.
* Durante un downgrade, l'importo non utilizzato del piano attuale viene aggiunto come credito interno e automaticamente applicato ai futuri rinnovi dell'abbonamento.
* Ad esempio, se il piano attuale è di 50 dollari e il cliente passa a un piano di 20 dollari, i restanti 30 dollari vengono accreditati e usati per il prossimo ciclo di fatturazione.

### Comportamento

* Quando invochi questa API, Dodo Payments inizia immediatamente un addebito in base alla tua opzione di ripartizione selezionata
* Se il cambio di piano è un downgrade e usi `prorated_immediately`, i crediti saranno automaticamente calcolati e aggiunti al saldo del credito dell'abbonamento. Questi crediti sono specifici per quell'abbonamento e saranno utilizzati solo per compensare i pagamenti ricorrenti futuri dello stesso abbonamento
* L'opzione `full_immediately` bypassa i calcoli del credito e addebita l'intero importo del nuovo piano

<Tip>
  **Scegli con attenzione l'opzione di ripartizione**: Usa `prorated_immediately` per una fatturazione equa che tenga conto del tempo non utilizzato, o `full_immediately` quando desideri addebitare l'intero importo del nuovo piano indipendentemente dal ciclo di fatturazione corrente.
</Tip>

### Elaborazione degli addebiti

* L'addebito immediato avviato al cambio del piano di solito completa l'elaborazione in meno di 2 minuti
* Se questo addebito immediato fallisce per qualsiasi motivo, l'abbonamento viene automaticamente messo in attesa fino a quando il problema non verrà risolto

## Abbonamenti on-demand

<Info>
  Gli abbonamenti on-demand ti permettono di addebitare ai clienti in modo flessibile, non solo su un programma fisso. Questa funzione è disponibile per tutti gli account.
</Info>

**Per creare un abbonamento on-demand:**

Per creare un abbonamento on-demand, utilizza l'endpoint API [POST /subscriptions](/api-reference/subscriptions/post-subscriptions) e includi il campo `on_demand` nel corpo della tua richiesta. Questo ti consente di autorizzare un metodo di pagamento senza un addebito immediato o impostare un prezzo iniziale personalizzato.

**Per addebitare un abbonamento on-demand:**

Per addebiti successivi, utilizza l'endpoint [POST /subscriptions/{subscription_id}/charge](/api-reference/subscriptions/create-charge) e specifica l'importo da addebitare al cliente per quella transazione.

<Note>
  Per una guida completa passo-passo — inclusi esempi di richiesta/risposta, politiche di riprova sicure e gestione dei webhook — vedi la <a href="/developer-resources/ondemand-subscriptions">Guida agli abbonamenti on-demand</a>.
</Note>

## Riferimento API correlato

<CardGroup cols={2}>
  <Card title="Create Subscription" icon="code" href="/api-reference/subscriptions/post-subscriptions">
    Riferimento API per la creazione di prodotti in abbonamento e gestione del ciclo di vita dell'abbonamento
  </Card>

  <Card title="Change Subscription Plan" icon="arrows-rotate" href="/api-reference/subscriptions/change-plan">
    Riferimento API per l'aggiornamento, il downgrade o il cambio dei piani di abbonamento con opzioni di ripartizione
  </Card>

  <Card title="Update Payment Method" icon="credit-card" href="/api-reference/subscriptions/update-payment-method">
    Riferimento API per l'aggiornamento dei metodi di pagamento e la riattivazione degli abbonamenti in attesa
  </Card>

  <Card title="Patch Subscription" icon="pen" href="/api-reference/subscriptions/patch-subscriptions">
    Riferimento API per l'aggiornamento dei dettagli dell'abbonamento e la configurazione
  </Card>
</CardGroup>
