Create a payment link
Creates a new transaction and returns a payment checkout URL for the
payer. Requires a unique X-Idempotency-Key header: resubmitting the
same key with an identical payload returns the original transaction
(never double-charges or double-creates); resubmitting the same key with
a different payload returns 409, as does a concurrent request still
in flight with the same key.
The payment subject (user_id or business_customer_id, exactly one)
must already exist; its KYC/KYB status does not gate payment link
generation. The project's Opco must be ACTIVATED and have a Sub-TPP ID on
file.
Response can be 200 or 202. Normally returns 200 with the transaction
in PENDING status and a checkout_url. If the outcome of initiating the
payment was uncertain (for example a network timeout — the payment may
or may not have actually been accepted), returns 202 Accepted
instead, with reconciliation_state: AWAITING_PROVIDER_CONFIRMATION and
checkout_url possibly null. Treat 202 as "submitted, outcome pending",
not as a failure — poll Get Transaction or wait for a status webhook
rather than retrying.
Errors:
- 400:
X-Idempotency-Keyis empty; no callback URL is configured (set
one in the dashboard or passcallback_url) or it isn't HTTPS; the
project's Opco is not ACTIVATED or has no Sub-TPP ID on file - 403: payment links are disabled for this account; the project is frozen
- 404: the user/business customer, project, or its Opco was not found
- 409: idempotency key reused with a different payload, or still
processing; the linkedcontract_request_idalready has an active
payment transaction - 500: payment initiation failed unexpectedly; the transaction is
recorded asFAILED. Retrying with the same idempotency key
returns this same failed transaction again (the payment is not
reattempted) — use a new idempotency key to try again.
| Time | Status | User Agent | |
|---|---|---|---|
Retrieving recent requests… | |||
Generate a checkout payment link for a transaction. The endpoint validates the input, creates a new transaction record with status pending, mints a checkout session, and returns the transaction together with the hosted checkout_url the payer uses to complete the payment.
Authentication & access
- Requires a client API token:
Authorization: Bearer <token>. - The caller must hold the
checkout.paylink.createpermission and have the OWNER or OPERATIONS role. - The client must have payment links enabled. If the feature is disabled the request returns
403.
Payment subject
Each payment is initiated for exactly one subject — provide either user_id (an individual customer) or business_customer_id (a KYB-verified company). Providing both, or neither, is rejected (422).
The subject must already exist under your client, and must be looked up with GET /kyc/users / GET /kyb/businesses beforehand if you don't already have its ID. Verification status is not checked here — a payment link can be generated for a subject whose kyc_status/kyb_status (or external_verification_status) is none, pending, rejected, or on_hold, exactly as for an approved/verified one. If your compliance policy requires a verified subject before you take payment, enforce that in your own application before calling this endpoint.
Project & operating company preconditions
project_idmust reference a project owned by your client and not frozen by an administrator.- The project's operating company (Opco) must be in
ACTIVATEDstatus and have a valid Sub-TPP ID. Otherwise the request returns400.
Amount & currency
amountmust be greater than0, at least0.01, and use at most 2 decimal places.currencyisEURonly for now.
Email notification
send_payer_email (optional boolean, default true) — when true, a payment-link invitation email is sent to the payer after the link is created. Set to false if you handle notifying the payer yourself.
Idempotency
X-Idempotency-Key (header, required) prevents duplicate payment links on retries.
- To retry, send the same key with an identical payload — you receive the original transaction instead of a new one.
- Reusing the same key with a different payload returns
409. - A genuinely new payment must use a new key.
- An empty key returns
400.
Callback URL
callback_url (optional, HTTPS only) is where the payer is redirected after completing or canceling the payment. When omitted, it falls back to your client's default callback URL; if neither is set, or the URL isn't HTTPS, the request is rejected (400).
UrbanPay appends transaction_id to whichever URL is used, keeping any query string you already put on it, so https://shop.example.com/done?order=42 becomes https://shop.example.com/done?order=42&transaction_id=8f14e45f-ceea-467a-9f9c-2ba1d9b8f73e. If your URL already carries a transaction_id of your own, it is left exactly as you set it and nothing is appended.
The redirect can carry further parameters, some added by UrbanPay and some by the payer's bank. transaction_id is the only one worth reading. A status among them is a hint and never proof: it is written before settlement is confirmed, so it is often stale, and a query string can be edited by anyone. Read the real state with Get Transaction or from the payment.status_changed webhook.
Responses
200— Link created.checkout_urlholds the hosted checkout URL andstatusispending.202— The checkout session result is uncertain (timeout or transport error). The transaction is persisted aspendingwithreconciliation_state = awaiting_provider_confirmationand is reconciled later via webhook. Do not retry with a new key — poll the transaction or wait for the webhook.
Error responses
| Status | When |
|---|---|
400 | Empty X-Idempotency-Key; no callback URL configured and none provided, or it isn't HTTPS; Opco not ACTIVATED; Opco missing a valid Sub-TPP ID |
403 | Payment links disabled for the client; project is frozen |
404 | User, business customer, project, or Opco not found under this client |
409 | Same idempotency key is still being processed, or was reused with a different payload |
422 | Request body failed validation (e.g. both/neither subject id, bad amount, non-EUR currency) |
500 | Payment initiation failed before the transaction was created |