API reference

Payments and transactions

  • 4 endpoints

Payments are created only by completing an on-chain checkout (a checkout session, Checkout sessions): there is no POST creating one directly.

List payments#

GET /payments

Lists the one-time payments of the request's space (with includeMembers, of the organization and its members; with userUuid, of one member), newest first (createdAt, then uuid). With reference, the payment with this reference: 0 or 1 item (one per space read).

Auth
X-API-Key: any key
On-Behalf-Of
Honored: acts in the member's space
Idempotency-Key
Ignored
Success
200
Request

request.sh

curl https://api.qbitflow.app/v2/payments \  -H "X-API-Key: $QBITFLOW_API_KEY"# 200: a page of Payment ({ items, hasMore, nextCursor? })
const page = await client.payments.list({	createdAfter: new Date(Date.now() - 30 * 24 * 3600 * 1000), // the last 30 days	limit: 10,});for (const payment of page.items) {	// Amounts are decimal strings: the token's (amount, in currency) and USD (amountUsd).	const { uuid, reference, amount, currency, amountUsd } = payment;	console.log(`${uuid} "${reference ?? ''}": ${amount} ${currency.symbol} (${amountUsd} USD)`);}if (page.hasMore) {	// Pass it back, verbatim, as the cursor param for the next page.	console.log(`next cursor: ${page.nextCursor}`);}
page = client.payments.list(refunded=False, limit=20)  # newest firstfor payment in page.items:    # Amounts are decimal strings: the token's (amount, with currency) and USD (amount_usd).    print(        payment.uuid,        payment.reference,        payment.amount,        payment.currency.symbol,        f"({payment.amount_usd} USD)",    )if page.has_more:    print("next page: cursor =", page.next_cursor)  # pass it back, verbatim, as cursor=
since := time.Now().AddDate(0, -1, 0)page, err := client.Payments.List(ctx, &qbitflow.PaymentListParams{	CreatedAfter: &since, // the last month	Limit:        20,})if err != nil {	log.Fatal(err)}for _, p := range page.Items {	// Amounts are decimal strings: the token's (Amount, with Currency) and USD (AmountUSD).	fmt.Printf("%s %q: %s %s (%s USD)\n", p.UUID, p.Reference, p.Amount, p.Currency.Symbol, p.AmountUSD)}if page.HasMore {	// Pass it back, verbatim, as PaymentListParams.Cursor for the next page.	fmt.Println("next cursor:", page.NextCursor)}
$page = $client->payments->list(new \QBitFlow\Params\PaymentListParams(	createdAfter: new \DateTimeImmutable('-30 days'),	limit: 20,));foreach ($page->items as $payment) {	// Amounts are decimal strings: the token's (amount, with its currency) and USD (amountUsd).	echo "{$payment->uuid} " . ($payment->reference ?? '-') . ": {$payment->amount} {$payment->currency->symbol} ({$payment->amountUsd} USD)\n";}if ($page->hasMore) {	$cursor = $page->nextCursor; // pass it back, verbatim, as `cursor` for the next page}

Also: Iterate over every page

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

  • customerUuidstringOptional

    Only this customer's

  • productUuidstringOptional

    Only this product's

  • createdAfterstringOptional

    Only those created after this instant, excluded (RFC 3339, e.g. 2026-10-04T12:00:00Z, or a date: its midnight UTC)

  • createdBeforestringOptional

    Only those created before this instant, excluded (RFC 3339 or a date, as createdAfter)

  • includeMembersbooleanOptional

    The organization's space only (the team, its keys without On-Behalf-Of): its members' too, each naming its member (userUuid). From a member's space → 400 on includeMembers

  • userUuidstringOptional

    The organization's space only (owners and admins): this member's only, read from the organization's space (a removed member's too). Not with includeMembers (400 on userUuid)

  • referencestringOptional

    Only the payment with this reference (the merchant's, set on its checkout): 0 or 1 item. References are unique per space: with includeMembers or userUuid, one per space read

    referencemax=100

  • refundedbooleanOptional

    Only the payments with (true) or without (false) an approved refund

Response

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

33 fields of each Payment
  • uuidstring

    allow read and create, (generated on creation of the payment link)

    A prefixed id (pay@…, sub@…)

  • createdAtstring
  • fromstring
  • tostring
  • amountstring

    The amount in the currency's units, exact, a decimal string ("10" for 10 USDC): amountMinUnits / 10^decimals

  • amountMinUnitsstring

    The amount in the currency's smallest unit, a string of digits ("10000000" for 10 USDC, 6 decimals)

  • amountUsdstring

    What the customer paid, in USD, a decimal string: the price (and, on a one-time payment, the fees its checkout added: fees), which the contracts split between QBitFlow's fee (the referrer's share included), the organization's fee and the merchant (settlement.split). The network fee a customer pays on top (settlement.split.networkFee) is not in it

  • currencyIdinteger

    The currency paid in, written as the currency object under currency (GET /currencies/:id)

  • txHashstring

    Hash of the transaction in the blockchain

  • chainstringOptional

    The chain it was paid on: ETH (Ethereum), BASE (Base) or SOL (Solana), the testnet's for a test-mode transfer (currency.test)

  • explorerUrlstringOptional

    Its transaction on the chain's block explorer (the testnet's in test mode). Omitted without a txHash

  • testboolean

    Whether this is test data (testnets) or live data

  • userUuidstringOptional

    Member the resource belongs to; omitted for the organization's own resources

    Only for the resource's owner

  • referencestringOptional

    The merchant's reference for the payment (an order or invoice id), set when creating its checkout. Only for the merchant: never in the public reads by uuid (GET /hosted/transactions/:txUuid)

    Only for the resource's owner

  • priceUsdstringOptional

    PriceUSD is the product's price in USD, as the checkout had it, a decimal string, always present: amountUsd is the price plus the fees' lines. (A payment recorded before checkouts had fees has none stored: its price is its amount, Complete.)

  • feesarray of FeeLine

    What the checkout added to the price, line by line, as the customer saw them (a tax, shipping, the processing fee when the customer paid it); [] without any

    4 fields of each FeeLine
    • typestring

      custom (the merchant's line) or processingFee (QBitFlow's fee, which the merchant has the customer pay)

      One of:

      • customThe merchant's own line: a tax, shipping, a service fee
      • processingFeeQBitFlow's fee, which the merchant has the customer pay (computed by QBitFlow)
    • labelstring

      The line's name, as the checkout shows it ("Processing fee" for the processing fee)

    • descriptionstringOptional

      Optional: more about the line, as the merchant wrote it. Omitted without one

    • amountUsdstring

      The line's amount in USD, a decimal string with at most 2 decimals

  • productNamestring

    What was paid for: the checkout's product name, as it was when the checkout was created (the product's, or the inline one). Later product edits don't change it

  • productDescriptionstringOptional

    Same, for the product's description; absent without one

  • metadatamapOptional

    Metadata is the merchant's own data, copied from the checkout session that created the payment (its metadata), read-only. {} without any. Only for the merchant

    Only for the resource's owner

  • productUuidstringOptional

    The product paid for; omitted when the payment has none (an inline product)

  • customerUuidstringOptional

    The customer, when QBitFlow has one (named by the checkout, found by its customerReference, or recorded from the details the customer gave); omitted otherwise

    Only for the resource's owner

  • customerReferencestringOptional

    The merchant's reference of the customer, as the checkout was given it (customerReference), whether or not QBitFlow has a customer with it; omitted otherwise

    Only for the resource's owner

  • notestringOptional

    A qbf.cash tipper's message to the handle's owner (only for them); omitted without one

    Only for the resource's owner

  • customerSummaryOptional

    The customer, named (merchant only, API reads): who paid, even once deleted. Omitted without one

    Only for the resource's owner

    6 fields of Summary
    • uuidstring

      The customer (GET /customers/:uuid)

    • firstNamestring

      First name

    • lastNamestringOptional

      Last name, when given

    • emailstring

      Email, lowercase

    • referencestringOptional

      The merchant's reference of the customer, when it has one

    • deletedboolean

      The merchant deleted the customer: it still names its rows, but GET /customers/:uuid answers 404

  • settlementSettlementOptional

    How it settled: its fees, its split and its transaction (only for the merchant)

    Only for the resource's owner

    5 fields of Settlement
    • feePercentnumber

      QBitFlow's fee on this payment, in bps (1 % = 100 bps), deducted from the amount paid. Written as feePercent, a percent string

    • organizationFeeOrganizationFeeOptional

      The organization's fee on its member's payment (a marketplace's commission), paid to the organization's wallet. It is taken from what remains after QBitFlow's fee (contracts SPEC §4.1): organization = (amount - QBitFlow's fee) × its rate, and the member receives the rest. While the organization holds the member's funds, it is withheld from what the organization owes them instead of paid on-chain. Absent: none

      2 fields of OrganizationFee
      • addressstringOptional

        The organization's wallet that receives the fee (only for the merchant)

        Only for the resource's owner

      • feePercentnumber

        The organization's fee, in bps, taken from what remains after the platform fee. Written as feePercent, a percent string

    • referralFeeReferralFeeOptional

      The referrer's share of QBitFlow's fee. Absent: none

      2 fields of ReferralFee
      • addressstringOptional

        The referrer's wallet that receives the fee (only for the merchant)

        Only for the resource's owner

      • feePercentnumber

        The referrer's share of the platform fee, in bps (2000 = 20 % of it). Written as feePercent, a percent string

    • splitSplitOptional

      How the contracts split what the payer paid. For a payment the organization held for its member, the organization's fee was withheld from the member's share (not paid on-chain): the split is the one a direct payment would have had. Absent on records made before the split was recorded

      5 fields of Split
      • platformTokenAmount

        QBitFlow's fee (the referrer's share not included)

        3 fields of TokenAmount
        • amountstring

          In the token's units, exact: amountMinUnits / 10^decimals, a decimal string ("12.5")

        • amountMinUnitsstring

          The on-chain integer, in the token's smallest unit, a string of digits ("12500000")

        • amountUsdstringOptional

          Its value in USD, a decimal string; absent when no price was known

      • organizationTokenAmountOptional

        The organization's fee; absent without one

        3 fields of TokenAmount
        • amountstring

          In the token's units, exact: amountMinUnits / 10^decimals, a decimal string ("12.5")

        • amountMinUnitsstring

          The on-chain integer, in the token's smallest unit, a string of digits ("12500000")

        • amountUsdstringOptional

          Its value in USD, a decimal string; absent when no price was known

      • referralTokenAmountOptional

        The referrer's share of QBitFlow's fee; absent without one

        3 fields of TokenAmount
        • amountstring

          In the token's units, exact: amountMinUnits / 10^decimals, a decimal string ("12.5")

        • amountMinUnitsstring

          The on-chain integer, in the token's smallest unit, a string of digits ("12500000")

        • amountUsdstringOptional

          Its value in USD, a decimal string; absent when no price was known

      • merchantTokenAmount

        What the merchant received (the member, for a member's payment), net of every fee

        3 fields of TokenAmount
        • amountstring

          In the token's units, exact: amountMinUnits / 10^decimals, a decimal string ("12.5")

        • amountMinUnitsstring

          The on-chain integer, in the token's smallest unit, a string of digits ("12500000")

        • amountUsdstringOptional

          Its value in USD, a decimal string; absent when no price was known

      • networkFeeTokenAmountOptional

        NetworkFee is the network fee the payer paid on top of the amount, in the payment's currency: the gas refund the contracts took in the token (their GasRefundProcessed event), or, for a payment in a chain's native coin, the fee of the transaction the payer's wallet paid (its gas and, on Base, its L1 data fee), bounded by what QBitFlow prepared. Not the transaction's own cost to its sender (transaction.fee). Absent on records made before it was recorded ("0" once recorded as none)

        3 fields of TokenAmount
        • amountstring

          In the token's units, exact: amountMinUnits / 10^decimals, a decimal string ("12.5")

        • amountMinUnitsstring

          The on-chain integer, in the token's smallest unit, a string of digits ("12500000")

        • amountUsdstringOptional

          Its value in USD, a decimal string; absent when no price was known

    • transactionSettlementTransactionOptional

      The transaction that paid it. Absent before its confirmation

      6 fields of SettlementTransaction
      • blockNumberstring

        The block (Ethereum, Base) or slot (Solana) it landed in, a string of digits

      • blockTimestringOptional

        When its block was produced (UTC); when it was recorded if the chain's node didn't give it. Absent only on records made before it was recorded

      • gasUsedintegerOptional

        The gas it consumed (Ethereum, Base). Absent on Solana

      • feeTokenAmount

        What the transaction cost its sender, in the chain's native coin (ETH, SOL; its currency is the payment currency's chain): its gas and, on Base, its L1 data fee. amountUsd at nativePriceUsd

        3 fields of TokenAmount
        • amountstring

          In the token's units, exact: amountMinUnits / 10^decimals, a decimal string ("12.5")

        • amountMinUnitsstring

          The on-chain integer, in the token's smallest unit, a string of digits ("12500000")

        • amountUsdstringOptional

          Its value in USD, a decimal string; absent when no price was known

      • l1FeeTokenAmountOptional

        The part of fee that paid Base's L1 data fee, in the native coin. Absent off Base, and on transactions recorded before it was

        3 fields of TokenAmount
        • amountstring

          In the token's units, exact: amountMinUnits / 10^decimals, a decimal string ("12.5")

        • amountMinUnitsstring

          The on-chain integer, in the token's smallest unit, a string of digits ("12500000")

        • amountUsdstringOptional

          Its value in USD, a decimal string; absent when no price was known

      • nativePriceUsdstringOptional

        NativePriceUSD is the USD price of the chain's native coin when the transaction was recorded (what its fee cost in USD). Absent when the price wasn't available then

  • confirmedAtstringOptional

    When the chain confirmed it: its block's time (settlement.transaction.blockTime). Absent only on records made before it was recorded

  • paidstringOptional

    Everything the customer's wallet sent, in the currency's units (a decimal string): the amount plus the network fee paid on top (settlement.split). A refund's base (refundPercent of it). Only for the merchant; absent when the split wasn't recorded

    Only for the resource's owner

  • paidMinUnitsstringOptional

    The same in the currency's smallest unit, a string of digits. Only for the merchant, like paid

    Only for the resource's owner

  • paidUsdstringOptional

    The same in USD, at the payment's time, a decimal string. Only for the merchant, like paid

    Only for the resource's owner

  • refundRefundSummaryOptional

    Its refund (one per transaction); omitted without one. The merchant's own refund appears once its transfer confirmed (approved)

    Only for the resource's owner

    9 fields of RefundSummary
    • uuidstring

      The refund (refund@…)

    • statusstring

      pending, approved or rejected

      One ofpendingapprovedrejected

      • failedDeclared, never set: an approval that fails leaves the refund pending, to approve again
    • initiatedBystring

      customer (a request) or merchant

    • refundPercentnumber

      The share of what the customer paid it sends back, a percent string ("100": all of it). Written as refundPercent

    • amountstringOptional

      What it sends back, in the currency's units (a decimal string). Absent when its currency isn't known (a refund requested before refunds named it)

    • amountMinUnitsstring

      The same in the currency's smallest unit (a string of digits)

    • amountUsdstringOptional

      The same in USD, at the payment's time (a decimal string). Absent when unknown (a refund requested before it was recorded)

    • createdAtstring

      When it was requested or started

    • respondedAtstringOptional

      When it was approved (confirmed) or rejected; absent while pending

  • refundablebooleanOptional

    Whether it can be refunded now

    Only for the resource's owner

  • notRefundableReasonstringOptional

    Why not: refundExists or heldFundsReleased. Omitted when refundable

    Only for the resource's owner

  • checkoutOpenedAtstringOptional

    When its checkout session was created (the payment's uuid is the session's). Omitted for a payment whose uuid doesn't say (made before UUIDv7s)

Get payment#

GET /payments/:uuid

Reads one of the caller's payments by its uuid (pay@… or bare), in the request's space (with includeMembers, its members' too), so in its mode too. Another kind of id (sub@…): 404.

Auth
X-API-Key: any key
On-Behalf-Of
Honored: acts in the member's space
Idempotency-Key
Ignored
Success
200
Request

request.sh

curl "https://api.qbitflow.app/v2/payments/$PAYMENT_UUID" \  -H "X-API-Key: $QBITFLOW_API_KEY"# 200: a Payment
const payment = await client.payments.get(paymentUuid); // pay@…, the checkout session's idconsole.log(payment.uuid, payment.reference, payment.amountUsd, 'USD', payment.metadata); // Runs GET /payments?reference= and returns its one payment: a NotFoundError (404,// not_found) until the customer paid.const byReference = await client.payments.getByReference('order-1042');console.log(`order-1042 was paid by ${byReference.from}`);
payment = client.payments.get(payment_uuid)  # pay@…, the id of its checkout sessionprint(payment.reference, payment.amount_usd, "USD", payment.tx_hash, payment.metadata) # Runs GET /payments?reference= and returns its one payment (NotFoundError when none).by_reference = client.payments.get_by_reference("order-1042")  # your order idprint(by_reference.uuid)
payment, err := client.Payments.Get(ctx, paymentUUID, nil) // pay@…if err != nil {	log.Fatal(err)}fmt.Println(payment.UUID, payment.Reference, payment.AmountUSD, "USD", payment.Metadata) // Runs GET /payments?reference= and returns its one payment.byReference, err := client.Payments.GetByReference(ctx, "order-1042") // your order idif err != nil {	log.Fatal(err) // a *qbitflow.NotFoundError (404, not_found) when no payment has this reference}fmt.Println("order-1042 was paid by", byReference.UUID)
$payment = $client->payments->get($paymentUuid); // pay@…echo "{$payment->uuid}: {$payment->amountUsd} USD, tx {$payment->txHash}\n"; // Runs GET /payments?reference= and returns its one payment (a NotFoundException when none).$payment = $client->payments->getByReference('order-1042'); // your order idecho "order-1042 was paid by {$payment->uuid}\n";

Path parameters

  • uuidstringRequired

    Its prefixed uuid (or the bare uuid)

    txuuid

Query parameters

  • includeMembersbooleanOptional

    The organization's space only (the team, its keys without On-Behalf-Of): a member's too, naming its member (userUuid). Read only: acting on it still switches into the member's space or uses On-Behalf-Of. From a member's space → 400 on includeMembers

Response

A Payment.

33 fields of Payment
  • uuidstring

    allow read and create, (generated on creation of the payment link)

    A prefixed id (pay@…, sub@…)

  • createdAtstring
  • fromstring
  • tostring
  • amountstring

    The amount in the currency's units, exact, a decimal string ("10" for 10 USDC): amountMinUnits / 10^decimals

  • amountMinUnitsstring

    The amount in the currency's smallest unit, a string of digits ("10000000" for 10 USDC, 6 decimals)

  • amountUsdstring

    What the customer paid, in USD, a decimal string: the price (and, on a one-time payment, the fees its checkout added: fees), which the contracts split between QBitFlow's fee (the referrer's share included), the organization's fee and the merchant (settlement.split). The network fee a customer pays on top (settlement.split.networkFee) is not in it

  • currencyIdinteger

    The currency paid in, written as the currency object under currency (GET /currencies/:id)

  • txHashstring

    Hash of the transaction in the blockchain

  • chainstringOptional

    The chain it was paid on: ETH (Ethereum), BASE (Base) or SOL (Solana), the testnet's for a test-mode transfer (currency.test)

  • explorerUrlstringOptional

    Its transaction on the chain's block explorer (the testnet's in test mode). Omitted without a txHash

  • testboolean

    Whether this is test data (testnets) or live data

  • userUuidstringOptional

    Member the resource belongs to; omitted for the organization's own resources

    Only for the resource's owner

  • referencestringOptional

    The merchant's reference for the payment (an order or invoice id), set when creating its checkout. Only for the merchant: never in the public reads by uuid (GET /hosted/transactions/:txUuid)

    Only for the resource's owner

  • priceUsdstringOptional

    PriceUSD is the product's price in USD, as the checkout had it, a decimal string, always present: amountUsd is the price plus the fees' lines. (A payment recorded before checkouts had fees has none stored: its price is its amount, Complete.)

  • feesarray of FeeLine

    What the checkout added to the price, line by line, as the customer saw them (a tax, shipping, the processing fee when the customer paid it); [] without any

    4 fields of each FeeLine
    • typestring

      custom (the merchant's line) or processingFee (QBitFlow's fee, which the merchant has the customer pay)

      One of:

      • customThe merchant's own line: a tax, shipping, a service fee
      • processingFeeQBitFlow's fee, which the merchant has the customer pay (computed by QBitFlow)
    • labelstring

      The line's name, as the checkout shows it ("Processing fee" for the processing fee)

    • descriptionstringOptional

      Optional: more about the line, as the merchant wrote it. Omitted without one

    • amountUsdstring

      The line's amount in USD, a decimal string with at most 2 decimals

  • productNamestring

    What was paid for: the checkout's product name, as it was when the checkout was created (the product's, or the inline one). Later product edits don't change it

  • productDescriptionstringOptional

    Same, for the product's description; absent without one

  • metadatamapOptional

    Metadata is the merchant's own data, copied from the checkout session that created the payment (its metadata), read-only. {} without any. Only for the merchant

    Only for the resource's owner

  • productUuidstringOptional

    The product paid for; omitted when the payment has none (an inline product)

  • customerUuidstringOptional

    The customer, when QBitFlow has one (named by the checkout, found by its customerReference, or recorded from the details the customer gave); omitted otherwise

    Only for the resource's owner

  • customerReferencestringOptional

    The merchant's reference of the customer, as the checkout was given it (customerReference), whether or not QBitFlow has a customer with it; omitted otherwise

    Only for the resource's owner

  • notestringOptional

    A qbf.cash tipper's message to the handle's owner (only for them); omitted without one

    Only for the resource's owner

  • customerSummaryOptional

    The customer, named (merchant only, API reads): who paid, even once deleted. Omitted without one

    Only for the resource's owner

    6 fields of Summary
    • uuidstring

      The customer (GET /customers/:uuid)

    • firstNamestring

      First name

    • lastNamestringOptional

      Last name, when given

    • emailstring

      Email, lowercase

    • referencestringOptional

      The merchant's reference of the customer, when it has one

    • deletedboolean

      The merchant deleted the customer: it still names its rows, but GET /customers/:uuid answers 404

  • settlementSettlementOptional

    How it settled: its fees, its split and its transaction (only for the merchant)

    Only for the resource's owner

    5 fields of Settlement
    • feePercentnumber

      QBitFlow's fee on this payment, in bps (1 % = 100 bps), deducted from the amount paid. Written as feePercent, a percent string

    • organizationFeeOrganizationFeeOptional

      The organization's fee on its member's payment (a marketplace's commission), paid to the organization's wallet. It is taken from what remains after QBitFlow's fee (contracts SPEC §4.1): organization = (amount - QBitFlow's fee) × its rate, and the member receives the rest. While the organization holds the member's funds, it is withheld from what the organization owes them instead of paid on-chain. Absent: none

      2 fields of OrganizationFee
      • addressstringOptional

        The organization's wallet that receives the fee (only for the merchant)

        Only for the resource's owner

      • feePercentnumber

        The organization's fee, in bps, taken from what remains after the platform fee. Written as feePercent, a percent string

    • referralFeeReferralFeeOptional

      The referrer's share of QBitFlow's fee. Absent: none

      2 fields of ReferralFee
      • addressstringOptional

        The referrer's wallet that receives the fee (only for the merchant)

        Only for the resource's owner

      • feePercentnumber

        The referrer's share of the platform fee, in bps (2000 = 20 % of it). Written as feePercent, a percent string

    • splitSplitOptional

      How the contracts split what the payer paid. For a payment the organization held for its member, the organization's fee was withheld from the member's share (not paid on-chain): the split is the one a direct payment would have had. Absent on records made before the split was recorded

      5 fields of Split
      • platformTokenAmount

        QBitFlow's fee (the referrer's share not included)

        3 fields of TokenAmount
        • amountstring

          In the token's units, exact: amountMinUnits / 10^decimals, a decimal string ("12.5")

        • amountMinUnitsstring

          The on-chain integer, in the token's smallest unit, a string of digits ("12500000")

        • amountUsdstringOptional

          Its value in USD, a decimal string; absent when no price was known

      • organizationTokenAmountOptional

        The organization's fee; absent without one

        3 fields of TokenAmount
        • amountstring

          In the token's units, exact: amountMinUnits / 10^decimals, a decimal string ("12.5")

        • amountMinUnitsstring

          The on-chain integer, in the token's smallest unit, a string of digits ("12500000")

        • amountUsdstringOptional

          Its value in USD, a decimal string; absent when no price was known

      • referralTokenAmountOptional

        The referrer's share of QBitFlow's fee; absent without one

        3 fields of TokenAmount
        • amountstring

          In the token's units, exact: amountMinUnits / 10^decimals, a decimal string ("12.5")

        • amountMinUnitsstring

          The on-chain integer, in the token's smallest unit, a string of digits ("12500000")

        • amountUsdstringOptional

          Its value in USD, a decimal string; absent when no price was known

      • merchantTokenAmount

        What the merchant received (the member, for a member's payment), net of every fee

        3 fields of TokenAmount
        • amountstring

          In the token's units, exact: amountMinUnits / 10^decimals, a decimal string ("12.5")

        • amountMinUnitsstring

          The on-chain integer, in the token's smallest unit, a string of digits ("12500000")

        • amountUsdstringOptional

          Its value in USD, a decimal string; absent when no price was known

      • networkFeeTokenAmountOptional

        NetworkFee is the network fee the payer paid on top of the amount, in the payment's currency: the gas refund the contracts took in the token (their GasRefundProcessed event), or, for a payment in a chain's native coin, the fee of the transaction the payer's wallet paid (its gas and, on Base, its L1 data fee), bounded by what QBitFlow prepared. Not the transaction's own cost to its sender (transaction.fee). Absent on records made before it was recorded ("0" once recorded as none)

        3 fields of TokenAmount
        • amountstring

          In the token's units, exact: amountMinUnits / 10^decimals, a decimal string ("12.5")

        • amountMinUnitsstring

          The on-chain integer, in the token's smallest unit, a string of digits ("12500000")

        • amountUsdstringOptional

          Its value in USD, a decimal string; absent when no price was known

    • transactionSettlementTransactionOptional

      The transaction that paid it. Absent before its confirmation

      6 fields of SettlementTransaction
      • blockNumberstring

        The block (Ethereum, Base) or slot (Solana) it landed in, a string of digits

      • blockTimestringOptional

        When its block was produced (UTC); when it was recorded if the chain's node didn't give it. Absent only on records made before it was recorded

      • gasUsedintegerOptional

        The gas it consumed (Ethereum, Base). Absent on Solana

      • feeTokenAmount

        What the transaction cost its sender, in the chain's native coin (ETH, SOL; its currency is the payment currency's chain): its gas and, on Base, its L1 data fee. amountUsd at nativePriceUsd

        3 fields of TokenAmount
        • amountstring

          In the token's units, exact: amountMinUnits / 10^decimals, a decimal string ("12.5")

        • amountMinUnitsstring

          The on-chain integer, in the token's smallest unit, a string of digits ("12500000")

        • amountUsdstringOptional

          Its value in USD, a decimal string; absent when no price was known

      • l1FeeTokenAmountOptional

        The part of fee that paid Base's L1 data fee, in the native coin. Absent off Base, and on transactions recorded before it was

        3 fields of TokenAmount
        • amountstring

          In the token's units, exact: amountMinUnits / 10^decimals, a decimal string ("12.5")

        • amountMinUnitsstring

          The on-chain integer, in the token's smallest unit, a string of digits ("12500000")

        • amountUsdstringOptional

          Its value in USD, a decimal string; absent when no price was known

      • nativePriceUsdstringOptional

        NativePriceUSD is the USD price of the chain's native coin when the transaction was recorded (what its fee cost in USD). Absent when the price wasn't available then

  • confirmedAtstringOptional

    When the chain confirmed it: its block's time (settlement.transaction.blockTime). Absent only on records made before it was recorded

  • paidstringOptional

    Everything the customer's wallet sent, in the currency's units (a decimal string): the amount plus the network fee paid on top (settlement.split). A refund's base (refundPercent of it). Only for the merchant; absent when the split wasn't recorded

    Only for the resource's owner

  • paidMinUnitsstringOptional

    The same in the currency's smallest unit, a string of digits. Only for the merchant, like paid

    Only for the resource's owner

  • paidUsdstringOptional

    The same in USD, at the payment's time, a decimal string. Only for the merchant, like paid

    Only for the resource's owner

  • refundRefundSummaryOptional

    Its refund (one per transaction); omitted without one. The merchant's own refund appears once its transfer confirmed (approved)

    Only for the resource's owner

    9 fields of RefundSummary
    • uuidstring

      The refund (refund@…)

    • statusstring

      pending, approved or rejected

      One ofpendingapprovedrejected

      • failedDeclared, never set: an approval that fails leaves the refund pending, to approve again
    • initiatedBystring

      customer (a request) or merchant

    • refundPercentnumber

      The share of what the customer paid it sends back, a percent string ("100": all of it). Written as refundPercent

    • amountstringOptional

      What it sends back, in the currency's units (a decimal string). Absent when its currency isn't known (a refund requested before refunds named it)

    • amountMinUnitsstring

      The same in the currency's smallest unit (a string of digits)

    • amountUsdstringOptional

      The same in USD, at the payment's time (a decimal string). Absent when unknown (a refund requested before it was recorded)

    • createdAtstring

      When it was requested or started

    • respondedAtstringOptional

      When it was approved (confirmed) or rejected; absent while pending

  • refundablebooleanOptional

    Whether it can be refunded now

    Only for the resource's owner

  • notRefundableReasonstringOptional

    Why not: refundExists or heldFundsReleased. Omitted when refundable

    Only for the resource's owner

  • checkoutOpenedAtstringOptional

    When its checkout session was created (the payment's uuid is the session's). Omitted for a payment whose uuid doesn't say (made before UUIDv7s)

