> For clean Markdown of any page, append .md to the page URL. > For a complete documentation index, see https://docs.paymentkit.com/guides/hosted-pages/payment-links/llms.txt. > For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.paymentkit.com/_mcp/server. # Payment links A payment link is a shareable URL backed by a product, price, or package. When a customer opens it, PaymentKit creates a fresh [checkout session](/guides/hosted-pages/checkout-sessions) and sends them to the hosted checkout page. The same link can be reused by any number of customers. Use payment links for one-off charges, subscription sign-ups, or saving a payment method — without writing any checkout integration. # Create a payment link #### Dashboard 1. Go to **Payment Links** in the sidebar 2. Click **Create Payment Link** 3. Choose the mode (one-time payment, subscription, or setup) 4. Add the prices or a package to charge for 5. Optionally set a coupon, success URL, and expiry 6. Click **Create**, then copy the shareable URL #### API ```bash curl -X POST https://app.paymentkit.com/api/{account_id}/payment-links \ -H "Authorization: Bearer sk_live_..." \ -H "Content-Type: application/json" \ -d '{ "name": "Pro plan signup", "mode": "subscription", "line_items": [ { "price_id": "price_abc123", "quantity": 1 } ], "success_url": "https://example.com/welcome", "expires_in_hours": 72 }' ``` The response includes a `url` you can share directly and a `secure_token` used by the public endpoint below. ## Modes | Mode | Use for | Notes | | -------------- | ------------------------------------------ | ------------------------------------------------------------------ | | `payment` | A one-time charge | Prices must be one-time. Default mode. | | `subscription` | Recurring billing | Requires at least one recurring price. Supports `free_trial_days`. | | `setup` | Collecting a payment method with no charge | No line items, coupon, or trial. | ## Request fields | Field | Type | Description | | -------------------------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | | `name` | `string` | Internal label for the link (max 255 chars). | | `mode` | `string` | `payment`, `subscription`, or `setup`. Defaults to `payment`. | | `line_items` | `array` | List of `{ price_id, quantity, description }`. Mutually exclusive with `package_ids`. Required for `payment`/`subscription` unless a package is used. | | `package_ids` | `array` | Package IDs to sell instead of individual prices. Mutually exclusive with `line_items`. | | `customer_id` | `string` | Pre-assign the link to an existing customer. | | `coupon_id` | `string` | Apply a coupon at checkout. | | `free_trial_days` | `integer` | Free trial length, 1–730 days. `subscription` mode only. | | `success_url` | `string` | Where to send the customer after a successful payment. | | `return_url` | `string` | Where to send the customer if they cancel. | | `expires_in_hours` | `integer` | How long the checkout session created from the link stays valid, 1–720 (max 30 days). Defaults to `24`. | | `allow_cart_edit` | `boolean` | Let customers change quantities at checkout. Defaults to `false`. | | `accepted_payment_methods` | `array` | Restrict to specific methods, e.g. `["credit_card", "apple_pay"]`. Omit for all enabled methods. | | `metadata` | `object` | Free-form JSON. | > **Note** > > All line items (or the chosen package) must share a single currency — mixed-currency links are > rejected. Prices and packages must be active. # The payment link object ```json { "id": "pl_live_x7k9m2n4p8q1", "secure_token": "dGhpcyBpcyBhIHRlc3QgdG9rZW4", "url": "https://app.paymentkit.com/api/pay/share/dGhpcyBpcyBhIHRlc3QgdG9rZW4", "name": "Pro plan signup", "mode": "subscription", "is_active": true, "line_items": [ /* ... */ ], "total_amount_atom": 4900, "currency": "USD", "expires_in_hours": 72, "success_url": "https://example.com/welcome", "created_at": "2026-06-17T14:00:00Z", "updated_at": "2026-06-17T14:00:00Z" } ``` | Field | Description | | -------------------------------- | --------------------------------------------------------------------- | | `id` | Payment link identifier, prefixed `pl_`. | | `secure_token` | Opaque token used by the public share endpoint. | | `url` | The full shareable URL. This is what you give customers. | | `is_active` | `false` once the link is deactivated. Inactive links can't be opened. | | `total_amount_atom` / `currency` | Computed cart total in the smallest currency unit, and its currency. | # How customers pay When a customer opens the link, the public share endpoint creates a checkout session and routes them to the hosted checkout: ``` GET /api/pay/share/{secure_token} ``` This endpoint is **public** — no API key required — and is rate-limited to 10 requests per minute per IP. * **Browsers** (HTML requests) are redirected straight to the hosted checkout page. * **API clients** (JSON requests) receive the session details to redirect themselves: ```json { "checkout_session_id": "cs_live_x7k9m2n4p8q1", "checkout_url": "https://app.paymentkit.com/checkout/tok_abc123" } ``` Each open creates a **new** checkout session, so a single link serves many customers. After payment the customer is sent to `success_url`; if they cancel, to `return_url`. # Manage payment links | Method | Path | Purpose | | -------- | -------------------------------------- | ---------------------------------------------------------------- | | `GET` | `/api/{account_id}/payment-links` | List payment links (paginated, filterable). | | `GET` | `/api/{account_id}/payment-links/{id}` | Retrieve a single link. | | `PATCH` | `/api/{account_id}/payment-links/{id}` | Update name, coupon, URLs, accepted methods, or set `is_active`. | | `DELETE` | `/api/{account_id}/payment-links/{id}` | Deactivate the link (soft delete; `is_active` becomes `false`). | > **Warning** > > Deactivating a link is permanent in effect for shared URLs — once `is_active` is `false`, opening > the link returns a generic error and no checkout session is created. Existing checkout sessions > already created from the link are unaffected. > Share a URL that opens a hosted checkout — no integration code required.