Skip to content

Pay the live balance with a card the guest presents

POST
/b/{token}/pay
curl --request POST \
--url https://quikstik-core.fly.dev/b/example/pay \
--header 'Content-Type: application/json' \
--data '{ "provider": "example", "instrument_token": "example" }'

Token-based auth. Customer-present only — no auto-charge, no vault use. The body names the processor and a freshly tokenized instrument and NEVER an amount: the charge is the obligation’s live balance, re-read here (not the one rendered) and derived server-side by the rail. Its idempotency key is bound to (link, balance): a double-submit replays the same movement, and a balance that changed since the page was rendered is charged fresh at the new amount, never the old. On success the capture is recorded through the standard capture path (a real ledger posting, not an out-of-band charge), the obligation is settled, the link is marked paid with the rail’s reference, and a receipt is sent.

A second submit on a paid link is 200 with already_paid: true and the original reference; no second charge.

token
required
string
Media typeapplication/json
object
provider
required

Opaque processor selector, as /p/{token}/pay.

string
instrument_token
required

Processor-tokenized payment instrument. Never a PAN.

string

Example generated

{
"provider": "example",
"instrument_token": "example"
}

Paid now (or already paid by an earlier submit).

Media typeapplication/json
object
processor_ref
required

Opaque rail-issued reference.

string
amount_minor

Null on a replay.

integer
nullable
currency
string
already_paid
required
boolean

Example generated

{
"processor_ref": "example",
"amount_minor": 1,
"currency": "example",
"already_paid": true
}

Card_declined, authentication_required, or processor_not_configured. Nothing charged.

Media typeapplication/json
object
reason
required
string
Allowed values: card_declined authentication_required processor_not_configured
message
required
string

Example

{
"reason": "card_declined"
}

Invalid_or_expired_token.

Link_expired, link_cancelled or link_paid. Nothing charged.

Unknown_provider. Nothing charged.

Balance_link_unavailable; safe to retry under the same link.