List transactions#

GET /transactions

Lists the one-time payments and the subscription bills of the request's space together (with includeMembers, of the organization and its members; with userUuid, of one member), newest first (createdAt, then uuid).

Auth
X-API-Key: any key
On-Behalf-Of
Honored: acts in the member's space
Idempotency-Key
Ignored
Success
200
Request

request.sh

curl https://api.qbitflow.app/v2/transactions \  -H "X-API-Key: $QBITFLOW_API_KEY"# 200: a page of Transaction ({ items, hasMore, nextCursor? })
// One feed of one-time payments and subscription bills, newest first; each row reads like its// resource. `type` filters it to one kind (TransactionKind.Payment or TransactionKind.Bill).const feed = await client.transactions.list({ limit: 20 });for (const tx of feed.items) {	console.log(tx.type, tx.uuid, tx.amountUsd, 'USD');}
# One feed of one-time payments and subscription bills, newest first; each row reads like# its resource. type= filters it to one kind (TransactionKind.PAYMENT or .BILL).feed = client.transactions.list(limit=20)for tx in feed.items:    print(tx.type, tx.uuid, tx.amount_usd, "USD")
// One feed of one-time payments and subscription bills, newest first; each row reads like// its resource. Type filters it to one kind (TransactionKindPayment or TransactionKindBill).feed, err := client.Transactions.List(ctx, &qbitflow.TransactionListParams{Limit: 20})if err != nil {	log.Fatal(err)}for _, tx := range feed.Items {	fmt.Println(tx.Type, tx.UUID, tx.AmountUSD, "USD")}
// One feed of one-time payments and subscription bills, newest first; each row reads like its// resource. `type` filters it to one kind (TransactionKind::PAYMENT or TransactionKind::BILL).$feed = $client->transactions->list(new \QBitFlow\Params\TransactionListParams(limit: 20));foreach ($feed->items as $transaction) {	echo "{$transaction->type} {$transaction->uuid} {$transaction->amountUsd} USD\n";}

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

  • customerUuidstringOptional

    Only this customer's

  • productUuidstringOptional

    Only this product's

  • createdAfterstringOptional

    Only those created after this instant, excluded (RFC 3339, e.g. 2026-10-04T12:00:00Z, or a date: its midnight UTC)

  • createdBeforestringOptional

    Only those created before this instant, excluded (RFC 3339 or a date, as createdAfter)

  • includeMembersbooleanOptional

    The organization's space only (the team, its keys without On-Behalf-Of): its members' too, each naming its member (userUuid). From a member's space → 400 on includeMembers

  • userUuidstringOptional

    The organization's space only (owners and admins): this member's only, read from the organization's space (a removed member's too). Not with includeMembers (400 on userUuid)

  • typestringOptional

    Only the one-time payments (payment) or only the subscriptions' bills (bill)

    oneof=payment bill

    One of:

    • paymentA one-time payment (pay@…): GET /payments/:uuid
    • billA subscription's bill (sub-hist@…): GET /bills/:uuid
  • subscriptionUuidstringOptional

    Only this subscription's bills (its sub@ uuid, or the bare uuid)

    txuuid

  • refundedbooleanOptional

    Only the rows with (true) or without (false) an approved refund

