> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stockshift.io/llms.txt
> Use this file to discover all available pages before exploring further.

# PHP

> Un cliente de PHP para la API de StockShift. Tiene un método por cada operación de la referencia de la API, generado a partir del documento OpenAPI de la API, con tipos de PHPStan para cada solicitud y respuesta.

Requiere PHP 8.2 o posterior y cualquier cliente HTTP [PSR-18](https://www.php-fig.org/psr/psr-18/).

## Instalación

```bash theme={null}
composer require stockshift/sdk-php
```

Si tu proyecto aún no tiene un cliente PSR-18, agrega uno, como Guzzle:

```bash theme={null}
composer require guzzlehttp/guzzle
```

## Inicio rápido

Crea un artículo y luego lista las existencias disponibles:

```php theme={null}
use StockShift\Sdk\StockShift;

$stockshift = new StockShift(getenv('STOCKSHIFT_TOKEN'));

$stockshift->catalog()->createItem(['sku' => 'BOLT-M4', 'name' => 'M4 hex bolt', 'type' => 'stocked', 'make_or_buy' => 'buy']);

foreach ($stockshift->inventory()->listStockOnHandAll() as $row) {
    echo $row['sku'], ' ', $row['location_code'], ' ', $row['available_to_promise'], "\n";
}
```

## Autenticación

Pasa una clave de API o un token de acceso OAuth como primer argumento. Crea una clave de API en la app, en Configuración > Acceso > Claves de API. La clave actúa como el miembro que la creó, y cada llamada necesita tanto el permiso del miembro como uno de los alcances de la clave.

Para un token OAuth que vence, pasa un closure. El cliente lo llama antes de cada solicitud:

```php theme={null}
$stockshift = new StockShift(fn (): string => $tokens->current());
```

Otros argumentos, todos con nombre:

| Argumento | Valor predeterminado | Significado |
| - | - | - |
| `baseUrl` | `https://app.stockshift.io/api/v1` | Dónde está la API. |
| `maxRetries` | `2` | Reintentos para una llamada que se puede reintentar. |
| `maxRetryAfter` | `60` | El `Retry-After` más largo, en segundos, que vale la pena esperar. |
| `headers` | ninguno | Encabezados que se envían en cada llamada. |
| `httpClient` | se encuentra solo | El cliente PSR-18. Define los tiempos de espera en él. |
| `requestFactory`, `streamFactory` | se encuentran solos | Factories PSR-17. |

El cliente y las factories se encuentran con [php-http/discovery](https://github.com/php-http/discovery) cuando los omites.

## Hacer llamadas

Cada área de la API tiene un método, como `catalog()` o `inventory()`, y cada operación es un método en él. Primero van los parámetros de ruta, luego el cuerpo y después la cadena de consulta:

```php theme={null}
$item = $stockshift->catalog()->getItem('01J8QZ4M...');
echo $item['data']['sku'];

$page = $stockshift->catalog()->listItems(['search' => 'bolt', 'status' => 'active']);
```

El comentario de documentación de cada método indica su ruta, como `GET /catalog/items/{item}`. También puedes llamar a una ruta directamente:

```php theme={null}
$item = $stockshift->get('/catalog/items/{item}', ['path' => ['item' => '01J8QZ4M...']]);
```

Una llamada devuelve el cuerpo JSON decodificado como un arreglo. Una respuesta vacía devuelve `null`, una exportación CSV su texto y un archivo la respuesta PSR-7.

Para comprobar tu propio código contra los tipos, impórtalos desde `Schemas` en un comentario de documentación de PHPStan:

```php theme={null}
/** @phpstan-import-type ItemResource from \StockShift\Sdk\Generated\Schemas */
```

## Paginación

Una lista que puede crecer devuelve una página a la vez. Cada lista paginada tiene un segundo método que termina en `All`, que sigue los cursores y entrega cada registro:

```php theme={null}
foreach ($stockshift->catalog()->listItemsAll(['search' => 'bolt']) as $item) {
    echo $item['sku'], "\n";
}
```

`$stockshift->paginate('/catalog/items')` hace lo mismo por ruta. Para paginar a mano, envía el `next_cursor` de cada página como parámetro de consulta `after` hasta que sea `null`.

## Errores

Una llamada fallida lanza una `ApiException` que contiene el cuerpo de detalles del problema de RFC 9457. Decide según `errorCode`, que es estable. El detalle está escrito para personas y puede cambiar.

```php theme={null}
use StockShift\Sdk\Exception\ApiException;

try {
    $stockshift->catalog()->createItem($item);
} catch (ApiException $error) {
    if ($error->errorCode === 'validation_failed') {
        print_r($error->errors()); // ['sku' => ['Another item already has the SKU BOLT-M4.']]
    }
}
```

`ApiException` también tiene `status`, `problem` y `response`. Una llamada que no recibe respuesta, porque falló la red, lanza una `ConnectionException`. Ambas extienden `StockShiftException`.

## Reintentos y claves de idempotencia

El cliente reintenta un `429` después del tiempo que indica `Retry-After`. Lo hace con todos los métodos, porque la API no ejecutó la llamada. Si `Retry-After` es mayor que `maxRetryAfter`, lanza una excepción en lugar de esperar.

Un `5xx` o una falla de red se reintenta para `GET`, `PUT` y `DELETE`, con una breve espera entre intentos. Un `POST` o `PATCH` solo se reintenta cuando le das una clave de idempotencia, para que un reintento no pueda hacer el cambio dos veces:

```php theme={null}
$stockshift->integrations()->pushStockNow($connectionId, ['idempotencyKey' => bin2hex(random_bytes(16))]);
```

Usa una clave nueva para cada cambio que quieras hacer. Los endpoints que respetan la clave lo indican en la referencia de la API.

## Webhooks

Revisa el encabezado `StockShift-Signature` antes de confiar en una entrega. `Webhook::verify()` necesita el cuerpo sin procesar, exactamente como llegó:

```php theme={null}
use StockShift\Sdk\Exception\WebhookVerificationException;
use StockShift\Sdk\Webhook;

try {
    $event = Webhook::verify(
        file_get_contents('php://input'),
        $_SERVER['HTTP_STOCKSHIFT_SIGNATURE'] ?? null,
        getenv('STOCKSHIFT_WEBHOOK_SECRET'),
    );
} catch (WebhookVerificationException) {
    http_response_code(400);
    exit;
}

if ($event['type'] === 'inventory.stock.adjusted') {
    echo $event['data']['item_id'], ' ', $event['data']['quantity'], "\n";
}
http_response_code(204);
```

Rechaza una entrega de más de cinco minutos de antigüedad. Pasa `tolerance`, en segundos, para cambiarlo. Los reintentos de un evento conservan su `id`, así que guárdalo y omite los eventos que ya procesaste.

Cada evento tiene un tipo de PHPStan en `Schemas`, como `InventoryStockAdjustedEvent`. Para probar tu propio receptor, `Webhook::sign()` firma un payload igual que StockShift.

## Versiones

La versión mayor cambia cuando la API cambia de una forma que puede romper tu código, como un campo eliminado o un parámetro obligatorio nuevo. Los endpoints y campos nuevos llegan en versiones menores. `StockShift\Sdk\Generated\Api::VERSION` contiene la versión de la referencia de la API con la que se compiló el paquete.


## Related topics

- [Laravel](https://docs.stockshift.io/es/sdks/laravel.md)
- [SDK](https://docs.stockshift.io/es/sdks/index.md)
- [StockShift para desarrolladores](https://docs.stockshift.io/es/index.md)


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