> ## 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 a reusable fixed-price payment link without building a backend.

Payment links are the no-backend path for a fixed price. Create and manage
them in the partner Dashboard, or use the server API with an `sk_` key. Once a
link exists, share its URL and check the Dashboard when the payment is
confirmed.

<Warning>
  Do not put an `sk_` key in browser code. The hosted `/link/` payer page is
  available once a link exists.
</Warning>

## The no-backend flow

In the partner Dashboard:

<Steps>
  <Step title="Add a payout address">
    Add the self-custody address that should receive the requested asset. You
    must prove control of it by signing a challenge from that address.
  </Step>

  <Step title="Create a link">
    Choose the destination chain, token, payout address, and fixed amount.
  </Step>

  <Step title="Copy and share the URL">
    Send the link to your customer by email, message, invoice, or any other
    channel.
  </Step>

  <Step title="Check the Dashboard">
    Fulfil only after the payment is shown as confirmed there.
  </Step>
</Steps>

Payout addresses are self-custody only. An exchange deposit address cannot be
used: the exchange, not your merchant account, controls its signing key. Do not
use an exchange deposit address as a payout destination; use a server-created
payment or a different self-custody destination.

## The link URL

The hosted URL has this shape:

```text theme={"system"}
https://pay.hypermid.io/link/<link-id>
```

Opening a reusable link creates a fresh checkout session. The link itself is
not consumed by opening it, so it can be shared and opened again when a payer
abandons a checkout. After the hosted page creates the session, it takes the
payer to that fresh checkout.

## Single-use links

Single-use is an option, not the default. A link created without
`singleUse: true` remains reusable. With `singleUse: true`, the **first
confirmed payment** consumes the link. Merely opening it, or opening it and
not paying, does not consume it.

Do not promise a customer that a single-use link is reserved for them just
because they opened it. The consumption decision happens when a payment is
confirmed.

## Create a link with the server API

The API is available today for server integrations. Send the secret key only
as `Authorization: Bearer ...` from your server:

```text theme={"system"}
POST https://server.hypermid.io/v1/payments/links
Authorization: Bearer sk_live_...
```

```json theme={"system"}
{
  "chain": 8453,
  "token": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
  "recipient": "0xYourSelfCustodyAddress",
  "amount": "1500000",
  "singleUse": false
}
```

The amount is in the destination token's base units. The response includes
the opaque link id used in the hosted URL. The other link operations are:

| Operation | Endpoint                         | What it does                                        |
| --------- | -------------------------------- | --------------------------------------------------- |
| List      | `GET /v1/payments/links`         | Lists this merchant's links                         |
| Read      | `GET /v1/payments/links/{id}`    | Reads one link                                      |
| Edit      | `PATCH /v1/payments/links/{id}`  | Versions the link and cancels unpaid prior sessions |
| Revoke    | `DELETE /v1/payments/links/{id}` | Revokes the link and cancels unpaid sessions        |

The generated [API reference](/api-reference/overview) lists the same CRUD
operations. The hosted redemption route is intentionally not a merchant CRUD
operation: it is called by the payer-facing link page.

## Editing and revoking

Editing the price or destination creates a new link version. Unpaid checkout
sessions minted from the previous version are cancelled. A customer who
opened the link but has not paid may therefore find that checkout no longer
works after you edit it.

Revoking a link has the same consequence for its unpaid sessions, and future
opens fail. Revoke is a soft operation: the link record remains with its
revoked status; it is not hard-deleted. A payment that has already been
confirmed is not turned into an unpaid payment by an edit or revoke.

### Removing a payout address

The redemption path checks the payout allowlist every time a link is opened.
Removing a destination permanently revokes active links that use it and
cancels their unpaid sessions. Re-adding the address does not revive those links.
This is separate from editing or revoking one link, but the consequence is the
same: a customer who has not paid can no longer use the old session.

## How to know you were paid

Never fulfil from the hosted page's success screen, a browser callback, or an
email. A payer can fake a screen, and an email is only a prompt to look.

For a no-backend merchant, the **Dashboard is authoritative**. Fulfil only
when the payment is shown there as confirmed. A server integration can use a
signed webhook as the prompt and then read the session server-side; the
server-side status is the authority.

### Exception states

These states mean that funds may have moved, but they are not a normal
confirmed payment to fulfil automatically:

| State           | What it means                                                                     | What to do                                                                                          |
| --------------- | --------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| `duplicate`     | A second confirmed payment reached a single-use link after the first payment won. | Do not fulfil automatically. Review it manually with the payer before taking any fulfilment action. |
| `late`          | The payment was confirmed after the session was cancelled or expired.             | Do not auto-credit it. Send it to reconciliation before taking any fulfilment action.               |
| `out-of-bounds` | The verified amount was below a session minimum or above its maximum.             | Treat it as held for review, not as a successful payment.                                           |

None of these states is money to act on as a completed order.

## Fees

A payment link mints an ordinary Checkout session, so it uses the same two-fee
policy: Hypermid's fee plus the merchant's optional developer fee on the same
input amount. The developer fee defaults to 0 and is limited to 0–100 basis
points. A partner-specific Hypermid override replaces the global rate outright.
Same-token EVM transfers remain the zero fee exception.

On EVM routes, developer earnings are held by Hypermid and settled periodically
by manual transfer. On the Near deposit-address rail, the provider keeps half
of each declared app fee and pays the developer fee directly to its recipient.

## Expiry and redirect fields

An `expiresAt` on a link must be in the future when the link is created. Once
it has passed, the link cannot mint a new checkout session. The redemption
path checks the expiry again, so a link that expires while it is being opened
does not race into a new session.

`successUrl` and `cancelUrl` must be absolute HTTPS URLs. The hosted payer page
redirects to the exact configured URL after verified completion or explicit
cancellation/abandon. It does not append a payment-status claim; use the
session read or webhook as the authoritative payment result.

## Payout-address rule

Ownership of a payout address is proved by signing from that address. This is
why exchange deposit addresses are not supported: the merchant does not hold
the exchange's signing key. See [Payout addresses](/guides/withdrawal#payout-addresses)
for the challenge flow.

## Next steps

* [Payments](/guides/payments) — choose a mode and integration method.
* [Checkout](/guides/checkout) — the server-created fixed-price flow.
* [Payments SDK](/sdk/payments) — server-side session creation and reads.
* [Payment-links SDK reference](/sdk/payment-links) — exact CRUD signatures and
  link lifecycle semantics.
* [Webhooks](/guides/webhooks) — signed delivery for server integrations.
