Vai al contenuto principale

Installazione

1

Installa il pacchetto

Esegui il seguente comando nella radice del tuo progetto:
npm install @dodopayments/remix
2

Configura le variabili d'ambiente

Crea un file .env nella radice del tuo progetto:
DODO_PAYMENTS_API_KEY=your-api-key
DODO_PAYMENTS_WEBHOOK_SECRET=your-webhook-secret
DODO_PAYMENTS_RETURN_URL=https://yourdomain.com/checkout/success
DODO_PAYMENTS_ENVIRONMENT="test_mode" or "live_mode"
Non impegnare mai il tuo file .env o segreti nel controllo di versione.

Esempi di Gestore Route

Tutti gli esempi presuppongono che tu stia utilizzando il Remix App Router.
Usa questo gestore per integrare il checkout di Dodo Payments nella tua app Remix. Supporta flussi di pagamento statici (GET), dinamici (POST) e di sessione (POST).
// app/routes/api.checkout.tsx
import { Checkout } from "@dodopayments/remix";
import type { LoaderFunctionArgs } from "@remix-run/node";

const checkoutGetHandler = Checkout({
    bearerToken: process.env.DODO_PAYMENTS_API_KEY,
    returnUrl: process.env.DODO_PAYMENTS_RETURN_URL,
    environment: process.env.DODO_PAYMENTS_ENVIRONMENT,
    type: "static"
});

const checkoutPostHandler = Checkout({
    bearerToken: process.env.DODO_PAYMENTS_API_KEY,
    returnUrl: process.env.DODO_PAYMENTS_RETURN_URL,
    environment: process.env.DODO_PAYMENTS_ENVIRONMENT,
    type: "dynamic", // for dynamic checkout
});

const checkoutSessionHandler = Checkout({
    bearerToken: process.env.DODO_PAYMENTS_API_KEY,
    returnUrl: process.env.DODO_PAYMENTS_RETURN_URL,
    environment: process.env.DODO_PAYMENTS_ENVIRONMENT,
    type: "session", // for checkout sessions
});

export const loader = ({ request }: LoaderFunctionArgs) => checkoutGetHandler(request);
export const action = ({ request }: LoaderFunctionArgs) => {
    // You can conditionally route to different handlers based on your needs
    // For checkout sessions, use checkoutSessionHandler(request)
    return checkoutPostHandler(request);
};
curl --request GET \
--url 'https://example.com/api/checkout?productId=pdt_fqJhl7pxKWiLhwQR042rh' \
--header 'User-Agent: insomnia/11.2.0' \
--cookie mode=test
curl --request POST \
--url https://example.com/api/checkout \
--header 'Content-Type: application/json' \
--header 'User-Agent: insomnia/11.2.0' \
--cookie mode=test \
--data '{
"billing": {
  "city": "Texas",
  "country": "US",
  "state": "Texas",
  "street": "56, hhh",
  "zipcode": "560000"
},
"customer": {
  "email": "[email protected]",
  	"name": "test"
},
"metadata": {},
"payment_link": true,
  "product_id": "pdt_QMDuvLkbVzCRWRQjLNcs",
  "quantity": 1,
  "billing_currency": "USD",
  "discount_code": "IKHZ23M9GQ",
  "return_url": "https://example.com",
  "trial_period_days": 10
}'
curl --request POST \
--url https://example.com/api/checkout \
--header 'Content-Type: application/json' \
--header 'User-Agent: insomnia/11.2.0' \
--cookie mode=test \
--data '{
"product_cart": [
  {
    "product_id": "pdt_QMDuvLkbVzCRWRQjLNcs",
    "quantity": 1
  }
],
"customer": {
  "email": "[email protected]",
  "name": "test"
},
"return_url": "https://example.com/success"
}'

Gestore Route Checkout

Dodo Payments supporta tre tipi di flussi di pagamento per integrare i pagamenti nel tuo sito web, questo adattatore supporta tutti i tipi di flussi di pagamento.
  • Link di Pagamento Statici: URL condivisibili istantaneamente per una rapida raccolta di pagamenti senza codice.
  • Link di Pagamento Dinamici: Genera programmaticamente link di pagamento con dettagli personalizzati utilizzando l’API o gli SDK.
  • Sessioni di Checkout: Crea esperienze di checkout sicure e personalizzabili con carrelli prodotti preconfigurati e dettagli del cliente.

Parametri di Query Supportati