Response

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

36 fields of each Transaction
  • typestring

    payment or bill

    One of:

    • paymentA one-time payment (pay@…): GET /payments/:uuid
    • billA subscription's bill (sub-hist@…): GET /bills/:uuid
  • uuidstring

    The payment's (pay@…) or the bill's (sub-hist@…) prefixed uuid

    A prefixed id (pay@…, sub@…)

  • createdAtstring

    When it was recorded, once confirmed on-chain

  • fromstring

    The customer's wallet that paid

  • tostring

    The wallet that received it (the merchant's, or the organization's while it holds the member's funds)

  • productNamestring

    What was paid for: a payment keeps its checkout's product name (the product's when the checkout was created, or the inline one), a bill its subscription's product name when it was billed. Later product edits don't change it

  • productDescriptionstringOptional

    Same, for the description; absent without one

  • priceUsdstringOptional

    The price in USD, a decimal string: a payment's checkout price, a bill's subscription's locked price. amountUsd is the price plus the fees' lines. Absent on a bill of a subscription without a locked price

  • feesarray of FeeLine

    What was added to the price, line by line: a payment's checkout lines, a bill's subscription's (locked with its price); [] without any

    4 fields of each FeeLine
    • typestring

      custom (the merchant's line) or processingFee (QBitFlow's fee, which the merchant has the customer pay)

      One of:

      • customThe merchant's own line: a tax, shipping, a service fee
      • processingFeeQBitFlow's fee, which the merchant has the customer pay (computed by QBitFlow)
    • labelstring

      The line's name, as the checkout shows it ("Processing fee" for the processing fee)

    • descriptionstringOptional

      Optional: more about the line, as the merchant wrote it. Omitted without one

    • amountUsdstring

      The line's amount in USD, a decimal string with at most 2 decimals

  • amountstring

    What the customer paid, in the currency's units, exact (a decimal string), as on the Payment or the Bill

  • amountMinUnitsstring

    The same in the currency's smallest unit, a string of digits

  • amountUsdstring

    What the customer paid, in USD, a decimal string: the price and the fees' lines (the network fee paid on top is settlement.split.networkFee)

  • currencyIdinteger

    The currency paid in, written as the currency object under currency

  • productUuidstringOptional

    The product paid for; absent when there is none (an inline product)

  • txHashstring

    The transaction that paid it

  • customerUuidstringOptional

    The customer, when QBitFlow has one; absent otherwise

    Only for the resource's owner

  • customerSummaryOptional

    The customer, named (merchant only, API reads): who paid, even once deleted. Absent without one

    Only for the resource's owner

    6 fields of Summary
    • uuidstring

      The customer (GET /customers/:uuid)

    • firstNamestring

      First name

    • lastNamestringOptional

      Last name, when given

    • emailstring

      Email, lowercase

    • referencestringOptional

      The merchant's reference of the customer, when it has one

    • deletedboolean

      The merchant deleted the customer: it still names its rows, but GET /customers/:uuid answers 404

  • customerReferencestringOptional

    The merchant's reference of the customer, as the checkout was given it; absent otherwise

    Only for the resource's owner

  • subscriptionUuidstringOptional

    A bill's subscription (sub@…); absent on a payment

  • periodStartstringOptional

    A bill's period's start (its due date); absent on a payment, and on bills recorded before periods were

  • periodEndstringOptional

    A bill's period's end: paid until then; absent on a payment, and on bills recorded before periods were

  • referencestringOptional

    A payment's own reference (a bill has none of its own). Only for the merchant

    Only for the resource's owner

  • subscriptionReferencestringOptional

    The reference of a bill's subscription, as in the subscription webhooks

  • metadatamapOptional

    Metadata is a payment's merchant data (copied from its checkout session); {} for a bill (a bill carries none: its subscription's is on the subscription). Only for the merchant

    Only for the resource's owner

  • chainstringOptional

    The chain it was paid on: ETH (Ethereum), BASE (Base) or SOL (Solana), the testnet's for a test-mode transfer (currency.test)

  • explorerUrlstringOptional

    Its transaction on the chain's block explorer (the testnet's in test mode). Omitted without a txHash

  • testboolean

    Whether this is test data (testnets) or live data

  • userUuidstringOptional

    Member the resource belongs to; omitted for the organization's own resources

    Only for the resource's owner

  • settlementSettlementOptional

    Its fees, split and transaction, as on the Payment or the Bill (only for the merchant)

    Only for the resource's owner

    5 fields of Settlement
    • feePercentnumber

      QBitFlow's fee on this payment, in bps (1 % = 100 bps), deducted from the amount paid. Written as feePercent, a percent string

    • organizationFeeOrganizationFeeOptional

      The organization's fee on its member's payment (a marketplace's commission), paid to the organization's wallet. It is taken from what remains after QBitFlow's fee (contracts SPEC §4.1): organization = (amount - QBitFlow's fee) × its rate, and the member receives the rest. While the organization holds the member's funds, it is withheld from what the organization owes them instead of paid on-chain. Absent: none

      2 fields of OrganizationFee
      • addressstringOptional

        The organization's wallet that receives the fee (only for the merchant)

        Only for the resource's owner

      • feePercentnumber

        The organization's fee, in bps, taken from what remains after the platform fee. Written as feePercent, a percent string

    • referralFeeReferralFeeOptional

      The referrer's share of QBitFlow's fee. Absent: none

      2 fields of ReferralFee
      • addressstringOptional

        The referrer's wallet that receives the fee (only for the merchant)

        Only for the resource's owner

      • feePercentnumber

        The referrer's share of the platform fee, in bps (2000 = 20 % of it). Written as feePercent, a percent string

    • splitSplitOptional

      How the contracts split what the payer paid. For a payment the organization held for its member, the organization's fee was withheld from the member's share (not paid on-chain): the split is the one a direct payment would have had. Absent on records made before the split was recorded

      5 fields of Split
      • platformTokenAmount

        QBitFlow's fee (the referrer's share not included)

        3 fields of TokenAmount
        • amountstring

          In the token's units, exact: amountMinUnits / 10^decimals, a decimal string ("12.5")

        • amountMinUnitsstring

          The on-chain integer, in the token's smallest unit, a string of digits ("12500000")

        • amountUsdstringOptional

          Its value in USD, a decimal string; absent when no price was known

      • organizationTokenAmountOptional

        The organization's fee; absent without one

        3 fields of TokenAmount
        • amountstring

          In the token's units, exact: amountMinUnits / 10^decimals, a decimal string ("12.5")

        • amountMinUnitsstring

          The on-chain integer, in the token's smallest unit, a string of digits ("12500000")

        • amountUsdstringOptional

          Its value in USD, a decimal string; absent when no price was known

      • referralTokenAmountOptional

        The referrer's share of QBitFlow's fee; absent without one

        3 fields of TokenAmount
        • amountstring

          In the token's units, exact: amountMinUnits / 10^decimals, a decimal string ("12.5")

        • amountMinUnitsstring

          The on-chain integer, in the token's smallest unit, a string of digits ("12500000")

        • amountUsdstringOptional

          Its value in USD, a decimal string; absent when no price was known

      • merchantTokenAmount

        What the merchant received (the member, for a member's payment), net of every fee

        3 fields of TokenAmount
        • amountstring

          In the token's units, exact: amountMinUnits / 10^decimals, a decimal string ("12.5")

        • amountMinUnitsstring

          The on-chain integer, in the token's smallest unit, a string of digits ("12500000")

        • amountUsdstringOptional

          Its value in USD, a decimal string; absent when no price was known

      • networkFeeTokenAmountOptional

        NetworkFee is the network fee the payer paid on top of the amount, in the payment's currency: the gas refund the contracts took in the token (their GasRefundProcessed event), or, for a payment in a chain's native coin, the fee of the transaction the payer's wallet paid (its gas and, on Base, its L1 data fee), bounded by what QBitFlow prepared. Not the transaction's own cost to its sender (transaction.fee). Absent on records made before it was recorded ("0" once recorded as none)

        3 fields of TokenAmount
        • amountstring

          In the token's units, exact: amountMinUnits / 10^decimals, a decimal string ("12.5")

        • amountMinUnitsstring

          The on-chain integer, in the token's smallest unit, a string of digits ("12500000")

        • amountUsdstringOptional

          Its value in USD, a decimal string; absent when no price was known

    • transactionSettlementTransactionOptional

      The transaction that paid it. Absent before its confirmation

      6 fields of SettlementTransaction
      • blockNumberstring

        The block (Ethereum, Base) or slot (Solana) it landed in, a string of digits

      • blockTimestringOptional

        When its block was produced (UTC); when it was recorded if the chain's node didn't give it. Absent only on records made before it was recorded

      • gasUsedintegerOptional

        The gas it consumed (Ethereum, Base). Absent on Solana

      • feeTokenAmount

        What the transaction cost its sender, in the chain's native coin (ETH, SOL; its currency is the payment currency's chain): its gas and, on Base, its L1 data fee. amountUsd at nativePriceUsd

        3 fields of TokenAmount
        • amountstring

          In the token's units, exact: amountMinUnits / 10^decimals, a decimal string ("12.5")

        • amountMinUnitsstring

          The on-chain integer, in the token's smallest unit, a string of digits ("12500000")

        • amountUsdstringOptional

          Its value in USD, a decimal string; absent when no price was known

      • l1FeeTokenAmountOptional

        The part of fee that paid Base's L1 data fee, in the native coin. Absent off Base, and on transactions recorded before it was

        3 fields of TokenAmount
        • amountstring

          In the token's units, exact: amountMinUnits / 10^decimals, a decimal string ("12.5")

        • amountMinUnitsstring

          The on-chain integer, in the token's smallest unit, a string of digits ("12500000")

        • amountUsdstringOptional

          Its value in USD, a decimal string; absent when no price was known

      • nativePriceUsdstringOptional

        NativePriceUSD is the USD price of the chain's native coin when the transaction was recorded (what its fee cost in USD). Absent when the price wasn't available then

  • confirmedAtstringOptional

    When the chain confirmed it: its block's time (settlement.transaction.blockTime). Absent only on records made before it was recorded

  • paidstringOptional

    Everything the customer's wallet sent, in the currency's units (a decimal string): the amount plus the network fee paid on top (settlement.split). A refund's base (refundPercent of it). Only for the merchant; absent when the split wasn't recorded

    Only for the resource's owner

  • paidMinUnitsstringOptional

    The same in the currency's smallest unit, a string of digits. Only for the merchant, like paid

    Only for the resource's owner

  • paidUsdstringOptional

    The same in USD, at the payment's time, a decimal string. Only for the merchant, like paid

    Only for the resource's owner

  • refundRefundSummaryOptional

    Its refund (one per transaction); omitted without one. The merchant's own refund appears once its transfer confirmed (approved)

    Only for the resource's owner

    9 fields of RefundSummary
    • uuidstring

      The refund (refund@…)

    • statusstring

      pending, approved or rejected

      One ofpendingapprovedrejected

      • failedDeclared, never set: an approval that fails leaves the refund pending, to approve again
    • initiatedBystring

      customer (a request) or merchant

    • refundPercentnumber

      The share of what the customer paid it sends back, a percent string ("100": all of it). Written as refundPercent

    • amountstringOptional

      What it sends back, in the currency's units (a decimal string). Absent when its currency isn't known (a refund requested before refunds named it)

    • amountMinUnitsstring

      The same in the currency's smallest unit (a string of digits)

    • amountUsdstringOptional

      The same in USD, at the payment's time (a decimal string). Absent when unknown (a refund requested before it was recorded)

    • createdAtstring

      When it was requested or started

    • respondedAtstringOptional

      When it was approved (confirmed) or rejected; absent while pending

  • refundablebooleanOptional

    Whether it can be refunded now

    Only for the resource's owner

  • notRefundableReasonstringOptional

    Why not: refundExists or heldFundsReleased. Omitted when refundable

    Only for the resource's owner

