op_api_sdk/apis/
accounts.rs

1//! Client and structures for OP
2//! [AccountsV3](https://op-developer.fi/docs/api/3Oo5zCujXGw2SGEi00skug/OP%20Accounts%20V3.0%20API)
3//! API
4
5use crate::options::Options;
6use crate::requests::Requests;
7use chrono::{DateTime, Utc};
8use log::debug;
9use serde::{Deserialize, Serialize};
10use std::error::Error;
11
12/// Link inside the results of Accounts API.
13#[derive(Deserialize, Debug)]
14pub struct Link {
15    pub href: String,
16}
17
18/// Describes a single Account in response.
19#[derive(Deserialize, Debug)]
20pub struct Account {
21    /// A surrogate identifier for the bank account.
22    #[serde(rename = "accountId")]
23    pub account_id: String,
24    /// Account name. This is a name assigned by the servicer and bears no significance to the
25    /// user.
26    pub name: String,
27    /// Nickname of the account, if assigned by the owner of the account.
28    pub nickname: Option<String>,
29    /// Current balance of the account. Note: This field will only be returned after the end user
30    /// has provided consent to the consuming application.
31    pub balance: Option<f64>,
32    /// Code of the currency of the account. All currency codes are ISO 4217-compliant strings.
33    pub currency: String,
34    /// "IBAN".
35    #[serde(rename = "identifierScheme")]
36    pub identifier_scheme: String,
37    /// Account identifier. Follows the scheme described by the field identifierScheme.
38    pub identifier: String,
39    /// Identifier of the scheme used for identifying the servicer.
40    #[serde(rename = "servicerScheme")]
41    pub servicer_scheme: String,
42    /// Identifier of the servicing bank. Follows the scheme described by the servicerScheme
43    /// parameter.
44    #[serde(rename = "servicerIdentifier")]
45    pub servicer_identifier: String,
46}
47
48/// Describes a list of Accounts in accounts response.
49#[derive(Deserialize, Debug)]
50pub struct AccountList {
51    pub accounts: Vec<Account>,
52}
53
54/// Optional parameters to fetch transactions.
55#[derive(Serialize, Debug, Default)]
56pub struct TransactionParams {
57    /// ISO 8601-compatible date-time string representing the earliest date-time from which
58    /// transactions will be queried. Timezone must not be set. Set time to to 00:00:00 for
59    /// Date-only queries.
60    #[serde(rename = "fromBookingDateTime")]
61    pub from_booking_datetime: Option<DateTime<Utc>>,
62    /// ISO 8601-compatible date-time string representing the latest date-time up to which
63    /// transactions will be queried. Timezone must not be set. Set time to 00:00:00 for Date-only
64    /// queries.
65    #[serde(rename = "toBookingDateTime")]
66    pub to_booking_datetime: Option<DateTime<Utc>>,
67    /// Number of transactions to be returned per each page.
68    #[serde(rename = "pageSize")]
69    pub page_size: Option<u32>,
70    /// Paging token used to retrieve the next page of data. Tokens are available in the links
71    /// located in the _links object.
72    #[serde(rename = "forwardPagingToken")]
73    pub forward_paging_token: Option<String>,
74}
75
76/// Implementation of the TransactionParams.
77impl TransactionParams {
78    /// Sets fromBookingDateTime parameter.
79    pub fn with_from_booking_datetime(mut self, datetime: DateTime<Utc>) -> Self {
80        self.from_booking_datetime = Some(datetime);
81        self
82    }
83
84    /// Sets toBookingDateTime parameter.
85    pub fn with_to_booking_datetime(mut self, datetime: DateTime<Utc>) -> Self {
86        self.to_booking_datetime = Some(datetime);
87        self
88    }
89
90    /// Sets pageSize parameter.
91    pub fn with_page_size(mut self, page_size: u32) -> Self {
92        self.page_size = Some(page_size);
93        self
94    }
95
96    /// Sets forwardPagingToken parameter.
97    pub fn with_forward_paging_token(mut self, token: String) -> Self {
98        self.forward_paging_token = Some(token);
99        self
100    }
101}
102
103/// Describes a single party in Transaction.
104#[derive(Deserialize, Debug)]
105pub struct TransactionParty {
106    /// Account identifier schema.
107    #[serde(rename = "accountIdentifierType")]
108    pub account_identifier_type: String,
109    /// Name of the account.
110    #[serde(rename = "accountName")]
111    pub account_name: String,
112    /// Identifier of the party's bank account.
113    #[serde(rename = "accountIdentifier")]
114    pub account_identifier: String,
115    /// A code identifying the party's servicer.
116    #[serde(rename = "servicerIdentifier")]
117    pub servicer_identifier: String,
118    /// Type of the servicerIdentifier, i.e. the scheme of the servicer ID.
119    #[serde(rename = "servicerIdentifierType")]
120    pub servicer_identifier_type: String,
121}
122
123/// Describes a single Transaction for Account in transactions response.
124#[derive(Deserialize, Debug)]
125pub struct Transaction {
126    /// Surrogate identifier for the transaction.
127    #[serde(rename = "transactionId")]
128    pub transaction_id: String,
129    /// Surrogate identifier for the account.
130    #[serde(rename = "accountId")]
131    pub account_id: String,
132    /// Archive ID of the transaction.
133    #[serde(rename = "archiveId")]
134    pub archive_id: Option<String>,
135    /// Reference number used in the transaction.
136    pub reference: Option<String>,
137    /// A message sent with the transaction. Created by the payer and comprises free-form text.
138    pub message: Option<String>,
139    /// Amount transferred in the transaction. The value is a string decimal. Debit transactions
140    /// are marked with a minus sign.
141    pub amount: String,
142    /// Currency of the transaction.
143    pub currency: String,
144    /// Enum(debit, credit)
145    /// Describes whether the transaction is a debit of credit transaction.
146    #[serde(rename = "creditDebitIndicator")]
147    pub credit_debit_indicator: String,
148    /// Balance of the account after the transaction.
149    #[serde(rename = "accountBalance")]
150    pub account_balance: String,
151    /// Account information of the creditor. The response body will only contain this field if the
152    /// transaction is of type debit, i.e. the counterparty in the transaction is the creditor.
153    pub creditor: Option<TransactionParty>,
154    /// Account information of the debtor. The response body will only contain this field if the
155    /// transaction is of type credit, i.e. the counterparty in the transaction is the debtor.
156    pub debtor: Option<TransactionParty>,
157    /// Date and time the transaction was entered into book-keeping. ISO 8601-formatted date-time string.
158    #[serde(rename = "bookingDateTime")]
159    pub booking_datetime: DateTime<Utc>,
160    /// The date and time when amount of the transaction was counted towards the balance of the
161    /// account. ISO 8601-formatted date-time string.
162    #[serde(rename = "valueDateTime")]
163    pub value_datetaime: DateTime<Utc>,
164    /// Enum(Authorised, AwaitingAuthorisation, Rejected, Revoked)
165    /// Current status of the transaction.
166    pub status: Option<String>,
167    /// ISO 20022-compliant transaction code for the transaction.
168    #[serde(rename = "isoTransactionCode")]
169    pub iso_transaction_code: Option<String>,
170    /// OP-specific transaction code for the transaction.
171    #[serde(rename = "opTransactionCode")]
172    pub op_transaction_code: Option<String>,
173}
174
175/// Describes links in the Transactions object in transactions response.
176#[derive(Deserialize, Debug)]
177pub struct TransactionListLinks {
178    pub next: Option<Link>,
179}
180
181/// Describes a list of Transactions in transactions response.
182#[derive(Deserialize, Debug)]
183pub struct TransactionList {
184    pub transactions: Vec<Transaction>,
185    #[serde(rename = "_links")]
186    pub links: TransactionListLinks,
187}
188
189/// Accounts client.
190///
191/// This client is used to access the OP AccountsV3 API.
192pub struct Accounts {
193    options: Options,
194}
195
196impl Accounts {
197    /// Creates new Accounts client.
198    ///
199    /// Bear in mind that this API is implemented to follow v3 so you must
200    /// specify v3 as version for the Options.
201    pub fn new(options: Options) -> Accounts {
202        Accounts { options }
203    }
204
205    /// Gets all accounts from the API and returns list of them.
206    pub async fn accounts(&self) -> Result<AccountList, Box<dyn Error>> {
207        let url = format!("/accounts/{}/accounts", self.options.version());
208        let response = Requests::get(&self.options, &url, None::<()>).await?;
209        debug!("Accounts response: {:#?}", response);
210        let accounts: AccountList = response.json().await?;
211        Ok(accounts)
212    }
213
214    /// Gets single account from the API based on accountId.
215    pub async fn account(&self, account_id: String) -> Result<Account, Box<dyn Error>> {
216        let url = format!(
217            "/accounts/{}/accounts/{}",
218            self.options.version(),
219            account_id
220        );
221        let response = Requests::get(&self.options, &url, None::<()>).await?;
222        debug!("Account response: {:#?}", response);
223        let account: Account = response.json().await?;
224        Ok(account)
225    }
226
227    /// Gets all transactions for a single account with account id
228    /// with optional parameters for filtering the results.
229    pub async fn transactions(
230        &self,
231        account_id: String,
232        params: Option<TransactionParams>,
233    ) -> Result<TransactionList, Box<dyn Error>> {
234        let url = format!(
235            "/accounts/{}/accounts/{}/transactions",
236            self.options.version(),
237            account_id
238        );
239        let response = Requests::get(&self.options, &url, params).await?;
240        debug!("Transactions response: {:#?}", response);
241        let list: TransactionList = response.json().await?;
242        Ok(list)
243    }
244}