productId
string
obbligatorio
Identificatore del prodotto (ad es., ?productId=pdt_nZuwz45WAs64n3l07zpQR).
quantity
integer
Quantità del prodotto.
fullName
string
Nome completo del cliente.
firstName
string
Nome di battesimo del cliente.
lastName
string
Cognome del cliente.
email
string
Indirizzo email del cliente.
country
string
Paese del cliente.
addressLine
string
Indirizzo del cliente.
city
string
Città del cliente.
state
string
Stato/provincia del cliente.
zipCode
string
Codice postale del cliente.
disableFullName
boolean
Disabilita il campo nome completo.
disableFirstName
boolean
Disabilita il campo nome di battesimo.
disableLastName
boolean
Disabilita il campo cognome.
disableEmail
boolean
Disabilita il campo email.
disableCountry
boolean
Disabilita il campo paese.
disableAddressLine
boolean
Disabilita il campo indirizzo.
disableCity
boolean
Disabilita il campo città.
disableState
boolean
Disabilita il campo stato.
disableZipCode
boolean
Disabilita il campo codice postale.
paymentCurrency
string
Specifica la valuta di pagamento (ad es., USD).
showCurrencySelector
boolean
Mostra il selettore di valuta.
paymentAmount
integer
Specifica l’importo del pagamento (ad es., 1000 per $10.00).
showDiscounts
boolean
Mostra i campi di sconto.
metadata_*
string
Qualsiasi parametro di query che inizia con metadata_ sarà passato come metadati.
Se productId è mancante, il gestore restituisce una risposta 400. Parametri di query non validi risultano anche in una risposta 400.

Formato di Risposta

Il checkout statico restituisce una risposta JSON con l’URL di checkout:
{
  "checkout_url": "https://checkout.dodopayments.com/..."
}

Formato di Risposta

Il checkout dinamico restituisce una risposta JSON con l’URL di checkout:
{
  "checkout_url": "https://checkout.dodopayments.com/..."
}
Le sessioni di checkout offrono un’esperienza di checkout più sicura e ospitata che gestisce l’intero flusso di pagamento sia per acquisti una tantum che per abbonamenti con pieno controllo sulla personalizzazione.Fai riferimento alla Guida all’integrazione delle sessioni di checkout per ulteriori dettagli e un elenco completo dei campi supportati.

Formato di Risposta

Le sessioni di checkout restituiscono una risposta JSON con l’URL di checkout:
{
  "checkout_url": "https://checkout.dodopayments.com/session/..."
}

Gestore Route Portale Clienti

Il Gestore Route Portale Clienti ti consente di integrare senza soluzione di continuità il portale clienti di Dodo Payments nella tua applicazione Remix.

Parametri di Query

customer_id
string
obbligatorio
L’ID cliente per la sessione del portale (ad es., ?customer_id=cus_123).
send_email
boolean
Se impostato su true, invia un’email al cliente con il link del portale.
Restituisce 400 se customer_id è mancante.

Gestore Route Webhook

  • Metodo: Solo le richieste POST sono supportate. Altri metodi restituiscono 405.
  • Verifica della Firma: Verifica la firma del webhook utilizzando webhookKey. Restituisce 401 se la verifica fallisce.
  • Validazione del Payload: Validato con Zod. Restituisce 400 per payload non validi.
  • Gestione degli Errori:
    • 401: Firma non valida
    • 400: Payload non valido
    • 500: Errore interno durante la verifica
  • Routing degli Eventi: Chiama il gestore di eventi appropriato in base al tipo di payload.

Gestori di Eventi Webhook Supportati

onPayload?: (payload: WebhookPayload) => Promise<void>;
onPaymentSucceeded?: (payload: WebhookPayload) => Promise<void>;
onPaymentFailed?: (payload: WebhookPayload) => Promise<void>;
onPaymentProcessing?: (payload: WebhookPayload) => Promise<void>;
onPaymentCancelled?: (payload: WebhookPayload) => Promise<void>;
onRefundSucceeded?: (payload: WebhookPayload) => Promise<void>;
onRefundFailed?: (payload: WebhookPayload) => Promise<void>;
onDisputeOpened?: (payload: WebhookPayload) => Promise<void>;
onDisputeExpired?: (payload: WebhookPayload) => Promise<void>;
onDisputeAccepted?: (payload: WebhookPayload) => Promise<void>;
onDisputeCancelled?: (payload: WebhookPayload) => Promise<void>;
onDisputeChallenged?: (payload: WebhookPayload) => Promise<void>;
onDisputeWon?: (payload: WebhookPayload) => Promise<void>;
onDisputeLost?: (payload: WebhookPayload) => Promise<void>;
onSubscriptionActive?: (payload: WebhookPayload) => Promise<void>;
onSubscriptionOnHold?: (payload: WebhookPayload) => Promise<void>;
onSubscriptionRenewed?: (payload: WebhookPayload) => Promise<void>;
onSubscriptionPlanChanged?: (payload: WebhookPayload) => Promise<void>;
onSubscriptionCancelled?: (payload: WebhookPayload) => Promise<void>;
onSubscriptionFailed?: (payload: WebhookPayload) => Promise<void>;
onSubscriptionExpired?: (payload: WebhookPayload) => Promise<void>;
onLicenseKeyCreated?: (payload: WebhookPayload) => Promise<void>;

