Vai al contenuto principale
In questo tutorial, imparerai come implementare prezzi basati sui posti utilizzando gli add-on di Dodo Payments. Creeremo un prodotto in abbonamento con add-on per posti aggiuntivi e ti mostreremo come generare link di pagamento con quantità di add-on personalizzate.
Questo tutorial fornisce codice di implementazione di esempio per un’applicazione Node.js/Express. Puoi modificare questo codice per il tuo framework specifico (Next.js, React, Vue, ecc.) e personalizzare l’interfaccia utente in base alle esigenze della tua applicazione.
Alla fine di questo tutorial, saprai come:
  • Creare prodotti in abbonamento con prezzi basati sui posti
  • Configurare add-on per posti aggiuntivi
  • Generare link di pagamento con quantità di add-on personalizzate
  • Gestire sessioni di checkout con conteggi di posti dinamici

Cosa stiamo costruendo

Creiamo un modello di prezzo basato sui posti:
  • Piano Base: $49/mese per un massimo di 5 membri del team
  • Add-on per Posto: $2/mese per ogni posto aggiuntivo
  • Link di Pagamento: Checkout dinamico con quantità di posti personalizzate
Prima di iniziare, assicurati di avere:
  • Un account Dodo Payments
  • Una conoscenza di base di TypeScript/Node.js

Passo 1: Crea il tuo Add-On per Posti

Ora dobbiamo creare un add-on che rappresenti posti aggiuntivi. Questo add-on sarà collegato al nostro abbonamento base e permetterà ai clienti di acquistare posti aggiuntivi.
Creating base subscription product
Cosa stiamo creando: un componente aggiuntivo che costa $2/mese per postazione e può essere aggiunto a qualsiasi abbonamento base.
1

Navigate to Add-Ons

  1. Nella dashboard di Dodo Payments, resta nella sezione Products
  2. Clicca sulla scheda Add-Ons
  3. Clicca su Create Add-On
Questo aprirà il modulo di creazione del componente aggiuntivo.
2

Enter add-on details

Compila questi valori per il nostro componente aggiuntivo per postazioni:Add-On Name: Additional Team SeatDescription: Add extra team members to your workspace with full access to all featuresPrice: Inserisci → 2.00Valuta: Deve corrispondere alla valuta del tuo abbonamento baseCategoria Fiscale: Seleziona la categoria appropriata per il tuo prodotto.
3

Save your add-on

  1. Controlla tutte le impostazioni:
    • Nome: Additional Team Seat
    • Prezzo: $2.00/mese
  2. Clicca su Create Add-On
Componenti aggiuntivo creato! Il tuo componente per le postazioni è ora disponibile per essere collegato agli abbonamenti.

Passo 2: Crea il tuo Prodotto in Abbonamento Base

Iniziamo creando un prodotto in abbonamento base che include 5 membri del team. Questa sarà la base del nostro modello di prezzo basato sui posti.
Creating base subscription product
1

Navigate to Products

  1. Accedi alla dashboard di Dodo Payments
  2. Clicca su Products nella barra laterale sinistra
  3. Clicca sul pulsante Create Product
  4. Seleziona Subscription come tipo di prodotto
Dovresti vedere un modulo in cui configureremo il nostro abbonamento base.
2

Fill in the subscription details

Ora inseriremo i dettagli specifici per il nostro piano base:Product Name: MotionDescription: Where your team's documentation lives.Recurring Price: Inserisci → 49.00Billing Cycle: Seleziona → MonthlyCurrency: Seleziona la valuta preferita (es. USD)

Passo 3: Collega l’Add-On all’Abbonamento

Ora dobbiamo associare il nostro add-on per posti con l’abbonamento base in modo che i clienti possano acquistare posti aggiuntivi durante il checkout.
1

Attach the seat add-on

Attaching add-on to subscription
  1. Scorri verso il basso fino alla sezione Add-Ons
  2. Clicca su Aggiungi Add-Ons
  3. Dal menu a discesa, seleziona il tuo add-on per posti
  4. Conferma che appare nella configurazione del tuo abbonamento
2

Save subscription changes

  1. Controlla l’intera configurazione dell’abbonamento:
    • Piano base: $49/mese per 5 postazioni
    • Componente aggiuntivo: $2/mese per postazione aggiuntiva
    • Prova gratuita: 14 giorni
  2. Clicca su Save Changes
Prezzi basati sui posti configurati! I clienti ora possono acquistare il piano base e aggiungere postazioni extra secondo necessità.
Ora creiamo un’applicazione Express.js che genera link di pagamento con quantità di add-on personalizzate. Qui entra in gioco il vero potere dei prezzi basati sui posti: puoi creare dinamicamente sessioni di checkout con qualsiasi numero di posti aggiuntivi.
1

