Skip to main content

monzo/endpoints/
accounts.rs

1//! Accounts API endpoint
2
3use chrono::{DateTime, Utc};
4use serde::Deserialize;
5
6/// A struct representing a Monzo Account
7#[derive(Deserialize, Debug, PartialEq, Eq, Hash, Clone)]
8#[non_exhaustive]
9pub struct Account {
10    /// The unique ID of the account
11    pub id: String,
12
13    /// The account details including type and banking information
14    #[serde(flatten)]
15    pub account_type: Type,
16
17    /// Whether the account has been closed
18    pub closed: bool,
19
20    /// The `DateTime` that the account was created
21    pub created: DateTime<Utc>,
22
23    /// The account description
24    pub description: String,
25
26    /// This the a three-letter currency code
27    pub currency: String,
28
29    /// This is a country code for the country where the account is held
30    pub country_code: String,
31
32    /// A vector of account owners
33    pub owners: Vec<Owner>,
34
35    /// The business ID
36    ///
37    /// This is only set for business accounts
38    pub business_id: Option<String>,
39}
40
41/// Struct representating an owner of a Monzo account
42#[derive(Deserialize, Debug, PartialEq, Eq, Hash, Clone)]
43pub struct Owner {
44    /// The user ID of the owner
45    pub user_id: String,
46
47    /// The preferred name of the owner
48    pub preferred_name: String,
49
50    /// The preferred first name of the owner
51    pub preferred_first_name: String,
52}
53
54/// Account details including type and banking information
55#[derive(Deserialize, Debug, PartialEq, Eq, Hash, Clone)]
56#[serde(tag = "type", rename_all = "snake_case")]
57#[non_exhaustive]
58pub enum Type {
59    /// A standard monzo account
60    UkRetail(AccountDetails),
61
62    /// A monzo joint account
63    UkRetailJoint(AccountDetails),
64
65    /// A monzo business account
66    UkBusiness(AccountDetails),
67
68    /// A monzo rewards account
69    UkRewards,
70
71    /// A monzo flex account
72    UkMonzoFlex,
73
74    /// A monzo loan account
75    UkLoan,
76}
77
78#[derive(Deserialize, Debug, PartialEq, Eq, Hash, Clone)]
79/// Banking information
80pub struct AccountDetails {
81    /// The account number
82    pub account_number: String,
83    /// The sort code
84    pub sort_code: String,
85}
86
87pub(crate) use list::Request as List;
88mod list {
89
90    use crate::endpoints::Endpoint;
91
92    /// An object representing a request to the Monzo API for a list of accounts
93    pub struct Request;
94
95    impl Endpoint for Request {
96        const METHOD: reqwest::Method = reqwest::Method::GET;
97
98        fn endpoint(&self) -> &'static str {
99            "/accounts"
100        }
101    }
102}
103
104#[cfg(test)]
105mod tests {
106    use test_case::test_case;
107
108    use super::Account;
109
110    #[test_case(
111        r#"
112            {
113      "id": "acc_00009",
114      "closed": false,
115      "created": "2021-06-12T00:00:00.000Z",
116      "description": "user_00009",
117      "type": "uk_retail",
118      "owner_type": "personal",
119      "is_flex": false,
120      "product_type": "standard",
121      "closed_account_app_access": false,
122      "currency": "GBP",
123      "legal_entity": "monzo_uk",
124      "country_code": "GB",
125      "country_code_alpha3": "GBR",
126      "owners": [
127        {
128          "user_id": "user_0000",
129          "preferred_name": "First Last",
130          "preferred_first_name": "First"
131        }
132      ],
133      "account_number": "12345678",
134      "sort_code": "040004",
135      "payment_details": {
136        "locale_uk": {
137          "account_number": "12345678",
138          "sort_code": "040004"
139        },
140        "iban": {
141          "unformatted": "GB90MONZXXXXXXXXXXX",
142          "formatted": "GB90MONZXXXXXXXXXXXXX",
143          "bic": "MONZGB2L",
144          "usage_description": "Receive international payments in over 40 currencies. We charge a currency conversion fee. [Learn more...](monzo://backend_screen?id=international-payment-views:bank-transfer-info&instance_params_id=acc_00009jmHyLkxAPVUSe8H45)",
145          "usage_description_web": "Receive international payments in over 40 currencies. We charge a currency conversion fee."
146        }
147      },
148      "monzo_branch_address_formatted": "Monzo Bank, Broadwalk House, 5 Appold St, London EC2A 2AG, United Kingdom",
149      "assets": {
150        "image_url": "https://public-images.monzo.com/card_styles/account_icon/personal@3x.png"
151      }
152    }
153        "#
154        ; "uk_retail"
155    )]
156    #[test_case(
157        r#"{
158            "id": "acc_ID",
159            "closed": false,
160            "created": "2024-01-20T00:00:00.000Z",
161            "description": "rewardsoptin_0000",
162            "type": "uk_rewards",
163            "owner_type": "personal",
164            "is_flex": false,
165            "product_type": "rewards",
166            "closed_account_app_access": false,
167            "currency": "GBP",
168            "legal_entity": "monzo_uk",
169            "country_code": "GB",
170            "country_code_alpha3": "GBR",
171            "owners": [
172                {
173                    "user_id": "user_0000",
174                    "preferred_name": "First Last",
175                    "preferred_first_name": "First"
176                }
177            ]
178        }"#
179        ; "uk_rewards"
180    )]
181    #[test_case(
182        r#"{
183            "id": "acc_0000",
184            "closed": false,
185            "created": "2024-01-01T00:00:00.000Z",
186            "description": "monzoflex_0000",
187            "type": "uk_monzo_flex",
188            "owner_type": "personal",
189            "is_flex": true,
190            "product_type": "flex",
191            "closed_account_app_access": false,
192            "currency": "GBP",
193            "legal_entity": "monzo_uk",
194            "country_code": "GB",
195            "country_code_alpha3": "GBR",
196            "owners": [
197                {
198                    "user_id": "user_0000",
199                    "preferred_name": "First Last",
200                    "preferred_first_name": "First"
201                }
202            ],
203            "assets": {
204                "image_url": "https://public-images.monzo.com/card_styles/account_icon/flex@3x.png"
205            }
206        }"#
207        ; "uk_monzo_flex"
208    )]
209    #[test_case(
210        r#"{
211            "id": "acc_0000",
212            "closed": false,
213            "created": "2024-01-01T00:00:00.000Z",
214            "description": "loan_0000",
215            "type": "uk_loan",
216            "owner_type": "unknown",
217            "is_flex": false,
218            "product_type": "loan",
219            "closed_account_app_access": false,
220            "currency": "GBP",
221            "legal_entity": "monzo_uk",
222            "country_code": "GB",
223            "country_code_alpha3": "GBR",
224            "owners": [
225                {
226                    "user_id": "user_0000",
227                    "preferred_name": "First Last",
228                    "preferred_first_name": "First"
229                }
230            ]
231        }"#
232        ; "uk_loan"
233    )]
234    fn parse_account(json_data: &str) {
235        let _account: Account = serde_json::from_str(json_data).unwrap();
236    }
237}