List payment failures#

GET /payment-failures

Lists the failed payment attempts of the request's space (with includeMembers, of the organization and its members; with userUuid, of one member), newest first: one-time payments, subscription checkouts and bills the customer tried to pay and couldn't, and why. A failure is never money: none is ever in the payments, the export or the volume.

Auth
X-API-Key: any key
On-Behalf-Of
Honored: acts in the member's space
Idempotency-Key
Ignored
Success
200
Request

request.sh

curl https://api.qbitflow.app/v2/payment-failures \  -H "X-API-Key: $QBITFLOW_API_KEY"# 200: a page of Failure ({ items, hasMore, nextCursor? })

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

  • customerUuidstringOptional

    Only this customer's

  • productUuidstringOptional

    Only this product's

  • createdAfterstringOptional

    Only those created after this instant, excluded (RFC 3339, e.g. 2026-10-04T12:00:00Z, or a date: its midnight UTC)

  • createdBeforestringOptional

    Only those created before this instant, excluded (RFC 3339 or a date, as createdAfter)

  • includeMembersbooleanOptional

    The organization's space only (the team, its keys without On-Behalf-Of): its members' too, each naming its member (userUuid). From a member's space → 400 on includeMembers

  • userUuidstringOptional

    The organization's space only (owners and admins): this member's only, read from the organization's space (a removed member's too). Not with includeMembers (400 on userUuid)

  • kindstringOptional

    Only one kind: payment, subscriptionCheckout or bill

    oneof=payment subscriptionCheckout bill

    One of:

    • paymentA one-time payment's attempt (its checkout: pay@…)
    • subscriptionCheckoutA subscription checkout's: its creation and first bill (sub@…)
    • billA subscription's bill (sub-hist@…)
  • categorystringOptional

    oneof=insufficientBalance allowanceExhausted approvalRevoked maxAmountExceeded reverted notConfirmed signatureRejected other

    One ofother

    • insufficientBalanceThe customer's wallet couldn't pay (the token, or the gas of a payment they send)
    • allowanceExhaustedA subscription's allowance is used up or expired
    • approvalRevokedThe customer's wallet no longer lets the subscription pull the token
    • maxAmountExceededA bill above the customer's maximum per period
    • revertedSent and reverted on-chain (the wallet changed between the check and the block)
    • notConfirmedSent, never taken or confirmed in time
    • signatureRejectedThe customer's signature was refused (expired, invalid)
  • subscriptionUuidstringOptional

    Only this subscription's bills (sub@…)

    txuuid

