alat/modules/account.rs
1//! Account maintenance — wallet balance/details and transaction history.
2//!
3//! These endpoints belong to the **Wallet Services – Account Management** product
4//! (`/ws-acct-mgt`) and let you inspect wallets your channel manages: their
5//! current balance/status, and a list of past transactions over a date range.
6//!
7//! # Ecosystem concepts
8//! - **NUBAN**: the standard 10-digit Nigerian account number identifying a wallet.
9//! - **Available vs. ledger balance**: the API exposes a single
10//! `availableBalance` here (the spendable amount). Note it is returned as a
11//! **string**, not a number — see [`WalletAccountDetails::available_balance`].
12
13use crate::client::Client;
14use crate::envelope::ServiceResponse;
15use crate::error::Result;
16use serde::{Deserialize, Serialize};
17
18/// A wallet's identity, balance, and status.
19///
20/// This is the `result` object of `B2BGetAccountV2ReponseServiceResponse`.
21#[derive(Debug, Clone, Serialize, Deserialize)]
22#[serde(rename_all = "camelCase")]
23pub struct WalletAccountDetails {
24 /// The 10-digit NUBAN of the wallet (the API names this `walletNumber`).
25 pub wallet_number: String,
26 /// The spendable balance. **Returned as a string by the API** (e.g.
27 /// `"1500.00"`); parse it yourself if you need arithmetic, to avoid the
28 /// rounding hazards of binary floating point on money.
29 pub available_balance: String,
30 /// The wallet's status (e.g. `"Active"`, `"Dormant"`, `"PND"`).
31 pub wallet_status: String,
32 /// The account/product type (e.g. `"Wallet"`).
33 pub account_type: String,
34}
35
36/// Request body for the transaction-history lookup.
37///
38/// Server type: `TransactionhistoryV2Request`. The window is expressed with
39/// `from`/`to` (the API does **not** offer page-number/page-size paging here).
40#[derive(Debug, Clone, Serialize, Deserialize)]
41#[serde(rename_all = "camelCase")]
42pub struct TransactionHistoryRequest {
43 /// The 10-digit NUBAN whose history to fetch.
44 pub account_number: String,
45 /// Start of the date range. The API accepts a date/date-time string; use the
46 /// format your channel was onboarded with (commonly `YYYY-MM-DD`).
47 pub from: String,
48 /// End of the date range (same format as [`from`](Self::from)).
49 pub to: String,
50 /// Optional free-text filter applied to the transactions (narration, etc.).
51 #[serde(skip_serializing_if = "Option::is_none")]
52 pub key_word: Option<String>,
53}
54
55/// A single transaction row.
56///
57/// Shared by both the account-history (`transhistoryV2`) and statement
58/// (`GetCustomerTransactions`) endpoints; fields absent from one of them are
59/// modeled as `Option`. Several JSON keys carry the API's own spellings
60/// (`recieverName`, etc.) and are mapped to clean Rust names via `serde(rename)`.
61#[derive(Debug, Clone, Serialize, Deserialize)]
62#[serde(rename_all = "camelCase")]
63pub struct Transaction {
64 /// Short title/label for the transaction.
65 pub title: Option<String>,
66 /// Transaction amount.
67 pub amount: f64,
68 /// Channel/route of the transaction (e.g. `"InterBank"`, `"IntraBank"`).
69 #[serde(rename = "type")]
70 pub transaction_type: Option<String>,
71 /// Display date string.
72 pub date: Option<String>,
73 /// Posting date/time (present on account history; absent on statements).
74 pub transaction_date: Option<String>,
75 /// Human-readable narration.
76 pub narration: Option<String>,
77 /// Transaction status (e.g. `"Default"`, `"Successful"`).
78 pub status: Option<String>,
79 /// Credit type classification (e.g. `"Default"`).
80 pub credit_type: Option<String>,
81 /// Sender's display name.
82 pub sender: Option<String>,
83 /// Sender's account number.
84 pub sender_account_number: Option<String>,
85 /// Destination bank name.
86 pub destination_bank: Option<String>,
87 /// Destination account number.
88 pub destination_account_number: Option<String>,
89 /// Receiver's display name (API key is the misspelled `recieverName`).
90 #[serde(rename = "recieverName")]
91 pub receiver_name: Option<String>,
92 /// Reference id for the transaction.
93 pub reference_id: Option<String>,
94 /// Whether a receipt can be viewed for this transaction.
95 pub is_view_receipt_enabled: Option<bool>,
96 /// Core-banking transaction id.
97 pub tran_id: Option<String>,
98}
99
100impl Client {
101 /// Fetches a wallet's balance, status, and type by NUBAN.
102 ///
103 /// `GET /ws-acct-mgt/api/AccountMaintenance/CustomerAccount/GetAccountV2/accountNumber/{accountNumber}`
104 pub async fn get_wallet_details(&self, account_number: &str) -> Result<WalletAccountDetails> {
105 let path = format!(
106 "ws-acct-mgt/api/AccountMaintenance/CustomerAccount/GetAccountV2/accountNumber/{}",
107 account_number
108 );
109 self.get_json::<ServiceResponse<WalletAccountDetails>>(&path, &[], &[])
110 .await?
111 .into_result()
112 }
113
114 /// Fetches a wallet's transaction history over a date range.
115 ///
116 /// `POST /ws-acct-mgt/api/AccountMaintenance/CustomerAccount/transhistoryV2`
117 pub async fn get_transaction_history(
118 &self,
119 request: &TransactionHistoryRequest,
120 ) -> Result<Vec<Transaction>> {
121 self.post_json::<_, ServiceResponse<Vec<Transaction>>>(
122 "ws-acct-mgt/api/AccountMaintenance/CustomerAccount/transhistoryV2",
123 request,
124 &[],
125 )
126 .await?
127 .into_result()
128 }
129}