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

# Quickstart

> Take your first payment with a hosted checkout session.

This walks through the shortest path to a working payment: a hosted checkout session in
sandbox. It takes about five minutes.

<Steps>
  <Step title="Get a sandbox key">
    Create a secret key in your [dashboard](https://app.orqex.com). Sandbox keys start with
    `sk_sandbox_`. The key decides which environment you are in — there is no separate base
    URL and no environment header.
  </Step>

  <Step title="Create a checkout session">
    Amounts on a payment are in **major units**: `50` means 50.00.

    <CodeGroup>
      ```bash cURL theme={null}
      curl -X POST https://api.orqex.com/v1/payment/checkouts \
        -H "Authorization: Bearer sk_sandbox_..." \
        -H "Content-Type: application/json" \
        -H "X-Idempotency-Key: order-1042-checkout" \
        -d '{
          "amount": 50,
          "currency": "USD",
          "description": "Order #1042",
          "return_url": "https://example.com/orders/1042/return",
          "webhook_url": "https://example.com/webhooks/orqex",
          "customer": {
            "email": "ada@example.com",
            "first_name": "Ada",
            "last_name": "Lovelace"
          }
        }'
      ```

      ```php PHP theme={null}
      use Orqex\Orchestrate\OrchestrateClient;

      $orqex = new OrchestrateClient('sk_sandbox_...');

      $checkout = $orqex->checkouts()->create([
          'amount'      => 50,
          'currency'    => 'USD',
          'description' => 'Order #1042',
          'return_url'  => 'https://example.com/orders/1042/return',
          'webhook_url' => 'https://example.com/webhooks/orqex',
          'customer'    => [
              'email'      => 'ada@example.com',
              'first_name' => 'Ada',
              'last_name'  => 'Lovelace',
          ],
      ]);
      ```
    </CodeGroup>

    The response carries both the session and the payment intent it created:

    ```json theme={null}
    {
      "message": "...",
      "data": {
        "checkout": {
          "id": "cs_...",
          "status": "open",
          "environment": "sandbox",
          "url": "https://pay.orqex.com/cs_...",
          "expires_at": "...",
          "created_at": "..."
        },
        "payment": {
          "id": "pi_...",
          "status": "pending",
          "amount": { "value": 50, "formatted": "$50.00", "short": "$50", "currency": "USD" }
        }
      }
    }
    ```

    Store `payment.id` against your order. That is the identifier you will see in every
    webhook.
  </Step>

  <Step title="Send the customer to the payment page">
    Redirect to `checkout.url`. Orchestrate renders the page, collects the payment details and
    handles whatever the payment method requires.

    In sandbox, pick the built-in test method and use a phone number ending in two digits
    that select the outcome you want to rehearse — see [Testing](/payments/testing).
  </Step>

  <Step title="Confirm the result">
    The customer returning to your `return_url` is **not** proof of payment. They may have
    closed the tab, and some methods settle after the redirect.

    Treat the webhook as the signal, and re-read the intent before you fulfil:

    ```bash theme={null}
    curl https://api.orqex.com/v1/payment/intents/pi_... \
      -H "Authorization: Bearer sk_sandbox_..."
    ```

    Fulfil when `data.status` is `completed`.
  </Step>
</Steps>

## Next

<Columns cols={2}>
  <Card title="Webhooks" icon="bell" href="/webhooks">
    The events Orchestrate sends, and how to verify them.
  </Card>

  <Card title="Direct API" icon="code" href="/payments/custom-checkout">
    Build your own payment interface instead of redirecting.
  </Card>

  <Card title="Testing" icon="flask" href="/payments/testing">
    Reproduce every outcome in sandbox.
  </Card>

  <Card title="Go live" icon="rocket" href="/authentication">
    Swap the sandbox key for a live one. Nothing else changes.
  </Card>
</Columns>
