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

# PHP SDK

> Official PHP library for creating payments and verifying webhooks, with no external dependencies.

[`bob-payments/sdk`](https://github.com/BobPayments/bob-payments-sdk-php) is the recommended way to integrate in PHP: zero dependencies (uses `ext-curl` and `ext-json`), PHP >= 8.1, analyzed with PHPStan level 9.

<Warning>
  Server-side only: the `sk_live_`/`sk_test_` API key is secret and must **never** reach the browser.
</Warning>

## Installation

```bash theme={"system"}
composer require bob-payments/sdk
```

## Client

```php theme={"system"}
use BobPayments\BobPaymentsClient;

$bob = new BobPaymentsClient([
    'apiKey' => getenv('BOB_API_KEY'), // sk_live_... or sk_test_...
    // 'timeoutMs' => 35_000,          // timeout per attempt
    // 'maxRetries' => 2,              // automatic retries; 0 disables
]);

$bob->environment; // 'live' | 'sandbox' — detected from the key prefix
```

## Create a checkout session (PIX)

Use the hosted checkout when you want Bob to present the payment screen. Today the available method is PIX; `credit_card` arrives when card is launched:

```php theme={"system"}
$session = $bob->checkoutSessions->create([
    'amountCents' => 25_000,
    'items' => [['name' => 'Assinatura Pro', 'quantity' => 1, 'unitAmountCents' => 25_000]],
    'paymentMethods' => ['pix'],
    'successUrl' => 'https://loja.example.com/pedido/sucesso',
    'webhookUrl' => 'https://loja.example.com/webhooks/bob',
]);

header('Location: ' . $session['checkoutUrl']);
```

See the field details in [Hosted checkout](/en/pages/checkout/overview).

## Create a PIX charge

```php theme={"system"}
$tx = $bob->transactions->create([
    'customer' => [
        'name' => 'João Silva',
        'document' => '12345678901',
        'documentType' => 'CPF',
        'email' => 'joao@example.com',
        'address' => [
            'street' => 'Rua das Flores',
            'streetNumber' => '123',
            'neighborhood' => 'Centro',
            'zipCode' => '01310-100',
            'city' => 'São Paulo',
            'state' => 'SP',
        ],
    ],
    'payment' => ['amountCents' => 10_000, 'product' => 'Assinatura Pro'], // always in cents
    'originDomain' => 'loja.example.com',
]);

$tx['pixCode'];        // PIX copy-and-paste (EMV)
$tx['expirationDate']; // when the PIX expires
$tx['persisted'];      // false = HTTP 202 (reconciliation pending; PIX valid)
$tx['replayed'];       // true = response replayed via idempotency
```

Every `create` sends an [`Idempotency-Key`](/en/pages/idempotency) header automatically (a UUID per call, or your own via `['idempotencyKey' => "pedido-{$orderId}"]` in the second argument), which makes the call safe to retry — the SDK retries with backoff on timeout, network failure, 429, and 5xx without risk of a duplicate payment.

## Lookups

```php theme={"system"}
$detail = $bob->transactions->get('clx1abc123');

$page = $bob->transactions->list([
    'status' => 'paid',
    'dateFrom' => new DateTimeImmutable('2026-07-01'),
    'limit' => 50,
]); // ['data' => [...], 'meta' => ['total' => ..., 'totalPages' => ...]]

$customers = $bob->customers->list(['email' => 'joao@example.com']);
$customer = $bob->customers->get($customers['data'][0]['id']);
```

## Hosted checkout

```php theme={"system"}
$session = $bob->checkoutSessions->create([
    'amountCents' => 25_000,
    'successUrl' => 'https://loja.example.com/obrigado',
    'webhookUrl' => 'https://loja.example.com/webhooks/bob', // SDK requests v2 by default
]);

header('Location: ' . $session['checkoutUrl']); // store $session['webhookSecret']!

$status = $bob->checkoutSessions->getStatus($session['checkoutToken']);
```

## Webhooks

`Webhooks::constructEvent` verifies the signature (v1 and v2, with `hash_equals` and anti-replay) and returns the decoded event:

```php theme={"system"}
use BobPayments\Webhooks;
use BobPayments\Exception\WebhookVerificationException;

$rawBody = file_get_contents('php://input'); // RAW body — never re-serialize
$signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? null;

try {
    $event = Webhooks::constructEvent($rawBody, $signature, getenv('BOB_WEBHOOK_SECRET'));

    if ($event['event'] === 'transaction.paid') {
        // v2: $event['data']['amountCents'] · v1: $event['data']['amount']
        liberarPedido($event['data']['transactionId']);
    }

    http_response_code(200);
    echo 'ok';
} catch (WebhookVerificationException $e) {
    http_response_code(401);
    echo 'invalid signature';
}
```

Payload and signature details: [Webhooks](/en/pages/webhooks).

## Error handling

Every non-2xx response becomes an `ApiException` with the API's RFC 7807 fields:

```php theme={"system"}
use BobPayments\Exception\ApiException;
use BobPayments\Exception\TimeoutException;

try {
    $bob->transactions->create($params);
} catch (ApiException $e) {
    $e->status;            // 400, 401, 422, 429, 503...
    $e->errorCode;         // 'ERR_INTEGRATION_006', ...
    $e->detail;            // descriptive message
    $e->retryAfterSeconds; // on 429/503 when the API sends Retry-After
} catch (TimeoutException $e) {
    // exceeded the client timeout
}
```

## Sandbox

With `sk_test_`, the outcome in the sandbox is controlled by the amount's cents — see [Sandbox](/en/pages/sandbox):

```php theme={"system"}
$bob->transactions->create([...['payment' => ['amountCents' => 10_001, ...]]]); // expires in ~5s
```

## Next steps

<CardGroup cols={2}>
  <Card title="Checkout SDK" icon="credit-card" href="/en/pages/sdk/checkout">
    Frontend layer: mount the checkout on your site with the session created here.
  </Card>

  <Card title="SDK overview" icon="cubes" href="/en/pages/sdk/overview">
    How the server libraries and the frontend SDK fit together.
  </Card>
</CardGroup>

<Card title="Source code and releases" icon="github" href="https://github.com/BobPayments/bob-payments-sdk-php">
  github.com/BobPayments/bob-payments-sdk-php — CHANGELOG and versions via semantic-release
</Card>
