> ## 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.

# Ruby

> Usa el SDK de Ruby de Dodo Payments para crear sesiones de checkout, clientes y suscripciones desde Ruby 3.2+, con paginación automática, reintentos y tipos de Sorbet.

El SDK de Ruby permite que las aplicaciones Ruby accedan a la API REST de Dodo Payments. Envía solicitudes con `net/http` de la biblioteca estándar y un pool de conexiones, reintenta las solicitudes fallidas, itera por las listas paginadas por ti e incluye definiciones de tipos RBI y RBS.

## Instalación

Agrega la gema a tu Gemfile:

```ruby Gemfile theme={null}
gem "dodopayments", "~> 2.30"
```

<Tip>
  Las nuevas versiones del SDK agregan compatibilidad con los cambios de la API. Ejecuta `bundle update dodopayments` periódicamente para mantenerte actualizado.
</Tip>

Después, instálalo:

```bash theme={null}
bundle install
```

<Info>
  El SDK requiere Ruby 3.2.0 o posterior.
</Info>

## Inicio Rápido

Crea un cliente y, después, crea una sesión de checkout:

```ruby theme={null}
require "bundler/setup"
require "dodopayments"

dodo_payments = Dodopayments::Client.new(
  bearer_token: ENV["DODO_PAYMENTS_API_KEY"], # This is the default and can be omitted
  environment: "test_mode" # defaults to "live_mode"
)

checkout_session_response = dodo_payments.checkout_sessions.create(
  product_cart: [{product_id: "pdt_123", quantity: 1}]
)

puts(checkout_session_response.session_id)
```

Si omites `bearer_token`, el cliente lee la variable de entorno `DODO_PAYMENTS_API_KEY`. Si omites `environment`, el cliente se conecta al modo live. Una clave de API del modo de prueba solo funciona con `environment: "test_mode"`.

<Warning>
  Mantén las claves de API en variables de entorno o en un gestor de secretos. Nunca las incluyas en el control de versiones ni las expongas en tu código.
</Warning>

## Funciones principales

<CardGroup cols={2}>
  <Card title="Ruby Conventions" icon="gem">
    Métodos y argumentos de palabra clave en snake\_case, con hashes simples aceptados para parámetros anidados.
  </Card>

  <Card title="Elegant Syntax" icon="code">
    Las respuestas son objetos con lectores de atributos, y `obj[:prop]` también lee los campos que el SDK no define.
  </Card>

  <Card title="Auto-Pagination" icon="arrows-rotate">
    `auto_paging_each` itera sobre cada elemento y obtiene la página siguiente cuando es necesario.
  </Card>

  <Card title="Type Safety" icon="shield-check">
    Definiciones RBI para Sorbet, sin dependencia de `sorbet-runtime`.
  </Card>
</CardGroup>

## Configuración

`Dodopayments::Client.new` acepta `bearer_token`, `webhook_key`, `environment`, `base_url`, `max_retries`, `timeout`, `initial_retry_delay` y `max_retry_delay`. Cuando los omites, lee `DODO_PAYMENTS_API_KEY`, `DODO_PAYMENTS_WEBHOOK_KEY` (tu secreto de firma de webhook) y `DODO_PAYMENTS_BASE_URL` del entorno. El cliente es seguro para subprocesos y mantiene su propio pool de conexiones, por lo que debes crear un cliente para tu aplicación y reutilizarlo.

Para verificar un webhook, pasa el cuerpo sin procesar de la solicitud y los encabezados a `dodo_payments.webhooks.unwrap(payload, headers: headers)`. Comprueba la firma con tu clave de webhook y devuelve el evento analizado. `dodo_payments.webhooks.unsafe_unwrap(payload)` analiza el cuerpo sin verificarlo, así que úsalo únicamente para pruebas. Consulta [Webhooks](/developer-resources/webhooks).

### Configuración del tiempo de espera

Las solicitudes agotan el tiempo de espera después de 60 segundos de forma predeterminada. Configura `timeout`, en segundos, en el cliente o en una sola solicitud:

