Skip to main content

Admin API

Administrative functions for user management, KYC approval, and admin operations. Access restricted to users with admin role. Includes Xendit integration for Indonesia users.

Get Admin List

GET/api/admins/list

Get Admin List

Retrieve list of all admin users with their KYC status. Joins users table with ekyc_info table to get verification status.

Response

200Admin list retrieved successfully
{
  "admins": [
    {
      "user_id": 1,
      "username": "admin_user",
      "email": "admin@example.com",
      "user_status": "ACTIVE",
      "kyc_status": "APPROVED"
    },
    {
      "user_id": 2,
      "username": "admin_user2",
      "email": "admin2@example.com",
      "user_status": "ACTIVE",
      "kyc_status": "PENDING"
    }
  ]
}
404No admins found
{
  "admins": []
}
500Server error
{
  "error": "Failed to get admin list.",
  "details": "Database connection failed"
}
curl -X GET https://api.brdz.link/api/admins/list \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "x-api-key: YOUR_API_KEY"

Create User by Admin

POST/api/admins/users

Create User by Admin

Create a new user account by admin. Automatically generates temporary password, creates eKYC entry with APPROVED status, and sends welcome email. Validates client existence and email uniqueness. Includes Xendit customer creation for Indonesia users.

Parameters

client_idnumberrequired

Client ID to associate user with

usernamestringrequired

Username for the new user

emailstringrequired

Email address for the new user

phonestringrequired

Phone number for the new user

country_codestringrequired

Country code for eKYC entry

rolestring

User role (default: 'user')

is_wishlistboolean

Wishlist status (default: false)

Request Body

{
  "client_id": 1,
  "username": "newuser123",
  "email": "newuser@example.com",
  "phone": "+628123456789",
  "country_code": "ID",
  "role": "user",
  "is_wishlist": false
}

Response

201User created successfully (Indonesia user with Xendit)
{
  "message": "New user successfully created.",
  "user": {
    "user_id": 123,
    "username": "newuser123",
    "email": "newuser@example.com",
    "phone": "+628123456789",
    "role": "user",
    "user_status": "ACTIVE",
    "created": "2024-01-15T10:30:00Z",
    "updated": "2024-01-15T10:30:00Z",
    "is_wishlist": false
  },
  "temp_password": "User1737888600000!",
  "ekyc_status": "APPROVED",
  "xendit_integration": {
    "psp_provider": "XENDIT",
    "customer_status": "success",
    "customer_id": "cust_1234567890",
    "customer_type": "INDIVIDUAL",
    "database_id": 1
  }
}
400Validation error
{
  "error": "All fields are required, including country_code."
}
404Client not found
{
  "error": "Client not found."
}
500Server error
{
  "error": "Failed to create new user.",
  "details": "Database constraint violation"
}
201_non_idUser created successfully (non-Indonesia user)
{
  "message": "New user successfully created.",
  "user": {
    "user_id": 124,
    "username": "newuser124",
    "email": "newuser2@example.com",
    "phone": "+1234567890",
    "role": "user",
    "user_status": "ACTIVE",
    "created": "2024-01-15T10:30:00Z",
    "updated": "2024-01-15T10:30:00Z",
    "is_wishlist": false
  },
  "temp_password": "User1737888600001!",
  "ekyc_status": "APPROVED"
}
400_duplicateEmail already exists
{
  "error": "Email is already registered under this client."
}
curl -X POST https://api.brdz.link/api/admins/users \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
  "client_id": 1,
  "username": "newuser123",
  "email": "newuser@example.com",
  "phone": "+628123456789",
  "country_code": "ID",
  "role": "user",
  "is_wishlist": false
}'

Approve User KYC

POST/api/admins/approve-kyc/{user_id}

Approve User KYC

Approve user's KYC status by admin. Updates ekyc_info table to set status as APPROVED and user_status as ACTIVE. Logs admin activity for audit trail. Includes Xendit status sync for Indonesia users.

Parameters

user_idnumberrequired

User ID to approve KYC for (path parameter)

Request Body

{}

Response

