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

# Payment links

> Create reusable checkout links backed by catalog, optional items, and collection rules.

Payment links are reusable hosted payment entry points. They are useful for invoices, quotes, low-code selling, support-assisted checkout, QR codes, and any flow where the buyer should open the same configured payment surface without your app creating a new checkout session first.

<Info>
  Payment link line items are catalog-backed. Create products and prices first, then use `price_id` in the link.
</Info>

On Node, `npm install @ionicfi/sdk` gives you typed calls for every request
below; the [server SDK](/sdks/server) guide has details. Each example also
shows raw curl.

## Create a link

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

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

  const link = await ionic.paymentLinks.create({
    "Idempotency-Key": "services_2026_implementation_link",
    name: "Implementation package",
    description: "Fixed-fee onboarding package",
    currency: "usd",
    amount_total: 250000,
    line_items: [{ price_id: "price_Implementation000000000", quantity: 1 }],
    optional_items: [{ price_id: "price_Expedite000000000000", quantity: 1 }],
    submit_type: "pay",
    success_url: "https://example.com/success",
    cancel_url: "https://example.com/cancel",
    metadata: { campaign: "services_2026" },
  });

  console.log(link.url); // the shareable link
  ```

  ```bash curl theme={null}
  curl https://api.ionicfi.com/v1/payment_links \
    -H "Authorization: Bearer sk_v1_test_..." \
    -H "Idempotency-Key: services_2026_implementation_link" \
    -H "Content-Type: application/json" \
    -d '{
      "name": "Implementation package",
      "description": "Fixed-fee onboarding package",
      "currency": "usd",
      "amount_total": 250000,
      "line_items": [
        {
          "price_id": "price_Implementation000000000",
          "quantity": 1
        }
      ],
      "optional_items": [
        {
          "price_id": "price_Expedite000000000000",
          "quantity": 1
        }
      ],
      "submit_type": "pay",
      "success_url": "https://example.com/success",
      "cancel_url": "https://example.com/cancel",
      "metadata": {
        "campaign": "services_2026"
      }
    }'
  ```
</CodeGroup>

The response includes a shareable `url`, link totals, active state, timestamps, and the line item configuration used to create buyer checkout sessions.

## Use catalog-backed line items

Payment links reference catalog prices.

```json theme={null}
{
  "name": "Starter subscription",
  "line_items": [
    {
      "price_id": "price_123",
      "quantity": 1
    }
  ],
  "success_url": "https://example.com/success",
  "cancel_url": "https://example.com/cancel"
}
```

Catalog-backed links let non-engineering workflows reuse products and prices without changing application code.

## Fields that shape the buyer experience

| Field              | Purpose                                                  |
| ------------------ | -------------------------------------------------------- |
| `collect_config`   | Collection behavior for buyer details.                   |
| `custom_fields`    | Additional buyer-provided fields.                        |
| `optional_items`   | Add-ons or cross-sells shown before payment.             |
| `submit_type`      | Button intent such as `pay`, `book`, or `donate`.        |
| `link_type`        | Product-defined link type for future behavior branching. |
| `theme_id`         | Theme selection when multiple checkout themes exist.     |
| `branding`         | Link-specific brand presentation.                        |
| `inactive_message` | Message shown when the link is inactive.                 |

## Manage links

List, retrieve, and update links:

<CodeGroup>
  ```ts TypeScript theme={null}
  const links = await ionic.paymentLinks.list();

  const link = await ionic.paymentLinks.retrieve({ id: "pl_00000000000001" });

  const updated = await ionic.paymentLinks.update({
    id: "pl_00000000000001",
    inactive_message: "This offer has expired.",
  });
  ```

  ```bash curl theme={null}
  curl https://api.ionicfi.com/v1/payment_links \
    -H "Authorization: Bearer sk_v1_test_..."

  curl https://api.ionicfi.com/v1/payment_links/pl_00000000000001 \
    -H "Authorization: Bearer sk_v1_test_..."

  curl -X POST https://api.ionicfi.com/v1/payment_links/pl_00000000000001 \
    -H "Authorization: Bearer sk_v1_test_..." \
    -H "Content-Type: application/json" \
    -d '{
      "inactive_message": "This offer has expired."
    }'
  ```
</CodeGroup>

Deactivate or reactivate a link with dedicated actions.

<CodeGroup>
  ```ts TypeScript theme={null}
  await ionic.paymentLinks.deactivate({ id: "pl_00000000000001" });
  ```

  ```bash curl theme={null}
  curl -X POST https://api.ionicfi.com/v1/payment_links/pl_00000000000001/deactivate \
    -H "Authorization: Bearer sk_v1_test_..."
  ```
</CodeGroup>

## What happens when a buyer opens a link

Ionic-hosted checkout opens the link, shows the payment page, and creates the checkout attempt. Your server does not need to create a session for each visit or handle raw card data.

<Info>
  Payment links and checkout sessions share many concepts, but they are different resources. A link is reusable configuration. A session is one buyer attempt.
</Info>