```ruby theme={null}
# Configure default for all requests (default is 60 seconds)
dodo_payments = Dodopayments::Client.new(
  timeout: nil # disable timeout
)

# Or, configure per-request
dodo_payments.checkout_sessions.create(
  product_cart: [{product_id: "pdt_123", quantity: 1}],
  request_options: {timeout: 5}
)
```

Cuando una solicitud agota el tiempo de espera, el SDK genera `Dodopayments::Errors::APITimeoutError`. Las solicitudes cuyo tiempo de espera se agotó se reintentan de forma predeterminada.

### Configuración de reintentos

El SDK reintenta los errores de conexión, los tiempos de espera y las respuestas con estado 408, 409, 429 o 500 y superiores. De forma predeterminada, reintenta dos veces con un breve backoff exponencial. Configura `max_retries` en el cliente o en una sola solicitud:

```ruby theme={null}
# Configure default for all requests (default is 2)
dodo_payments = Dodopayments::Client.new(
  max_retries: 0 # disable retries
)

# Or, configure per-request
dodo_payments.checkout_sessions.create(
  product_cart: [{product_id: "pdt_123", quantity: 1}],
  request_options: {max_retries: 5}
)
```

## Operaciones comunes

Los ejemplos de esta sección usan el cliente `dodo_payments` de [Inicio rápido](#quick-start).

### Crear una Checkout Session

Crea una sesión de checkout y, después, redirige al cliente a la `checkout_url` devuelta:

```ruby theme={null}
session = dodo_payments.checkout_sessions.create(
  product_cart: [
    {
      product_id: "pdt_123",
      quantity: 1
    }
  ],
  return_url: "https://yourdomain.com/return"
)

# In a Rails controller, redirect to checkout
redirect_to session.checkout_url, allow_other_host: true
```

Cada URL de checkout funciona una sola vez y caduca después de 24 horas. Consulta [Checkout Sessions](/developer-resources/checkout-session) para ver todas las opciones de sesión.

### Gestionar clientes

Crea un cliente con una dirección de correo electrónico y un nombre y, después, recupéralo por su ID:

```ruby theme={null}
# Create a customer
customer = dodo_payments.customers.create(
  email: "customer@example.com",
  name: "John Doe",
  metadata: {
    user_id: "12345"
  }
)

# Retrieve customer
customer = dodo_payments.customers.retrieve("cus_123")
puts "Customer: #{customer.name} (#{customer.email})"
```

### Gestionar suscripciones

Crea una suscripción, cobra una suscripción bajo demanda y actualiza los metadatos de una suscripción.

<Warning>
  `POST /subscriptions` (el método `subscriptions.create` del SDK) está **obsoleto**. Sigue funcionando para las integraciones existentes, pero las nuevas integraciones deben crear suscripciones mediante una [Checkout Session](/developer-resources/checkout-session).
</Warning>

```ruby theme={null}
# Create a subscription
subscription = dodo_payments.subscriptions.create(
  billing: {
    country: "US",
    city: "San Francisco",
    state: "CA",
    street: "1 Market St",
    zipcode: "94105"
  },
  customer: { customer_id: "cus_123" }, # or { email: "...", name: "..." } for a new customer
  product_id: "pdt_456",
  quantity: 1
)

# Charge an on-demand subscription
# product_price is in the lowest currency denomination (e.g., 2500 = $25.00 USD)
charge = dodo_payments.subscriptions.charge(
  subscription.subscription_id,
  product_price: 2500
)

# Update subscription metadata
updated = dodo_payments.subscriptions.update(
  subscription.subscription_id,
  metadata: { plan_type: "premium" }
)
```

<Info>
  `billing` solo requiere `country`, un código de país ISO de dos letras. `customer` acepta `{ customer_id: "..." }` para asociar un cliente existente o `{ email: "...", name: "..." }` para crear uno. `charge` es para [suscripciones bajo demanda](/developer-resources/ondemand-subscriptions), y `product_price` está expresado en la unidad monetaria más pequeña.
</Info>

## Paginación

### Paginación automática

Los métodos de listado devuelven una página. Lee `items` para consultar la página actual o llama a `auto_paging_each` para iterar sobre cada elemento. Obtiene la página siguiente cuando la necesita:

```ruby theme={null}
page = dodo_payments.payments.list

# Fetch single item from page
payment = page.items[0]
puts(payment.brand_id)

# Automatically fetches more pages as needed
page.auto_paging_each do |payment|
  puts(payment.brand_id)
end
```

### Paginación manual

Para avanzar una página a la vez, llama a `next_page?` y `next_page`:

```ruby theme={null}
page = dodo_payments.payments.list

if page.next_page?
  new_page = page.next_page
  puts(new_page.items[0].brand_id)
end
```

## Gestión de errores

Cuando el SDK no puede conectarse a la API o la API devuelve un estado 4xx o 5xx, el SDK genera una subclase de `Dodopayments::Errors::APIError`:

```ruby theme={null}
begin
  checkout_session = dodo_payments.checkout_sessions.create(
    product_cart: [{product_id: "pdt_123", quantity: 1}]
  )
rescue Dodopayments::Errors::APIConnectionError => e
  puts("The server could not be reached")
  puts(e.cause)  # an underlying Exception, likely raised within `net/http`
rescue Dodopayments::Errors::RateLimitError => e
  puts("A 429 status code was received; we should back off a bit.")
rescue Dodopayments::Errors::APIStatusError => e
  puts("Another non-200-range status code was received")
  puts(e.status)
end
```

La clase de error depende de la causa. Cada error tiene los atributos `status`, `headers` y `body`:

| Causa | Clase de error |
| - | - |
| HTTP 400 | `BadRequestError` |
| HTTP 401 | `AuthenticationError` |
| HTTP 403 | `PermissionDeniedError` |
| HTTP 404 | `NotFoundError` |
| HTTP 409 | `ConflictError` |
| HTTP 422 | `UnprocessableEntityError` |
| HTTP 429 | `RateLimitError` |
| HTTP 500 y superiores | `InternalServerError` |
| Otro error HTTP | `APIStatusError` |
| Tiempo de espera agotado | `APITimeoutError` |
| Error de red | `APIConnectionError` |

<Tip>
  El SDK ya reintenta las respuestas 429 con backoff exponencial. Un `RateLimitError` significa que esos reintentos también fallaron, así que espera más tiempo antes de enviar la solicitud de nuevo.
</Tip>

## Seguridad de tipos con Sorbet

El SDK incluye definiciones RBI y no depende de `sorbet-runtime`. Para obtener parámetros de solicitud verificados por tipos, pasa clases de modelo en lugar de hashes:

```ruby theme={null}
# Type-safe using Sorbet RBI definitions
dodo_payments.checkout_sessions.create(
  product_cart: [
    Dodopayments::ProductItemReq.new(
      product_id: "pdt_123",
      quantity: 1
    )
  ]
)

# Hashes work, but are not typesafe
dodo_payments.checkout_sessions.create(
  product_cart: [{product_id: "pdt_123", quantity: 1}]
)

# You can also splat a full Params class
params = Dodopayments::CheckoutSessionCreateParams.new(
  product_cart: [
    Dodopayments::ProductItemReq.new(
      product_id: "pdt_123",
      quantity: 1
    )
  ]
)
dodo_payments.checkout_sessions.create(**params)
```

## Uso avanzado

### Endpoints no documentados

Para llamar a un endpoint que no tiene un método del SDK, usa `request`. Aplica la misma autenticación y los mismos reintentos que los métodos del SDK:

```ruby theme={null}
response = dodo_payments.request(
  method: :post,
  path: '/undocumented/endpoint',
  query: {"dog": "woof"},
  headers: {"useful-header": "interesting-value"},
  body: {"hello": "world"}
)
```

### Parámetros no documentados

Para enviar parámetros que el SDK no define, pásalos en `request_options`. Un parámetro `extra_*` con el mismo nombre que un parámetro documentado lo reemplaza:

```ruby theme={null}
checkout_session_response = dodo_payments.checkout_sessions.create(
  product_cart: [{product_id: "pdt_123", quantity: 1}],
  request_options: {
    extra_query: {my_query_parameter: "value"},
    extra_body: {my_body_parameter: "value"},
    extra_headers: {"my-header": "value"}
  }
)

# Access undocumented response properties
puts(checkout_session_response[:my_undocumented_property])
```

## Integración con Rails

### Crear un inicializador

Crea un cliente cuando se inicie Rails, en `config/initializers/dodo_payments.rb`:

```ruby theme={null}
require "dodopayments"

DODO_CLIENT = Dodopayments::Client.new(
  bearer_token: Rails.application.credentials.dodo_api_key,
  environment: Rails.env.production? ? "live_mode" : "test_mode"
)
```

### Patrón de objeto de servicio

Envuelve el cliente en un objeto de servicio:

```ruby theme={null}
# app/services/payment_service.rb
class PaymentService
  def initialize
    @client = DODO_CLIENT
  end

  def create_checkout(items)
    @client.checkout_sessions.create(
      product_cart: items,
      return_url: Rails.application.routes.url_helpers.checkout_return_url
    )
  end

  def process_payment(product_id:, customer_id:, billing:)
    # Note: POST /payments is deprecated — prefer checkout sessions for new integrations
    @client.payments.create(
      billing: billing,
      customer: { customer_id: customer_id },
      product_cart: [{ product_id: product_id, quantity: 1 }]
    )
  end
end
```

### Integración con controladores

Llama al servicio desde un controlador y redirige a la página de checkout:

```ruby theme={null}
# app/controllers/checkouts_controller.rb
class CheckoutsController < ApplicationController
  def create
    service = PaymentService.new
    session = service.create_checkout(checkout_params[:items])
    
    redirect_to session.checkout_url, allow_other_host: true
  rescue Dodopayments::Errors::APIError => e
    flash[:error] = "Payment error: #{e.message}"
    redirect_to cart_path
  end

  private

  def checkout_params
    params.require(:checkout).permit(items: [:product_id, :quantity])
  end
end
```

## Integración con Sinatra

Crea el cliente una sola vez en un bloque `configure` y úsalo en tus rutas:

```ruby theme={null}
require "sinatra"
require "dodopayments"

configure do
  set :dodo_client, Dodopayments::Client.new(
    bearer_token: ENV["DODO_PAYMENTS_API_KEY"]
  )
end

post "/create-checkout" do
  content_type :json
  
  begin
    session = settings.dodo_client.checkout_sessions.create(
      product_cart: JSON.parse(request.body.read)["items"],
      return_url: "#{request.base_url}/return"
    )
    
    { checkout_url: session.checkout_url }.to_json
  rescue Dodopayments::Errors::APIError => e
    status 400
    { error: e.message }.to_json
  end
end
```

## Recursos

<CardGroup cols={2}>
  <Card title="GitHub Repository" icon="github" href="https://github.com/dodopayments/dodopayments-ruby">
    Código fuente, versiones y la lista completa de métodos.
  </Card>

  <Card title="API Reference" icon="book" href="/api-reference/introduction">
    Cada endpoint, parámetro y respuesta.
  </Card>

  <Card title="Discord Community" icon="discord" href="https://discord.gg/bYqAp4ayYh">
    Haz preguntas y conversa con otros desarrolladores.
  </Card>

  <Card title="Report Issues" icon="bug" href="https://github.com/dodopayments/dodopayments-ruby/issues">
    Informa de errores o solicita funciones.
  </Card>
</CardGroup>

## Soporte

Para obtener ayuda con el SDK de Ruby:

* **Discord**: Únete al [servidor de la comunidad](https://discord.gg/bYqAp4ayYh) para recibir ayuda en tiempo real.
* **Correo electrónico**: Contacta con [support@dodopayments.com](mailto:support@dodopayments.com).
* **GitHub**: Abre un issue en el [repositorio](https://github.com/dodopayments/dodopayments-ruby).

## Contribuir

Para contribuir, lee las [directrices de contribución](https://github.com/dodopayments/dodopayments-ruby/blob/main/CONTRIBUTING.md).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.