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

# Refunds and captures for connected accounts

> Refund, capture, or cancel a connected account's payment from your platform.

Your platform refunds, captures, and cancels a connected account's payments
with the server SDK's `account` option or the `Ionic-Account` header. A refund
belongs to the same merchant as the original payment. Each operation behaves as
it does for a direct merchant in
[Refunds, captures, and cancellations](/guides/refunds-captures).

## Before you begin

* A platform [secret key](/guides/authentication) from **Connect → API keys**, kept on your server.
* An active connection in the same mode. The platform key and the merchant's
  connection both grant each permission an operation needs:

| Operation | Permission |
| - | - |
| Create a refund | `refunds:write` |
| List and retrieve refunds | `refunds:read` |
| Capture or cancel a PaymentIntent | `payments:write` |
| List and retrieve PaymentIntents and Charges | `payments:read` |

* `@ionicfi/sdk` 0.4.1 or later for the TypeScript examples,
  [installed from npm](/sdks/server#install).

## Refund a payment

Send the merchant's PaymentIntent ID. Include `amount` for a partial refund.

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

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

  const refund = await ionic.refunds.create(
    {
      "Idempotency-Key": "merchant:mer_BBBBBBBBBBBBBB:refund:order_123",
      payment_intent_id: "pi_000000000000000000000000",
      amount: 1500,
      reason: "requested_by_customer",
    },
    { account: "mer_BBBBBBBBBBBBBB" },
  );
  ```

  ```bash curl theme={null}
  curl https://api.ionicfi.com/v1/refunds \
    -H "Authorization: Bearer $IONIC_PLATFORM_SECRET_KEY" \
    -H "Ionic-Account: mer_BBBBBBBBBBBBBB" \
    -H "Idempotency-Key: merchant:mer_BBBBBBBBBBBBBB:refund:order_123" \
    -H "Content-Type: application/json" \
    -d '{
      "payment_intent_id": "pi_000000000000000000000000",
      "amount": 1500,
      "reason": "requested_by_customer"
    }'
  ```
</CodeGroup>

Retry a refund with the same `Idempotency-Key` so a repeated click or timeout
does not refund twice. The key's scope includes the receiving merchant and mode.
Check the refund's status before telling the buyer the refund is complete.

A refund for an in-person payment can include `terminal_id` to run it on that
terminal. When the merchant has automatic refund receipts on, its
receipt prints there. See
[Refunds on the Terminal](/concepts/terminal-object#refunds-on-the-terminal).

## Capture an authorization

A PaymentIntent created with `capture_method: "manual"` waits in
`requires_capture` after confirmation. Capture it for the same merchant:

<CodeGroup>
  ```ts TypeScript theme={null}
  const captured = await ionic.paymentIntents.capture(
    {
      id: "pi_...",
      "Idempotency-Key": "merchant:mer_BBBBBBBBBBBBBB:capture:order_8241",
    },
    { account: "mer_BBBBBBBBBBBBBB" },
  );
  ```

  ```bash curl theme={null}
  curl -X POST https://api.ionicfi.com/v1/payment_intents/pi_.../capture \
    -H "Authorization: Bearer $IONIC_PLATFORM_SECRET_KEY" \
    -H "Ionic-Account: mer_BBBBBBBBBBBBBB" \
    -H "Idempotency-Key: merchant:mer_BBBBBBBBBBBBBB:capture:order_8241"
  ```
</CodeGroup>

Capture takes no body and captures the full authorized amount.

## Cancel before capture

Cancel an uncaptured PaymentIntent to release the buyer's authorization hold:

<CodeGroup>
  ```ts TypeScript theme={null}
  const canceled = await ionic.paymentIntents.cancel(
    {
      id: "pi_...",
      reason: "requested_by_customer",
    },
    { account: "mer_BBBBBBBBBBBBBB" },
  );
  ```

  ```bash curl theme={null}
  curl -X POST https://api.ionicfi.com/v1/payment_intents/pi_.../cancel \
    -H "Authorization: Bearer $IONIC_PLATFORM_SECRET_KEY" \
    -H "Ionic-Account: mer_BBBBBBBBBBBBBB" \
    -H "Content-Type: application/json" \
    -d '{"reason": "requested_by_customer"}'
  ```
</CodeGroup>

Before capture, cancel the PaymentIntent. After capture, refund it.

## Refund events

A platform webhook endpoint receives a merchant's `refund.created`,
`refund.succeeded`, `refund.failed`, and `refund.settled` events when that
merchant's connection grants `refunds:read`. Payment events, including
`payment_intent.canceled`, require `payments:read`. The event's `account` field
names the merchant. See [Webhooks for platforms](/guides/connect-webhooks).

## What's next

<CardGroup cols={2}>
  <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>

  <Card title="Manage customers" icon="users" href="/guides/connect-customers">
    Create a connected account's customers and choose the saved card used for future charges.
  </Card>
</CardGroup>

* [Create a refund](/api-reference/refunds/create-a-refund): every field and
  status.
* [Capture a payment intent](/api-reference/payment-intents/capture-a-payment-intent)
  and [Cancel a payment intent](/api-reference/payment-intents/cancel-a-payment-intent).


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