Response

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

20 fields of each Failure
  • uuidstring

    The failure's own id, a plain uuid (a failed attempt isn't a transaction: it has no prefix)

  • kindstring

    payment, subscriptionCheckout or bill

    One of:

    • paymentA one-time payment's attempt (its checkout: pay@…)
    • subscriptionCheckoutA subscription checkout's: its creation and first bill (sub@…)
    • billA subscription's bill (sub-hist@…)
  • txUuidstring

    What failed: the checkout (pay@…, sub@…: the id its payment or subscription would have had) or the bill (sub-hist@…: its id once paid)

  • attemptinteger

    Its number among its transaction's failed attempts, from 1

  • subscriptionUuidstringOptional

    A bill's subscription (sub@…)

  • codestring

    The error code (errors), e.g. insufficient_funds

  • categorystring

    What it means, from the code: insufficientBalance, allowanceExhausted, approvalRevoked, maxAmountExceeded, reverted, notConfirmed, signatureRejected or other

    One ofother

    • insufficientBalanceThe customer's wallet couldn't pay (the token, or the gas of a payment they send)
    • allowanceExhaustedA subscription's allowance is used up or expired
    • approvalRevokedThe customer's wallet no longer lets the subscription pull the token
    • maxAmountExceededA bill above the customer's maximum per period
    • revertedSent and reverted on-chain (the wallet changed between the check and the block)
    • notConfirmedSent, never taken or confirmed in time
    • signatureRejectedThe customer's signature was refused (expired, invalid)
  • messagestringOptional

    What the customer was told; absent without a message

  • attemptedstring

    What the customer tried to pay, in the currency's units, exact (a decimal string): never received

  • attemptedMinUnitsstring

    The same in the currency's smallest unit, a string of digits

  • attemptedUsdstring

    The same in USD, a decimal string

  • currencyIdinteger

    The currency it was tried in, written as the currency object under currency

  • fromstring

    The customer's wallet

  • txHashstringOptional

    The transaction, when one was sent (a revert, a timeout)

  • customerUuidstringOptional

    The customer, when QBitFlow has one

    Only for the resource's owner

  • productUuidstringOptional

    The product, when it had one

  • createdAtstring

    When it failed

  • customerSummaryOptional

    The customer, named (API reads)

    Only for the resource's owner

    6 fields of Summary
    • uuidstring

      The customer (GET /customers/:uuid)

    • firstNamestring

      First name

    • lastNamestringOptional

      Last name, when given

    • emailstring

      Email, lowercase

    • referencestringOptional

      The merchant's reference of the customer, when it has one

    • deletedboolean

      The merchant deleted the customer: it still names its rows, but GET /customers/:uuid answers 404

  • testboolean

    Whether this is test data (testnets) or live data

  • userUuidstringOptional

    Member the resource belongs to; omitted for the organization's own resources

    Only for the resource's owner

