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

# PHP

> Usa el SDK de PHP de Dodo Payments para crear sesiones de checkout, clientes y suscripciones desde PHP 8.1+, con objetos de valor tipados, reintentos y paginación.

El SDK de PHP permite que las aplicaciones PHP 8.1+ accedan a la API REST de Dodo Payments. Los métodos aceptan parámetros con nombre, las respuestas son objetos tipados y Composer carga el SDK mediante autoloading PSR-4.

## Instalación

Instala el SDK con Composer:

```bash theme={null}
composer require "dodopayments/client 6.27.0"
```

<Info>
  El SDK requiere PHP 8.1.0 o posterior y Composer. Envía solicitudes mediante un cliente HTTP PSR-18 de tu proyecto, como Guzzle, que encuentra con `php-http/discovery`.
</Info>

## Inicio rápido

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

```php theme={null}
<?php

use Dodopayments\Client;

$client = new Client(
  bearerToken: getenv('DODO_PAYMENTS_API_KEY') ?: 'My Bearer Token',
  baseUrl: 'https://test.dodopayments.com',
);

$checkoutSessionResponse = $client->checkoutSessions->create(
  productCart: [["productID" => "pdt_123", "quantity" => 1]]
);

var_dump($checkoutSessionResponse->sessionID);
```

Si omites `bearerToken`, el cliente lee la variable de entorno `DODO_PAYMENTS_API_KEY`. Si omites `baseUrl`, el cliente lee `DODO_PAYMENTS_BASE_URL` y se conecta al modo live (`https://live.dodopayments.com`) cuando esa variable tampoco está configurada. Una API key del modo de prueba solo funciona con la URL del modo de prueba, `https://test.dodopayments.com`.

<Warning>
  Conserva las API keys en variables de entorno o en un gestor de secretos. Nunca las expongas en
  tu base de código ni las confirmes en el control de versiones.
</Warning>

## Funciones principales

<CardGroup cols={2}>
  <Card title="PSR-4 Compliant" icon="check">
    Composer carga el namespace `Dodopayments` mediante autoloading PSR-4.
  </Card>

  <Card title="Modern PHP" icon="php">
    Diseñado para PHP 8.1 o posterior, con parámetros tipados y tipos estrictos.
  </Card>

  <Card title="Extensive Testing" icon="vial">
    El repositorio del SDK incluye un conjunto de pruebas para los servicios de la API.
  </Card>

  <Card title="Exception Handling" icon="shield-check">
    Una clase de excepción para cada estado de error HTTP, además de excepciones de tiempo de espera y conexión.
  </Card>
</CardGroup>

## Objetos de valor

Los métodos aceptan parámetros con nombre, y los parámetros que tienen un valor predeterminado deben pasarse por nombre. Para crear un objeto de valor, usa su constructor estático `with` con parámetros con nombre:

```php theme={null}
<?php

use Dodopayments\Payments\AttachExistingCustomer;

// Recommended: Use static 'with' constructor with named parameters
$customer = AttachExistingCustomer::with(customerID: "cus_123");
```

Cada objeto de valor también tiene un builder:

```php theme={null}
<?php

use Dodopayments\Payments\AttachExistingCustomer;

// Alternative: Use builder pattern
$customer = (new AttachExistingCustomer)->withCustomerID("cus_123");
```

Los métodos también aceptan arrays simples con las mismas claves camelCase, como `["productID" => "pdt_123", "quantity" => 1]`. Las propiedades de respuesta también usan nombres camelCase, por ejemplo, `$session->checkoutURL`.

## Configuración

El constructor `Client` acepta `bearerToken`, `webhookKey`, `baseUrl` y `requestOptions`. 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.

Para verificar un webhook, pasa el cuerpo sin procesar de la solicitud y los headers a `$client->webhooks->unwrap($body, headers: $headers)`. Comprueba la firma con tu clave de webhook, devuelve el evento analizado y lanza `WebhookException` si la comprobación falla. Si omites `headers`, `unwrap` no verifica la firma. `$client->webhooks->unsafeUnwrap($body)` analiza el cuerpo sin verificarlo, así que úsalo solo para pruebas. Consulta [Webhooks](/developer-resources/webhooks).

### Configuración de reintentos