200KYC approved successfully (Indonesia user)
{
  "message": "KYC Successfully APPROVED by Admin.",
  "user": {
    "user_id": 123,
    "username": "user123",
    "email": "user@example.com",
    "ekyc_status": "APPROVED",
    "user_status": "ACTIVE"
  },
  "xendit_info": {
    "country_code": "ID",
    "psp_provider": "XENDIT",
    "kyc_approved_in_brdz": true
  }
}
404User not found
{
  "error": "User not Found or cant APPROVED."
}
500Server error
{
  "error": "Failed approve KYC.",
  "details": "Database update failed"
}
200_non_idKYC approved successfully (non-Indonesia user)
{
  "message": "KYC Successfully APPROVED by Admin.",
  "user": {
    "user_id": 124,
    "username": "user124",
    "email": "user2@example.com",
    "ekyc_status": "APPROVED",
    "user_status": "ACTIVE"
  }
}
curl -X POST https://api.brdz.link/api/admins/approve-kyc/123 \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "x-api-key: YOUR_API_KEY"

Get User Details

GET/api/admins/users/{user_id}

Get User Details

Get detailed user information including client data, eKYC status, and Xendit integration info (for Indonesia users). Provides comprehensive user profile for admin management with complete Xendit customer information.

Parameters

user_idnumberrequired

User ID to get details for (path parameter)

Request Body

{}

Response

200User details retrieved successfully (Indonesia user with Xendit)
{
  "user": {
    "user_id": 123,
    "username": "user123",
    "email": "user@example.com",
    "phone": "+628123456789",
    "role": "user",
    "user_status": "ACTIVE",
    "created": "2024-01-15T10:30:00Z",
    "updated": "2024-01-15T10:30:00Z",
    "client_id": 1,
    "client_alias": "Example Corp",
    "client_type": "CORPORATE",
    "country_code": "ID",
    "client_code": "EXM001",
    "ekyc_status": "APPROVED",
    "ekyc_verified_at": "2024-01-15T10:35:00Z"
  },
  "xendit_integration": {
    "country_code": "ID",
    "psp_provider": "XENDIT",
    "customer_info": {
      "xendit_customer_id": "cust_1234567890",
      "customer_type": "INDIVIDUAL",
      "status": "ACTIVE",
      "created_at": "2024-01-15T10:30:00Z"
    }
  }
}
404User not found
{
  "error": "User not found."
}
500Server error
{
  "error": "Failed to get user details.",
  "details": "Database connection failed"
}
200_non_idUser details for non-Indonesia user
{
  "user": {
    "user_id": 124,
    "username": "user124",
    "email": "user2@example.com",
    "phone": "+1234567890",
    "role": "user",
    "user_status": "ACTIVE",
    "created": "2024-01-15T10:30:00Z",
    "updated": "2024-01-15T10:30:00Z",
    "client_id": 2,
    "client_alias": "US Corp",
    "client_type": "CORPORATE",
    "country_code": "US",
    "client_code": "USC001",
    "ekyc_status": "APPROVED",
    "ekyc_verified_at": "2024-01-15T10:35:00Z"
  },
  "xendit_integration": null
}
200_no_xenditIndonesia user without Xendit customer
{
  "user": {
    "user_id": 125,
    "username": "user125",
    "email": "user3@example.com",
    "phone": "+628987654321",
    "role": "user",
    "user_status": "ACTIVE",
    "created": "2024-01-15T10:30:00Z",
    "updated": "2024-01-15T10:30:00Z",
    "client_id": 1,
    "client_alias": "Example Corp",
    "client_type": "CORPORATE",
    "country_code": "ID",
    "client_code": "EXM001",
    "ekyc_status": "PENDING",
    "ekyc_verified_at": null
  },
  "xendit_integration": {
    "country_code": "ID",
    "psp_provider": "XENDIT",
    "customer_info": null
  }
}
curl -X GET https://api.brdz.link/api/admins/users/123 \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "x-api-key: YOUR_API_KEY"

Database Operations

Tables Involved

Based on controller implementation with Xendit integration:

