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

# Payment Links

> Create reusable payment URLs for email campaigns, social media, or invoices

Create reusable payment URLs for email campaigns, social media, or invoices.

## What Are Payment Links?

Payment Links are URLs you can share with customers. When they click the link, a checkout session is automatically created for them.

**Perfect for:**

* Email invoices
* Social media bio links
* SMS campaigns
* QR codes
* Donation pages

## Create a Payment Link

```
POST /api/payment-links/create
```

### Headers

| Header            | Value                 |
| :---------------- | :-------------------- |
| `Content-Type`    | `application/json`    |
| `X-API-KEY`       | Your Vault API Key    |
| `X-OZURA-API-KEY` | Your Merchant API Key |

### Request Body

| Field                      | Type   |  Required | Default | Description                                                                                                                                                                                            |
| :------------------------- | :----- | :-------: | :------ | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `merchantId`               | string |  **Yes**  | —       | Your Merchant ID                                                                                                                                                                                       |
| `merchantName`             | string |  **Yes**  | —       | Business name shown to customer                                                                                                                                                                        |
| `amount`                   | string | **Yes**\* | —       | Payment amount (e.g., `"25.00"`)                                                                                                                                                                       |
| `currency`                 | string |     No    | `"USD"` | Currency code                                                                                                                                                                                          |
| `successUrl`               | string |  **Yes**  | —       | Redirect after payment                                                                                                                                                                                 |
| `cancelUrl`                | string |  **Yes**  | —       | Redirect if cancelled                                                                                                                                                                                  |
| `errorUrl`                 | string |  **Yes**  | —       | Redirect if failed                                                                                                                                                                                     |
| `metadata`                 | object |     No    | `{}`    | Custom data (max 10KB) passed to each session spawned from this link                                                                                                                                   |
| `expiresInDays`            | number |     No    | `7`     | Days until link expires (1-3650)                                                                                                                                                                       |
| `usageLimit`               | number |     No    | `null`  | Max payments (null for unlimited)                                                                                                                                                                      |
| `merchantPayLinkReference` | string |     No    | —       | Link-scoped correlation ID returned on **every** transaction from this link (max 128 chars; letters, numbers, `. _ : -`). See [Correlate Payments to Your Orders](#correlate-payments-to-your-orders). |

\*Not required when using `items` or `checkoutMode: "donation"`.

### Example Request

```bash theme={null}
curl -X POST https://checkout.ozura.com/api/payment-links/create \
  -H "Content-Type: application/json" \
  -H "X-API-KEY: your_vault_api_key" \
  -H "X-OZURA-API-KEY: your_merchant_api_key" \
  -d '{
    "merchantId": "your_merchant_id",
    "merchantName": "My Store",
    "amount": "50.00",
    "currency": "USD",
    "successUrl": "https://mystore.com/thank-you",
    "cancelUrl": "https://mystore.com/cancelled",
    "errorUrl": "https://mystore.com/error",
    "expiresInDays": 7,
    "usageLimit": 1,
    "metadata": {
      "invoiceId": "INV-12345"
    }
  }'
```

### Response

```json theme={null}
{
  "success": true,
  "data": {
    "paymentLinkId": "pl_xxxxxxxxxxxxxx",
    "url": "https://checkout.ozura.com/pay/pl_xxxxxxxxxxxxxx",
    "expiresAt": "2025-01-14T00:00:00.000Z"
  }
}
```

## Branding and `appearance`

Payment links store the same request fields as session creation. Include an `appearance` object (and `merchantName`) on **create payment link** to brand every session spawned from that link. Options match [Customize Appearance](/guides/payments/checkout/appearance) and the [Appearance Reference](/guides/payments/checkout/appearance-reference).

## Share the Link

Send the `url` from the response to your customer:

```
https://checkout.ozura.com/pay/pl_xxxxxxxxxxxxxx
```

When they click it:

1. A new checkout session is created automatically
2. They see the checkout page with the amount you specified
3. After payment, they're redirected to your success URL

## Correlate Payments to Your Orders

Because a reusable link shares one `paymentLinkId` across every customer, that ID alone can't tell you *which* of your orders a given payment belongs to. Ozura gives you two correlation references, and they work together:

* **`merchantReference`** — a **per-payer** value you set via a `?ref=` query parameter, unique to each checkout. Use it to tie a payment to a specific order or customer.
* **`merchantPayLinkReference`** — a **static, link-level** value you set once when creating the link. It comes back on *every* transaction from that link, so you can identify which link or campaign produced a payment.

To tie a payment back to your own order or customer, append a `ref` query parameter when you render the link for that customer:

```
https://checkout.ozura.com/pay/pl_xxxxxxxxxxxxxx?ref=ORD-12345
```

Ozura captures `ref` on the checkout session and returns it to you after a successful payment as `merchantReference` — alongside the `paymentLinkId` and the processor `transactionId` — so you can match the transaction to your order without guesswork.

<Note>
  This is the recommended setup for links **embedded on your website** (a "Pay" button, a stored link, etc.). Render the link per customer with that customer's order ID in `ref`. You choose the value.
</Note>

### How it comes back

After payment, `ref` is returned inside the `metadata` object appended to your `successUrl`, as `merchantReference`:

```
https://yoursite.com/thank-you?success=true&transactionId=2603130000113B86C&amount=25.00&metadata=%7B%22paymentLinkId%22%3A%22pl_xxx%22%2C%22merchantReference%22%3A%22ORD-12345%22%7D
```

```javascript theme={null}
const params = new URL(location.href).searchParams;
const metadata = JSON.parse(params.get('metadata') || '{}');

metadata.merchantReference; // "ORD-12345"        ← the value you set in ?ref=
metadata.paymentLinkId;     // "pl_xxxxxxxxxxxxxx"
const transactionId = params.get('transactionId');

// Look up your order by merchantReference, then record transactionId against it.
```

See [Handle the Payment Result](/guides/payments/checkout/handle-result) for every success parameter.

### Requirements for `ref`

| Rule                           | Detail                                                                                                                                                                                               |
| :----------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Opaque ID only**             | Use an order ID, cart ID, or similar. **Never** put PII (names, emails) or secrets in `ref` — it is visible in the URL, browser history, and server logs.                                            |
| **Allowed characters**         | Letters, numbers, and `. _ : -` only. URL-encode the value before appending it.                                                                                                                      |
| **Max length**                 | 128 characters.                                                                                                                                                                                      |
| **Invalid values are dropped** | A `ref` with disallowed characters or over 128 characters is ignored — the payment still succeeds, but no `merchantReference` is returned. Validate the value on your side before building the link. |
| **One value per customer**     | Generate the `ref` per checkout so each payment maps to exactly one of your orders.                                                                                                                  |

<Warning>
  The shopper's browser supplies `ref` in the URL, so treat `merchantReference` as a **correlation hint, not a trusted value** — a customer could change it. Always confirm the payment [server-side](/guides/payments/checkout/handle-result#always-verify-before-fulfilling-orders) before fulfilling an order, and reconcile on the `transactionId`.
</Warning>

### Link-level reference (`merchantPayLinkReference`)

When you need the *same* value returned on every payment from a link — for example to attribute payments to a campaign, an invoice batch, or the link itself — set `merchantPayLinkReference` when you **create the link** (see the [request body](#request-body) above):

```bash theme={null}
curl -X POST https://checkout.ozura.com/api/payment-links/create \
  -H "Content-Type: application/json" \
  -H "X-API-KEY: your_vault_api_key" \
  -H "X-OZURA-API-KEY: your_merchant_api_key" \
  -d '{
    "merchantId": "your_merchant_id",
    "merchantName": "My Store",
    "amount": "50.00",
    "successUrl": "https://mystore.com/thank-you",
    "cancelUrl": "https://mystore.com/cancelled",
    "errorUrl": "https://mystore.com/error",
    "merchantPayLinkReference": "CAMPAIGN-Q3"
  }'
```

Every transaction created from that link then returns `merchantPayLinkReference` in the same `metadata` object as `merchantReference` and `paymentLinkId`. It follows the same character/length rules as `ref` (max 128 chars; letters, numbers, `. _ : -`).

`merchantPayLinkReference` and `?ref=` compose — a single payment can return both: the link/campaign it came from, and the specific order that payer was checking out.

### Which reference should I use?

|                             | Set when                          | Same for every payer?         | Returned on                   | Use for                                  |
| :-------------------------- | :-------------------------------- | :---------------------------- | :---------------------------- | :--------------------------------------- |
| Link `metadata`             | At link creation                  | **Yes** — baked into the link | Every txn from the link       | Arbitrary static data (SKU, notes)       |
| `merchantPayLinkReference`  | At link creation                  | **Yes** — one value per link  | Every txn from the link       | Which link/campaign produced the payment |
| `ref` → `merchantReference` | Per click, as you render the link | **No** — unique per customer  | The one txn for that checkout | Per-order / per-customer correlation     |

<Note>
  For **recurring** payment links there is a third reference, `merchantRecurringReference`, which is tied to the subscription plan — set it in `recurringConfig`. It's returned in the success `metadata` alongside the other two, and is also persisted on the plan so you can look the plan up by it. See [Recurring Payments](/guides/payments/checkout/recurring-mode).
</Note>

<Note>
  **Coming soon — server-to-server delivery.** Today `merchantReference` and `merchantPayLinkReference` are returned on the **success redirect** (above). We're rolling out delivery of these references on your **transaction webhook**, plus the ability to look them up directly — so you'll be able to reconcile orders entirely server-side, even if a customer never returns to your `successUrl`. No integration changes will be needed: start setting them now and they will flow through automatically the moment this lands.
</Note>

## One-Time vs Reusable Links

**One-Time Payment Link** (Invoice style):

```json theme={null}
{
  "usageLimit": 1
}
```

**Reusable Link** (Donation/Tip Jar style):

```json theme={null}
{
  "usageLimit": null
}
```

**Limited Uses**:

```json theme={null}
{
  "usageLimit": 100
}
```

## Itemized Product Link

Create a payment link with a rich itemized checkout display:

```json theme={null}
{
  "merchantId": "store_abc123",
  "merchantName": "Fashion Boutique",
  "items": [
    {
      "productId": "JACKET-001",
      "name": "Winter Jacket",
      "price": 149.99,
      "quantity": 1,
      "imageUrl": "https://cdn.example.com/jacket.jpg",
      "originalPrice": 199.99,
      "discountLabel": "25% OFF"
    }
  ],
  "currency": "USD",
  "successUrl": "https://fashionboutique.com/thank-you",
  "cancelUrl": "https://fashionboutique.com/cart",
  "errorUrl": "https://fashionboutique.com/error"
}
```

## Donation Link

```json theme={null}
{
  "merchantId": "charity_abc123",
  "merchantName": "Save The Whales Foundation",
  "successUrl": "https://savethewhales.org/thank-you",
  "cancelUrl": "https://savethewhales.org/donate",
  "errorUrl": "https://savethewhales.org/error",
  "checkoutMode": "donation",
  "donationConfig": {
    "presets": [25, 50, 100, 250],
    "defaultAmount": 50,
    "allowCustomAmount": true
  },
  "expiresInDays": 365,
  "usageLimit": null
}
```

## Check Link Availability

Before directing a customer to a payment link, you can verify it's still valid:

```
GET /api/payment-links/{linkId}/check-availability
```

**Response (Available):**

```json theme={null}
{
  "success": true,
  "available": true,
  "message": "Payment link is available"
}
```

**Response (Limit Reached):**

```json theme={null}
{
  "success": false,
  "available": false,
  "error": "Payment link usage limit reached"
}
```