De forma predeterminada, el SDK reintenta algunos errores dos veces, con un breve backoff exponencial. Estos errores activan un reintento:

* Errores de conexión (problemas de conectividad de red)
* 408 Request Timeout
* 409 Conflict
* 429 Rate Limit
* 500+ Internal errors
* Tiempos de espera

Configura `maxRetries` en `requestOptions`, en el cliente o en una única solicitud:

```php theme={null}
<?php

use Dodopayments\Client;

// Configure default for all requests (disable retries)
$client = new Client(requestOptions: ['maxRetries' => 0]);

// Or, configure per-request
$result = $client->checkoutSessions->create(
  productCart: [["productID" => "pdt_123", "quantity" => 1]],
  requestOptions: ['maxRetries' => 5],
);
```

Las solicitudes agotan el tiempo de espera después de 60 segundos de forma predeterminada. Para cambiar el límite, establece `timeout`, en segundos, en el mismo array `requestOptions`.

## Operaciones comunes

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

### Crear una sesión de checkout

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

```php theme={null}
$session = $client->checkoutSessions->create(
  productCart: [
    ["productID" => "pdt_123", "quantity" => 1]
  ],
  returnURL: "https://yourdomain.com/return"
);

header('Location: ' . $session->checkoutURL);
```

Cada URL de checkout funciona una 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 email y un nombre y, después, recupéralo por su ID:

```php theme={null}
// Create a customer
$customer = $client->customers->create(
  email: "customer@example.com",
  name: "John Doe",
  metadata: [
    "user_id" => "12345"
  ]
);

// Retrieve customer
$customer = $client->customers->retrieve("cus_123");
echo "Customer: {$customer->name} ({$customer->email})";
```

### Gestionar suscripciones

Crea una suscripción y, después, cárgala si es una suscripción on-demand.

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

```php theme={null}
use Dodopayments\Payments\AttachExistingCustomer;
use Dodopayments\Payments\BillingAddress;

// Create a subscription
$subscription = $client->subscriptions->create(
  billing: BillingAddress::with(
    country: 'US',
    city: 'San Francisco',
    state: 'CA',
    street: '1 Market St',
    zipcode: '94105',
  ),
  customer: AttachExistingCustomer::with(customerID: 'cus_123'),
  productID: 'pdt_456',
  quantity: 1,
);

// Charge an on-demand subscription
// productPrice is in the lowest currency denomination (e.g., 2500 = $25.00 USD)
$charge = $client->subscriptions->charge(
  $subscription->subscriptionID,
  productPrice: 2500,
);
```

<Info>
  `billing` solo requiere `country`, un código de país ISO de dos letras. Pasa `AttachExistingCustomer::with(customerID: '...')` para asociar un cliente existente o `NewCustomer::with(email: '...', name: '...')` para crear uno. Ambas clases se encuentran en el namespace `Dodopayments\Payments`. `charge` se usa para [suscripciones on-demand](/developer-resources/ondemand-subscriptions), y `productPrice` se expresa en la unidad monetaria más pequeña.
</Info>

## Paginación

Los métodos de lista devuelven un objeto de página. `getItems()` devuelve los elementos de la página actual, y `pagingEachItem()` devuelve todos los elementos desde la página actual, solicitando más páginas según sea necesario:

```php theme={null}
$page = $client->payments->list();

var_dump($page);

// Fetch items from the current page
foreach ($page->getItems() as $item) {
  var_dump($item->brandID);
}

// Auto-paginate: fetch items from all pages
foreach ($page->pagingEachItem() as $item) {
  var_dump($item->brandID);
}
```

Para avanzar una página a la vez, llama a `hasNextPage()` y `getNextPage()`.

## Gestión de errores

Cuando el SDK no puede conectarse a la API o la API devuelve un estado 4xx o 5xx, el SDK lanza una subclase de `Dodopayments\Core\Exceptions\APIException`:

```php theme={null}
<?php

use Dodopayments\Core\Exceptions\APIConnectionException;
use Dodopayments\Core\Exceptions\RateLimitException;
use Dodopayments\Core\Exceptions\APIStatusException;

try {
  $checkoutSessionResponse = $client->checkoutSessions->create(
    productCart: [["productID" => "pdt_123", "quantity" => 1]]
  );
} catch (APIConnectionException $e) {
  echo "The server could not be reached", PHP_EOL;
  var_dump($e->getPrevious());
} catch (RateLimitException $_) {
  echo "A 429 status code was received; we should back off a bit.", PHP_EOL;
} catch (APIStatusException $e) {
  echo "Another non-200-range status code was received", PHP_EOL;
  echo $e->getMessage();
}
```