users Table

- user_id (primary key)
- client_id (foreign key)
- username (varchar)
- email (varchar)
- phone (varchar)
- password (encrypted with bcrypt)
- role (varchar) - 'admin', 'user', etc.
- user_status (varchar) - 'ACTIVE', 'INACTIVE'
- created (timestamp)
- updated (timestamp)
- is_wishlist (boolean)

ekyc_info Table

- user_id (foreign key)
- country_code (varchar)
- ekyc_status (varchar) - 'PENDING', 'APPROVED', 'REJECTED'
- user_status (varchar) - 'ACTIVE', 'INACTIVE'
- ekyc_verified_at (timestamp)
- created_at (timestamp)
- updated_at (timestamp)

user_activity_logs Table

- user_id (foreign key)
- activity_type (varchar) - 'ADMIN_CREATE_USER', 'ADMIN_APPROVE_KYC'
- description (text)
- created_at (timestamp)

xendit_customers Table

- id (primary key)
- user_id (foreign key to users)
- client_id (foreign key to clients)
- xendit_customer_id (varchar) - Xendit's customer ID
- customer_type (enum) - 'INDIVIDUAL' or 'BUSINESS'
- status (varchar) - 'ACTIVE', 'INACTIVE'
- created_at (timestamp)
- updated_at (timestamp)

xendit_accounts Table

- id (primary key)
- xendit_customer_id (foreign key)
- account_type (varchar)
- account_id (varchar)
- currency (varchar) - default 'IDR'
- balance (numeric)
- status (varchar)
- created_at (timestamp)

SQL Queries Used

Admin List Query

SELECT u.user_id, u.username, u.email, u.user_status, 
COALESCE(e.ekyc_status, 'PENDING') AS kyc_status
FROM users u
LEFT JOIN ekyc_info e ON u.user_id = e.user_id
WHERE u.role = 'admin'
ORDER BY u.user_id DESC;

User Creation Queries

-- Insert user with encrypted password
INSERT INTO users (
client_id, username, email, phone, password, role,
user_status, created, updated, is_wishlist
) VALUES (
$1, $2, $3, $4, crypt($5, gen_salt('bf')), $6,
'ACTIVE', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, $7
)

-- Auto-create eKYC with APPROVED status
INSERT INTO ekyc_info (
user_id, country_code, ekyc_status, user_status,
ekyc_verified_at, created_at, updated_at
) VALUES (
$1, $2, 'APPROVED', 'ACTIVE', CURRENT_TIMESTAMP,
CURRENT_TIMESTAMP, CURRENT_TIMESTAMP
)

User Details Query

SELECT u.user_id, u.username, u.email, u.phone, u.role, u.user_status, u.created, u.updated,
c.client_id, c.client_alias, c.client_type, c.country_code, c.client_code,
e.ekyc_status, e.ekyc_verified_at
FROM users u
LEFT JOIN clients c ON u.client_id = c.client_id
LEFT JOIN ekyc_info e ON u.user_id = e.user_id
WHERE u.user_id = $1

KYC Approval Query

UPDATE ekyc_info
SET ekyc_status = 'APPROVED',
user_status = 'ACTIVE',
ekyc_verified_at = CURRENT_TIMESTAMP
WHERE user_id = $1

Xendit Customer Query (for Indonesia users)

SELECT xendit_customer_id, customer_type, status, created_at
FROM xendit_customers
WHERE user_id = $1

Admin Features

User Creation Process

  1. Validation: Check client existence and email uniqueness
  2. Password Generation: Temporary password format User{timestamp}!
  3. User Insert: Create user with encrypted password using bcrypt
  4. eKYC Setup: Auto-approve KYC status for admin-created users
  5. Xendit Integration: Auto-create Xendit customer for Indonesia users
  6. Activity Logging: Log admin action for audit trail
  7. Email Notification: Send welcome email with temporary password

KYC Approval Process

  1. Status Update: Change ekyc_status to 'APPROVED'
  2. User Activation: Set user_status to 'ACTIVE'
  3. Timestamp: Record ekyc_verified_at timestamp
  4. Activity Logging: Log admin approval action
  5. Xendit Sync: Update customer status for Indonesia users

