This commit is contained in:
+187
-132
@@ -1,62 +1,58 @@
|
||||
# Contacts (Beneficiaries)
|
||||
|
||||
Manage the user's saved beneficiary list. All endpoints use WebView session auth — see [README](README.md).
|
||||
Manage the user's saved beneficiary list. All endpoints are on the encrypted API (`sfunc=n`, session key) — see [README](README.md) for the request format.
|
||||
|
||||
```
|
||||
Referer: https://faisamobilex-wv.mib.com.mv/beneficiary?dashurl=1
|
||||
```
|
||||
Contacts belong to the **currently selected** profile — call `P47` for the profile first (see [03-accounts.md](03-accounts.md)).
|
||||
|
||||
Every write returns a `beneficiaryVersion` counter that increments on each change.
|
||||
|
||||
---
|
||||
|
||||
## List Categories
|
||||
|
||||
```
|
||||
POST https://faisamobilex-wv.mib.com.mv/ajaxBeneficiary/getCategories
|
||||
```
|
||||
|
||||
Empty POST body.
|
||||
|
||||
### Response
|
||||
## List Contacts — `routePath: B41`
|
||||
|
||||
**Request**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": [
|
||||
{ "id": "100001", "categoryName": "Myself", "numBenef": "2" },
|
||||
{ "id": "100002", "categoryName": "Friends", "numBenef": "10" },
|
||||
{ "id": "100003", "categoryName": "Business", "numBenef": "8" },
|
||||
{ "id": "100004", "categoryName": "Family", "numBenef": "5" }
|
||||
]
|
||||
"sfunc": "n",
|
||||
"xxid": "<session xxid>",
|
||||
"data": {
|
||||
"start": 1,
|
||||
"end": 10,
|
||||
"benefType": "A",
|
||||
"search": "",
|
||||
"includeCount": 1,
|
||||
"searchCategoryId": 0,
|
||||
"sortBenef": "",
|
||||
"nonce": "<computed nonce>",
|
||||
"appId": "<appId>",
|
||||
"sodium": "<random 20-bit int>",
|
||||
"routePath": "B41",
|
||||
"xxid": "<session xxid>"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Description |
|
||||
|---|---|
|
||||
| `id` | Category ID — use as `searchCategoryId` when filtering contacts |
|
||||
| `categoryName` | Display name |
|
||||
| `numBenef` | Number of beneficiaries in this category (string) |
|
||||
|
||||
---
|
||||
|
||||
## List Contacts
|
||||
|
||||
```
|
||||
POST https://faisamobilex-wv.mib.com.mv/ajaxBeneficiary/main
|
||||
```
|
||||
|
||||
### Request Body (form-urlencoded)
|
||||
|
||||
| Field | Example | Description |
|
||||
|---|---|---|
|
||||
| `page` | `1` | Page number (1-based) |
|
||||
| `search` | `` | Search query (empty = all) |
|
||||
| `searchCategoryId` | `0` | Category filter (`0` = all) |
|
||||
| `start` | `1` | First row (`rnum`, 1-based, inclusive) |
|
||||
| `end` | `10` | Last row (inclusive) |
|
||||
| `benefType` | `A` | `A`=All, `L`=Local, `I`=Internal, `S`=Swift |
|
||||
| `sortBenef` | `name` | Sort field |
|
||||
| `sortDir` | `asc` | Sort direction |
|
||||
| `start` | `1` | Start record index (1-based) |
|
||||
| `end` | `100` | End record index |
|
||||
| `search` | `` | Search query (empty = all) |
|
||||
| `includeCount` | `1` | Include `total_count` |
|
||||
| `searchCategoryId` | `0` | Category filter (`0` = all) |
|
||||
| `sortBenef` | `` | Sort field (empty = default) |
|
||||
|
||||
### Pagination
|
||||
|
||||
Rows are selected by their 1-based `rnum`, both ends inclusive. The client pages in windows of 10:
|
||||
|
||||
| Page | `start` | `end` |
|
||||
|---|---|---|
|
||||
| 1 | `1` | `10` |
|
||||
| 2 | `11` | `20` |
|
||||
| N | `(N-1)*10 + 1` | `N*10` |
|
||||
|
||||
The last row of the final page has `last: "1"`. Stop there, or when total fetched equals `total_count`.
|
||||
|
||||
### Beneficiary Types
|
||||
|
||||
@@ -71,24 +67,42 @@ POST https://faisamobilex-wv.mib.com.mv/ajaxBeneficiary/main
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"total_count": "48",
|
||||
"responseCode": "1",
|
||||
"reasonCode": "103",
|
||||
"reasonText": "beneficiary retrieval success",
|
||||
"total_count": "47",
|
||||
"pos": "0",
|
||||
"data": [
|
||||
{
|
||||
"benefNo": "100001",
|
||||
"benefName": "Person Name",
|
||||
"benefNickName": "Nickname",
|
||||
"benefAccount": "7700000000001",
|
||||
"benefType": "L",
|
||||
"bankColor": "#AC0000",
|
||||
"benefBankName": "Bank of Maldives PLC",
|
||||
"bankCode": "BML",
|
||||
"benefSwiftCode": "MALBMVMV",
|
||||
"benefStatus": "A",
|
||||
"benefBankId": "3",
|
||||
"benefNickName": "Nickname",
|
||||
"benefSwiftCode": "MALBMVMV",
|
||||
"transferCy": "462",
|
||||
"transferCyDesc": "MVR",
|
||||
"customerImgHash": "abcd1234hash",
|
||||
"benefCategoryID": "100002"
|
||||
"customerImgHash": "<image hash>",
|
||||
"benefImgHash": "<image hash>",
|
||||
"benefCategoryID": "100002",
|
||||
"createdDate": "2025-05-25 10:38:49",
|
||||
"rnum": "1",
|
||||
"last": "0"
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"id": "100002",
|
||||
"categoryName": "Friends",
|
||||
"icon": "f095",
|
||||
"createdDate": "2023-05-18 14:35:22",
|
||||
"modifiedDate": "2023-05-19 12:06:05",
|
||||
"numBenef": "23"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -96,37 +110,51 @@ POST https://faisamobilex-wv.mib.com.mv/ajaxBeneficiary/main
|
||||
|
||||
| Field | Consumed | Description |
|
||||
|---|---|---|
|
||||
| `benefNo` | yes | Unique beneficiary ID — use for delete |
|
||||
| `benefNo` | yes | Unique beneficiary ID — use for update and delete |
|
||||
| `benefName` | yes | Legal/full name; used as fallback when nickname is blank |
|
||||
| `benefNickName` | yes | User-assigned nickname (prefer over `benefName` for display) |
|
||||
| `benefAccount` | yes | Account number |
|
||||
| `benefType` | yes | `L`, `I`, or `S` |
|
||||
| `bankColor` | yes | Hex color for placeholder avatar background |
|
||||
| `benefBankName` | yes | Bank display name. Shown as transfer subtitle and contact detail (`MibContactParser.kt:23, 26`). |
|
||||
| `benefBankName` | yes | Bank display name. Shown as transfer subtitle and contact detail (`MibContactParser.kt`). |
|
||||
| `bankCode` | yes | Short bank code (e.g. `"BML"`, `"MIB"`) |
|
||||
| `benefStatus` | yes | Beneficiary status (`"A"` = active) |
|
||||
| `transferCyDesc` | yes | Currency (e.g. `"MVR"`, `"USD"`) |
|
||||
| `customerImgHash` | yes | Hash for fetching profile photo. May be missing, blank, or the literal **string** `"null"` — the client filters all three (`MibContactsClient.kt:120`) so downstream code only sees a real hash or `null`. |
|
||||
| `customerImgHash` | yes | Hash for fetching the contact photo via `B46`. May be missing, blank, or the literal **string** `"null"` — the client filters all three so downstream code only sees a real hash or `null`. |
|
||||
| `benefCategoryID` | yes | Category ID — `"0"` means uncategorized |
|
||||
| `benefSwiftCode` | server-only | SWIFT BIC of the beneficiary's bank — present in payload, not read by the app |
|
||||
| `benefImgHash` | server-only | Photo set on the beneficiary itself; equals `customerImgHash` when set |
|
||||
| `benefSwiftCode` | server-only | SWIFT BIC — present in payload, not read by the app |
|
||||
| `benefBankId` | server-only | Numeric bank ID — not consumed |
|
||||
| `transferCy` | server-only | Currency numeric code (e.g. `"462"`) — only `transferCyDesc` is consumed |
|
||||
| `rnum` / `last` | server-only | Row number and last-row flag, used for paging |
|
||||
|
||||
### Categories
|
||||
|
||||
Every `B41` response carries the full category list in `categories` — there is no separate categories call.
|
||||
|
||||
| Field | Description |
|
||||
|---|---|
|
||||
| `id` | Category ID — use as `searchCategoryId` / `categoryId` |
|
||||
| `categoryName` | Display name |
|
||||
| `numBenef` | Number of beneficiaries in this category (string) |
|
||||
| `icon` | Icon code |
|
||||
|
||||
---
|
||||
|
||||
## Get Profile Image
|
||||
## Get Contact Photo — `routePath: B46`
|
||||
|
||||
**Request** — route fields:
|
||||
```json
|
||||
{ "imageHash": "<customerImgHash>", "routePath": "B46" }
|
||||
```
|
||||
POST https://faisamobilex-wv.mib.com.mv/ajaxBeneficiary/getProfileImage
|
||||
```
|
||||
|
||||
Body: `imageHash=<customerImgHash>`
|
||||
|
||||
### Response
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"msg": "image found",
|
||||
"message": "image found",
|
||||
"profileImage": "<base64-encoded JPEG>"
|
||||
}
|
||||
```
|
||||
@@ -135,98 +163,125 @@ Body: `imageHash=<customerImgHash>`
|
||||
|
||||
---
|
||||
|
||||
## Create Contact
|
||||
## Create Contact — `routePath: B43`
|
||||
|
||||
**Request** — route fields:
|
||||
```json
|
||||
{
|
||||
"benefName": "RECIPIENT NAME",
|
||||
"benefAccount": "7700000000001",
|
||||
"bankNo": "3",
|
||||
"nickName": "Nickname",
|
||||
"transferCy": "462",
|
||||
"categoryId": "0",
|
||||
"image": "<base64 JPEG, optional>",
|
||||
"bankName": "Bank of Maldives PLC",
|
||||
"bankSwift": "MALBMVMV",
|
||||
"routePath": "B43"
|
||||
}
|
||||
```
|
||||
POST https://faisamobilex-wv.mib.com.mv/ajaxBeneficiary/createLocalBeneficiary
|
||||
```
|
||||
|
||||
```
|
||||
Referer: https://faisamobilex-wv.mib.com.mv/beneficiary/createNew
|
||||
```
|
||||
|
||||
### Request Body (form-urlencoded)
|
||||
|
||||
| Field | Description |
|
||||
|---|---|
|
||||
| `benefType` | `"I"` = MIB internal, `"L"` = local/BML |
|
||||
| `benefName` | Full name (from account lookup) |
|
||||
| `benefAccount` | Beneficiary account number |
|
||||
| `benefName` | Full name |
|
||||
| `nickName` | Display nickname |
|
||||
| `bankNo` | `2` = MIB, `3` = BML/local |
|
||||
| `transferCy` | Currency numeric code (`"462"` = MVR) |
|
||||
| `bankNo` | `"2"` = MIB, `"3"` = BML |
|
||||
| `nickName` | Display nickname — **max 20 characters** |
|
||||
| `transferCy` | Currency numeric code (`"462"` = MVR, `"840"` = USD) |
|
||||
| `categoryId` | Category ID (`"0"` = uncategorized) |
|
||||
| `imageSet` | `"1"` if image provided, `"0"` otherwise |
|
||||
| `image` | Base64-encoded image (empty string if none) |
|
||||
| `benefIban` | Leave blank |
|
||||
| `benefAddress` | Leave blank |
|
||||
| `benefCity` | Leave blank |
|
||||
| `benefCountry` | `"4"` |
|
||||
| `benefBankSwift` | Leave blank |
|
||||
| `benefBankName` | Leave blank |
|
||||
| `benefBankBranch` | Leave blank |
|
||||
| `benefBankAddress` | Leave blank |
|
||||
| `benefBankCity` | Leave blank |
|
||||
| `benefBankCountry` | `"4"` |
|
||||
| `intBankSwift` | Leave blank |
|
||||
| `intBankName` | Leave blank |
|
||||
| `intBankAddress` | Leave blank |
|
||||
| `intBankBranch` | Leave blank |
|
||||
| `intBankCity` | Leave blank |
|
||||
| `intBankCountry` | `"4"` |
|
||||
| `transferCySwift` | `"840"` (USD numeric — static) |
|
||||
| `email` | Leave blank |
|
||||
| `contactNumber` | Leave blank |
|
||||
| `website` | Leave blank |
|
||||
| `image` | Base64 JPEG photo. Omit the field when there is no photo. |
|
||||
| `bankName` | Bank name from the login bank list (`A41` `bankData`) |
|
||||
| `bankSwift` | Bank BIC from the same list |
|
||||
|
||||
### Response
|
||||
|
||||
```json
|
||||
{ "success": true }
|
||||
```
|
||||
|
||||
`success: true` confirms the contact was saved.
|
||||
|
||||
---
|
||||
|
||||
## Delete Contact
|
||||
|
||||
```
|
||||
POST https://faisamobilex-wv.mib.com.mv/ajaxBeneficiary/deleteBeneficiary
|
||||
```
|
||||
|
||||
Body: `benefNo=<benefNo>`
|
||||
|
||||
### Response
|
||||
|
||||
```json
|
||||
{ "success": true }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Contact Stats
|
||||
|
||||
```
|
||||
POST https://faisamobilex-wv.mib.com.mv/ajaxBeneficiary/getStats
|
||||
```
|
||||
|
||||
Empty POST body.
|
||||
| `bankNo` | `bankName` | `bankSwift` |
|
||||
|---|---|---|
|
||||
| `2` | Maldives Islamic Bank | `MADVMVMV` |
|
||||
| `3` | Bank of Maldives PLC | `MALBMVMV` |
|
||||
|
||||
### Response
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": [
|
||||
{ "type": "L", "count": "30" },
|
||||
{ "type": "I", "count": "10" },
|
||||
{ "type": "S", "count": "2" }
|
||||
]
|
||||
"responseCode": "1",
|
||||
"reasonCode": "102",
|
||||
"reasonText": "beneficiary creation success",
|
||||
"data": [ { "benefNo": "1336023", "benefNickName": "Nickname", "customerImgHash": "<image hash>", ... } ],
|
||||
"beneficiaryVersion": 8
|
||||
}
|
||||
```
|
||||
|
||||
Gives counts per beneficiary type. Useful for showing tab badges.
|
||||
### Errors
|
||||
|
||||
A nickname over 20 characters is rejected with HTTP `400`:
|
||||
|
||||
```json
|
||||
{ "success": false, "responseCode": "2", "reasonCode": "201", "reasonText": "invalid nick name", "errorKey": "nickName" }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Update Contact — `routePath: B52`
|
||||
|
||||
Same fields as `B43`, plus:
|
||||
|
||||
| Field | Description |
|
||||
|---|---|
|
||||
| `benefNo` | Beneficiary to update |
|
||||
| `imageChanged` | `"1"` when a new `image` is sent, `"0"` to keep the current photo |
|
||||
|
||||
**Request** — route fields:
|
||||
```json
|
||||
{
|
||||
"benefName": "RECIPIENT NAME",
|
||||
"benefAccount": "7700000000001",
|
||||
"bankNo": "3",
|
||||
"nickName": "New nickname",
|
||||
"transferCy": "462",
|
||||
"categoryId": "100002",
|
||||
"benefNo": "240301",
|
||||
"imageChanged": "0",
|
||||
"bankName": "Bank of Maldives PLC",
|
||||
"bankSwift": "MALBMVMV",
|
||||
"routePath": "B52"
|
||||
}
|
||||
```
|
||||
|
||||
### Response
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"responseCode": "1",
|
||||
"reasonCode": "107",
|
||||
"reasonText": "Beneficiary Updated Successfully",
|
||||
"data": [ { "benefNo": "240301", "benefNickName": "New nickname", "customerImgHash": "<image hash>", ... } ],
|
||||
"beneficiaryVersion": 6
|
||||
}
|
||||
```
|
||||
|
||||
Reload the list with `B41` afterwards to pick up the change.
|
||||
|
||||
---
|
||||
|
||||
## Delete Contact — `routePath: B48`
|
||||
|
||||
**Request** — route fields:
|
||||
```json
|
||||
{ "benefNo": "240301", "routePath": "B48" }
|
||||
```
|
||||
|
||||
### Response
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"responseCode": "1",
|
||||
"reasonCode": "108",
|
||||
"reasonText": "Beneficiary deleted Successfully",
|
||||
"beneficiaryVersion": 7
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user