173 lines
4.8 KiB
Markdown
173 lines
4.8 KiB
Markdown
# MIB Faisanet — List Accounts & Balances
|
||
|
||
Account numbers and balances are returned by the **Select Profile** call (`routePath: P47`).
|
||
The login initialization call (`A41`) returns an empty `accountBalance` array until a profile is selected.
|
||
|
||
---
|
||
|
||
## Flow to Get Account Balances
|
||
|
||
```
|
||
[0] sfunc=i (key1) → DH key exchange → derive session_key
|
||
[1] sfunc=n A44 → get userSalt
|
||
[2] sfunc=n A41 → login with password → returns operatingProfiles (no balances yet)
|
||
[3] sfunc=n A42 → OTP verify
|
||
[4] sfunc=n P47 → select profile → returns accountBalance array
|
||
```
|
||
|
||
Steps 0–3 are the standard login flow (see `LOGIN_FLOW.md`). Step 4 is the new call.
|
||
|
||
---
|
||
|
||
## Step 1 — Get Profile List from A41 Response
|
||
|
||
The `A41` login initialization response includes `operatingProfiles` — the list of
|
||
profiles available to the user (personal, business, etc.).
|
||
|
||
**Relevant fields from A41 response:**
|
||
|
||
```json
|
||
{
|
||
"defaultProfile": "2",
|
||
"operatingProfiles": [
|
||
{
|
||
"profileId": "<profile ID>",
|
||
"customerProfileId": "<customer profile ID>",
|
||
"annexId": "<annex ID>",
|
||
"customerId": "<customer ID>",
|
||
"name": "<profile display name>",
|
||
"cifType": "Individual",
|
||
"customerImage": "<image hash>",
|
||
"profileType": "0",
|
||
"color": "<hex color>"
|
||
},
|
||
{
|
||
"profileId": "<profile ID>",
|
||
"customerProfileId": "<customer profile ID>",
|
||
"annexId": "<annex ID>",
|
||
"customerId": "<customer ID>",
|
||
"name": "<business name / owner name>",
|
||
"cifType": "Sole Propr",
|
||
"customerImage": "<image hash>",
|
||
"profileType": "1",
|
||
"color": "<hex color>"
|
||
}
|
||
],
|
||
"selectedProfileId": null,
|
||
"selectedProfileType": null,
|
||
"profileSelected": false
|
||
}
|
||
```
|
||
|
||
`profileType` values observed:
|
||
| Value | Meaning |
|
||
|---|---|
|
||
| `"0"` | Individual (personal) |
|
||
| `"1"` | Sole Proprietor (business) |
|
||
|
||
---
|
||
|
||
## Step 2 — Select Profile (`sfunc=n`, `routePath: P47`)
|
||
|
||
**Key**: session key (derived from `sfunc=i` response)
|
||
|
||
**Request:**
|
||
```json
|
||
{
|
||
"sfunc": "n",
|
||
"xxid": "<session xxid>",
|
||
"data": {
|
||
"profileType": "<profileType from operatingProfiles>",
|
||
"profileId": "<profileId from operatingProfiles>",
|
||
"nonce": "<computed nonce>",
|
||
"appId": "<appId>",
|
||
"sodium": "<random 20-bit int>",
|
||
"routePath": "P47",
|
||
"xxid": "<session xxid>"
|
||
}
|
||
}
|
||
```
|
||
|
||
**Response:**
|
||
```json
|
||
{
|
||
"success": true,
|
||
"reasonCode": "101",
|
||
"reasonText": "Profile Selected!",
|
||
"landingPage": "0",
|
||
"accountBalance": [ ... ],
|
||
"accessRights": { ... },
|
||
"services": []
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## accountBalance Array
|
||
|
||
Each element in `accountBalance` represents one account:
|
||
|
||
```json
|
||
{
|
||
"cif": "<CIF number>",
|
||
"accountNumber": "<full account number>",
|
||
"accountBriefName": "<short label, e.g. 'SAR MVR - Savings'>",
|
||
"template": "<display template ID>",
|
||
"currencyCode": "<ISO 4217 numeric code>",
|
||
"currencyName": "<ISO 4217 alpha code>",
|
||
"accountTypeName": "<account type label>",
|
||
"transfer": "Y",
|
||
"branchName": "<branch name>",
|
||
"availableBalance": "<decimal string>",
|
||
"currentBalance": "<decimal string>",
|
||
"blockedAmount": "<decimal string, may be negative>",
|
||
"settlementBalance": "<decimal string>",
|
||
"mvrBalance": "<MVR equivalent as decimal string>",
|
||
"statusDesc": "Active"
|
||
}
|
||
```
|
||
|
||
### Field reference
|
||
|
||
| Field | Description |
|
||
|---|---|
|
||
| `accountNumber` | Full account number |
|
||
| `accountBriefName` | Human-readable account label |
|
||
| `currencyCode` | ISO 4217 numeric (e.g. `"462"` = MVR, `"840"` = USD) |
|
||
| `currencyName` | ISO 4217 alpha (e.g. `"MVR"`, `"USD"`) |
|
||
| `accountTypeName` | Account type (e.g. `"Saving Account"`) |
|
||
| `availableBalance` | Spendable balance |
|
||
| `currentBalance` | Ledger balance |
|
||
| `blockedAmount` | Held/blocked funds (negative means funds are held) |
|
||
| `settlementBalance` | Balance including pending settlements |
|
||
| `mvrBalance` | All balances converted to MVR for display |
|
||
| `transfer` | `"Y"` if account can be used as transfer source |
|
||
| `statusDesc` | Account status (e.g. `"Active"`) |
|
||
| `cif` | Customer Information File number |
|
||
| `template` | UI template ID (controls how card is rendered in-app) |
|
||
|
||
---
|
||
|
||
## accessRights
|
||
|
||
Also returned in the P47 response, describes what the selected profile can do:
|
||
|
||
```json
|
||
{
|
||
"numAccounts": "<number of accounts>",
|
||
"packageRights": "[1,2,3,4,6,7,8,9,10,11,12,...]",
|
||
"roleRights": "[]"
|
||
}
|
||
```
|
||
|
||
`packageRights` is a JSON array encoded as a string — parse it separately.
|
||
|
||
---
|
||
|
||
## Notes
|
||
|
||
- `accountBalance` in the `A41` response is always `[]`. Balances are only returned after `P47`.
|
||
- To switch between profiles (personal ↔ business), call `P47` again with the other profile's `profileId` and `profileType`.
|
||
- `mvrBalance` is always in MVR regardless of the account's native currency, useful for showing a unified total.
|
||
- All balance fields are **decimal strings**, not numbers — parse with `Decimal` for precision.
|