6.5 KiB
Account Lookup & Transfer
Two-step process: look up the recipient to validate the account and get the holder name, then execute the transfer.
All endpoints are on the WebView subdomain. See README for cookie and AJAX header format.
Referer: https://faisamobilex-wv.mib.com.mv/transfer/quick
Step 1 — Account Lookup
The lookup endpoint depends on the format of the input:
| Input format | Endpoint | Body field |
|---|---|---|
Starts with 7, exactly 13 digits |
AjaxAlias/getIPSAccount |
benefAccount |
Starts with 9, exactly 17 digits |
ajaxBeneficiary/getAccountName |
accountNo |
Starts with 7 or 9, exactly 7 digits |
AjaxAlias/getAlias |
aliasName |
Starts with A followed by 6 digits |
AjaxAlias/getAlias |
aliasName |
Contains @ (email) |
AjaxAlias/getAlias |
aliasName |
1a. IPS Account — BML / local bank (13 digits, starts with 7)
POST https://faisamobilex-wv.mib.com.mv/AjaxAlias/getIPSAccount
Body: benefAccount=7700000000000
Response:
{
"success": true,
"responseCode": "2",
"accountName": "ACCOUNT HOLDER NAME",
"bankBic": "MALBMVMV"
}
accountName— account holder namebankBic— bank BIC (e.g.MALBMVMVfor BML)- Account number is the input itself — not returned in response
Use bankNo=3 and transferLocal for the transfer.
USD cross-bank accounts:
getIPSAccountonly succeeds for MVR cross-bank accounts. A 13-digit7…account that is denominated in USD returnssuccess: falsehere and cannot be resolved via IPS at all. The client hardcodescurrency = "MVR"for IPS results (MibTransferClient.kt:135-137). For USD BML→MIB transfers the user must first save a BML contact (see Notes below).
1b. MIB Internal Account (17 digits, starts with 9)
POST https://faisamobilex-wv.mib.com.mv/ajaxBeneficiary/getAccountName
Body: accountNo=90100000000000000
Response:
{
"success": true,
"accountName": "ACCOUNT HOLDER NAME",
"currencyCode": "462"
}
accountNamemay be at root level or inside adataobject — check both (MibTransferClient.kt:160-161)currencyCodemay also be at root level or insidedata(MibTransferClient.kt:162-163)."462"= MVR,"840"= USD. The client maps this intoMibIpsAccountInfo.currency∈{"MVR", "USD", ""}— this is the MIB→MIB USD detection fix from commit16fd909.- Bank is always MIB (
MADVMVMV)
Use bankNo=2 and transferInternal for the transfer.
1c. Favara Alias — shortcodes, A-IDs, emails
POST https://faisamobilex-wv.mib.com.mv/AjaxAlias/getAlias
Body: aliasName=<alias>
Response:
{
"success": true,
"responseCode": "2",
"data": {
"BfyNm": "Account Holder Name",
"CdtrAcct": {
"Acct": "90100000000000000",
"FinInstnId": "MADVMVMV"
}
}
}
BfyNm— beneficiary name (trim whitespace)CdtrAcct.Acct— resolved account number to use for the transferCdtrAcct.FinInstnId— bank BIC (MADVMVMV= MIB,MALBMVMV= BML)
Use bankNo=2 (MIB) or 3 (BML/local) depending on FinInstnId, and the matching transfer endpoint.
Lookup Errors
All three lookup endpoints return success: false with a human-readable reasonText on failure:
{
"success": false,
"reasonText": "Account not found"
}
Always show reasonText directly to the user.
Step 2 — Execute Transfer
Two endpoints depending on the destination bank:
bankNo |
Endpoint | Destination |
|---|---|---|
2 |
ajaxTransfer/transferInternal |
MIB internal account |
3 |
ajaxTransfer/transferLocal |
BML or other local bank |
POST https://faisamobilex-wv.mib.com.mv/ajaxTransfer/transferInternal
POST https://faisamobilex-wv.mib.com.mv/ajaxTransfer/transferLocal
Request Body (form-urlencoded)
| Field | Description |
|---|---|
benefName |
Recipient name (from lookup) |
benefNo |
0 (not a saved contact) |
fromAccountNo |
Source account number |
benefAccountNo |
Destination account number |
transferCy |
Currency numeric code ("462" = MVR, "840" = USD) |
benefCurrencyCode |
Same as transferCy |
amount |
Amount as string (e.g. "100.00") |
bankNo |
2 = MIB internal, 3 = local/BML |
purpose |
Transfer purpose; send "-" if blank |
otp |
OTP from the user |
otpType |
"3" (SMS/authenticator OTP) |
Response — Success
{
"success": true,
"data": [
{
"trxId": "TRX20260516001",
"date": "2026-05-16 15:10:25"
}
]
}
| Field | Description |
|---|---|
trxId |
Transaction ID |
date |
Completion timestamp |
Response — Failure
{
"success": false,
"reasonText": "Insufficient balance"
}
reasonText contains the error reason. On HTTP 419, the session has expired — re-login required.
Transfer Type Summary
| Recipient | Lookup endpoint | bankNo |
Transfer endpoint |
|---|---|---|---|
MIB (17-digit 9…) |
getAccountName |
2 |
transferInternal |
BML (13-digit 7…) |
getIPSAccount |
3 |
transferLocal |
| Favara alias → MIB | getAlias |
2 |
transferInternal |
| Favara alias → BML | getAlias |
3 |
transferLocal |
Currency Codes
transferCy |
Currency |
|---|---|
"462" |
MVR (Maldivian Rufiyaa) |
"840" |
USD |
MibIpsAccountInfo (client model)
All three lookups return this unified structure (MibModels.kt:42-47):
| Field | Description |
|---|---|
accountName |
Account holder name (trimmed) |
accountNumber |
Resolved account number |
bankId |
Bank BIC (MADVMVMV = MIB, MALBMVMV = BML, etc.) |
currency |
"MVR", "USD", or "" (unknown). Populated from currencyCode for MIB internal lookups; hardcoded "MVR" for IPS lookups; default "" for alias lookups. |
Notes
- BML → MIB USD transfers require a saved BML contact first. Because
getIPSAccountrejects USD accounts (success: false), the app cannot validate the BML USD account number directly. The workaround inTransferFragment.ktis to callMibContactsClient.createContact(see 09-contacts.md) to auto-add the BML account as a beneficiary, then transfer to that beneficiary. Introduced in commit16fd909. - Session expiry: HTTP
419on either lookup or transfer means the session expired. See README for the unified expiry detection rules.
← Personal Profile Next → Contacts