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

# Payments API

> Charge a card directly from your backend: authorize, capture, void, and refund.

Process card payments directly from your server, without redirecting the customer to a hosted page. You send the payment details (or a stored instrument's ID) to lite. lite authorizes the card, and you capture, void, or refund from your backend.

This is the most controllable payment integration option, because card data can pass through your systems, however it carries the highest PCI scope. Use it when you need full control of the payment flow, charge stored cards for recurring subscriptions, or other merchant-initiated payments.

## Authorize and capture

A card payment happens in two moves. **Authorization** checks the card and holds the funds, **Capture** moves the funds. You choose whether these happen together or separately with `capture_mode`:

* `INSTANT` captures the moment authorization succeeds. Use it when you fulfill immediately, like digital goods.
* `MANUAL` authorizes now and waits for you to capture later. Ideal when you ship before charging, so you capture on dispatch.

Between an authorization and capture you can also **void** if needed to release the hold. After a capture you can **refund**.

## Payments are asynchronous

Every payment action returns `202 Accepted` immediately with a payment `id` and a `status` of `PENDING`. lite processes the work in the background. The `202` means accepted for processing, not succeeded. Get the final outcome by retrieving the payment, following the `_links` returned on the response, or via your webhook events.

### Payment status

A payment reports one of these states. The ones you'll handle most are `AUTHORIZED`, `CAPTURED`, `PARTIALLY_CAPTURED`, `VOIDED`, `REFUNDED`, and `FAILED`.

| Status                   | Meaning                                      |
| ------------------------ | -------------------------------------------- |
| `CREATED`                | Created and queued for processing.           |
| `PENDING`                | Being processed.                             |
| `AUTHORIZED`             | Funds held, not yet captured.                |
| `CAPTURED`               | Full authorized amount captured.             |
| `PARTIALLY_CAPTURED`     | Only part of the authorization was captured. |
| `VOIDED`                 | Authorization reversed before capture.       |
| `AUTHORIZATION_REVERSED` | Authorization reversed by the system.        |
| `EXPIRED`                | Authorization expired before capture.        |
| `FAILED`                 | Processing failed.                           |
| `REFUNDED`               | Fully refunded after capture.                |

## Before you begin

Authenticate with `x-api-key`. All examples use `https://{{url}}/v1`. Amounts are integer minor units (`10000` is 100.00 SAR).

Optionally, use an `x-idempotency-key` (a UUID) on every create, capture, void, and refund, so a retried request does not charge twice. Add `x-correlation-id` (a UUID) to trace a request through logs and support.

## Create a payment

`POST /v1/payments`

Required: `amount`, `currency`, and `device`. The `device` block (IP, user agent, screen, timezone, and so on) is mandatory because it feeds 3DS and risk assessment. Supply the card either as a stored instrument (`payment_instrument.id`) or as encrypted inline card data (`payment_instrument.encrypted_instrument_data`).

```bash theme={null}
curl https://{{url}}/v1/payments \
  -H "x-api-key: $LITE_API_KEY" \
  -H "x-idempotency-key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 10000,
    "currency": "SAR",
    "payment_instrument": { "id": "e835c96f-3ede-47ff-85e3-3515b7ac125f" },
    "capture_options": { "capture_mode": "MANUAL" },
    "order": { "reference": "ORD-123456", "amount": 10000, "currency": "SAR" },
    "customer": { "email": "john.doe@email.com", "first_name": "John", "last_name": "Doe" },
    "device": {
      "ip": "192.168.1.100",
      "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
      "accept_header": "text/html,application/xhtml+xml,application/xml;q=0.9",
      "language": "en-US",
      "screen_height": 1080,
      "screen_width": 1920,
      "color_depth": 24,
      "timezone": -180,
      "java_enabled": false,
      "java_script_enabled": true
    }
  }'
```

### Key request fields

| Field                                                        | Required                                   | Notes                                                                                                            |
| ------------------------------------------------------------ | ------------------------------------------ | ---------------------------------------------------------------------------------------------------------------- |
| `amount`                                                     | Yes                                        | Minor units, minimum 1.                                                                                          |
| `currency`                                                   | Yes                                        | ISO 4217.                                                                                                        |
| `device`                                                     | Yes                                        | Browser and device data for 3DS and risk. All listed sub-fields are required.                                    |
| `payment_instrument.id`                                      | Conditional                                | A stored instrument's UUID. Use this to charge a saved card.                                                     |
| `payment_instrument.encrypted_instrument_data`               | Conditional                                | Encrypted inline card data, as an alternative to a stored instrument.                                            |
| `capture_options.capture_mode`                               | Conditional when `capture_options` is sent | `INSTANT` or `MANUAL`. Default is `MANUAL`.                                                                      |
| `processing.processing_type`                                 | Conditional                                | `REGULAR`, `CARD_ON_FILE`, or `UNSCHEDULED_CARD_ON_FILE`.                                                        |
| `processing.initiator`                                       | Conditional                                | `CARD_HOLDER` (customer present) or `MERCHANT` (merchant-initiated).                                             |
| `threeds.force`                                              | No                                         | Force 3DS regardless of the risk engine assessment.                                                              |
| `threeds.data`                                               | No                                         | Pre-authenticated 3DS results, if you ran 3DS yourself on different rails.                                       |
| `order`, `customer`, `metadata`, `channel_id`, `return_info` | No                                         | Order detail, customer detail, your own metadata, channel, and redirect URLs for flows that need a 3DS redirect. |

### Response

```json theme={null}
{
  "payment": {
    "id": "baf6a8e2-0c89-46ef-9ca5-faa65b99bcd5",
    "status": "PENDING",
    "merchant_reference": "ORD-123456"
  },
  "_links": {
    "self": { "href": "/v1/payments/baf6a8e2-...", "method": "GET" },
    "capture": { "href": "/v1/payments/baf6a8e2-.../capture", "method": "POST" },
    "void": { "href": "/v1/payments/baf6a8e2-.../void", "method": "POST" },
    "refund": { "href": "/v1/payments/baf6a8e2-.../refund", "method": "POST" }
  }
}
```

Keep the `id`. It identifies the payment for every capture, void, refund, and lookup. The `_links` tell you which actions are currently allowed, follow them rather than building the URLs by hand. A `redirect` link appears when the payment needs a 3DS challenge; send the customer there to complete it.

## Charging a stored card (card on file)

To charge a saved instrument for a subscription or other merchant-initiated payment, reference the instrument and describe the transaction so it stays scheme-compliant:

```bash theme={null}
curl https://{{url}}/v1/payments \
  -H "x-api-key: $LITE_API_KEY" \
  -H "x-idempotency-key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 4999,
    "currency": "SAR",
    "payment_instrument": {
      "id": "e835c96f-3ede-47ff-85e3-3515b7ac125f",
      "agreement_id": "a499c5c1-35e8-448c-b0f1-9c5a9527eba4"
    },
    "processing": { "processing_type": "CARD_ON_FILE", "initiator": "MERCHANT" },
    "capture_options": { "capture_mode": "INSTANT" },
    "device": { "...": "required as above" }
  }'
```

Use `initiator: MERCHANT` for payments you trigger without the cardholder present, and `CARD_HOLDER` when the customer is actively checking out. The `agreement_id` links back to the card-on-file agreement you set up when storing the instrument.

## Capture an authorized payment

`POST /v1/payments/{payment_id}/capture`

Captures a payment that was authorized with `MANUAL`. Omit `amount` to capture the full authorization, or pass a smaller `amount` for a partial capture. For multiple partial captures, set `metadata.is_final` to `true` on the last one to release any remaining authorized funds.

```bash theme={null}
curl https://{{url}}/v1/payments/{payment_id}/capture \
  -H "x-api-key: $LITE_API_KEY" \
  -H "x-idempotency-key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{ "amount": 10000, "metadata": { "is_final": true } }'
```

## Void an authorized payment

`POST /v1/payments/{payment_id}/void`

Reverses an authorization before it is captured, releasing the hold on the customer's card. Once a payment is captured, void no longer applies, refund instead. The body is optional; include a `reason` to record why.

```bash theme={null}
curl https://{{url}}/v1/payments/{payment_id}/void \
  -H "x-api-key: $LITE_API_KEY" \
  -H "x-idempotency-key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{ "reason": "Customer requested cancellation" }'
```

## Refund a captured payment

`POST /v1/payments/{payment_id}/refund`

Returns funds after capture. Omit `amount` to refund the full remaining captured amount, or pass a smaller `amount` for a partial refund. You can refund multiple times up to the captured total.

```bash theme={null}
curl https://{{url}}/v1/payments/{payment_id}/refund \
  -H "x-api-key: $LITE_API_KEY" \
  -H "x-idempotency-key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{ "amount": 5000, "reason": "Customer returned item" }'
```

## Retrieve a payment

`GET /v1/payments/{payment_id}`

Fetch the current state of a payment. Expand related data with `include=instrument,operations`, where `operations` lists the authorizations, captures, voids, and refunds applied so far.

```bash theme={null}
curl "https://{{url}}/v1/payments/{payment_id}?include=instrument,operations" \
  -H "x-api-key: $LITE_API_KEY"
```

The response wraps the `payment` object and, when relevant, two extras:

* `next_action.redirect`: present only when the payment needs the customer sent somewhere, the URL for a 3DS challenge.
* `operations`: the audit trail. Each entry is one `AUTHORIZE`, `CAPTURE`, `REFUND`, `VOID`, or `REVERSE`, with its own `status` (`PENDING`/`SUCCESS`/`FAILURE`), amount, and the underlying gateway response codes. This is where you see what happened and why a step failed.

The payment object also reports `payment_method`, the channel the card ran through: `CARD`, the wallets (`APPLE_PAY`, `GOOGLE_PAY`, `SAMSUNG_PAY`), network tokens (`VTS`, `SCOF`). With `include=instrument`, the masked card detail (brand, last four, expiry) comes back too.

You can also look a payment up by your own order reference with `GET /v1/payments/by-order/{order_reference}` (same `include` options), and list a merchant's payments with `GET /v1/payments` using pagination and filters.

## Errors

| Code  | Meaning                                                                                                                                          |
| ----- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `400` | The request is invalid, or the action isn't allowed in the payment's current state (for example, capturing a payment that was never authorized). |
| `401` | Authentication failed. The API key or token is missing or invalid.                                                                               |
| `403` | Blocked by security policy, including a payer whose country doesn't match the client region.                                                     |
| `404` | No payment matches the given ID.                                                                                                                 |
| `500` | An unexpected server error. Retry with exponential backoff.                                                                                      |
