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

# Hosted checkout for connected accounts

> Create a checkout session for a connected account and send the buyer to an Ionic-hosted payment page.

Your server creates the [checkout session](/checkout/overview) with the platform secret key and the
merchant's ID, the buyer pays on a page Ionic hosts, and the payment belongs to
that merchant. The buyer pays on Ionic's domain, so this flow needs no payment
form and no payment domain registration.

Session fields and options are the same as in [Hosted Checkout](/guides/checkout).

## Before you begin

* Platform test keys from **Connect → API keys**, with the secret key on your server.
* An active connection granting `sessions:write` and `sessions:read`, with those
  permissions also on the platform key.
* The connected account's ID (`mer_…`), selected by your application's
  authorization logic.
* `@ionicfi/sdk` 0.4.1 or later for the TypeScript examples,
  [installed from npm](/sdks/server#install).

Live payments also require the merchant's account to accept live payments. See
[Know when payments are enabled](/guides/hosted-account-links#4-know-when-payments-are-enabled).

## Create the session on your server

Pass the merchant with the server SDK's `account` option, or send it as the
`Ionic-Account` header. The session and the payment it creates belong to that
merchant.

<CodeGroup>
  ```ts TypeScript theme={null}
  import { Ionic } from "@ionicfi/sdk";

  const ionic = new Ionic({ token: process.env.IONIC_PLATFORM_SECRET_KEY });

  const session = await ionic.checkout.sessions.create(
    {
      "Idempotency-Key": "merchant:mer_BBBBBBBBBBBBBB:order:1001",
      mode: "payment",
      line_items: [
        {
          name: "Cleaning visit",
          amount: 15000,
          currency: "usd",
          quantity: 1,
        },
      ],
      client_reference_id: "order_1001",
      success_url: "https://platform.example.com/orders/1001/paid?session_id={CHECKOUT_SESSION_ID}",
      cancel_url: "https://platform.example.com/orders/1001",
      metadata: {
        order_id: "order_1001",
      },
    },
    { account: "mer_BBBBBBBBBBBBBB" },
  );
  ```

  ```bash curl theme={null}
  curl https://api.ionicfi.com/v1/checkout/sessions \
    -H "Authorization: Bearer $IONIC_PLATFORM_SECRET_KEY" \
    -H "Ionic-Account: mer_BBBBBBBBBBBBBB" \
    -H "Idempotency-Key: merchant:mer_BBBBBBBBBBBBBB:order:1001" \
    -H "Content-Type: application/json" \
    -d '{
      "mode": "payment",
      "line_items": [
        {
          "name": "Cleaning visit",
          "amount": 15000,
          "currency": "usd",
          "quantity": 1
        }
      ],
      "client_reference_id": "order_1001",
      "success_url": "https://platform.example.com/orders/1001/paid?session_id={CHECKOUT_SESSION_ID}",
      "cancel_url": "https://platform.example.com/orders/1001",
      "metadata": {
        "order_id": "order_1001"
      }
    }'
  ```
</CodeGroup>

The [idempotency key](/api-reference/idempotency)'s scope includes the receiving merchant and mode. Store the
merchant ID with your order and the returned session `id`.

Line items can be inline amounts, as above, or the merchant's catalog prices by
`price_id`. The merchant creates its products and prices. Your platform can
list them with `Ionic-Account` and `products:read`.

## Redirect the buyer

Return the session's `url` to your frontend and redirect the buyer to it. The
buyer completes the payment on the Ionic-hosted page and returns to your
`success_url`.

## Confirm the payment

Retrieve the session for the same merchant to confirm the result. The redirect
only updates the buyer's screen.

<CodeGroup>
  ```ts TypeScript theme={null}
  const session = await ionic.checkout.sessions.retrieve(
    { id: "cs_000000000000000000001001" },
    { account: "mer_BBBBBBBBBBBBBB" },
  );

  const paid = session.status === "complete" && session.payment_status === "paid";
  ```

  ```bash curl theme={null}
  curl https://api.ionicfi.com/v1/checkout/sessions/cs_000000000000000000001001 \
    -H "Authorization: Bearer $IONIC_PLATFORM_SECRET_KEY" \
    -H "Ionic-Account: mer_BBBBBBBBBBBBBB"
  ```
</CodeGroup>

Fulfill when the session is both `complete` and `paid`.

## Fulfill from platform webhooks

A platform webhook endpoint receives `checkout.session.completed` for a
connected account when that account's connection grants `sessions:read`. The
event's `account` field names the merchant. Match it, the session ID, and the
mode to the order your application stored before fulfilling. See
[Webhooks for platforms](/guides/connect-webhooks).

## Keep checkout data with the correct merchant

| Value | Owner or scope |
| - | - |
| Platform secret key | The platform, in the intended mode. |
| Checkout session and its payment | The selected connected account. |
| Catalog prices used as line items | The same connected account. |
| `client_reference_id` and `metadata` | Your application's correlation data. Ionic does not enforce uniqueness across merchants. |

## Availability

Embedded checkout renders only on websites in the merchant's own **Web domains** list, so a
platform's own website takes payments with hosted checkout or
[Ionic Blocks](/guides/connect-blocks). Your platform can list and retrieve a
connected account's payment links; the connected account creates and edits them with
its own keys.

## What's next

<CardGroup cols={2}>
  <Card title="Refund and capture" icon="rotate-left" href="/guides/connect-refunds-captures">
    Refund, capture, or cancel a connected account's payment from your platform.
  </Card>

  <Card title="Handle webhooks" icon="tower-broadcast" href="/guides/connect-webhooks">
    Receive every connected account's events on one endpoint and match each to its connected account.
  </Card>
</CardGroup>

* [Accept a payment with Hosted Checkout](/guides/checkout): every session
  field and option.
* [Create a checkout session](/api-reference/checkout-sessions/create-a-checkout-session):
  the full request and response contract.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.