Prompt per LLM


You are an expert Remix developer assistant. Your task is to guide a user through integrating the @dodopayments/remix adapter into their existing Remix project.

The @dodopayments/remix adapter provides route handlers for Dodo Payments' Checkout, Customer Portal, and Webhook functionalities, designed for Remix route handlers.

First, install the necessary packages. Use the package manager appropriate for your project (npm, yarn, or bun) based on the presence of lock files (e.g., package-lock.json for npm, yarn.lock for yarn, bun.lockb for bun):

npm install @dodopayments/remix

Here's how you should structure your response:

    Ask the user which functionalities they want to integrate.

"Which parts of the @dodopayments/remix adapter would you like to integrate into your project? You can choose one or more of the following:

    Checkout Route Handler (for handling product checkouts)

    Customer Portal Route Handler (for managing customer subscriptions/details)

    Webhook Route Handler (for receiving Dodo Payments webhook events)

    All (integrate all three)"

    Based on the user's selection, provide detailed integration steps for each chosen functionality.

If Checkout Route Handler is selected:

Purpose: This handler redirects users to the Dodo Payments checkout page.
File Creation: Create a new file at app/routes/api.checkout.tsx in your Remix project.

Code Snippet:

// app/routes/api.checkout.tsx
import { Checkout } from "@dodopayments/remix";
import type { LoaderFunctionArgs } from "@remix-run/node";

const checkoutGetHandler = Checkout({
  bearerToken: process.env.DODO_PAYMENTS_API_KEY,
  returnUrl: process.env.DODO_PAYMENTS_RETURN_URL,
  environment: process.env.DODO_PAYMENTS_ENVIRONMENT,
  type: "static",
});

const checkoutPostHandler = Checkout({
  bearerToken: process.env.DODO_PAYMENTS_API_KEY,
  returnUrl: process.env.DODO_PAYMENTS_RETURN_URL,
  environment: process.env.DODO_PAYMENTS_ENVIRONMENT,
  type: "dynamic", // for dynamic checkout
});

const checkoutSessionHandler = Checkout({
  bearerToken: process.env.DODO_PAYMENTS_API_KEY,
  returnUrl: process.env.DODO_PAYMENTS_RETURN_URL,
  environment: process.env.DODO_PAYMENTS_ENVIRONMENT,
  type: "session", // for checkout sessions
});

export const loader = ({ request }: LoaderFunctionArgs) => checkoutGetHandler(request);

export const action = ({ request }: LoaderFunctionArgs) => {
  // You can conditionally route to different handlers based on your needs
  // For checkout sessions, use checkoutSessionHandler(request)
  return checkoutPostHandler(request);
};

If Customer Portal Route Handler is selected:

Purpose: This handler redirects authenticated users to their Dodo Payments customer portal.
File Creation: Create a new file at app/routes/api.customer-portal.tsx in your Remix project.

Code Snippet:

// app/routes/api.customer-portal.tsx
import { CustomerPortal } from "@dodopayments/remix";
import type { LoaderFunctionArgs } from "@remix-run/node";

const customerPortalHandler = CustomerPortal({
  bearerToken: process.env.DODO_PAYMENTS_API_KEY,
  environment: process.env.DODO_PAYMENTS_ENVIRONMENT
});

export const loader = ({ request }: LoaderFunctionArgs) => customerPortalHandler(request);

Query Parameters:

    customer_id (required): The customer ID for the portal session (e.g., ?customer_id=cus_123)

    send_email (optional, boolean): If set to true, sends an email to the customer with the portal link.

    Returns 400 if customer_id is missing.

If Webhook Route Handler is selected:

