Payments
Settings
Read current runtime settings and update the exchange-rate adjustment percentage.
Flow Summary
The current settings flow is:
Step 1. Read current settingsGET /api/v1/settings
Step 2. Update exchange-rate adjustment percentagePATCH /api/v1/settings/exchange-rate-adjustment-percentage
Both routes should be treated as protected and require Authorization.
Important Access Note
- the route is mounted behind the global
AuthMiddleware() GET /api/v1/settingsalso explicitly requires a validagent_idin request context- although the Swagger comment says the GET route is public, the current code is not public
1. Get Current Settings
GET /api/v1/settings
Returns the singleton settings row as an array with exactly one object.
Success response shape
{
"status_code": 200,
"message": "Success",
"data": [
{
"is_topup_enabled": false,
"is_static_wallet_enabled": true,
"is_auto_approve_kyc": false,
"is_auto_approve_card_request": false,
"wallet_address": "T...",
"is_withdrawal_enabled": true,
"withdrawal_fee_rate": "1.5",
"exchange_rate_adjustment_percentage": "3.5",
"hold_withdrawal_card_id": 12,
"hold_withdrawal_card_uuid": "d4c7..."
}
]
}
Important backend behavior
- the service loads one settings record but still returns it wrapped in an array
withdrawal_fee_rateandexchange_rate_adjustment_percentageare stored as scaled integers in the database, then unscaled before responsehold_withdrawal_card_uuidis joined from thecardstable and may be empty if no hold card is configured- if the authenticated
agent_idmatchesAGENT_WHITELISTin config, the service forcibly setsis_topup_enabled = truein the response even if the stored database value isfalse
Error behavior
- if no settings row exists, the service returns a logical
404 - if auth succeeds but
agent_idis missing from context, the handler returns a logical401
2. Update Exchange Rate Adjustment Percentage
PATCH /api/v1/settings/exchange-rate-adjustment-percentage
Updates the exchange-rate adjustment percentage using a string payload.
Request body
{
"exchange_rate_adjustment_percentage": "3.5"
}
Validation rules
- the field is parsed as a decimal string
- empty values are rejected
- valid range is
0to99.99 - more than two decimal places are rejected
- the value is scaled by
100before storage
Success response
{
"status_code": 200,
"message": "Success",
"data": {
"exchange_rate_adjustment_percentage": "3.5"
}
}
Important backend behavior
- the repository updates the first settings row ordered by
id ASC - this endpoint updates only
exchange_rate_adjustment_percentage - the response echoes the original request string, not the normalized stored value
Security caveat
- the route is protected by auth, but the current handler does not perform any role or agent-ownership check
- in the current implementation, any authenticated bearer token that reaches this route can attempt to update the global setting
Integration Notes
- Treat
GET /api/v1/settingsas an authenticated bootstrap read for runtime flags. - Do not assume
datais an object; it is currently an array with one item. - If you expose the patch route in a client tool, add your own role guard until the backend enforces one.