BIO.RE
Payment

Get Wallet Balance

Read the calling user's FAN wallet balance and frozen flag. Returns 0.00 + frozen=false if no wallet row exists yet (no auto-create on read).

GET /api/v1/wallet/balance — 🔑 Bearer

Returns the calling user's FAN-type wallet balance (decimal as string, fixed 2 places) and the frozen flag. If no wallet row exists yet, returns { balance: '0.00', frozen: false } without creating one — the wallet is auto-created lazily on first load (POST /wallet/load).

frozen: true blocks debits. When admin / fraud detection freezes a wallet, debits (e.g. paying for a DM) are rejected, but the balance is still readable. Surface a banner on frozen: true so the user understands why their next payment fails.

Decimal as string. Balance is returned as a string ("25.00", not 25.00) to preserve precision across JS clients. Parse with Number(s) or a decimal library — never compare two balance strings with === after arithmetic.

Request

No body, no params.

HeaderRequiredNotes
Authorization: Bearer <accessToken>JWT from POST /auth/login

Response

200 OKApiResponseOf<WalletBalanceResponseDto>

{
  "success": true,
  "data": {
    "balance": "25.00",
    "frozen": false
  }
}
FieldTypeNotes
balancestring (decimal)Always 2 decimal places. "0.00" when no wallet row exists yet.
frozenbooleantrue when admin / fraud detection has frozen the wallet (blocks debits, not reads).

Errors

HTTPcode / i18nKeyReason
401(guard)Missing / invalid bearer token
503features.payment_disabledAdmin kill switch PAYMENT is active

Side effects

  1. prisma.wallet.findUnique({ where: { userId_type: { userId, type: 'FAN' } } }).
  2. Wallet missing — short-circuit return { balance: '0.00', frozen: false }. No row creation, no mutations.
  3. Wallet exists — return { balance: <Prisma.Decimal>.toFixed(2), frozen: wallet.frozen }.

Code samples

curl https://api.bio.re/api/v1/wallet/balance \
  -H "Authorization: Bearer $ACCESS_TOKEN"
type WalletBalance = {
  balance: string; // decimal as string, e.g. "25.00"
  frozen: boolean;
};

async function getWalletBalance(accessToken: string): Promise<WalletBalance> {
  const res = await fetch('https://api.bio.re/api/v1/wallet/balance', {
    headers: { Authorization: `Bearer ${accessToken}` },
  });
  const json = await res.json();
  if (!res.ok || !json.success) {
    throw Object.assign(new Error(json?.error?.message ?? 'Wallet balance fetch failed'), {
      code: json?.error?.code,
    });
  }
  return json.data;
}
import { useQuery } from '@tanstack/react-query';

export const walletKeys = {
  balance: () => ['wallet', 'balance'] as const,
};

export function useWalletBalance() {
  return useQuery({
    queryKey: walletKeys.balance(),
    queryFn: async () => {
      const res = await fetch('/api/v1/wallet/balance');
      const json = await res.json();
      if (!res.ok || !json.success) {
        throw Object.assign(new Error(json?.error?.message ?? 'Wallet balance fetch failed'), {
          code: json?.error?.code,
          i18nKey: json?.error?.i18nKey,
        });
      }
      return json.data as WalletBalance;
    },
    // Balance changes via /load (user action) and via webhook (server-side). Refresh on focus.
    staleTime: 30_000,
  });
}

Try it

GET
/api/v1/wallet/balance
AuthorizationBearer <token>

In: header

Response Body

application/json

application/json

curl -X GET "https://loading/api/v1/wallet/balance"
{
  "success": true,
  "data": {
    "balance": "25.00",
    "frozen": false
  }
}
{
  "success": false,
  "error": {
    "code": "AUTH_UNAUTHORIZED",
    "message": "Invalid credentials",
    "i18nKey": "auth.login.invalid_credentials",
    "i18nVars": {
      "field": "email"
    },
    "details": [
      {
        "message": "email must be an email"
      }
    ],
    "correlationId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
  }
}

Source

SourcePathLines
Controllerapps/api-core/src/modules/payment/wallet.controller.ts30–36 (getBalance)
DTO (response)apps/api-core/src/modules/payment/dto/wallet-response.dto.ts30–37 (WalletBalanceResponseDto)
Serviceapps/api-core/src/modules/payment/wallet.service.ts59–65 (getBalance)
Prisma modelpackages/prisma/prisma/schema.prismaWallet (compound unique userId_type), enum WalletType.FAN

On this page