Purpose: This handler processes incoming webhook events from Dodo Payments, allowing your application to react to events like successful payments, refunds, or subscription changes.
File Creation: Create a new file at app/routes/api.webhook.tsx in your Remix project.

Code Snippet:

// app/routes/api.webhook.tsx
import { Webhooks } from "@dodopayments/remix";
import type { LoaderFunctionArgs } from "@remix-run/node";

const webhookHandler = Webhooks({
  webhookKey: process.env.DODO_PAYMENTS_WEBHOOK_SECRET,
  onPayload: async (payload) => {
    //Handle Payload Here
    console.log(payload)
  }
});

export const action = ({ request }: LoaderFunctionArgs) => webhookHandler(request);

Handler Details:

    Method: Only POST requests are supported. Other methods return 405.

    Signature Verification: The handler verifies the webhook signature using the webhookKey and returns 401 if verification fails.

    Payload Validation: The payload is validated with Zod. Returns 400 for invalid payloads.

Error Handling:

    401: Invalid signature

    400: Invalid payload

    500: Internal error during verification

Event Routing: Calls the appropriate event handler based on the payload type.

Supported Webhook Event Handlers:

    onPayload?: (payload: WebhookPayload) => Promise<void>

    onPaymentSucceeded?: (payload: WebhookPayload) => Promise<void>

    onPaymentFailed?: (payload: WebhookPayload) => Promise<void>

    onPaymentProcessing?: (payload: WebhookPayload) => Promise<void>

    onPaymentCancelled?: (payload: WebhookPayload) => Promise<void>

    onRefundSucceeded?: (payload: WebhookPayload) => Promise<void>

    onRefundFailed?: (payload: WebhookPayload) => Promise<void>

    onDisputeOpened?: (payload: WebhookPayload) => Promise<void>

    onDisputeExpired?: (payload: WebhookPayload) => Promise<void>

    onDisputeAccepted?: (payload: WebhookPayload) => Promise<void>

    onDisputeCancelled?: (payload: WebhookPayload) => Promise<void>

    onDisputeChallenged?: (payload: WebhookPayload) => Promise<void>

    onDisputeWon?: (payload: WebhookPayload) => Promise<void>

    onDisputeLost?: (payload: WebhookPayload) => Promise<void>

    onSubscriptionActive?: (payload: WebhookPayload) => Promise<void>

    onSubscriptionOnHold?: (payload: WebhookPayload) => Promise<void>

    onSubscriptionRenewed?: (payload: WebhookPayload) => Promise<void>

    onSubscriptionPaused?: (payload: WebhookPayload) => Promise<void>

    onSubscriptionPlanChanged?: (payload: WebhookPayload) => Promise<void>

    onSubscriptionCancelled?: (payload: WebhookPayload) => Promise<void>

    onSubscriptionFailed?: (payload: WebhookPayload) => Promise<void>

    onSubscriptionExpired?: (payload: WebhookPayload) => Promise<void>

    onLicenseKeyCreated?: (payload: WebhookPayload) => Promise<void>

    Environment Variable Setup:

To ensure the adapter functions correctly, you will need to manually set up the following environment variables in your Remix project's deployment environment (e.g., Vercel, Netlify, AWS, etc.):

    DODO_PAYMENTS_API_KEY: Your Dodo Payments API Key (required for Checkout and Customer Portal).

    DODO_PAYMENTS_RETURN_URL: (Optional) The URL to redirect to after a successful checkout (for Checkout handler).

    DODO_PAYMENTS_ENVIRONMENT: (Optional) The environment for the API (e.g., test or live).

    DODO_PAYMENTS_WEBHOOK_SECRET: Your Dodo Payments Webhook Secret (required for Webhook handler).

Example .env file:

DODO_PAYMENTS_API_KEY=your-api-key
DODO_PAYMENTS_RETURN_URL=your-return-url
DODO_PAYMENTS_ENVIRONMENT=test
DODO_PAYMENTS_WEBHOOK_SECRET=your-webhook-secret

Usage in your code:

bearerToken: process.env.DODO_PAYMENTS_API_KEY
webhookKey: process.env.DODO_PAYMENTS_WEBHOOK_SECRET

Important: Never commit sensitive environment variables directly into your version control. Use environment variables for all sensitive information.

If the user needs assistance setting up environment variables for their specific deployment environment, ask them what platform they are using (e.g., Vercel, Netlify, AWS, etc.), and provide guidance. You can also add comments to their PR or chat depending on the context