User Details Retrieval

  1. Comprehensive Data: Fetch user, client, and eKYC information
  2. Xendit Integration: Include Xendit customer details for Indonesia users
  3. Flexible Response: Null xendit_integration for non-Indonesia users
  4. Admin Overview: Complete user profile for administrative purposes

Email Integration

Admin user creation triggers automatic email using emailService:

await sendEmail({
to: email,
subject: "Your New Account",
htmlContent: `
Hello ${username},
Your account has been created by an administrator.
Please login using this email and the temporary password: ${tempPassword}
For your security, please change your password after logging in.
Thank you,
Anantla Team
`
});

Xendit Integration

Admin user creation and KYC approval include Xendit integration for Indonesia users:

// Auto-create Xendit customer for Indonesia users
if (clientCountryCode === 'ID') {
const userPspData = {
user_id: userId,
email: email,
username: username,
phone: phone
};

xenditCustomerResult = await pspService.getPspUser(userPspData, clientCountryCode);
}

Xendit Customer Types

  • INDIVIDUAL: Personal users
  • BUSINESS: Corporate clients

Xendit Features

  • Auto-Creation: Indonesia users automatically get Xendit customer account
  • PSP Integration: Uses pspService.getPspUser() for customer creation
  • Account Management: Links to xendit_accounts for balance tracking
  • Status Sync: KYC approval updates Xendit customer status

Security Features

Password Security

  • bcrypt Encryption: Uses crypt() with gen_salt('bf') for password hashing
  • Temporary Passwords: Format includes timestamp for uniqueness
  • Password Change Required: Users should change temporary password on first login

Access Control

  • Admin Role Required: All endpoints require admin authentication
  • JWT Token Validation: Bearer token authentication required
  • API Key Validation: x-api-key header required

Audit Trail

  • Activity Logging: All admin actions logged to user_activity_logs
  • Detailed Descriptions: Specific action descriptions for tracking
  • Timestamp Tracking: All operations include created/updated timestamps

Xendit Security

  • PSP Service Integration: Secure Xendit customer creation via pspService
  • Country Validation: Xendit integration only for Indonesia (ID) users
  • Error Handling: Xendit failures don't prevent user creation
  • Status Tracking: Customer status tracked in local database

Error Handling

Validation Errors

  • Required Fields: All mandatory fields validated
  • Email Uniqueness: Prevents duplicate emails per client
  • Client Validation: Ensures client exists before user creation

Database Errors

  • Transaction Safety: Database operations wrapped in try-catch
  • Constraint Violations: Foreign key and unique constraint handling
  • Connection Issues: Database connection error handling

Xendit Errors

  • Non-Blocking: Xendit failures don't prevent user creation
  • Graceful Degradation: Service continues without Xendit integration
  • Error Logging: Xendit errors logged for monitoring

Response Format

All errors follow consistent format:

{
error: "Error description",
details: "Technical details" // Optional
}

SDK Integration

The admin module is available in the BRDZ SDK with all 4 functions:

const brdzSDK = require('@anantla/brdz-sdk');

// Get admin list
const adminList = await brdzSDK.admin.getListAdmin();

// Create user by admin
const newUser = await brdzSDK.admin.createUserByAdmin({
client_id: 1,
username: 'newuser123',
email: 'user@example.com',
phone: '+628123456789',
country_code: 'ID'
});

// Approve user KYC
const kycResult = await brdzSDK.admin.approveUserKYC('123');

// Get user details
const userDetails = await brdzSDK.admin.getUserDetails('123');

Admin Access Required

All admin endpoints require authenticated admin user with valid JWT token and API key.

Password Security

Temporary passwords are sent via email. Users should change passwords immediately after first login.

Auto-Approval

Admin-created users automatically receive APPROVED eKYC status, bypassing standard verification process.

Xendit Integration

Indonesia users (country_code: 'ID') automatically get Xendit customer accounts created through PSP service integration.