Edge cases

The contract's rules for these routes: The customer's receipt · Authentication & roles · Spaces · Reads · Response fields · Who paid (customer) · Refund state (refund, refundable) · When (confirmedAt, checkoutOpenedAt) · What the amounts mean · Failed payment attempts (GET /payment-failures).

Read all 10

The customer's receipt

  • Once a payment is recorded, its customer is emailed its receipt, once: what was charged, the network fee on its own row, the total that left their wallet, the network, their wallet and the transaction on the explorer, all from the recorded split (settlement.split). Sent in the merchant's name; the setting emails.customerReceipts turns it off (on by default). Never in test mode, nor without a customer with an email. A receipt that can't be sent never affects the payment.

Authentication & roles

The v1 / beta paths are gone (/transaction/payments, /transaction/payments/combined, /transaction/payment/:uuid, /transaction/payment/reference/:reference, /transaction/failures, /transaction/info/:txUuid, /transaction/status[/ws], /transaction/payment[/intent], /transaction/payment/run-test-tx): 404.

  • POST /hosted/payments/intent (and the subscription intent, Hosted subscriptions) takes customerInformation when the session has no customer: what its customerDetails asks is required: email → customerInformation.email; full → also the first name and lastName (400 validation_failed on customerInformation or the missing field); a session asking nothing (no customerDetails) → optional, and ignored (nothing is kept). The intent writes no customer: the details are kept with the session, and the customer is recorded with the payment (a subscription: with it; a free trial: when it starts), so an intent never paid adds none. The space's unverified customer with the same email, whatever its casing, is reused; a customer the merchant created (verified) never is, whatever its email: the payer's email then becomes an unverified customer of its own (a deleted customer is never reused either; Customers § Verified customers). customerInformation has no reference (the merchant's own id is never the customer's to give). Ignored when the merchant named the customer (customerUuid, or its own customerReference: the checkout then asks nothing, Checkout sessions § The customer).
  • A payer who can't pay is told at the intent (payment, subscription): a wallet that doesn't hold the amount (with a 5 % margin for the price and the network fee) → 422 insufficient_funds (a token), 422 insufficient_native_funds (the chain's own coin), the codes the network's own refusal gives (errors). Nothing is prepared; top the wallet up and make the intent again. A signer that isn't an address of the currency's chain → 400 validation_failed on signer.
  • The paying wallet can't be the receiving one: a signer that is the merchant's receiving wallet (or the organization's, while it holds the member's funds) → 400 sender_is_receiver, nothing prepared.
  • A currency the checkout doesn't take: one of the catalog the session never offered, or one its merchant (or the organization) removed since it opened → 409 currency_not_accepted, details.currency (its code): pick another of the hosted session's availableCurrencies. A currency that isn't a code of the session's mode → 400 validation_failed on currency.
  • Amounts fit the chain (an intent: payment, subscription, allowance): the price converted to the chosen token's smallest unit must fit what the chain holds, u64 on Solana, uint160 for an EVM token (Permit2), uint256 for an EVM chain's coin, and be at least one unit. Too large or below one unit → 400 validation_failed on currency (another token may hold it); a subscription's allowance (a period's amount × numPeriods, with its buffer and network fees) too large → 400 validation_failed on numPeriods. Never truncated.
  • The intent's and the send's uuid is the checkout session's pay@ id, or its bare uuid.

