---
title: Sending payment links | API Docs
description: Deliver the checkout URL as a link, a card, or an App Clip part, and how Apple Pay App Clips vs web checkout work.
---

Every payment request returns a `checkout_url`. How you deliver it decides how well it converts.

## Send it as a link part

Deliver the `checkout_url` over iMessage as a **`link` message part** — not as plain text. A `link` part renders a rich card showing your display name, the amount, and your brand image, which converts far better than a bare URL.

Post it to an existing chat with `POST /v3/chats/{chatId}/messages`:

```
{
  "message": {
    "parts": [
      { "type": "link", "value": "https://zero.linqapp.com/pay/acme?session=tok_..." }
    ]
  }
}
```

A `link` part must be the **only** part in the message — it can’t be combined with text or media. See [Rich Link Previews](/guides/messaging/rich-link-previews/index.md) for the full behavior.

**A new chat can't open with a link.**

When you **start** a new chat with `POST /v3/chats`, the first message can’t contain a link. Send a short intro message to open the chat, then send the payment link as a follow-up with the returned chat id.

## Send it as a card

A second option is the **`agentpay` experience** — the same request delivered as a native card inside Linq’s iMessage app, rather than as a link out to a checkout page. The amount and reason are drawn in the bubble, and once the payment succeeds the card turns itself into “Paid” in place, without you sending a second message.

```
{
  "message": {
    "experience": {
      "name": "agentpay",
      "action": "request_payment",
      "params": { "checkout_url": "https://zero.linqapp.com/pay/acme?session=tok_..." }
    }
  }
}
```

`checkout_url` is the only field you have to send — pass back exactly what the payment request returned. The amount and reason are read from that request rather than from you, so a card can never show a figure the checkout won’t actually charge. Optional `title` and `note` override the copy only.

## Send it as an App Clip card

The third option is an **`app_clip` part**: the same checkout link delivered as an Apple Pay card with an **Open** button, so the recipient goes straight into the App Clip checkout sheet instead of tapping through a link preview.

```
{
  "message": {
    "parts": [
      { "type": "app_clip", "value": "https://zero.linqapp.com/pay/acme?session=tok_..." }
    ]
  }
}
```

As with `agentpay`, the link is the only field you send. The merchant name, amount, description and image are composed by Linq from the checkout session itself — the same content the checkout page already shows — so the card can’t display a figure the checkout won’t charge.

An `app_clip` part must be the **only** part in the message.

**App Clip cards never fall back.**

`app_clip` is **iMessage only and never downgrades.** Explicitly asking for SMS or RCS alongside it is rejected up front with [`2028` (AppClipServiceUnsupported)](/error/codes/2xxx/2028/index.md). If the recipient simply isn’t reachable over iMessage, the send is accepted and then fails asynchronously with a `message.failed` webhook carrying [`4005` (RecipientUnsupportedMessageType)](/error/codes/4xxx/4005/index.md) — it never falls back to a plain link. [Check capability](/guides/messaging/protocol-selection#protocol-capabilities/index.md) before sending, or use a `link` part when you aren’t sure.

### Which one to send

|                                   | `link` part                                 | `agentpay` card            | `app_clip` part                       |
| --------------------------------- | ------------------------------------------- | -------------------------- | ------------------------------------- |
| Works on                          | iMessage, SMS, RCS — anywhere the URL opens | iMessage only              | iMessage only                         |
| Apple Pay App Clip                | Yes, on supported iPhones                   | No — paid in the app       | Yes, opened directly from the card    |
| Recipients without Linq’s app     | Rich link card                              | Static version of the card | Works — the App Clip needs no install |
| Updates itself when paid          | No                                          | Yes, in place              | No                                    |
| If the recipient can’t receive it | N/A — always deliverable                    | Static fallback            | Send fails (`4005`)                   |

A link is the safer default when you don’t know what the recipient is on. An `agentpay` card is the better experience inside an ongoing iMessage conversation, especially when you want the bubble itself to reflect that it’s been paid. An `app_clip` part is the shortest path to payment for a recipient you already know is on iMessage — it removes a tap versus the link, at the cost of having no fallback. All three settle the same payment request and fire the same webhooks.

See [Experiences](/guides/messaging/experiences/index.md) for the full invocation rules.

## Apple Pay App Clip vs web checkout

The `checkout_url` works everywhere, and picks the best experience for the recipient automatically:

- **Supported iPhone** → the link opens an **Apple Pay App Clip**: a native, no-install checkout sheet the recipient can pay in a couple of taps.
- **Everywhere else** (Android, desktop, iPhones where the App Clip isn’t available yet) → the same URL opens the **web checkout**.

You don’t choose or configure this — send the one `checkout_url` and the recipient gets the right one.

### App Clip experiences and timing

Linq registers the Apple App Clip experience for your payment links automatically, and **refreshes it whenever you update your payments branding** (display name or brand image). Two timing details worth knowing:

- A **newly registered** experience can take **up to \~24 hours** to activate on Apple’s side. During that window your links open the **web checkout** — nothing is broken, and payments still go through.
- After you change your branding, Apple similarly takes time to propagate the refreshed card. The link keeps working throughout.

Because the web checkout is always available as the fallback, you never have to wait on Apple to start collecting — the App Clip simply upgrades the experience as it becomes available.

## Expiry and cancellation

- A request is payable until its `expires_at`. After that it moves to `expired` and the link no longer accepts payment — create a new request if you need to.
- To retract a request before it’s paid, call `POST /v3/payment_requests/{paymentRequestId}/cancel`. Cancelling a request that’s already `succeeded` or otherwise terminal returns `409`.

## Related

- [Payments overview](/guides/payments/index.md)
- [Connected accounts](/guides/payments/connected-accounts/index.md) — one-time Stripe setup.
- [Payment webhooks](/guides/payments/webhooks/index.md)
