# Payment links

A payment link is one reusable public checkout page, opened by many customers, who each pick their own coin: a product sold again and again, a tip jar, a link on your site. Create it once and share it. To charge one customer, create a charge instead: do not make a new link per customer or per order.

[Not sure a link is what you need? See which one to use](https://velirapay.com/docs/charge-a-customer)

## The payment link object

| Field | Type | Description |
| --- | --- | --- |
| `id` | string | Public code, also the last path segment of the checkout URL. |
| `object` | "payment_link" | The kind of object. |
| `title` | string | Shown to the customer. Up to 255 characters. |
| `description` | string\|null | Optional, shown under the title. Up to 2,000 characters. |
| `pricing_type` | "fixed" \| "open" | Fixed price, or the customer types the amount. |
| `amount` | string\|null | Decimal string with two places when fixed (0.01 or more), null when open. |
| `suggested_amounts` | array | Up to four one-click amounts offered on an open-amount checkout, each within min_amount and max_amount; the customer can still type another. They come back as you sent them, numbers or strings. Always empty for fixed pricing. Creating a link also accepts them as one string, such as "5, 10, 25". |
| `currency` | string | USD, EUR, GBP, CAD, AUD, CHF, TRY |
| `status` | "active" \| "archived" | Archived links return 404 to customers. |
| `success_url` | string\|null | Once the customer has paid, the checkout shows a button back to it; there is no automatic redirect. An https:// address on a public website, up to 2,048 characters. |
| `accepted_assets` | array\|null | The coins the checkout offers, for example ["BTC", "ETH"]: at least one, each a coin the platform takes in this mode. A coin you have no payout address for is accepted here but only offered once you add one. null offers every coin the account can receive, including ones added later. |
| `min_amount, max_amount` | string\|null | For open pricing: the least and the most the customer may enter, 0.01 or more, the maximum no lower than the minimum. null for no limit, and always null on fixed pricing. |
| `cancel_url` | string\|null | Adds a "cancel and return" link to the checkout. An https:// address on a public website, up to 2,048 characters. |
| `collect_name, require_email` | boolean | Ask for the customer name, and make the email mandatory, on the hosted checkout. |
| `expires_at, max_payments` | string\|null, integer\|null | Close the link after a date or a number of paid charges (1 to 1,000,000). expires_at is ISO 8601 and has to lie in the future; a bare date such as 2026-12-31 means 23:59:59 UTC that day. |
| `accepting_payments` | boolean | Whether the link takes payments right now: active, not past expires_at and short of max_payments. |
| `views_count` | integer | How many visitors opened the checkout page, counted once per browser session. |
| `custom_fields` | array | Up to five extra questions the hosted checkout asks: label (up to 60 characters, no two alike) and required. Questions without a label are dropped. The answers, up to 255 characters each, come back on the charge. |
| `success_message` | string\|null | Up to 1,000 characters, shown to the customer after payment and included in the receipt email. |
| `checkout_url` | string | The hosted page to share. |
| `created_at, updated_at` | string | ISO 8601 timestamps in UTC. |

collect_name, require_email and the required custom_fields are asked for on the hosted checkout only. A charge you create through the link with POST /v1/charges skips them, and takes the answers you have under customer and custom_fields.

## Endpoints

- GET `/v1/payment-links` List links, newest first, to find one to share again. Filter with ?status= and ?search= (the title). Paginated with ?page= and ?per_page= (max 100).
- POST `/v1/payment-links` Create a link. Body: title, description, pricing_type, amount, suggested_amounts, currency, accepted_assets, min_amount, max_amount, success_url, cancel_url, collect_name, require_email, custom_fields, success_message, expires_at, max_payments. title, pricing_type and currency are required, and amount too for fixed pricing.
- GET `/v1/payment-links/{id}` Retrieve a link.
- PATCH `/v1/payment-links/{id}` Update any subset of the same fields. Switching to fixed pricing requires an amount, and switching to open clears it. custom_fields replaces the whole list. Suggested amounts are not checked against min_amount and max_amount here; any outside them are left off the checkout and the response.
- POST `/v1/payment-links/{id}/archive` Stop accepting payments.
- DELETE `/v1/payment-links/{id}/archive` Restore an archived link.

## Example: create a link

```bash
curl -X POST 'https://api.velirapay.com/v1/payment-links' \
  --fail-with-body --silent --show-error --max-time 30 \
  -H "Authorization: Bearer ${VELIRAPAY_API_KEY:?Set VELIRAPAY_API_KEY}" \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
    "title": "Consulting hour",
    "pricing_type": "fixed",
    "amount": "150.00",
    "currency": "USD",
    "success_url": "https://example.com/thanks"
  }'
```

**Response: 201 Created**

```json
{
  "data": {
    "id": "6dprcllogj1a",
    "object": "payment_link",
    "title": "Consulting hour",
    "pricing_type": "fixed",
    "amount": "150.00",
    "currency": "USD",
    "status": "active",
    "accepting_payments": true,
    "checkout_url": "https://velirapay.com/pay/6dprcllogj1a",
    …
  }
}
```

## Filling in what you already know

Add email and name to the checkout URL to fill those fields in for a customer who is signed in on your site; they can still change them. The name is only used when the link asks for one, and an email that is not valid is ignored. The values travel in the URL, so they end up in browser history. To charge one customer with their details already on the payment, create a charge instead.

**Checkout link**

```
https://velirapay.com/pay/6dprcllogj1a?email=jane%40example.com&name=Jane%20Doe
```

Add coupon to apply one of your coupons for the customer, for example ?coupon=SPRING10. [See coupons](https://velirapay.com/docs/coupons)
