Deposits history¶
Purpose¶
The Deposits screen is a read-only audit log of every player deposit (crypto, fiat, Skindeck steam-skins). Operators use it to confirm received amounts, investigate "I deposited but balance didn't update" complaints, and reconcile against vault inflow.
Audience¶
Customer support (primary), finance (reconciliation), risk (chargeback investigation). No write actions on this screen.
Path in admin-fe¶
| Screen | URL | Page |
|---|---|---|
| Deposits list | /deposits |
ebit-admin-fe/src/app/(dashboard)/deposits/page.tsx → components/pages/deposits/ |
Backing API endpoints¶
| Endpoint | Source |
|---|---|
GET /admin/payments/deposit (list) |
apps/api/src/payment/deposit/admin.deposit.controller.ts:20 |
GET /admin/payments/deposit/:id |
apps/api/src/payment/deposit/admin.deposit.controller.ts:31 |
Frontend wiring: ebit-admin-fe/src/queries/deposit-history/.
Key actions¶
| Action | Required permission | API call | DB tables touched | Audit-logged? |
|---|---|---|---|---|
| List deposits | deposits.view |
GET /admin/payments/deposit |
Deposit, User (joined) |
yes |
| View one deposit | deposits.view |
GET /admin/payments/deposit/:id |
Deposit, provider raw payload |
yes |
There is no admin re-credit endpoint on this screen. To compensate a player for a stuck deposit, use the tip flow on user-profile.md (POST /admin/admin-tips) — that path is auditable and SuperAdmin-only.
Filters and views¶
- Status —
PENDING,CONFIRMED,FAILED,EXPIRED. - User ID — drill-in from a profile.
- Provider — NowPayments, CCPayment, Skindeck.
- Currency / network — BTC, ETH, USDT-erc20, etc.
- Amount range (USD-equiv).
- Date range.
- Sort —
CREATED_AT,AMOUNT_USD.
Common workflows¶
- "I deposited but my balance didn't update." CS asks for tx hash. Filter
/depositsby user, look for matching tx. Ifstatus=PENDING, advise the player to wait for confirmations. Ifstatus=CONFIRMEDbut balance not credited, escalate (this is theflows/deposit-flowfailure mode — seeflows/). - Reconcile a vault deposit. Finance picks a date range, exports CSV, sums by currency, cross-checks against on-chain ledger and
Vault*tables visible on dashboard.md → finances tab. - Investigate a chargeback. Compliance opens the deposit by ID, copies the provider tx ref, opens provider dashboard for full chain proof. Cross-links to player profile for follow-up restrictions.
- Find Skindeck deposits stuck. Filter
provider=skindeckANDstatus=PENDING. Skindeck has its own BullMQ queue and known timing variability — seeproject_evologger_trace_correlationmemory. - Monthly first-time-deposit (FTD) cohort. Filter
status=CONFIRMEDAND first deposit per user. Cross-reference dashboard.md FTD KPI for sanity.
Edge cases / gotchas¶
PENDINGcan sit for hours on slow networks (BTC). Don't escalate before checking confirmations on-chain.- Skindeck deposits ride a separate webhook + BullMQ queue. State transitions are async; UI may show stale data for ~30s. Refresh.
- Provider
paymentIdis NOTDeposit.id. They are separate identifiers; player ID must come from theDeposit.userIdjoin. Don't paste a Deposit.id into the provider dashboard. - No "credit manually" button. This is intentional. To credit a player off-flow, use the admin-tips path. There is no audit-equivalent direct-credit on Deposit.
- No CSV export from the API. The frontend table component supports browser-side CSV. There is no
?format=csvparam onGET /admin/payments/deposit. - Exchange rate at time of deposit is fixed.
Deposit.amountUsdis computed at confirmation time. Later FX changes do not retro-update — finance uses this on purpose for daily P&L.
Cross-links¶
- Mirror screen: withdrawals.md
- Per-user deposits: user-profile.md → Deposits tab
- Vault balance reconciliation: dashboard.md → finances tab
- Player deposit flow:
flows/→ deposit - Payment provider recipe:
recipes/add-payment-provider.md - KYC tier-gated deposit limits: kyc-limits.md
Sequence — investigating a stuck deposit¶
sequenceDiagram
actor admin
participant admin-fe
participant api
participant pg as Postgres
participant provider as Payment provider
admin->>admin-fe: open /deposits, filter user=123, status=PENDING
admin-fe->>api: GET /admin/payments/deposit?userId=123&status=PENDING
api->>api: PermissionGuard('deposits.view')
api->>pg: SELECT Deposit JOIN User WHERE userId=123 AND status=PENDING
pg-->>api: 1 row
api-->>admin-fe: list
admin->>admin-fe: click row → drill-in
admin-fe->>api: GET /admin/payments/deposit/:id
api->>pg: SELECT Deposit by id (with raw provider payload)
pg-->>api: row + payload JSON
api-->>admin-fe: full record
admin->>provider: open provider dashboard with tx ref
provider-->>admin: 12 confirms — should have credited
admin->>admin-fe: escalate via Telegram + incident channel