Skip to content

Mint a single-use link that collects an obligation's live balance

POST
/obligations/{obligation_ref}/balance-links
curl --request POST \
--url https://quikstik-core.fly.dev/obligations/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/balance-links \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'x-idempotency-key: example' \
--data '{ "expires_in_hours": 1, "reason": "example" }'

Session bearer ONLY — writes are never operator-key. Requires x-idempotency-key. Replaces the hand-cut processor-dashboard payment link: the returned url is a core-issued /b/{token} page on which the guest, present with a card, pays exactly the obligation’s LIVE balance (read at render and again at pay; the link stores no amount). The token is stored only as its SHA-256; the plaintext is returned once, here, inside url.

Minting again for the same obligation cancels the previous open link in the same transaction (a commerce.balance_link.cancelled event with superseded: true), so a guest never holds two live links. Repeating the same x-idempotency-key is 200 with the stored link and url: null — the plaintext is not recoverable.

Refuses 409 nothing_owed when the balance is zero and 409 obligation_not_open when the booking behind the obligation is cancelled or refunded. No money moves at mint.

obligation_ref
required
string format: uuid
x-idempotency-key
required
string
Media typeapplication/json
object
expires_in_hours

Lifetime in hours; defaults to (and is capped at) 14 days.

integer
>= 1 <= 336
reason
string
<= 500 characters

Example generated

{
"expires_in_hours": 1,
"reason": "example"
}

Replay of an earlier mint with the same idempotency key; url is null.

Media typeapplication/json
object
link_id
required
string format: uuid
obligation_ref
required
string format: uuid
url
required

The canonical /b/{token} page URL, carrying the one-time plaintext token. Null on a replay of the same idempotency key — only the token’s hash is stored.

string
nullable
expires_at
required
string format: date-time
status

Present on a replay only.

string
Allowed values: open paid cancelled expired
already_minted

Present (true) on a replay only.

boolean

Example

{
"status": "open"
}

Link minted. url carries the one-time token.

Media typeapplication/json
object
link_id
required
string format: uuid
obligation_ref
required
string format: uuid
url
required

The canonical /b/{token} page URL, carrying the one-time plaintext token. Null on a replay of the same idempotency key — only the token’s hash is stored.

string
nullable
expires_at
required
string format: date-time
status

Present on a replay only.

string
Allowed values: open paid cancelled expired
already_minted

Present (true) on a replay only.

boolean

Example

{
"status": "open"
}

Idempotency_key_required.

Missing/invalid session, or an operator key (not accepted here).

No membership in the tenant.

Obligation_not_found (unknown, or another tenant’s).

Nothing_owed, obligation_not_open, or idempotency_key_reused.

Media typeapplication/json
object
reason
required
string
Allowed values: nothing_owed obligation_not_open idempotency_key_reused

Example

{
"reason": "nothing_owed"
}

Invalid_obligation_ref, expires_in_hours_invalid, expires_in_hours_too_long, or reason_too_long.

Backend unavailable; the transaction rolled back, safe to retry.