Skip to main content
POST
Error

Authorizations

Authorization
string
header
required

A staff session token, uk_st_…. Minted by sign-up, sign-in or the two-factor exchange. Only a 401 means it is spent; not_a_member (403) is about the organization named in X-Organization-Id and leaves the token good for the others.

Headers

X-Organization-Id
string

The organization the caller is acting on — the org_… code that appears in the panel URL. It identifies; the membership JOIN is what authorizes, so a forged code reads nothing: the answer is not_a_member (403), which does not mean the session is over. Absent, the session's default organization answers, or — if that membership was revoked while the session was open — any other one the caller still holds.

Idempotency-Key
string

Forwarded to the payment gateway as its idempotency key, so a retry of this call does not charge twice or move a subscription twice.

This is not the guarantee Idempotency-Key carries on the API-key surface: nothing is stored here and a replay is not answered with the original response. It is passed through, and what it buys is whatever the gateway does with it — for Stripe, the original result is replayed for 24 hours.

Send a fresh key per act you mean to perform, and the same key with the same body when you are retrying one. The gateway compares the parameters, so a key reused for a different act is refused there rather than replayed.

Maximum string length: 255

Path Parameters

id
string<uuid>
required

The invoice's id in this system — not the gateway's reference.

Query Parameters

environment
enum<string>
default:live

Which environment to act in. A view parameter, valid only on the staff surface — a machine credential never chooses its environment, it is resolved from the key.

Available options:
live,
test

Body

application/json
reason
string
required

Why, in your own words. Required: the line outlives the conversation that produced it, and a refund nobody can explain is one nobody dares repeat or account for. Recorded at the gateway as metadata, never mapped onto its own reason vocabulary — those carry consequences (Stripe's fraudulent marks the payment in its dispute tooling) that a support note must not trigger by wording.

amount_minor
integer<int64>

How much to hand back, in the payment's minor units. Omit it — or send 0 — for everything that remains, which is the commonest act and the one nobody should have to type a number for.

Required range: x >= 0

Response

The refund, as the gateway made it.

One refund, as the gateway made it.

invoice_id
string<uuid>
environment
enum<string>
Available options:
live,
test
refund_ref
string

The gateway's id for the refund itself.

charge_ref
string

The payment the money came out of.

currency
string
Example:

"BRL"

amount_minor
integer<int64>

What this refund handed back. Stated by the gateway rather than echoed from the request, which is the difference that matters when the amount was omitted.

refunded_minor
integer<int64>

What the payment has handed back in total, re-read after the act. 0 when that re-read did not get through — the refund still happened, and see remaining_minor.

remaining_minor
integer<int64> | null

What is still refundable afterwards, or null when the gateway could not be re-read. Null rather than a computed guess on purpose: a screen rendering "nothing left" over a payment nobody re-read is the reassurance that stops the next person checking.