Spaces

  • Every payment belongs to one space (spaces): the organization's or a member's, in one mode. Every route works in the request's space: the team (and organization keys) sees the organization's payments, a member (and their keys) their own, and an organization key with On-Behalf-Of: <userUuid> (or the dashboard switched into the member's space) the member's.
  • A payment of another space, of another organization or of the other mode is never listed, and answers 404 by uuid: existence is never revealed. Another organization's payment uuid answers like an unknown one.
  • Organization-wide lists (?includeMembers=true on both lists): the organization's space (the team's sessions, the organization's keys without On-Behalf-Of) lists its members' payments and bills too, in its mode only, each naming its member (userUuid; the organization's own have none). Every member's space of the mode is read, removed members' included (their data stays the organization's, Members and held funds § Remove), and so is the personal space an admin kept from before their promotion. From a member's space (a member's session or key, On-Behalf-Of, the dashboard switched into a member) → 400 validation_failed on includeMembers. Without it a list is the request's space only. A webhook's userUuid is the member to name in On-Behalf-Of for follow-up reads of that member's resources.
  • One member's rows (?userUuid=<member> on both lists and the failures log): from the organization's space, owners and admins (and the organization's keys, capped at admin) read that member's rows only, without switching into their space or On-Behalf-Of: the marketplace dashboard's drill-down. A member removed from the mode still reads; a user who isn't a member in this mode → 404; from a member's space → 400 validation_failed on userUuid; with includeMembers → 400 on userUuid.
  • Organization-wide reads by uuid: GET /payments/:uuid?includeMembers=true (and GET /bills/:uuid, GET /subscriptions/:uuid, Subscriptions and bills) read a member's row from the organization's space, in its mode, with its userUuid: the row a list with includeMembers showed. Same rules as the lists (a member's space → 400 on includeMembers; another organization's or the other mode's → 404). Read only: refunding it still switches into the member's space (or uses On-Behalf-Of).

Reads

  • GET /payments/:uuid returns one of the space's payments, by its pay@-prefixed uuid (the value emitted as the payment's uuid, its checkout session's) or its bare uuid. Unknown uuid, another kind of id (sub@…: it isn't a payment), another space's or mode's → 404; malformed → 400 validation_failed on uuid.
  • By reference: GET /payments?reference=<reference> (it was GET /transaction/payment/reference/:reference): the list filtered on the merchant's reference, an envelope of 0 or 1 item (items: [] when no payment has it; never 404). References are unique per space, so with includeMembers (or userUuid) it may list one per space read. reference follows the reference validator (max=100): anything else → 400 validation_failed on reference.
  • GET /payments and GET /transactions are cursor-paginated (pagination): the envelope { items, hasMore, nextCursor? }, nextCursor present only when hasMore; ?limit= (20 by default, at most 100: larger is clamped) and ?cursor= (the previous page's nextCursor, verbatim: anything else → 400 validation_failed on cursor).
  • Order: newest first, by createdAt (when the payment or the bill was recorded) then uuid, both descending. Rows recorded at the same instant are told apart by their uuid, so a walk visits every row exactly once, whatever the page size.
  • Filters (both lists, each optional, combined with AND): customerUuid, productUuid, createdAfter, createdBefore (RFC 3339 instants or dates, both excluded; pagination), includeMembers, userUuid (above), refunded (true: only the rows with an approved refund, what a "Refunded" badge means; false: the others, a pending or rejected refund included). GET /payments also takes reference (above). GET /transactions also takes type (payment or bill: one kind of row; it was source, with subscriptionHistory) and subscriptionUuid (sub@… or a bare uuid: that subscription's bills only, so no payment row; another space's subscription gives an empty list). A malformed value → 400 validation_failed on its name (type: one of the two values).
  • The transactions feed (GET /transactions, it was GET /transaction/payments/combined) merges one-time payments and subscription bills into Transaction rows, each with its type (payment or bill; it was source). A row reads like its resource (Payment or Bill): amount / amountMinUnits / amountUsd, currency, priceUsd and fees (a bill's are its subscription's locked price and lines, what each bill charges; priceUsd absent on a bill of a subscription without a locked price), productName, productDescription, settlement, confirmedAt, paid / paidMinUnits / paidUsd, refund / refundable, customer, metadata (a payment's; {} on a bill: its subscription's is on the subscription), and for a bill its subscriptionUuid, subscriptionReference, periodStart and periodEnd.
  • References: a payment row carries its own reference (when it has one). A bill has none of its own (billing runs automatically), so it carries subscriptionReference, its subscription's reference, as the subscription webhooks do. Each is absent when empty. reference, customerUuid, metadata and settlement are the merchant's (whenAuth), as on Payment.

Response fields

  • A payment's uuid is written with its pay@ prefix (a bill's sub-hist@).
  • Absent means no value (naming): reference, customerUuid, customerReference, productUuid, productDescription, note, refund, confirmedAt (only on records made before it was recorded: § When), paid*, userUuid (the organization's own) are absent when they have none (never null or ""). fees is always present ([] without any), metadata too ({}).
  • userUuid, customerUuid, customerReference, reference, note, customer, metadata, settlement, paid* and the refund state are the merchant's (resource:"whenAuth"): present on the authenticated reads, never on the hosted pages' public reads. A payment names no organization.
  • productUuid names the product paid for; absent when the payment has none (an inline product).
  • The currency is the currency object (Currencies: id, code, symbol, name, chain, decimals, address, mainCurrencyId, test) on Payment and Transaction rows; the currencyId key is gone.
  • Where to check it: chain (ETH, BASE or SOL: the chain it was paid on; a test-mode payment's is that chain's testnet, test: true) and explorerUrl (its transaction on the chain's block explorer: Etherscan, Basescan, Solscan, their testnets' in test mode) on Payment, bills, Transaction rows, refunds, and in payment.completed and subscription.billed. Link to explorerUrl rather than building explorer links: QBitFlow may change explorers.
  • Merchant metadata (metadata): the checkout session's metadata, copied once when the payment is recorded (Checkout sessions § Metadata). Read-only on the payment (no route changes it); {} when the checkout had none (a product link's visit, a tip). payment.completed carries it. Never on the hosted pages.
  • The settlement (settlement, the merchant's; it was metadata): how the payment settled: feePercent (QBitFlow's fee, a percent string), organizationFee / referralFee (feePercent, address; absent without one), split (below) and transaction (blockNumber, blockTime, gasUsed, fee and Base's l1Fee in the chain's native coin, nativePriceUsd; absent before the confirmation). referralFee never shows its referral's id nor its terms (until when the referrer earns its share).

Who paid (customer)

  • Every payment, bill and transactions row (and subscription, refund) names its customer (merchant only, API reads): customer: { uuid, firstName, lastName?, email, reference?, deleted }, read with the row, one lookup per page. Absent when the row has no customer. Webhooks keep customerUuid only.
  • A deleted customer still names its rows, with deleted: true (while GET /customers/:uuid answers 404).
  • A customer is always read in its row's own space: a row never names another space's customer.
  • A transactions row also carries customerReference, as Payment does.

Refund state (refund, refundable)

On Payment, bills and Transaction rows (merchant only, API reads):

  • refund: the transaction's refund, if any (uuid, status, initiatedBy, refundPercent, amount, amountMinUnits, amountUsd, createdAt, respondedAt: the Refund fields of the same names, Refunds). One refund per transaction, whatever it became: a payment is never refunded twice (a partial refund isn't followed by another). Its uuid and status are what a "refunded" badge needs (no flat refundUuid / refundStatus keys: one name per concept).
  • refundable: whether a refund would be accepted now (the customer's request, the merchant's POST /refunds/intent). false with notRefundableReason:
    • heldFundsReleased: held for a member and released to them since (checked first);
    • refundExists: it has its refund (a customer's request, pending or answered, or a merchant's refund sent and confirmed). A merchant's refund prepared or being confirmed isn't recorded yet: refundable stays true until it confirms (its intent then answers 409 refund_already_exists).
  • paid / paidMinUnits / paidUsd: everything the customer paid, the refund's base (Refunds § What a refund pays back), from the recorded split. Absent when the split wasn't recorded.

