Files
thijooree/docs/mibapi/08-transfer.md
T
shihaam a8cd22cbe1
Auto Tag on Version Change / check-version (push) Failing after 13m32s
update docs
2026-06-13 21:30:12 +05:00

233 lines
6.5 KiB
Markdown

# 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](README.md) 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**:
```json
{
"success": true,
"responseCode": "2",
"accountName": "ACCOUNT HOLDER NAME",
"bankBic": "MALBMVMV"
}
```
- `accountName` — account holder name
- `bankBic` — bank BIC (e.g. `MALBMVMV` for BML)
- Account number is the input itself — not returned in response
Use `bankNo=3` and `transferLocal` for the transfer.
> **USD cross-bank accounts**: `getIPSAccount` only succeeds for **MVR** cross-bank accounts. A 13-digit `7…` account that is denominated in USD returns `success: false` here and cannot be resolved via IPS at all. The client hardcodes `currency = "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**:
```json
{
"success": true,
"accountName": "ACCOUNT HOLDER NAME",
"currencyCode": "462"
}
```
- `accountName` may be at root level or inside a `data` object — check both (`MibTransferClient.kt:160-161`)
- `currencyCode` may also be at root level or inside `data` (`MibTransferClient.kt:162-163`). `"462"` = MVR, `"840"` = USD. The client maps this into `MibIpsAccountInfo.currency``{"MVR", "USD", ""}` — this is the **MIB→MIB USD detection** fix from commit `16fd909`.
- 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**:
```json
{
"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 transfer
- `CdtrAcct.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:
```json
{
"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
```json
{
"success": true,
"data": [
{
"trxId": "TRX20260516001",
"date": "2026-05-16 15:10:25"
}
]
}
```
| Field | Description |
|---|---|
| `trxId` | Transaction ID |
| `date` | Completion timestamp |
### Response — Failure
```json
{
"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 `getIPSAccount` rejects USD accounts (`success: false`), the app cannot validate the BML USD account number directly. The workaround in `TransferFragment.kt` is to call `MibContactsClient.createContact` (see [09-contacts.md](09-contacts.md)) to auto-add the BML account as a beneficiary, then transfer to that beneficiary. Introduced in commit `16fd909`.
- **Session expiry**: HTTP `419` on either lookup or transfer means the session expired. See [README](README.md) for the unified expiry detection rules.
---
&nbsp;
---
[← Personal Profile](07-profile.md) &nbsp;&nbsp;&nbsp; **Next →** [Contacts](09-contacts.md)