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

# Payment Sessions API — hosted and embedded checkout

> Create payment sessions for hosted checkout (redirect) or embedded checkout flows, then retrieve them by ID to check status and collect credentials.

A payment session represents a checkout interaction. Use `mode: "hosted"` to redirect your customer to a Borga-hosted checkout page, or `mode: "embedded"` to render checkout directly in your own page using the `client_secret`.

Sessions expire after a short window. Retrieve a session to check its status and whether the underlying payment succeeded.

***

## Create a payment session

`POST /v1/payment_sessions`

Creates a new payment session. The required parameters vary by `mode` — see the examples below.

### Request parameters

<ParamField body="mode" type="string">
  Checkout mode. Use `"hosted"` to redirect the customer to a Borga-hosted page, or `"embedded"` to render checkout within your own page. Defaults to `"hosted"`.
</ParamField>

<ParamField body="payment" type="string">
  ID of an existing payment to attach this session to. If omitted, a new payment is created using the `amount` and `currency` fields.
</ParamField>

<ParamField body="amount" type="number">
  Amount for the payment in whole ISK kronur. Required when `payment` is not provided.
</ParamField>

<ParamField body="currency" type="string">
  Three-letter ISO 4217 currency code. Defaults to `ISK`.
</ParamField>

<ParamField body="customer" type="string">
  ID of an existing customer to associate with the session.
</ParamField>

<ParamField body="customer_email" type="string">
  Customer email address. Pre-fills the email field in hosted checkout.
</ParamField>

<ParamField body="return_url" type="string">
  URL the customer is redirected to after completing or attempting checkout. Required for `mode: "hosted"`. Borga appends a `session_id` query parameter so you can retrieve the session on load.
</ParamField>

<ParamField body="cancel_url" type="string">
  URL the customer is redirected to if they cancel checkout. Only used in `mode: "hosted"`.
</ParamField>

<ParamField body="origin" type="string">
  The origin of the page embedding checkout (e.g. `https://example.com`). Required for `mode: "embedded"`. Borga uses this for `postMessage` communication.
</ParamField>

<ParamField body="enabled_methods" type="string[]">
  Array of payment method types to enable (e.g. `["card", "apple_pay"]`). When omitted, all methods available to your merchant account are enabled.
</ParamField>

<ParamField body="locale" type="string">
  BCP 47 language tag controlling the checkout UI language (e.g. `"is"`, `"en"`). Defaults to the customer's browser locale.
</ParamField>

<ParamField body="save_payment_method" type="boolean">
  When `true`, prompts the customer to save their payment method for future use.
</ParamField>

<ParamField body="external_reference" type="string">
  Your own reference string for this session — an order ID, invoice number, or similar.
</ParamField>

<ParamField body="metadata" type="object">
  Set of key-value pairs to attach to the session. Values must be strings.
</ParamField>

<Tabs>
  <Tab title="Hosted">
    <RequestExample>
      ```bash cURL theme={null}
      curl --request POST \
        --url https://api.borga.is/v1/payment_sessions \
        --header "Authorization: Bearer sk_live_..." \
        --header "X-Merchant-Id: mer_xxx" \
        --header "Content-Type: application/json" \
        --data '{
          "mode": "hosted",
          "amount": 9900,
          "currency": "ISK",
          "customer_email": "jondoe@example.com",
          "return_url": "https://example.com/checkout/complete",
          "cancel_url": "https://example.com/checkout/cancel",
          "external_reference": "order_2077"
        }'
      ```
    </RequestExample>

    <ResponseExample>
      ```json 201 theme={null}
      {
        "id": "pses_01hxa1r5nvpq8kd2wfm3cjt9yb",
        "mode": "hosted",
        "url": "https://checkout.borga.is/s/pses_01hxa1r5nvpq8kd2wfm3cjt9yb",
        "client_secret": null,
        "status": "open",
        "payment": "pay_01hxa1r5mzgq8kd2wfm3abcxyz",
        "expires_at": "2026-04-29T11:15:00Z"
      }
      ```
    </ResponseExample>

    Redirect your customer to the `url` returned in the response. After checkout, Borga redirects them to your `return_url` with `?session_id=pses_...` appended. Retrieve the session on that page to confirm the outcome.
  </Tab>

  <Tab title="Embedded">
    <RequestExample>
      ```bash cURL theme={null}
      curl --request POST \
        --url https://api.borga.is/v1/payment_sessions \
        --header "Authorization: Bearer sk_live_..." \
        --header "X-Merchant-Id: mer_xxx" \
        --header "Content-Type: application/json" \
        --data '{
          "mode": "embedded",
          "amount": 9900,
          "currency": "ISK",
          "origin": "https://example.com",
          "customer_email": "jondoe@example.com",
          "external_reference": "order_2077"
        }'
      ```
    </RequestExample>

    <ResponseExample>
      ```json 201 theme={null}
      {
        "id": "pses_01hxa1r5nvpq8kd2wfm3cjt9yb",
        "mode": "embedded",
        "url": null,
        "client_secret": "pses_secret_01hxa1r5nvpq8kd2wfm3cjt9yb_abc123",
        "status": "open",
        "payment": "pay_01hxa1r5mzgq8kd2wfm3abcxyz",
        "expires_at": "2026-04-29T11:15:00Z"
      }
      ```
    </ResponseExample>

    Pass the `client_secret` to your front-end to initialise the Borga.js embedded checkout element. The `client_secret` is sensitive — do not log it or expose it beyond the client session.
  </Tab>