When (confirmedAt, checkoutOpenedAt)

  • confirmedAt (payments and bills alike): when the chain confirmed it, its block's time (settlement.transaction.blockTime, the same instant). When the chain's node doesn't give the block's time, both are the time QBitFlow recorded the confirmation (to the second), so every payment and bill recorded with its settlement.transaction has one; it is absent only on records made before QBitFlow recorded it (and then settlement.transaction.blockTime is absent too). createdAt is when QBitFlow recorded the payment, moments after its block.
  • checkoutOpenedAt (payments): when its checkout session was created (the payment's uuid is the session's).

What the amounts mean

  • USD amounts are decimal strings (naming): amountUsd, priceUsd, paidUsd, a fee line's amountUsd, every …Usd: the exact value, canonical ("12.5", "1000", "0"), never a JSON number. Computed values (a split part, a network fee) have at most 6 decimals.
  • Token amounts come in pairs: amount (in the currency's units, exact: "12.5") and amountMinUnits (the on-chain integer: "12500000"), with amountUsd next to them. amount changed meaning: it was the USD amount (a number); it is now the token amount, and the USD value is amountUsd.
  • amountUsd is what the customer paid, in USD (the price, at the checkout, plus a payment's fees), on Payment, bills and Transaction rows alike; amount / amountMinUnits the same in the currency. It is what the contracts split.
  • A payment's priceUsd is its product's price at the checkout (it was price, a number), and fees what its checkout added (Checkout sessions § Fees: the merchant's lines and the processing fee the customer paid, {type, label, description?, amountUsd}, [] without any): amountUsd = priceUsd + Σ fees.amountUsd. On payments recorded before fees existed, priceUsd is amountUsd and fees is []. QBitFlow's fee is taken on the amount; with a processing fee, the merchant's share (settlement.split.merchant, plus organization on a member's payment) is at least the price and the other lines.
  • settlement.split is how the contracts split it, each part a token amount { amount, amountMinUnits, amountUsd }: platform (QBitFlow's fee), referral (the referrer's share of QBitFlow's fee, apart from platform), organization (the organization's fee on a member's payment) and merchant (what the merchant's wallet received, or what the organization owes a member whose funds it holds); organization and referral are absent when none. platform + referral + organization + merchant = amount, exactly, in each unit (the USD parts are rounded to 6 decimals, the merchant's computed last so they add up to amountUsd). QBitFlow's fee as the accounting export counts it (platformFee) is platform + referral.
  • settlement.split.networkFee is the network fee the customer paid on top of the amount, in the token (absent on payments recorded before it was; "0" when none): not part of the amount, nor of the split. Everything the customer's wallet sent is paid (amount + networkFee): a refund's base (Refunds). settlement.transaction.fee is something else: what the transaction cost its sender, in the chain's native coin.
  • Show the split as recorded: never recompute it from the rates (settlement.feePercent, settlement.organizationFee.feePercent), which round per step.
  • productName and productDescription (they were name and description) are a copy of what was paid for: a payment keeps its checkout's product (the product's name and description when the checkout was created, or its inline ones), a bill its subscription's product when it was billed (the first bill: the checkout's). Editing or deleting the product later never changes them.

Failed payment attempts (GET /payment-failures)

The failures log (it was GET /transaction/failures): every attempt a customer made to pay and couldn't, for the dashboard (why customers fail, and what it costs). A failure is never money: never a payment or a bill, never in the payment lists, the accounting export, the ledger or the metrics' volume (metrics.md counts them apart, under failures). No webhook announces one.

  • What is logged: an attempt the payer signed and sent, or that was refused at send:
    • kind: payment: a one-time payment's attempt; txUuid is pay@…, the uuid its payment has once paid;
    • kind: subscriptionCheckout: a subscription checkout's (its first bill, or a trial's start); txUuid is sub@…, the subscription's uuid once created;
    • kind: bill: every failed bill (sub-hist@…, the bill's uuid once paid), with its subscriptionUuid, the notice of a bill waiting for a new maximum included (category: maxAmountExceeded).

Never an intent refused (a wallet that can't pay is refused at the intent, before anything is signed), never a checkout left to expire, never a bill of a paused or stopped subscription (not billed: nothing failed).

  • A failure's own uuid is a plain uuid (no prefix): a failed attempt isn't a transaction.
  • Once per attempt: an attempt recorded again (a retried step) is still one row. attempt numbers a transaction's failed attempts from 1; a bill's is its dunning's attempt, and the notice of a new maximum spends none (it carries the last attempt's number).
  • code is the error code the payer got (errors), message what they were told (absent when nothing was), createdAt when it failed. category is what the code means, one table for every kind:

| category | Codes | |------------|-------| | insufficientBalance | insufficient_funds, insufficient_native_funds | | allowanceExhausted | insufficient_allowance, allowance_expired, allowance_too_low | | approvalRevoked | token_not_approved | | maxAmountExceeded | max_amount_exceeded | | reverted | tx_failed | | notConfirmed | tx_not_sent (and tx_not_confirmed, no longer sent: only on failures recorded before, errors) | | signatureRejected | invalid_signature, signature_expired | | other | any other code |

A new code may join a category (or other); a new category is a new enum value (clients with exhaustive switches must handle it).

  • What the customer tried to pay, never received: attempted (in the currency's units), attemptedMinUnits (its smallest unit) and attemptedUsd (a decimal string; it was a number), in currency (the currency object; it was currencyId). from: the customer's wallet. txHash: the transaction, when one of this payment was sent (a revert, a timeout); absent otherwise (refused at send, or the hash a payer sent was another transaction's). productUuid when it had a product. customerUuid and customer (as on payments, § Who paid) when QBitFlow knows the customer: a bill's always, a checkout's when the merchant named the customer (a new payer's details are only recorded with their payment).
  • Order and pages: newest first, by createdAt then uuid; the list envelope (pagination), limit 20 by default, at most 100.
  • Filters (each optional, combined with AND): kind, category (a value not listed → 400 validation_failed on its name), subscriptionUuid (sub@… or a bare uuid: that subscription's bills), and the list filters customerUuid, productUuid, createdAfter, createdBefore, includeMembers, userUuid (as the payment lists: § Reads, § Spaces; each member's row names its userUuid).
  • Spaces: the request's space, each mode its own; another organization's attempts are never listed.
  • Kept 25 months (the dashboard's window, and the month before), then deleted.

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)

  • 400invalid_signature

    POST /webhooks/verify: the signature doesn't match, or is older than 5 minutes; a send route: the transaction isn't the payer's signature over what the intent prepared (Payments and transactions § Sending a signed transaction)

  • 400sender_is_receiver

    a transfer whose paying wallet is the wallet it pays (a payment, a subscription, a refund, a release)

  • 422insufficient_funds

    doesn't hold enough of the token (or SOL, for a native payment): top up

  • 422insufficient_native_funds

    can't pay the network fee (ETH, SOL…): top up the network's coin

  • 422insufficient_allowance

    granted QBitFlow less than this amount: increase the allowance

  • 422allowance_expired

    granted an allowance that expired: approve again

  • 422token_not_approved

    hasn't approved Permit2 for the token (EVM): approve it, then retry

  • 422signature_expired

    signed too long ago: sign again (a free trial's message: ask a new intent)

  • 422max_amount_exceeded

    a bill above the subscription's maximum per period (the price moved): approve a higher maximum

  • 422allowance_too_low

    asked for an amount outside the subscription's limits (allowance_too_low, Solana only: a top-up of fewer periods than were spent since the last one granted, which its program refuses until its upgrade; details.minPeriods, the fewest periods it takes)

  • 422tx_failed

    can't act: the transaction failed for a reason no decoder recognized