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

# Usage

> Services, responses, pagination, idempotency and errors.

## Services

The client exposes one service per resource group. Each returns typed objects.

```php theme={null}
$orqex->checkouts();       // hosted checkout sessions
$orqex->paymentIntents();  // payment intents, country and method discovery
$orqex->attempts();        // payment attempts and confirmation
$orqex->refunds();         // refunds
$orqex->payouts();         // payouts
$orqex->exchangeRates();   // exchange rates
```

The [API Reference](/api-reference) is the authoritative list of endpoints, parameters and
response fields. The SDK mirrors it; where the SDK has not caught up with a newly released
endpoint, call it directly:

```php theme={null}
$response = $orqex->request('GET', '/payouts/po_.../inspect');
$payload  = $response->json;
```

## A payment, end to end

```php theme={null}
$intent = $orqex->paymentIntents()->create([
    'amount'      => 50,           // major units
    'currency'    => 'USD',
    'description' => 'Order #1042',
    'customer'    => [
        'email'      => 'ada@example.com',
        'first_name' => 'Ada',
        'last_name'  => 'Lovelace',
    ],
]);

// Never hard-code these: read them for this specific payment.
$countries = $orqex->paymentIntents()->availableCountries($intent->id);
$methods   = $orqex->paymentIntents()->availableMethods($intent->id, 'US');

$intent = $orqex->attempts()->create($intent->id, [
    'method_code' => $methods[0]->value,
    'country'     => 'US',
    'phone'       => ['number' => '+15550000000', 'country' => 'US'],
]);

$nextAction = $intent->active_attempt->next_action;
```

Handle `next_action` as described in [Next actions](/payments/next-actions). When it asks
for an OTP:

```php theme={null}
$intent = $orqex->paymentIntents()->authorize($intent->id, ['otp' => '123456']);
```

## Responses

Responses are read-only objects with typed nested resources. Properties are also reachable
as array keys, and unknown fields returned by a newer API version are preserved rather than
dropped — so an SDK release never hides data from you.

```php theme={null}
$intent->status;                 // 'completed'
$intent->amount->formatted;      // '$50.00'
$intent->amount->currency;       // 'USD'
$intent['id'];                   // same as $intent->id
```

## Pagination

List calls return a collection you can iterate page by page, or walk end to end.

```php theme={null}
$page = $orqex->paymentIntents()->all(['per_page' => 50]);

foreach ($page as $intent) {
    // current page only
}

foreach ($page->autoPagingIterator() as $intent) {
    // every page, fetched lazily
}
```

## Idempotency

Writes send an idempotency key automatically, so a retry inside the SDK never duplicates a
payment. Supply your own when the retry might come from outside the process — a queued job
that runs twice, a webhook you reprocess:

```php theme={null}
$orqex->paymentIntents()->create($params, ['idempotency_key' => 'order-1042-intent']);
```

Per-request options also accept `timeout` and extra `headers`.

## Errors

Every failure throws. Catch the specific exception where you can act on it, and the base
`ApiException` otherwise.

| Exception                 | When                                              |
| ------------------------- | ------------------------------------------------- |
| `AuthenticationException` | `401` — missing, invalid, inactive or expired key |
| `PermissionException`     | `403` — address not on the key's IP allowlist     |
| `NotFoundException`       | `404`                                             |
| `InvalidRequestException` | `400`, `422` — validation or a rejected operation |
| `IdempotencyException`    | `409`, `428`                                      |
| `RateLimitException`      | `429`                                             |
| `ServerException`         | `5xx`                                             |
| `ApiConnectionException`  | the request never reached Orchestrate             |

```php theme={null}
use Orqex\Orchestrate\Exception\ApiException;
use Orqex\Orchestrate\Exception\InvalidRequestException;

try {
    $refund = $orqex->refunds()->create($intentId, [
        'amount' => 50,
        'reason' => 'requested_by_customer',
    ]);
} catch (InvalidRequestException $e) {
    $e->errors;       // field-by-field validation messages
} catch (ApiException $e) {
    $e->httpStatus;
    $e->requestId;    // quote this to support
}
```

Remember that a declined payment does not throw: the call succeeds and the failure is on the
attempt. See [Errors](/errors).