### Tipos de error

La clase de excepción depende de la causa. Todas las clases se encuentran en el namespace `Dodopayments\Core\Exceptions`:

| Causa | Tipo de error |
| - | - |
| HTTP 400 | `BadRequestException` |
| HTTP 401 | `AuthenticationException` |
| HTTP 403 | `PermissionDeniedException` |
| HTTP 404 | `NotFoundException` |
| HTTP 409 | `ConflictException` |
| HTTP 422 | `UnprocessableEntityException` |
| HTTP 429 | `RateLimitException` |
| HTTP >= 500 | `InternalServerException` |
| Otro error HTTP | `APIStatusException` |
| Tiempo de espera | `APITimeoutException` |
| Error de red | `APIConnectionException` |

<Tip>
  Captura estas excepciones alrededor de las llamadas a la API para que tu aplicación pueda mostrar un
  mensaje claro o volver a intentarlo más tarde. En el caso de un error que permita reintentos, el SDK lanza
  la excepción solo después de que fallen sus reintentos automáticos.
</Tip>

## Uso avanzado

### Endpoints no documentados

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

```php theme={null}
<?php

$response = $client->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 `requestOptions`:

```php theme={null}
<?php

use Dodopayments\RequestOptions;

$checkoutSessionResponse = $client->checkoutSessions->create(
  productCart: [["productID" => "pdt_123", "quantity" => 1]],
  requestOptions: [
    'extraQueryParams' => ["my_query_parameter" => "value"],
    'extraBodyParams' => ["my_body_parameter" => "value"],
    'extraHeaders' => ["my-header" => "value"],
  ],
);
```

<Note>
  Un parámetro `extra*` que tenga el mismo nombre que un parámetro documentado lo reemplaza.
</Note>

## Integración con frameworks

### Laravel

Envuelve el cliente en una clase de servicio. Este ejemplo establece la URL de la API a partir del entorno configurado:

```php theme={null}
<?php

namespace App\Services;

use Dodopayments\Client;

class PaymentService
{
    protected $client;

    public function __construct()
    {
        $this->client = new Client(
            bearerToken: config('services.dodo.api_key'),
            baseUrl: config('services.dodo.environment') === 'live_mode'
                ? 'https://live.dodopayments.com'
                : 'https://test.dodopayments.com',
        );
    }

    public function createCheckout(array $items)
    {
        return $this->client->checkoutSessions->create(
            productCart: $items,
            returnURL: route('checkout.return')
        );
    }
}
```

Añade la configuración a `config/services.php`:

```php theme={null}
'dodo' => [
    'api_key' => env('DODO_PAYMENTS_API_KEY'),
    'environment' => env('DODO_PAYMENTS_ENVIRONMENT', 'test_mode')
],
```

### Symfony

Crea un servicio que reciba la API key mediante su constructor:

```php theme={null}
<?php

namespace App\Service;

use Dodopayments\Client;

class DodoPaymentService
{
    private Client $client;

    public function __construct(string $apiKey)
    {
        $this->client = new Client(bearerToken: $apiKey);
    }

    public function createPayment(string $productId, string $customerId, array $billing): object
    {
        // Note: POST /payments is deprecated — prefer checkout sessions for new integrations
        return $this->client->payments->create(
            billing: $billing,
            customer: ['customerID' => $customerId],
            productCart: [['productID' => $productId, 'quantity' => 1]],
        );
    }
}
```

Registra el servicio en `config/services.yaml`:

```yaml theme={null}
services:
  App\Service\DodoPaymentService:
    arguments:
      $apiKey: "%env(DODO_PAYMENTS_API_KEY)%"
```

## Recursos

<CardGroup cols={2}>
  <Card title="GitHub Repository" icon="github" href="https://github.com/dodopayments/dodopayments-php">
    Código fuente, versiones y 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 habla con otros desarrolladores.
  </Card>

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

## Soporte

Para obtener ayuda con el SDK de PHP:

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

## Contribuciones

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


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