Customer Payouts
Send money from your Luxury Fintech balance to your own customers ā refunds, goodwill payments, settling a dispute. You create the payout; the recipient chooses how and where to receive it, in their own browser.
You never handle a receiving address, and you never see one.
š Base URLā
| Environment | Host |
|---|---|
| Production | https://luxfin.org |
| Sandbox | https://sandbox.luxfintech.org |
ā Before you startā
Three things must be true before any payout can be created. Each is checked on every request, not once at onboarding.
| Requirement | How it is set |
|---|---|
| Your account is approved for payouts | Luxury Fintech operations |
| Payouts are switched on for your account | Your administrator, in the dashboard |
You hold an API credential with payouts:write | Your administrator, in the dashboard |
A webhook is not a requirement ā it is optional, and only announces payouts that have been paid.
A payout is not a draft. The amount plus the fee leaves your available balance the moment the create call returns, and comes back only if the payout is cancelled or expires unclaimed.
š Authenticationā
Every call carries a Bearer credential:
Authorization: Bearer pok_a1b2c3d4e5f6a7b8.xK9ā¦
- The credential is shown once, when it is issued. We store only a verifier, so a lost key is replaced, never recovered.
- Two scopes:
payouts:readandpayouts:write. Give an integration that only checks status a read-only credential. - Revoking takes effect immediately, on the next request.
- Credentials are per account. A credential belonging to one account can never act for another.
- Credentials are per environment. A sandbox credential is refused on production,
and the reverse, with
wrong_environment(403).
Payout credentials are separate from your checkout API key. Using the wrong kind
of credential returns wrong_credential_kind (403).
šØ Two delivery modesā
link | redirect | |
|---|---|---|
| Who the recipient is | An email address you supply | A customer you have just authenticated |
| How they get in | A claim link you send them | A one-time handoff you redirect them to |
| Email verification | A code sent to that fixed address | Not needed ā you already authenticated them |
| Access link lifetime | Until the payout expires | 10 minutes, single use ā request a fresh one |
| Payout expires if unclaimed | 7 days after creation | 24 hours after creation |
| Required fields | customer_email | customer_id, return_url |
return_url must exactly match an origin registered for your account ā scheme,
host and port, no wildcards.
link modeā
- Create the payout with
delivery: "link"andcustomer_email. - Store the returned
payout_urlā it is returned once. - Send the link to your customer yourself. We do not email it.
- The recipient opens the link and verifies the email address you supplied (we email them a code), then chooses how to receive the money. A link that reaches the wrong person is not enough to claim it.
If the link is lost, fetch it again with Get or rotate claim link. If it went to the wrong person, rotate it.
redirect modeā
- Authenticate your customer on your own site.
- Create the payout with
delivery: "redirect",customer_idandreturn_url. - Redirect the customer's browser to the returned
payout_urlwithin 10 minutes. - If the handoff expires, request a fresh one with Create redirect session.
The browser returning to your return_url proves nothing. Always confirm the
outcome by polling the payout, or
with a webhook ā which is sent only when a payout is paid.
š A complete flowā
# 1. Check what you can commit, and the current fee
curl -s https://luxfin.org/api/payout/balance \
-H "Authorization: Bearer $PAYOUT_KEY"
# 2. Create the payout (money is reserved here)
KEY=$(uuidgen)
curl -s -X POST https://luxfin.org/api/payout/create \
-H "Authorization: Bearer $PAYOUT_KEY" \
-H "Idempotency-Key: $KEY" \
-H "Content-Type: application/json" \
-d '{"amount":"25.00","merchant_reference":"refund-ORD-10231",
"delivery":"link","customer_email":"person@example.com"}'
# 3. Send the payout_url to your customer.
# 4. Follow it: poll (or receive the webhook, sent only when it is paid)
curl -s https://luxfin.org/api/payout/po_9f3c1d7b2a8e4c15d0b6a291 \
-H "Authorization: Bearer $PAYOUT_KEY"
# 5. Changed your mind, before they confirm
curl -s -X POST https://luxfin.org/api/payout/po_9f3cā¦/cancel \
-H "Authorization: Bearer $PAYOUT_KEY" \
-H "Idempotency-Key: $(uuidgen)"
A payout that nobody claims expires on its own and the money returns to your balance. You never have to clean up.
After the recipient confirms, the payout is normally sent within minutes. If it
shows processing with safe_reason: "awaiting_float", it is queued on our side
and will be sent automatically ā the money stays reserved and there is nothing to
do.