Admin API
The Admin API powers GullyPay internal risk, compliance, and platform-operations tooling: risk monitoring, fraud detection, KYC/KYB review, transaction monitoring, merchant management, chargeback management, and revenue analytics.
Every endpoint below is mounted under /admin and protected by both the JWT auth guard and a role guard requiring the platform admin role. These routes are not available to merchant or developer API keys — a normal authenticated user receives 403 Forbidden. This is an internal operations surface.
Authentication
All requests require a bearer JWT belonging to a user with the admin platform role.
Both guards apply to the entire controller:
JwtAuthGuard— authenticates the caller.RolesGuard+@Roles('admin')— enforces theadminrole.
Endpoints
| Method | Path | Description |
|---|---|---|
GET | /admin/dashboard | Platform risk metrics (rates, blocked count, revenue MTD) |
GET | /admin/risk-alerts | Live risk/fraud alerts derived from real rows |
GET | /admin/merchants | List merchants (optionally by status) |
PATCH | /admin/merchants/:id/status | Set a merchant account status |
PATCH | /admin/merchants/:id/kyc | Record a KYC/KYB review decision |
GET | /admin/transactions | Recent platform transactions |
GET | /admin/audit-logs | Platform-wide audit trail |
GET | /admin/fraud-assessments | Per-transaction fraud/risk assessments |
GET | /admin/chargebacks | Chargebacks / disputes with money + merchant context |
PATCH | /admin/chargebacks/:id | Update a chargeback status (contest / accept / resolve) |
GET | /admin/users | List all users with wallet counts (optional search) |
GET | /admin/users/:id | One user's wallets, activity, and linked merchants |
PATCH | /admin/users/:id/status | Lock / unlock / suspend an account |
PATCH | /admin/wallets/:id/status | Freeze / unfreeze a wallet |
Dashboard
GET /admin/dashboard
Returns platform-wide risk metrics. Rates are decimal fractions (e.g. 0.0123 = 1.23%) and are null when there is no source data in the window (for example, no authorized transactions yet).
Query parameters
| Param | Values | Default | Description |
|---|---|---|---|
window | 24h, 7d, 30d | 30d | Rate-computation window |
platformRevenueMtd is an integer amount in the smallest currency unit (cents) — sum of real fee_ledger_entries for the current month.
Fraud detection
GET /admin/fraud-assessments
Lists per-transaction fraud/risk assessments from the real fraud_assessments table, newest first. Returns an empty array when nothing has been scored.
Query parameters
| Param | Default | Description |
|---|---|---|
limit | 50 | Max rows to return |
offset | 0 | Pagination offset |
decision is one of allow, review, or block. riskScore is 0–100.
Chargeback management
Chargebacks are modelled as rows in the disputes table (a chargeback is a dispute). The list endpoint joins the underlying transaction so each row carries real amount, currency, and merchant context.
List chargebacks
GET /admin/chargebacks
Query parameters
| Param | Default | Description |
|---|---|---|
limit | 50 | Max rows to return |
status | — | Optional filter by status |
Update a chargeback
PATCH /admin/chargebacks/:id
Updates a chargeback's status. Terminal statuses (won, lost, accepted) stamp resolvedAt. The transition is audit-logged with the reviewing admin under the action admin.chargeback.status_changed.
Body
| Field | Type | Description |
|---|---|---|
status | string | One of open, under_review, won, lost, accepted |
notes | string? | Optional reviewer note (stored in the audit log) |
Merchant management
Update merchant status
PATCH /admin/merchants/:id/status
Sets a merchant account status (e.g. active, suspended, blocked). The change is audit-logged under admin.merchant.status_changed, which is a real signal feeding blocked24h and the risk alerts feed.
Body
| Field | Type | Description |
|---|---|---|
status | string | One of pending, active, suspended, deactivated, blocked, banned, rejected |
reason | string? | Optional reason |
KYC / KYB review
PATCH /admin/merchants/:id/kyc
Records a KYC/KYB decision. Approval activates the merchant; rejection sets status rejected. Audit-logged under admin.merchant.kyc_reviewed.
Body
| Field | Type | Description |
|---|---|---|
decision | string | approved or rejected |
notes | string? | Optional reviewer note |
Users & wallets
Every account is a user with a personal wallet; becoming a merchant is an opt-in upgrade. Admins therefore need visibility and compliance controls over all users, including wallet-only ones.
GET /admin/users?search=&limit=50&offset=0 lists users (newest first) with a real per-user wallet count. search matches email / first / last name (case-insensitive).
GET /admin/users/:id returns one user's profile, their wallets (chain, address, status — never the encrypted key), recent ledger activity across those wallets, and any merchants they can access via the org/team chain. Real rows only; empty arrays when there is nothing.
Compliance actions
PATCH /admin/users/:id/status with { "status": "locked" | "suspended" | "active" }. Locking or suspending revokes all of the user's sessions, and login + token refresh fail-close on a non-active status — so the account is locked out immediately.
PATCH /admin/wallets/:id/status with { "status": "frozen" | "active" }. A frozen wallet can still be read (balances, address, history) but cannot move funds — send and swap fail-close on status = "frozen".
Both actions are audit-logged (admin.user.status_changed, admin.wallet.status_changed).
Risk monitoring
GET /admin/risk-alerts returns a real-time, derived alert feed (blocked merchants, open disputes, large refunds, failed-payment spikes, high-value pending payouts, and blocked fraud assessments). Each alert has a severity of low, medium, or high. Returns [] when nothing qualifies.
GET /admin/transactions?limit=50 returns recent platform transactions for transaction monitoring.
Audit log
GET /admin/audit-logs?limit=100 returns the platform-wide audit trail (newest first), including the admin actions above (admin.merchant.status_changed, admin.merchant.kyc_reviewed, admin.chargeback.status_changed, admin.user.status_changed, admin.wallet.status_changed).
Errors
| Status | Meaning |
|---|---|
401 Unauthorized | Missing or invalid JWT |
403 Forbidden | Authenticated user lacks the admin role |
404 Not Found | Referenced merchant or chargeback does not exist |