Skip to main content

Payments & Payouts

Admins can see platform-wide and per-user revenue, review the creator cashout queue, and configure global payout/monetization settings. Four pages: /payments (overview), /payments/cashouts (manual cashout review), /payments/settings (global config), /payments/users/[userId] (per-user drill-down).

This is the admin-side counterpart the user-facing Creator Payouts doc explicitly defers to ("Admin review of manual cashout requests ... and the platform-wide Stripe-vs-manual toggle live in the separate admin GraphQL schema and frontend-admin — not covered by this page"). It was previously undocumented — this is a new doc.

Implementation checklist

Payments overview (/payments)

  • Global revenue dashboard (adminGetGlobalRevenue)

Cashout review queue (/payments/cashouts)

  • List cashout requests, filterable by status/user/provider/date range (adminGetCashouts)
  • Look up a single cashout by id, no ownership check (adminGetCashout)
  • View a user's registered CLABE/RFC/billing address for manual review (adminGetPayoutProfile)
  • Cancel a cashout, with a reason (adminCancelCashout)
  • Mark a manual cashout as processing (adminMarkCashoutProcessing)
  • Complete a manual cashout, with a reference (adminCompleteManualCashout)
  • Reject a manual cashout, returning coins to the creator (adminRejectManualCashout)
  • Emergency-freeze/unfreeze a user's payout account, independent of their Stripe Connect status (adminSetPayoutAccountDisabled)

Global payout settings (/payments/settings)

  • View current settings (adminGetPayoutSettings)
  • Update settings (adminUpdatePayoutSettings), covering:
    • coinsPerUsd — coin→cash conversion rate
    • payoutHoldDays — hold period before a cashout is eligible
    • minCashoutCoins — minimum balance to request a cashout
    • payoutsEnabledGlobally — platform-wide kill switch
    • platformCashoutFeePercent — platform's cut of each cashout
    • cashoutProvider — the Stripe-vs-manual toggle the payouts doc refers to
    • verificationPriceCoins — price of paid verification (also configured here, not on a dedicated verification-settings screen)
    • referralReferrerBonusCoins / referralReferredBonusCoins — the two referral signup bonuses (see Referral Program)

Per-user revenue (/payments/users/[userId])

  • Per-user revenue drill-down (adminGetUserRevenue)

Where this lives

Backend

Frontendapps/frontend-admin/src/app/payments/page.tsx, payments/cashouts/page.tsx, payments/settings/page.tsx, payments/users/[userId]/page.tsx.

GraphQL reference

query GlobalRevenue($dateFrom: DateTime, $dateTo: DateTime) {
adminGetGlobalRevenue(dateFrom: $dateFrom, dateTo: $dateTo) {
totalCoinsPurchased totalPurchaseRevenue completedPurchases totalCashedOut
paidCashoutCount pendingCashoutCount canceledCashoutCount failedCashoutCount
netRevenue activePayoutAccounts
}
}

query Cashouts($filters: AdminCashoutFilters, $limit: Int, $offset: Int) {
adminGetCashouts(filters: $filters, limit: $limit, offset: $offset) {
id coinAmount cashAmount currency status provider providerTransferId
createdAt failureReason canceledReason user { id username }
}
}
# AdminCashoutFilters: { status, userId, provider, dateFrom, dateTo }

query Cashout($id: ID!) { adminGetCashout(id: $id) { id status coinAmount cashAmount provider } }

query PayoutProfile($userId: ID!) {
adminGetPayoutProfile(userId: $userId) { clabe rfc billingAddressLine1 billingCity billingState billingZip billingCountry }
}

mutation CancelCashout($id: ID!, $reason: String) { adminCancelCashout(id: $id, reason: $reason) { id status } }
mutation MarkCashoutProcessing($id: ID!) { adminMarkCashoutProcessing(id: $id) { id status } }
mutation CompleteManualCashout($id: ID!, $reference: String) {
adminCompleteManualCashout(id: $id, reference: $reference) { id status }
}
mutation RejectManualCashout($id: ID!, $reason: String) {
adminRejectManualCashout(id: $id, reason: $reason) { id status }
}
mutation SetPayoutAccountDisabled($userId: ID!, $disabled: Boolean!, $reason: String) {
adminSetPayoutAccountDisabled(userId: $userId, disabled: $disabled, reason: $reason) { userId adminDisabled }
}

query PayoutSettings { adminGetPayoutSettings {
coinsPerUsd payoutHoldDays minCashoutCoins payoutsEnabledGlobally
platformCashoutFeePercent cashoutProvider verificationPriceCoins
referralReferrerBonusCoins referralReferredBonusCoins
}}

mutation UpdatePayoutSettings($input: PayoutSettingsInput!) {
adminUpdatePayoutSettings(input: $input) { id coinsPerUsd payoutHoldDays cashoutProvider }
}

query UserRevenue($userId: ID!) {
adminGetUserRevenue(userId: $userId) {
totalCoinsPurchased totalAmountSpent completedPurchases lifetimeEarned
lifetimeCashedOut totalCashedOutAmount currentBalance availableForCashout cashoutCount
}
}