</Tabs>

### Response fields

<ResponseField name="id" type="string" required>
  Unique identifier for the session.
</ResponseField>

<ResponseField name="mode" type="string" required>
  Checkout mode: `"hosted"` or `"embedded"`.
</ResponseField>

<ResponseField name="url" type="string">
  The hosted checkout URL to redirect your customer to. Present when `mode` is `"hosted"`, `null` otherwise.
</ResponseField>

<ResponseField name="client_secret" type="string">
  Secret used to initialise the embedded checkout element. Present when `mode` is `"embedded"`, `null` otherwise.
</ResponseField>

<ResponseField name="status" type="string" required>
  Session status. One of `open`, `complete`, `expired`.
</ResponseField>

<ResponseField name="payment" type="string" required>
  ID of the payment associated with this session.
</ResponseField>

<ResponseField name="expires_at" type="string" required>
  ISO 8601 timestamp after which the session can no longer be used to complete checkout.
</ResponseField>

***

## Retrieve a payment session

`GET /v1/payment_sessions/{id}`

Retrieves an existing payment session. Call this endpoint from your server after the customer returns to your `return_url` to confirm the payment outcome before fulfilling the order.

### Path parameters

<ParamField path="id" type="string" required>
  The ID of the payment session to retrieve.
</ParamField>

<RequestExample>
  ```bash cURL theme={null}
  curl --request GET \
    --url https://api.borga.is/v1/payment_sessions/pses_01hxa1r5nvpq8kd2wfm3cjt9yb \
    --header "Authorization: Bearer sk_live_..." \
    --header "X-Merchant-Id: mer_xxx"
  ```
</RequestExample>

### Response fields

<ResponseField name="id" type="string" required>
  Unique session identifier.
</ResponseField>

<ResponseField name="mode" type="string" required>
  Checkout mode: `"hosted"` or `"embedded"`.
</ResponseField>

<ResponseField name="url" type="string">
  Hosted checkout URL. `null` for embedded sessions.
</ResponseField>

<ResponseField name="client_secret" type="string">
  Embedded checkout secret. `null` for hosted sessions.
</ResponseField>

<ResponseField name="status" type="string" required>
  Session status. One of `open`, `complete`, `expired`.
</ResponseField>

<ResponseField name="payment" type="string" required>
  ID of the associated payment.
</ResponseField>

<ResponseField name="expires_at" type="string" required>
  ISO 8601 expiry timestamp.
</ResponseField>

<ResponseExample>
  ```json 200 theme={null}
  {
    "id": "pses_01hxa1r5nvpq8kd2wfm3cjt9yb",
    "mode": "hosted",
    "url": "https://checkout.borga.is/s/pses_01hxa1r5nvpq8kd2wfm3cjt9yb",
    "client_secret": null,
    "status": "complete",
    "payment": "pay_01hxa1r5mzgq8kd2wfm3abcxyz",
    "expires_at": "2026-04-29T11:15:00Z"
  }
  ```
</ResponseExample>

<Warning>
  Always retrieve the session from your server and check that `status` is `"complete"` and the associated payment's status is `"succeeded"` before fulfilling an order. Do not rely solely on the redirect URL to confirm payment.
</Warning>
