Generate Payment Link

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-Key is empty; no callback URL is configured (set
    one in the dashboard or pass callback_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 linked contract_request_id already has an active
    payment transaction
  • 500: payment initiation failed unexpectedly; the transaction is
    recorded as FAILED. 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.
Recent Requests
Log in to see full request history
TimeStatusUser Agent
Retrieving recent requests…
LoadingLoading…

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.create permission 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_id must reference a project owned by your client and not frozen by an administrator.
  • The project's operating company (Opco) must be in ACTIVATED status and have a valid Sub-TPP ID. Otherwise the request returns 400.

Amount & currency

  • amount must be greater than 0, at least 0.01, and use at most 2 decimal places.
  • currency is EUR only 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_url holds the hosted checkout URL and status is pending.
  • 202 — The checkout session result is uncertain (timeout or transport error). The transaction is persisted as pending with reconciliation_state = awaiting_provider_confirmation and is reconciled later via webhook. Do not retry with a new key — poll the transaction or wait for the webhook.

Error responses

StatusWhen
400Empty 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
403Payment links disabled for the client; project is frozen
404User, business customer, project, or Opco not found under this client
409Same idempotency key is still being processed, or was reused with a different payload
422Request body failed validation (e.g. both/neither subject id, bad amount, non-EUR currency)
500Payment initiation failed before the transaction was created
Body Params
required

The amount of the transaction

string
required
length between 3 and 3

The currency of the transaction (EUR only for now)

The user id (individual customer). Mutually exclusive with business_customer_id.

The business customer id. Mutually exclusive with user_id.

string
required

The ID of the project associated with the transaction

string
required

The description of the transaction

Optional secondary remittance information attached to the bank transfer

Optional contract request to bind to this payment transaction

Optional hard deadline after which the link will no longer mint new sessions

Optional HTTPS return URL the payer is redirected to after completing or canceling this payment. Falls back to the client's default callback URL when omitted. UrbanPay appends transaction_id to whatever URL is used, preserving any query string already on it; read the authoritative status from GET /transactions/{transaction_id}, never from the query string on the return URL.

boolean
Defaults to true

When true, UrbanPay sends a payment-link invitation email to the payer after the link is created.

Headers
string
required
Responses

Language
LoadingLoading…
Response
Click Try It! to start a request and see the response here! Or choose an example:
application/json