monzo_webhook/
lib.rs

1#![doc = include_str!("../README.md")]
2#![deny(unsafe_code)]
3#![deny(clippy::pedantic)]
4#![allow(clippy::struct_excessive_bools, reason = "structs cannot be changed due to serialization")]
5
6use chrono::{DateTime, Utc};
7use serde::Deserialize;
8
9#[cfg(test)]
10mod tests;
11
12/// The main webhook data type.
13#[derive(Clone, Debug, Deserialize)]
14pub struct Webhook {
15    /// The type of webhook update.
16    /// Always one of:
17    /// - `transaction.created`
18    /// - `transaction.updated`
19    pub r#type: String,
20    pub data: WebhookData,
21}
22
23#[derive(Clone, Debug, Deserialize)]
24pub struct WebhookData {
25    pub id: String,
26    pub created: DateTime<Utc>,
27    pub description: String,
28    /// The amount of money in the transaction, in whole pence (or equivalent for foreign currency)
29    pub amount: i64,
30    /// The ISO 4127 currency code of [`Self::amount`]
31    pub currency: String,
32    pub is_load: bool,
33    pub settled: SettledTimestamp,
34    /// The amount of money in the transaction, in whole pence (or equivalent for foreign currency)
35    pub local_amount: i64,
36    /// The ISO 4127 currency code of [`Self::local_amount`]
37    pub local_currency: String,
38    pub merchant: Option<Merchant>,
39    pub merchant_feedback_uri: String,
40    pub notes: String,
41    pub metadata: WebhookMetadata,
42    pub category: String,
43    pub updated: DateTime<Utc>,
44    pub account_id: String,
45    pub user_id: String,
46    pub counterparty: CounterpartyOrNone,
47    pub scheme: String,
48    pub dedupe_id: String,
49    pub originator: bool,
50    pub include_in_spending: bool,
51    pub can_be_excluded_from_breakdown: bool,
52    pub can_be_made_subscription: bool,
53    pub can_split_the_bill: bool,
54    pub can_add_to_tab: bool,
55    pub can_match_transactions_in_categorization: bool,
56    pub amount_is_pending: bool,
57    pub parent_account_id: String,
58}
59
60#[derive(Clone, Debug, Deserialize)]
61#[serde(untagged)]
62pub enum SettledTimestamp {
63    Settled(DateTime<Utc>),
64    /// If not yet settled, a string it returned, however it always seems to be empty.
65    NotYetSettled(String),
66}
67
68#[derive(Clone, Debug, Deserialize)]
69pub struct Merchant {
70    pub address: MerchantAddress,
71    pub created: DateTime<Utc>,
72    pub group_id: String,
73    pub id: String,
74    pub logo: String,
75    pub emoji: String,
76    pub name: String,
77    pub category: String,
78}
79
80#[derive(Clone, Debug, Deserialize)]
81pub struct MerchantAddress {
82    pub address: String,
83    pub city: String,
84    pub country: String,
85    pub latitude: f64,
86    pub longitude: f64,
87    pub postcode: String,
88    pub region: String,
89}
90
91#[derive(Clone, Debug, Deserialize)]
92pub struct WebhookMetadata {
93    #[serde(flatten)]
94    pub subtype: WebhookMetadataSubtype,
95    pub ledger_committed_timestamp_earliest: DateTime<Utc>,
96    pub ledger_committed_timestamp_latest: DateTime<Utc>,
97}
98
99#[derive(Clone, Debug, Deserialize)]
100#[serde(untagged)]
101pub enum WebhookMetadataSubtype {
102    FasterPayment(FasterPayment),
103    MoneyTransfer(MoneyTransfer),
104}
105
106#[derive(Clone, Debug, Deserialize)]
107#[serde(untagged)]
108pub enum CounterpartyOrNone {
109    Counterparty(Counterparty),
110    None {},
111}
112
113#[derive(Clone, Debug, Deserialize)]
114pub struct Counterparty {
115    pub account_number: String,
116    pub name: String,
117    pub sort_code: String,
118    pub user_id: String,
119}
120
121/// A Faster Payments transaction
122#[derive(Clone, Debug, Deserialize)]
123pub struct FasterPayment {
124    pub faster_payment: String,
125    pub fps_fpid: String,
126    pub fps_payment_id: String,
127    pub insertion: String,
128    pub notes: String,
129    pub standin_correlation_id: String,
130    pub trn: String,
131}
132
133/// A move of money between pots or accounts
134#[derive(Clone, Debug, Deserialize)]
135pub struct MoneyTransfer {
136    #[serde(flatten)]
137    pub subtype: MoneyTransferSubtype,
138    pub external_id: String,
139    pub ledger_insertion_id: String,
140    pub move_money_transfer_id: String,
141    pub pot_account_id: String,
142    pub pot_id: String,
143    pub transaction_description_localised: String,
144    pub transaction_locale_country: String,
145    pub trigger: String,
146    pub user_id: String,
147}
148
149#[derive(Clone, Debug, Deserialize)]
150#[serde(untagged)]
151pub enum MoneyTransferSubtype {
152    PotWithdrawal(PotWithdrawal),
153    PotDeposit(PotDeposit),
154}
155
156#[derive(Clone, Debug, Deserialize)]
157pub struct PotWithdrawal {
158    pub money_transfer_id: String,
159    pub pot_withdrawal_id: String,
160}
161
162#[derive(Clone, Debug, Deserialize)]
163pub struct PotDeposit {
164    pub pot_deposit_id: String,
165}