Cards

Card Top-Ups

Create top-ups and list top-up records for mobile users.

Flow Summary

The top-up flow is:

Step 1. Make sure the source card is active Use Card List to confirm card status first

Step 2. Start a top-up Use POST /api/v1/card-topup

Step 3. Check the top-up record Use GET /api/v1/card-topup

Step 4. Load the authenticated user's top-up history Use GET /api/v1/card-topup/history

Step 5. Load only the filtered total amount when needed Use GET /api/v1/card-topup/history/sum

All routes below should be treated as protected routes and sent with:

Authorization: Bearer <access_token>

1. Create Card Top-Up

POST /api/v1/card-topup

Creates a new top-up order for a card.

Request

{
  "amount": 100.00,
  "card_id": 508
}

URL Query Parameters:

  • method (optional): Payment method
    • agent_pay: Agent pays on behalf of user using agent's prepaid balance
    • user_pay: User pays directly via payment gateway (default)

Request rules

  • amount is required
  • card_id is required
  • card_id is the local numeric card record ID
  • method is optional URL parameter, defaults to user_pay if not provided

Important backend behavior

  • The card must belong to the current user
  • The card must currently be ACTIVE
  • The input amount is treated as the user's USDT funding amount
  • Fees, adjusted exchange rate, and the final net amount are calculated server-side
  • The new top-up row is created with status = PENDING
  • After the DB row is created, the service makes a synchronous RPC call to create a payment order

Success response

{
  "status_code": 201,
  "message": "Success",
  "data": {
    "id": 123,
    "uuid": "550e8400-e29b-41d4-a716-446655440000",
    "card_id": "508",
    "amount": "100.00",
    "amount_usdt": "100.00",
    "net_amount": "99.20",
    "top_up_fee": "0.80",
    "exchange_rate": 0.998857,
    "status": "PENDING",
    "merchant_order_sn": "HTP-550e8400-e29b-41d4-a716-446655440000",
    "created_at": "2024-01-15T10:30:00Z"
  }
}

Response fields:

  • id: Local database ID
  • uuid: Top-up unique identifier
  • card_id: Card ID (as string)
  • amount: Gross amount in cents, formatted to 2 decimal places
  • amount_usdt: USDT amount from user
  • net_amount: Net amount after fee, formatted to 2 decimal places
  • top_up_fee: Fee charged for top-up, formatted to 2 decimal places
  • exchange_rate: Exchange rate applied at time of top-up
  • status: Top-up status (PENDING, SUCCESS, FAILED, etc.)
  • merchant_order_sn: Unique merchant order reference for payment tracking
  • created_at: ISO 8601 timestamp

2. List Card Top-Ups

GET /api/v1/card-topup

Lists top-up records with pagination.

Query parameters

NameRequiredNotes
pageNoDefault 1
limitNoDefault 10
searchNoFree-text search
statusNoFilters by top-up status
start_dateNoDate range start (Note: uses start_date, not from_date)
end_dateNoDate range end (Note: uses end_date, not to_date)

Important backend caveat

  • The current repository implementation is not explicitly scoped to the authenticated mobile user
  • In practice, this behaves more like a shared top-up list filtered only by the provided query params
  • Clients should treat this as an implementation gap and avoid assuming strict user-only isolation until the backend is tightened

3. Get Current User Top-Up History

GET /api/v1/card-topup/history

Returns the authenticated user's top-up history with pagination.

Query parameters

NameRequiredNotes
pageNoDefault 1
limitNoDefault 10
statusNoCommon values include SUCCESS, FAILED, PENDING, EXPIRED, REFUNDED
date_fromNoStart date in YYYY-MM-DD
date_toNoEnd date in YYYY-MM-DD

Important backend behavior

  • This history endpoint is scoped to the authenticated mobile_user_id
  • The response includes top-up records across all cards that belong to that mobile user, not just one specific card
  • Use this route instead of the broader list endpoint when the app needs a user-safe history view
  • If date_from or date_to cannot be parsed, the backend returns an empty success response instead of a validation error
  • If both dates are provided and date_to is earlier than date_from, the backend also returns an empty success response
  • If you only need the filtered total amount, prefer GET /api/v1/card-topup/history/sum

4. Get Current User Top-Up History Sum

GET /api/v1/card-topup/history/sum

Returns only the filtered total top-up amount for the authenticated user.

Query parameters

NameRequiredNotes
pageNoIgnored by the backend. Accepted only for compatibility with the history list endpoint
limitNoIgnored by the backend. Accepted only for compatibility with the history list endpoint
statusNoCommon values include SUCCESS, FAILED, PENDING, EXPIRED, REFUNDED
date_fromNoStart date in YYYY-MM-DD
date_toNoEnd date in YYYY-MM-DD

Success response

{
  "status_code": 200,
  "message": "Success",
  "data": {
    "total_top_up_usd": "250.00"
  }
}

Important backend behavior

  • This endpoint uses the same filter rules as GET /api/v1/card-topup/history
  • The result is scoped to the authenticated mobile_user_id
  • The sum is calculated across all cards that belong to that mobile user under the current filters
  • If date_from or date_to cannot be parsed, the backend returns success with total_top_up_usd = "0.00"
  • If both dates are provided and date_to is earlier than date_from, the backend also returns 0.00
  • Use this route when the app needs only the filtered total and does not need the paginated history items
Copyright © 2026