Skip to content

Payment Links

A payment link lets you create a shareable URL for a single payment request without building Card Handoff integration. The buyer opens this URL in their own browser, picks an installment count (if offered), and completes the payment themselves; your checkout does not collect the card. It is an alternative to the POST /v1/payments + handoff flow, useful when you want to avoid the card surface entirely (for example, sharing an order by phone or message).

POST /v1/payment-links
Authorization: Bearer ptk_live_…
Content-Type: application/json
{
"amount": 125050,
"terminalId": "trm_3Kd9x",
"customerCommissionShareBps": 0,
"description": "Order #8841",
"redirectUrl": "https://yourstore.example/payment"
}
Field Required Description
amount Yes The base amount you are requesting, integer in minor units (kuruş) (1,250.50 TRY → 125050). See Amounts and Currency.
terminalId Yes The terminal the payment is routed to. Must belong to you and be active; otherwise terminal_not_allowed is returned.
customerCommissionShareBps No The share of the commission passed on to the buyer, integer basis points (0-10000; 2.5% → 250). Defaults to 0 (you absorb the entire commission).
description No Link description.
redirectUrl No The base address the buyer is redirected to after the payment is settled; validated at creation time (see redirectUrl behavior).
allowedInstallmentCounts No The list of installment counts accepted for this link. If omitted (or null), there is no restriction and your terminal’s effective installment set (Installment Options) applies. If you supply it, the list cannot be empty and must be a subset of your terminal’s effective installment set; otherwise the request is rejected with 422 installment_not_allowed. This restriction cannot be changed once the link is created.

201 Created:

{
"id": "01J9K5QATN6M1PXG7VYSD3HZWB",
"token": "plk_EXAMPLE0000000000…",
"url": "https://pay.lydiagate.example/link/plk_EXAMPLE0000000000…",
"partnerReference": 42,
"status": "pending",
"amount": 125050,
"customerCommissionShareBps": 0,
"description": "Order #8841",
"redirectUrl": "https://yourstore.example/payment",
"firstOpenedAt": null,
"lastOpenedAt": null,
"expiresAt": "2026-06-21T12:00:00Z",
"createdAt": "2026-06-14T12:00:00Z",
"updatedAt": "2026-06-14T12:00:00Z",
"allowedInstallmentCounts": null
}
Field Description
id The link’s permanent identifier; used in the single-item query, cancel calls, and the paymentLinkId field in the webhook body.
token The secret component of url. You do not need to store it separately; url already contains it.
url The full address you share with the buyer.
partnerReference An increasing sequence number scoped to your account (for display/reference only).
status The link’s current status. See Lifecycle.
amount The base amount you requested (kuruş).
firstOpenedAt / lastOpenedAt The instant the buyer first/last opened the link; null if not opened yet.
expiresAt The link’s expiry instant. See Window (TTL).
createdAt / updatedAt Timestamps (UTC).
allowedInstallmentCounts The installment restriction you sent in the request, sorted ascending; null if there is no restriction.
Status Meaning
pending The link was created; the buyer has not opened it yet.
launched The buyer opened the link.
initiated A payment attempt is in 3D Secure; in flight. No new attempt can be started while in this status. If the attempt fails without completing, the link becomes payable again.
completed The payment was completed (terminal — no further transition).
expired The window (TTL) elapsed; the link became invalid unpaid (terminal).
failed A payment attempt failed; not terminal — the link can be paid again.
cancelled You cancelled it (terminal).

A link’s default validity window is 7 days from creation. Once expiresAt has passed, the link moves to expired and can no longer be paid.

GET /v1/payment-links?status=pending&status=launched&page=0&size=20
Authorization: Bearer ptk_live_…
Parameter Description
status Filter by one or more statuses; repeat the parameter (status=pending&status=launched).
minAmount / maxAmount Amount range (kuruş).
createdFrom / createdTo Creation time range (UTC, ISO 8601).
page / size Pagination; page starts at 0, size defaults to 20.

Response (200 OK):

{
"items": [
{
"id": "01J9K5QATN6M1PXG7VYSD3HZWB",
"token": "plk_EXAMPLE0000000000…",
"url": "https://pay.lydiagate.example/link/plk_EXAMPLE0000000000…",
"partnerReference": 42,
"status": "pending",
"amount": 125050,
"customerCommissionShareBps": 0,
"description": "Order #8841",
"redirectUrl": "https://yourstore.example/payment",
"firstOpenedAt": null,
"lastOpenedAt": null,
"expiresAt": "2026-06-21T12:00:00Z",
"createdAt": "2026-06-14T12:00:00Z",
"updatedAt": "2026-06-14T12:00:00Z",
"allowedInstallmentCounts": null
}
],
"page": 0,
"size": 20,
"hasMore": false
}
Field Description
items The links on this page; each item carries the same fields as the creation response.
hasMore true when the number of returned items equals size. Increment page for the next page.
GET /v1/payment-links/{id}
Authorization: Bearer ptk_live_…

{id} is the id field from the creation or listing response (not token).

DELETE /v1/payment-links/{id}
Authorization: Bearer ptk_live_…

Only links in a non-terminal status (pending / launched / initiated / failed) can be cancelled; a successful call moves the link to cancelled and returns the updated link record. Trying to cancel a link that has already completed, expired, or was already cancelled fails (see below).

If you supply a redirectUrl, Lydia Gate validates it at link creation time:

  • The address must be an absolute URL with the http or https scheme; otherwise the request is rejected with 400 validation_error.
  • If your account has an allowed host list configured, the redirectUrl host must appear on that list; a host that is not on the list is rejected the same way, with 400 validation_error. If no such list is configured, only the scheme is checked. This is the same open-redirect protection as the returnUrl validation on POST /v1/payments.

Once redirectUrl passes validation, after the buyer sees the payment result, they are redirected to:

  • On a completed payment{redirectUrl}/payment/success,
  • On a failed attempt{redirectUrl}/payment/failure.

If you do not send a redirectUrl, the buyer sees the result on a Lydia Gate-hosted page.

Code HTTP Reason
payment_link_not_found 404 The link was not found or does not belong to this partner.
payment_link_already_paid 409 The link is already completed. (Rarely, the same error is returned if your cancellation races with a payment completing at that exact moment.)
payment_link_expired 409 The link’s window has expired; it can no longer be cancelled.
payment_link_cancelled 409 The link was already cancelled.
installment_not_allowed 422 allowedInstallmentCounts was sent empty, or is not a subset of your terminal’s effective installment set.

Full list: Error Codes.

When a link completes or expires, Lydia Gate sends you a webhook (payment_link.completed / payment_link.expired); the body carries this page’s id field (named paymentLinkId) instead of paymentCode. Detail and a sample body: Webhooks.