API reference

Members and held funds

  • 5 endpoints

Get members#

GET /members

A page of the organization's members in the request's mode, newest first by when they joined in it (default 20, at most 100).

Auth
X-API-Key: an admin key
On-Behalf-Of
Refused: the admin role is needed
Idempotency-Key
Ignored
Success
200
Request

request.sh

curl https://api.qbitflow.app/v2/members \  -H "X-API-Key: $QBITFLOW_API_KEY"# 200: a page of Member ({ items, hasMore, nextCursor? })
const page = await client.members.list({ limit: 20 });for (const member of page.items) {	console.log(`${member.email}: fee ${member.organizationFeePercent} %`);}
page = client.members.list()for member in page.items:    print(member.user_uuid, member.email, f"fee {member.organization_fee_percent}%")
page, err := client.Members.List(ctx, &qbitflow.MemberListParams{Limit: 20})if err != nil {	log.Fatal(err)}for _, m := range page.Items {	fmt.Printf("%s %s %s, fee %s %%, trusted: %v\n", m.UserUUID, m.FirstName, m.Email, m.OrganizationFeePercent, m.TrustedAt != nil)}
foreach ($client->members->iterate() as $member) {	printf("%s %s %s: fee %s %%, %s\n", $member->userUuid, $member->firstName, $member->email,		$member->organizationFeePercent, $member->trustedAt !== null ? 'trusted' : 'funds held');}

Query parameters

  • limitintegerOptional

    Page size: 20 when absent or ≤ 0, at most 100 (a larger one is clamped, not refused)

  • cursorstringOptional

    The previous page's nextCursor, verbatim; omit for the first page

    max=200

Response

A page: { "items": Member[], "hasMore": …, "nextCursor"?: … }. Pass nextCursor back as cursor for the next page; it is absent when hasMore is false.

10 fields of each Member
  • userUuidstring
  • firstNamestring
  • lastNamestring

    Absent when the account has none

  • emailstring
  • testboolean

    The mode

  • organizationFeePercentnumber

    The organization's fee on the member's payments in this mode, in bps. Written as organizationFeePercent ("0": none)

  • trustedAtstringOptional

    When the organization started paying them directly; absent while it holds their funds

  • joinedAtstring

    When they joined in this mode

  • acceptedCurrencyIdsarray of integer

    The currencies (GET /currencies/:id) a checkout of the member can be paid in now: those their wallets accept, always within the organization's (the organization's own while it holds their funds: its wallets receive their payments). Subscriptions take the tokens among them. Empty: a checkout of theirs answers 409 merchant_not_ready. Written as acceptedCurrencies, the currency objects

  • spaceUuidstring

    Their personal space in this mode: what POST /auth/switch-space takes for an owner or admin to act as them

An item of the response