Set up your project

Crea un nuovo progetto Node.js e installa le dipendenze richieste:
mkdir seat-based-pricing
cd seat-based-pricing
npm init -y
npm install dodopayments express dotenv
npm install -D @types/node @types/express typescript ts-node
Crea un file tsconfig.json:
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  }
}
2

Create your environment file

Crea un file .env con la tua chiave API di Dodo Payments:
DODO_PAYMENTS_API_KEY=your_actual_dodo_api_key_here
Non inserire mai la tua chiave API nel controllo di versione. Aggiungi .env al tuo file .gitignore.
3

Implement the checkout session creation

Crea un file src/server.ts con il seguente codice:
// Add this new endpoint for dynamic seat quantities
import 'dotenv/config';
import DodoPayments from 'dodopayments';
import express, { Request, Response } from 'express';

const app = express();

// Initialize the Dodo Payments client
const client = new DodoPayments({
  bearerToken: process.env.DODO_PAYMENTS_API_KEY,
  environment: 'test_mode'
});

async function createCheckoutSession(seatCount: number) {
  try {
    const session = await client.checkoutSessions.create({
      // Products to sell - use IDs from your Dodo Payments dashboard
      product_cart: [
        {
          product_id: 'pdt_7Rl9OWT2Mz4wwUTKz74iZ', // Replace with your actual product ID
          quantity: 1,
          addons: [
            {
              addon_id: 'adn_eKQbNakKrivDpaxmI8wKI', // Replace with your actual addon ID
              quantity: seatCount
            }
          ]
        }
      ],
      
      // Pre-fill customer information to reduce friction
      customer: {
        email: 'steve@example.com',
        name: 'Steve Irwin',
      },
      // Where to redirect after successful payment
      return_url: 'https://example.com/checkout/success',
    });

    // Redirect your customer to this URL to complete payment
    console.log('Checkout URL:', session.checkout_url);
    console.log('Session ID:', session.session_id);
    
    return session;
    
  } catch (error) {
    console.error('Failed to create checkout session:', error);
    throw error;
  }
}

// Example usage in an Express.js route
app.post('/create-checkout/:seatCount', async (req: Request, res: Response) => {
  try {
    const seatCount = parseInt(req.params.seatCount);
    const session = await createCheckoutSession(seatCount);
    res.json({ checkout_url: session.checkout_url });
  } catch (error) {
    res.status(500).json({ error: 'Failed to create checkout session' });
  }
});

// Add this line after your other middleware
app.use(express.static('public'));

// Add this route to serve the demo page
app.get('/', (req, res) => {
  res.sendFile(__dirname + '/../public/index.html');
});

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});
4

Add a simple web interface

