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

# Connect a merchant

> Let an existing Ionic merchant authorize your platform, then use their merchant ID to make requests.

Connect lets an existing Ionic merchant grant your platform access to their
account. Your server starts the request, the merchant approves it on Ionic,
and your server exchanges the returned code for the merchant ID and granted
permissions. This flow connects an existing account; it does not create one.

## Before you begin

* An active Platform Program with the permissions and mode your integration uses.
* A platform secret key with `platform:act`. Keep it on your server.
* An approved HTTPS redirect origin. The callback must be exactly that origin
  followed by `/connect/callback`, for example `https://platform.example.com/connect/callback`,
  with no query string or fragment.

Redirect origins are separate from [payment domains](/guides/platform-payment-domains).
The requests on this page use your platform key without `Ionic-Account`.

## 1. Start the connection on your server

Create a random, single-use `state` and a PKCE verifier for this attempt. The
verifier is a cryptographically random string of 43–128 characters. Derive
`code_challenge` by SHA-256 hashing the verifier, then encoding the digest as
base64url without padding. Use `S256` as the challenge method.

Store the state, verifier, exact callback URI, and test/live mode against the
signed-in user starting the connection. Keep the verifier on your server.

Call `POST /v1/account_authorizations` with those values and only the permissions
your integration needs. This example requests payment access; substitute the
state and challenge generated for the attempt:

```bash theme={null}
curl https://api.ionicfi.com/v1/account_authorizations \
  -H "Authorization: Bearer $IONIC_PLATFORM_SECRET_KEY" \
  -H "Idempotency-Key: $AUTHORIZATION_REQUEST_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "redirect_uri": "https://platform.example.com/connect/callback",
    "state": "REPLACE_WITH_RANDOM_STATE",
    "code_challenge": "REPLACE_WITH_S256_CHALLENGE",
    "code_challenge_method": "S256",
    "permissions": ["payments:read", "payments:write"]
  }'
```

Save the returned authorization `id` (`aauth_…`) with that attempt. Redirect the
merchant's browser to the returned `authorization_url` before `expires_at`.
Reuse the same idempotency key and body when retrying this create request.

For card saving, request `setup_intents:read` and `setup_intents:write` instead.
Add `customers:write` if you create customer records, and `customers:read` if you
read them. Requested permissions must be allowed by your Platform Program;
they do not expand your API key's permissions.

## 2. Handle the merchant's decision

Ionic redirects to your callback with the original `state` and either a
one-time `code` or an `error`.

Verify that `state` matches the pending attempt for the signed-in user before
accepting either result. Reject missing or mismatched state. If the merchant
denies access, show that the connection was not completed; do not exchange a
code. For an expired attempt, let the user start again.

Keep callback codes and the PKCE verifier out of logs and analytics.

## 3. Exchange the code on your server

Use the saved authorization ID, the callback code, the original verifier, and
the exact callback URI from step 1. Use the platform credential in the same mode.
Replace the example body values with the values from that attempt:

```bash theme={null}
curl "https://api.ionicfi.com/v1/account_authorizations/$AUTHORIZATION_ID/exchange" \
  -H "Authorization: Bearer $IONIC_PLATFORM_SECRET_KEY" \
  -H "Idempotency-Key: $EXCHANGE_REQUEST_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "code": "REPLACE_WITH_CALLBACK_CODE",
    "code_verifier": "REPLACE_WITH_ORIGINAL_VERIFIER",
    "redirect_uri": "https://platform.example.com/connect/callback"
  }'
```

A successful response has `status: "approved"`, `account` (the merchant's
`mer_…` ID), `permissions`, and `livemode`. It returns the approved connection
result, not a new API key. For a retry, preserve the exchange's idempotency key
and request body. A code is single-use.

Store the returned merchant ID and mode against the authorized business in your
application, together with the granted permissions. Mark the pending attempt
complete so the callback cannot link the merchant again. Do not take the
merchant ID from an unverified browser parameter.

## 4. Use the connected merchant

`GET /v1/connected_accounts/{id}` reads the current connection. Check its
`connection_status`, `account_status`, `payments_enabled`, `permissions`, and
`livemode` before offering payment features. Approval connects the merchant;
it does not activate their payment capability. Access can change after approval.

For merchant-owned resources, use your platform key and select that merchant
with `Ionic-Account`, or the SDK's `account` option. Use the same merchant ID in
the browser client. Your key and the active connection must both allow the
operation. See [How Connect works](/guides/connect-overview).

Continue with [Accept payments](/guides/connect-blocks) or
[Save cards](/guides/connect-save-cards). See **API Reference → Platform Connect** for authorization and connected-account
endpoints.