{  "acceptedCurrencies": [    {      "address": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",      "chain": "BASE",      "code": "BASE:USDC",      "decimals": 6,      "id": 8,      "mainCurrencyId": 3,      "name": "USD Coin",      "symbol": "USDC",      "test": false    }  ],  "email": "alice@example.com",  "firstName": "Alice",  "joinedAt": "2026-06-15T09:00:00Z",  "lastName": "Martin",  "organizationFeePercent": "5",  "spaceUuid": "019eca82-5680-7b00-8000-0000000000b2",  "test": false,  "trustedAt": "2026-07-01T09:00:00Z",  "userUuid": "019eca82-5680-7b00-8000-0000000000b1"}
From the data of the member.removed event's example: the same type.

Get member#

GET /members/:userUuid

A member in the request's mode.

Auth
X-API-Key: an admin key
On-Behalf-Of
Refused: the admin role is needed
Idempotency-Key
Ignored
Success
200
Request

request.sh

curl "https://api.qbitflow.app/v2/members/$MEMBER_UUID" \  -H "X-API-Key: $QBITFLOW_API_KEY"# 200: a Member
const member = await client.members.get(memberUuid);console.log(`${member.firstName} ${member.lastName ?? ''} <${member.email}>`);console.log(`fee ${member.organizationFeePercent} %, trusted: ${member.trustedAt ?? 'no'}`);for (const currency of member.acceptedCurrencies) console.log(`  accepts ${currency.code}`);
member = client.members.get(member_uuid)  # their user uuidprint(member.first_name, member.last_name, "trusted:", member.trusted_at is not None)for currency in member.accepted_currencies:  # empty: their checkouts answer 409    print("  accepts", currency.code)
member, err := client.Members.Get(ctx, memberUUID) // their userUuidif err != nil {	log.Fatal(err)}fmt.Printf("%s %s <%s>, fee %s %%, trusted: %v\n",	member.FirstName, member.LastName, member.Email, member.OrganizationFeePercent, member.TrustedAt != nil)for _, c := range member.AcceptedCurrencies {	fmt.Println("  accepts", c.Code)}
$member = $client->members->get($memberUuid); // the member's userUuidecho "{$member->firstName} " . ($member->lastName ?? '') . " <{$member->email}>, joined {$member->joinedAt->format('Y-m-d')}\n";foreach ($member->acceptedCurrencies as $currency) {	echo "  accepts {$currency->code}\n"; // none: their checkouts answer 409 merchant_not_ready}

Path parameters

  • userUuidstringRequired

Response

A Member.

10 fields of Member
  • userUuidstring
  • firstNamestring
  • lastNamestring

    Absent when the account has none

  • emailstring
  • testboolean

    The mode

  • organizationFeePercentnumber

    The organization's fee on the member's payments in this mode, in bps. Written as organizationFeePercent ("0": none)

  • trustedAtstringOptional

    When the organization started paying them directly; absent while it holds their funds

  • joinedAtstring

    When they joined in this mode

  • acceptedCurrencyIdsarray of integer

    The currencies (GET /currencies/:id) a checkout of the member can be paid in now: those their wallets accept, always within the organization's (the organization's own while it holds their funds: its wallets receive their payments). Subscriptions take the tokens among them. Empty: a checkout of theirs answers 409 merchant_not_ready. Written as acceptedCurrencies, the currency objects

  • spaceUuidstring

    Their personal space in this mode: what POST /auth/switch-space takes for an owner or admin to act as them

An example response

{  "acceptedCurrencies": [    {      "address": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",      "chain": "BASE",      "code": "BASE:USDC",      "decimals": 6,      "id": 8,      "mainCurrencyId": 3,      "name": "USD Coin",      "symbol": "USDC",      "test": false    }  ],  "email": "alice@example.com",  "firstName": "Alice",  "joinedAt": "2026-06-15T09:00:00Z",  "lastName": "Martin",  "organizationFeePercent": "5",  "spaceUuid": "019eca82-5680-7b00-8000-0000000000b2",  "test": false,  "trustedAt": "2026-07-01T09:00:00Z",  "userUuid": "019eca82-5680-7b00-8000-0000000000b1"}
From the data of the member.removed event's example: the same type.

Update member#

PATCH /members/:userUuid

Changes a member's organization fee in the request's mode. A checkout already created keeps the fee it was created with.

Auth
X-API-Key: an admin key
On-Behalf-Of
Refused: the admin role is needed
Idempotency-Key
Ignored
Success
200
Request

request.sh

curl -X PATCH "https://api.qbitflow.app/v2/members/$MEMBER_UUID" \  -H "X-API-Key: $QBITFLOW_API_KEY" \  -H "Content-Type: application/json" \  -d '{    "organizationFeePercent": "10"  }'# 200: a Member
// A percent string ('0' to '50'). Applies to their new checkouts: one already created keeps// its fee.const updated = await client.members.update(memberUuid, { organizationFeePercent: '10' });console.log(`fee now ${updated.organizationFeePercent} %`);
# The fee on their new payments, a percent string from "0" to "50" (a checkout already# created keeps its fee).member = client.members.update(member_uuid, organization_fee_percent="10")print(member.organization_fee_percent)
// The organization's commission on their payments, a percent string ("0" to "50"; a// checkout already created keeps its fee).member, err := client.Members.Update(ctx, memberUUID, &qbitflow.UpdateMemberParams{	OrganizationFeePercent: "10",})if err != nil {	log.Fatal(err)}fmt.Println("fee now", member.OrganizationFeePercent, "%")
$member = $client->members->update($memberUuid, new \QBitFlow\Params\UpdateMemberParams(	organizationFeePercent: '10', // a percent string ("0" to "50"); existing checkouts keep their fee));echo "Fee now {$member->organizationFeePercent} %\n";

Path parameters

  • userUuidstringRequired

Body

  • organizationFeePercentnumberRequired

    The organization's fee on the member's payments from now on, 0 to 50 %: a checkout already created keeps its fee, a running subscription's next bills take the new one

    percent=50

Response

A Member.

10 fields of Member
  • userUuidstring
  • firstNamestring
  • lastNamestring

    Absent when the account has none

  • emailstring
  • testboolean

    The mode

  • organizationFeePercentnumber

    The organization's fee on the member's payments in this mode, in bps. Written as organizationFeePercent ("0": none)

  • trustedAtstringOptional

    When the organization started paying them directly; absent while it holds their funds

  • joinedAtstring

    When they joined in this mode

  • acceptedCurrencyIdsarray of integer

    The currencies (GET /currencies/:id) a checkout of the member can be paid in now: those their wallets accept, always within the organization's (the organization's own while it holds their funds: its wallets receive their payments). Subscriptions take the tokens among them. Empty: a checkout of theirs answers 409 merchant_not_ready. Written as acceptedCurrencies, the currency objects

  • spaceUuidstring

    Their personal space in this mode: what POST /auth/switch-space takes for an owner or admin to act as them

An example response

{  "acceptedCurrencies": [    {      "address": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",      "chain": "BASE",      "code": "BASE:USDC",      "decimals": 6,      "id": 8,      "mainCurrencyId": 3,      "name": "USD Coin",      "symbol": "USDC",      "test": false    }  ],  "email": "alice@example.com",  "firstName": "Alice",  "joinedAt": "2026-06-15T09:00:00Z",  "lastName": "Martin",  "organizationFeePercent": "5",  "spaceUuid": "019eca82-5680-7b00-8000-0000000000b2",  "test": false,  "trustedAt": "2026-07-01T09:00:00Z",  "userUuid": "019eca82-5680-7b00-8000-0000000000b1"}
From the data of the member.removed event's example: the same type.

Remove member#

DELETE /members/:userUuid

Removes a member from the request's mode: their sessions (in this mode) and API keys stop working at once, their checkouts stop taking payments, their data stays with the organization. They leave the organization once they have no mode left. Then their subscriptions are cancelled, their products hidden and their webhook endpoints disabled (after the answer). Refused (409 held_funds_pending) while the organization holds their live funds. Answers 204.

Auth
X-API-Key: an admin key
On-Behalf-Of
Refused: the admin role is needed
Idempotency-Key
Ignored
Success
204
Request

request.sh

curl -X DELETE "https://api.qbitflow.app/v2/members/$MEMBER_UUID" \  -H "X-API-Key: $QBITFLOW_API_KEY"# 200: { "message": … }
// Ends their membership: their keys stop working and their checkouts close.try {	await client.members.remove(memberUuid);	console.log('member removed');} catch (err) {	if (!(err instanceof ConflictError && err.code === 'held_funds_pending')) throw err;	console.log('funds are still held for them: release them first');}
try:    client.members.remove(member_uuid)  # their keys stop working, their checkouts close    print("removed")except qbitflow.ConflictError as exc:    if exc.code != "held_funds_pending":        raise    print("release their held funds first")  # from the dashboard
err := client.Members.Remove(ctx, memberUUID)var conflict *qbitflow.ConflictErrorswitch {case errors.As(err, &conflict) && conflict.Code == "held_funds_pending":	fmt.Println("not removed: release the funds held for them first")case err != nil:	log.Fatal(err)default:	fmt.Println("removed: their keys stop working and their checkouts close")}
try {	$client->members->remove($memberUuid); // their keys stop working, their checkouts close	echo "Removed\n";} catch (\QBitFlow\Exceptions\ConflictException $e) {	if ($e->apiCode !== 'held_funds_pending') {		throw $e;	}	echo "You still hold their funds: release them in the dashboard first\n";}

Path parameters

  • userUuidstringRequired

Response

No JSON body: the edge cases below say what it answers.

Errors

  • 409held_funds_pending

    removing a member (DELETE /members/:userUuid, DELETE /team/:userUuid for an admin who kept a personal space), or closing an organization, while the organization holds a member's live funds: release them first (Members and held funds); deleting the organization's live wallet of a chain (DELETE /wallets/:uuid) while it holds members' live funds in that chain's currencies, which their release is paid from (Wallets)

Trust member#

POST /members/:userUuid/trust

Makes a member's payments in the request's mode go to them directly from now on. What the organization already holds for them stays held until released.

Auth
X-API-Key: an admin key
On-Behalf-Of
Refused: the admin role is needed
Idempotency-Key
Ignored
Success
200
Request

request.sh

curl -X POST "https://api.qbitflow.app/v2/members/$MEMBER_UUID/trust" \  -H "X-API-Key: $QBITFLOW_API_KEY"# 200: a Member
// Their new payments go to their own wallets directly (one-way). What is already held stays// held until you release it from the dashboard (heldFunds.released tells you).try {	const trusted = await client.members.trust(memberUuid);	console.log(`trusted since ${trusted.trustedAt}`);} catch (err) {	if (!(err instanceof ConflictError && err.code === 'member_has_no_wallet')) throw err;	console.log('not trusted: their own wallets accept none of your currencies yet');}
# Their new payments go to their own wallets from now on (one-way). What is held stays held# until you release it from the dashboard (heldFunds.released tells you).try:    member = client.members.trust(member_uuid)    print("trusted since", member.trusted_at)except qbitflow.ConflictError as exc:    if exc.code != "member_has_no_wallet":        raise    print("not trusted: their own wallets accept none of your currencies yet")
// Their new payments go to their own wallets from now on (one-way). What is held stays// held until you release it in the dashboard (heldFunds.released tells you).member, err := client.Members.Trust(ctx, memberUUID)var conflict *qbitflow.ConflictErrorswitch {case errors.As(err, &conflict) && conflict.Code == "member_has_no_wallet":	fmt.Println("not trusted: their own wallets accept none of your currencies yet")case err != nil:	log.Fatal(err)case member.TrustedAt != nil:	fmt.Println("trusted since", member.TrustedAt.Format(time.RFC3339))}
// Their new payments go to their own wallets from now on (one-way). What is already held stays// held until you release it from the dashboard (heldFunds.released tells you).try {	$member = $client->members->trust($memberUuid);	echo 'Trusted since ' . ($member->trustedAt?->format(DATE_ATOM) ?? '?') . "\n";} catch (\QBitFlow\Exceptions\ConflictException $e) {	if ($e->apiCode !== 'member_has_no_wallet') {		throw $e;	}	echo "Not trusted: their own wallets accept none of your currencies yet\n";}

Path parameters

  • userUuidstringRequired

Response

A Member.

10 fields of Member
  • userUuidstring
  • firstNamestring
  • lastNamestring

    Absent when the account has none

  • emailstring
  • testboolean

    The mode

  • organizationFeePercentnumber

    The organization's fee on the member's payments in this mode, in bps. Written as organizationFeePercent ("0": none)

  • trustedAtstringOptional

    When the organization started paying them directly; absent while it holds their funds

  • joinedAtstring

    When they joined in this mode

  • acceptedCurrencyIdsarray of integer

    The currencies (GET /currencies/:id) a checkout of the member can be paid in now: those their wallets accept, always within the organization's (the organization's own while it holds their funds: its wallets receive their payments). Subscriptions take the tokens among them. Empty: a checkout of theirs answers 409 merchant_not_ready. Written as acceptedCurrencies, the currency objects

  • spaceUuidstring

    Their personal space in this mode: what POST /auth/switch-space takes for an owner or admin to act as them

An example response

{  "acceptedCurrencies": [    {      "address": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",      "chain": "BASE",      "code": "BASE:USDC",      "decimals": 6,      "id": 8,      "mainCurrencyId": 3,      "name": "USD Coin",      "symbol": "USDC",      "test": false    }  ],  "email": "alice@example.com",  "firstName": "Alice",  "joinedAt": "2026-06-15T09:00:00Z",  "lastName": "Martin",  "organizationFeePercent": "5",  "spaceUuid": "019eca82-5680-7b00-8000-0000000000b2",  "test": false,  "trustedAt": "2026-07-01T09:00:00Z",  "userUuid": "019eca82-5680-7b00-8000-0000000000b1"}
From the data of the member.removed event's example: the same type.

Errors

  • 409member_has_no_wallet

    trusting a member (POST /members/:userUuid/trust) whose own wallets accept none of the organization's currencies: trusted, nobody could pay them (their checkouts would all answer merchant_not_ready), and trust can't be undone. Trust them once they've added one (Members and held funds)

Edge cases

The contract's rules for these routes: Access · Read · Update — PATCH /members/:userUuid · Remove — DELETE /members/:userUuid · The organization fee on held funds · Trust and held funds.

Read all 6

Access

  • Owners and admins in the space (a member, or an organization key acting On-Behalf-Of a member → 403). An organization API key works (SDK). The held-funds routes under /members/…/held-funds are documented in Held funds.
  • :userUuid is the member's user uuid (Member.userUuid; it was the numeric :userId), a member of the request's organization in the request's mode: a user of another organization, an unknown uuid, a removed member, a member of the other mode only, an owner or an admin → 404; a malformed uuid → 400 validation_failed on userUuid. Only exception: the held-funds routes (Held funds) also reach a member removed from this mode, so what was held when they left can still be paid out.

Read

  • GET /members → 200 a page of the mode's members, newest first by when they joined in this mode (joinedAt, then userUuid; limit default 20, at most 100; cursor = the previous page's nextCursor, absent on the last page; a cursor that isn't one → 400 validation_failed on cursor). Never the team.
  • Member: userUuid, firstName, lastName (absent when the account has none), email, test, organizationFeePercent (this mode's, a string, "0" when none), trustedAt (absent while the organization holds their funds), joinedAt (in this mode), acceptedCurrencies (the currency objects a checkout of theirs can be paid in now, [] when none), spaceUuid (their personal space in this mode: an owner or admin acts as them with POST /auth/switch-space { "spaceUuid" }, Account and credential § Sessions). member.joined / member.removed carry the same Member.

Update — PATCH /members/:userUuid

  • organizationFeePercent (required, a string, "0" to "50"; re-authentication) → 200 Member. Per mode: the other mode keeps its own fee. Missing or above 50 → 400 validation_failed on organizationFeePercent.
  • Which payments the new fee applies to (today's rule). A checkout session already created keeps the fee it was created with. A running subscription's next bills take the new fee: a bill reads the member's fee when it is charged (the rate isn't part of what the subscriber signed, only the organization's address is; contracts SPEC §4.1). Exception: a subscription created while the fee was 0 (or without an organization wallet on its chain) never pays one. Nothing tells the member of the change today (no event, no email): tell them yourself. This rule is under review; the CHANGELOG will flag any change.

Remove — DELETE /members/:userUuid

  • Refused with 409 held_funds_pending while the organization holds live funds for the member: release them first (POST /members/:userUuid/held-funds/release/…, Held funds). Nothing changes then. Test-mode funds never block (test money isn't owed): they stay in the removed member's test ledger, which the team can still read and release.
  • Otherwise removes the member from the request's mode (re-authentication) → 204 with no body, answered once the removal is done:
    • Their sessions in this mode and their API keys of this mode stop working at once (401). Signing in lands in the mode they still have. Removed from their last mode, they leave the organization: only their membership ends (soft: kept, with a removal date). Their account stays theirs: signing in with the right password gives a session without an organization (a wrong one 401 invalid_credentials, as ever; Account and credential § Sessions), from which they create their own organization or accept an invitation; an invitation brings them back (their personal space reopens with the new invitation's terms, their data still there).
    • Their checkouts take no more payments, a permanent link or an open session included (410 merchant_closed).
    • Their data stays with the organization; their referral code too.
    • The organization's endpoints receive member.removed once (Webhook events).
  • Then, within moments:
    • their products are hidden;
    • their subscriptions in this mode created before the removal are cancelled on-chain (off-chain for a trial), each with subscription.statusChanged to cancelled;
    • about 10 minutes after the cancellations, their webhook endpoints are disabled (the cancellations' events are sent to them first). It used to leave their subscriptions billing.
  • A member invited back while that cleanup runs stops it: what they kept stays theirs, the subscriptions they create afterwards are never touched. Removed again, it's a new removal (its own member.removed, its own cleanup).
  • A payment already sent when the member was removed may still confirm and be held for them: the team releases it the usual way (Held funds), the member being removed.
  • A seller can't leave on their own: the organization removes them (this route, from the dashboard or with an organization key). Their subscriptions (created once trusted) are cancelled like the others; what they were owed must be released first (the 409 above).

The organization fee on held funds

While the organization holds a member's funds (their trustedAt absent), their payments go to the organization's wallet. The organization's fee (organizationFeePercent) is still taken, without going on-chain:

  • On-chain, the payment pays QBitFlow's fee as usual, and the member's whole share to the organization's wallet, without an organization fee (the contracts refuse a fee paid to the payment's own recipient).
  • The payment records the split a direct payment would have had: settlement.organizationFee (the rate, and the organization's wallet address), settlement.split.organization (the fee, computed as the contracts do: on what remains after QBitFlow's fee, rounded down) and settlement.split.merchant (the member's net). The fee is the organization's like any other: its fee record, GET /metrics and GET /accounting/export count it as earned (it stays in the organization's wallet, where it belongs).
  • The organization owes the member the net (settlement.split.merchant, the line's owed / owedUsd in the member's held funds), and a release pays exactly that (Held funds). A refund of a held payment still pays the customer back their share of everything they paid (Refunds), from the organization's wallet, and the member bears it: what they are owed drops by what the refund sent back (Held funds § Refunds of held payments).
  • The rate is the one the payment would have paid directly (§ Update says which), read when it is paid and recorded with it: a later change of the member's fee never changes what an entry owes.
  • Held members sell one-time payments only. A subscription's receiver is fixed on-chain when it is created, for its whole life: one created while the organization holds the member's funds would pay the organization's wallet forever, the organization forwarding every bill by hand. So a held member's subscription checkout is refused (409 merchant_not_ready, details.reason: "fundsHeld", Checkout sessions), and so is their subscription product's link. Once trusted, they sell subscriptions, paid to their own wallet with the organization's fee taken on-chain. Held funds are only ever payments (and refunds of them).
  • The fee needs an organization wallet on the chain. It is paid to the organization's wallet of the payment's chain, so members sell only where the organization has one: a member accepts only its organization's currencies, and removing the organization's wallet of a chain removes that chain's currencies from every member at once (Wallets; a checkout already open then refuses them at the payer's intent: 409 currency_not_accepted, pick another currency). Behind it, the fee is never silently dropped from a new payment: should a member's payment or subscription still reach a chain without an organization wallet, its intent answers 409 merchant_not_ready (details.reason: "organizationFeeNoWallet"), nothing prepared (a guard, not a flow to expect). A subscription signed before the organization removed that wallet keeps billing, without the organization's fee (its subscriber signed for it; a removed address may no longer be the organization's). Held funds need that wallet anyway: it is the one that receives them.

Trust and held funds

  • POST /members/:userUuid/trust → 200 Member with trustedAt: their new payments in this mode go to their own wallets. What is already held stays held until released. Per mode.
  • Trust is one-way: there is no untrust. It narrows what the member accepts to their own wallets' currencies (within the organization's): the answer's acceptedCurrencies is what their checkouts take from now on.
  • A member whose own wallets accept none of the organization's currencies isn't trusted: 409 member_has_no_wallet, nothing changes (they stay held, their checkouts keep working). Trusted, every checkout of theirs would answer 409 merchant_not_ready (noWallet). Trust them once they've added a wallet (their acceptedCurrencies while held are the organization's, so read their wallets in the dashboard, or retry the trust). Trusting a trusted member answers 200 and changes nothing.
  • QBitFlow emails the member when the trust changes them (not on a repeat): their sales are paid directly to their wallet now, on their terms (the commission and what it is taken on, as the invitation words it), and what the organization still holds for them from before, in USD, paid out separately. Each release confirmed on-chain emails them too: what they received, for how many sales, and whether their next sales are still held. Both are sent in test mode as well, marked "Test mode", in QBitFlow's name, with no setting to turn them off (they are about the member's own money). Nothing to do on your side.
  • From then on they sell subscriptions too (refused while held: § The organization fee on held funds).
  • Reading what is held (GET /members/held-funds, GET /members/:userUuid/held-funds, the member's own GET /held-funds), releasing it (POST /members/:userUuid/held-funds/release/intent, then …/release) and closing it (POST /members/:userUuid/held-funds/close): Held funds.

The codes named here

  • 400validation_failed

    path/query/body failed binding or validation, or a business rule about one input (a field named in errors)

  • 409held_funds_pending

    removing a member (DELETE /members/:userUuid, DELETE /team/:userUuid for an admin who kept a personal space), or closing an organization, while the organization holds a member's live funds: release them first (Members and held funds); deleting the organization's live wallet of a chain (DELETE /wallets/:uuid) while it holds members' live funds in that chain's currencies, which their release is paid from (Wallets)

  • 409member_has_no_wallet

    trusting a member (POST /members/:userUuid/trust) whose own wallets accept none of the organization's currencies: trusted, nobody could pay them (their checkouts would all answer merchant_not_ready), and trust can't be undone. Trust them once they've added one (Members and held funds)

  • 410merchant_closed

    a checkout of a removed member's or a closed organization's space: it takes no payment (Checkout sessions)

  • 409merchant_not_ready

    opening a checkout nobody could pay: the space's wallets (the organization's, while it holds the member's funds) accept no currency, or no token for a subscription; a subscription for a member whose funds the organization holds (fundsHeld: one-time payments only until trusted) (Checkout sessions); at a payer's intent (POST /hosted/payments/intent, POST /hosted/subscriptions/intent), a member's checkout whose organization takes a fee on it and has no wallet on the paid currency's chain anymore (organizationFeeNoWallet: a guard, the fee never dropped from a new payment; removing the organization's wallet of a chain already removes that chain's currencies from its members, so an open checkout meets currency_not_accepted first; a subscription signed before keeps billing without the fee, Members and held funds)