Crea un file public/index.html per testare facilmente:
<!DOCTYPE html>
<html>
<head>
    <title>Seat-Based Pricing Demo</title>
    <style>
        body { font-family: Arial, sans-serif; max-width: 600px; margin: 50px auto; padding: 20px; }
        .form-group { margin: 20px 0; }
        label { display: block; margin-bottom: 5px; font-weight: bold; }
        input { width: 100%; padding: 10px; border: 1px solid #ddd; border-radius: 4px; }
        button { background: #007bff; color: white; padding: 10px 20px; border: none; border-radius: 4px; cursor: pointer; }
        button:hover { background: #0056b3; }
        .result { margin-top: 20px; padding: 15px; background: #f8f9fa; border-radius: 4px; }
    </style>
</head>
<body>
    <h1>Seat-Based Pricing Demo</h1>
    <p>Generate checkout links with custom seat quantities:</p>
    
    <div class="form-group">
        <label for="seatCount">Number of Additional Seats:</label>
        <input type="number" id="seatCount" value="3" min="0" max="50">
    </div>
    
    <button onclick="createCheckout()">Generate Checkout Link</button>
    
    <div id="result" class="result" style="display: none;">
        <h3>Checkout Link Generated!</h3>
        <p><strong>Seat Count:</strong> <span id="seatCountDisplay"></span></p>
        <p><strong>Total Cost:</strong> $<span id="totalCost"></span>/month</p>
        <p><strong>Checkout URL:</strong></p>
        <a id="checkoutUrl" href="#" target="_blank">Click here to checkout</a>
    </div>

    <script>
        async function createCheckout() {
            const seatCount = document.getElementById('seatCount').value;
            
            try {
                const response = await fetch(`/create-checkout/${seatCount}`, {
                    method: 'POST'
                });
                
                const data = await response.json();
                
                if (response.ok) {
                    document.getElementById('seatCountDisplay').textContent = seatCount;
                    document.getElementById('totalCost').textContent = data.total_cost;
                    document.getElementById('checkoutUrl').href = data.checkout_url;
                    document.getElementById('result').style.display = 'block';
                } else {
                    alert('Error: ' + data.error);
                }
            } catch (error) {
                alert('Error creating checkout session');
            }
        }
    </script>
</body>
</html>
Interfaccia Web creata! Ora hai una semplice interfaccia per provare diverse quantità di postazioni.
5

Serve static files

Aggiungi questo al tuo src/server.ts per servire il file HTML:
// Add this line after your other middleware
app.use(express.static('public'));

// Add this route to serve the demo page
app.get('/', (req, res) => {
  res.sendFile(__dirname + '/../public/index.html');
});
File statici configurati! Visita http://localhost:3000 per vedere la tua interfaccia demo.

Passo 5: Testa la tua Implementazione

Testiamo la nostra implementazione dei prezzi basati sui posti per assicurarci che tutto funzioni correttamente.
1

Start your server

  1. Assicurati di avere il file .env con la chiave API corretta
  2. Aggiorna gli ID di prodotto e componente aggiuntivo nel tuo codice con i valori effettivi della dashboard Dodo Payments
  3. Avvia il server:
npm run dev
Il server dovrebbe avviarsi correttamente e mostrare “Server running on http://localhost:3000
2

Test the web interface

Creating base subscription product
  1. Apri il browser e vai su http://localhost:3000
  2. Dovresti vedere l’interfaccia demo basata sui posti
  3. Prova diverse quantità di postazioni (0, 3, 10, ecc.)
  4. Clicca su “Generate Checkout Link” per ogni quantità
  5. Verifica che gli URL di checkout vengano generati correttamente
3

Test a checkout session

  1. Genera un link di checkout con 3 postazioni aggiuntive
  2. Clicca sull’URL di checkout per aprire il checkout di Dodo Payments
  3. Verifica che il checkout mostri:
    • Piano base: $49/mese
    • Postazioni aggiuntive: 3 × 2 dollari = $6/mese
  4. Completa l’acquisto di prova
Il checkout dovrebbe mostrare la suddivisione corretta dei prezzi e permetterti di completare l’acquisto.
4

Listen for webhooks and update your DB

Per mantenere il database sincronizzato con i cambiamenti dell’abbonamento e delle postazioni, devi ascoltare gli eventi webhook di Dodo Payments. I webhook notificano il backend quando un cliente completa il checkout, aggiorna l’abbonamento o modifica il numero di postazioni.Segui la guida ufficiale ai webhook di Dodo Payments per istruzioni passo-passo su come impostare gli endpoint webhook e gestire gli eventi:

Dodo Payments Webhooks Documentation

Scopri come ricevere e elaborare in modo sicuro gli eventi webhook per la gestione degli abbonamenti e delle postazioni.

Risoluzione dei Problemi

Problemi comuni e le loro soluzioni:
Possibili cause:
  • ID del prodotto o del componente aggiuntivo non valido
  • La chiave API non ha autorizzazioni sufficienti
  • Il componente aggiuntivo non è correttamente associato all’abbonamento
  • Problemi di connettività di rete
Soluzioni:
  1. Verifica che gli ID di prodotto e componente aggiuntivo esistano nella dashboard Dodo Payments
  2. Controlla che il componente aggiuntivo sia correttamente attaccato all’abbonamento
  3. Assicurati che la chiave API abbia i permessi per creare sessioni di checkout
  4. Testa la connettività API con una semplice richiesta GET

Congratulazioni! Hai Implementato Prezzi Basati sui Posti

Hai creato con successo un sistema di prezzi basati sui posti con Dodo Payments! Ecco cosa hai realizzato:

Base Subscription

Creato un prodotto di abbonamento con 5 postazioni incluse a $49/mese

Seat Add-ons

Configurati i componenti aggiuntivi per postazioni aggiuntive a $2/mese ciascuna

Checkout

Costruita un’API che genera sessioni di checkout con quantità di postazioni personalizzate

Web Interface

Creata una semplice interfaccia web per testare diverse quantità di postazioni
Questo esempio dimostra solo un’implementazione minima dei prezzi basati sulle postazioni. Per l’uso in produzione, dovresti aggiungere un solido handling degli errori, autenticazione, validazione dei dati, misure di sicurezza e adattare la logica alle esigenze della tua applicazione.