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

# Payment links

> Create and manage reusable, fixed-price checkout links from your server.

<Warning>
  Server-side only. Payment-link functions send your secret key and throw if
  `window` exists. Never put an `sk_` key in browser code.
</Warning>

A payment link stores a fixed checkout configuration behind a stable id. Build
the hosted URL from that id and share it with your customer:

```typescript theme={"system"}
import { createPaymentLink } from "@hypermid/sdk/payment-links";

const link = await createPaymentLink(
  {
    chain: 8453,
    token: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
    recipient: "0xYourTreasury…",
    amount: "10000000", // 10 USDC at 6 decimals
    successUrl: "https://shop.example/thanks",
    cancelUrl: "https://shop.example/cart",
  },
  { secretKey: process.env.HYPERMID_SECRET_KEY! },
);

const url = `https://pay.hypermid.io/link/${encodeURIComponent(link.id)}`;
```

Opening the link mints a fresh checkout session. The link is reusable unless
you set `singleUse: true`.

## Functions

| Function                               | Wire request                    | Returns               |
| -------------------------------------- | ------------------------------- | --------------------- |
| `createPaymentLink(req, opts)`         | `POST /v1/payments/links`       | `PaymentLink`         |
| `listPaymentLinks(opts)`               | `GET /v1/payments/links`        | `PaymentLinkList`     |
| `getPaymentLink(id, opts)`             | `GET /v1/payments/links/:id`    | `PaymentLink`         |
| `updatePaymentLink(id, changes, opts)` | `PATCH /v1/payments/links/:id`  | `PaymentLinkMutation` |
| `revokePaymentLink(id, opts)`          | `DELETE /v1/payments/links/:id` | `PaymentLinkMutation` |

All operations are scoped to the secret key's merchant and environment. The
key is sent as `Authorization: Bearer`, not as `x-api-key`.

```typescript theme={"system"}
function createPaymentLink(
  req: CreatePaymentLinkRequest,
  opts: PaymentLinksClientOptions,
): Promise<PaymentLink>;
function listPaymentLinks(
  opts: PaymentLinksClientOptions,
): Promise<PaymentLinkList>;
function getPaymentLink(
  id: string,
  opts: PaymentLinksClientOptions,
): Promise<PaymentLink>;
function updatePaymentLink(
  id: string,
  changes: UpdatePaymentLinkRequest,
  opts: PaymentLinksClientOptions,
): Promise<PaymentLinkMutation>;
function revokePaymentLink(
  id: string,
  opts: PaymentLinksClientOptions,
): Promise<PaymentLinkMutation>;
```

## Create fields

```typescript theme={"system"}
interface CreatePaymentLinkRequest {
  chain: number;
  token: string;
  recipient: string;
  amount: string;
  singleUse?: boolean;
  metadata?: Record<string, unknown>;
  successUrl?: string;
  cancelUrl?: string;
  expiresAt?: string;
}
```

`amount` is required and is a positive integer in destination-token base
units. Payment links do not support open amounts. `expiresAt`, when present,
must be a future ISO 8601 timestamp. `singleUse` defaults to `false`.

The update type is `Partial<CreatePaymentLinkRequest>`:

```typescript theme={"system"}
type UpdatePaymentLinkRequest = Partial<CreatePaymentLinkRequest>;
```

## Link lifecycle semantics

These operations have effects beyond changing the returned fields:

* **Single-use is consumed by the first confirmed payment.** Opening the link
  does not consume it. Until a payment is confirmed, it can mint sessions;
  after confirmation, further redemptions are refused.
* **Editing versions the link.** A `PATCH` cancels every unpaid session minted
  from the previous version. `cancelledSessions` tells you how many sessions
  were canceled, and a payer who opened the old version but has not paid must
  start again.
* **Revoking is a soft delete.** `DELETE` retains the row, sets `revokedAt`,
  cancels unpaid sessions already minted from the link, and never reuses its
  id. Call it `revokePaymentLink` in application code even though the wire verb
  is `DELETE`.
* **De-allowlisting is permanent.** Removing a payout address from the
  merchant's allowlist permanently revokes every link that uses it. Adding the
  address again does not revive those links.

`consumedBySessionId` identifies the session that consumed a single-use link;
it is not payment proof by itself. Check the session status or your dashboard
before fulfilling an order.

## Manage links

```typescript theme={"system"}
import {
  getPaymentLink,
  listPaymentLinks,
  revokePaymentLink,
  updatePaymentLink,
} from "@hypermid/sdk/payment-links";

const opts = { secretKey: process.env.HYPERMID_SECRET_KEY! };
const { links } = await listPaymentLinks(opts);
const current = await getPaymentLink(link.id, opts);

const revised = await updatePaymentLink(
  link.id,
  { amount: "12000000" },
  opts,
);
console.log(revised.version, revised.cancelledSessions);

const revoked = await revokePaymentLink(link.id, opts);
console.log(revoked.revokedAt, revoked.cancelledSessions);
```

## Options and response

```typescript theme={"system"}
interface PaymentLinksClientOptions {
  secretKey: string;       // sk_live_… or sk_test_…
  apiBase?: string;        // defaults to https://server.hypermid.io
  signal?: AbortSignal;
}
```

`PaymentLink` includes the stable `id`, `version`, `environment`, destination
(`chain`, `token`, `recipient`), fixed `amount`, `singleUse`, `metadata`,
redirects, `expiresAt`, `revokedAt`, `consumedBySessionId`, and creation/update
timestamps. `PaymentLinkMutation` includes all of those fields plus
`cancelledSessions`.
