1use std::fmt;
2
3use derive_builder::Builder;
4use serde::{Deserialize, Serialize};
5
6use super::{Authorization, Subscription, TransactionStatusData};
7
8#[derive(Debug, Deserialize, Serialize, Clone, Default)]
10pub struct CustomerResponseData {
11 pub id: u64,
12 pub integration: Option<u64>,
13 pub domain: Option<String>,
14 pub identified: Option<bool>,
15 pub first_name: Option<String>,
16 pub last_name: Option<String>,
17 pub email: String,
18 pub customer_code: String,
19 pub phone: Option<String>,
20 pub risk_action: Option<RiskAction>,
21 pub international_format_phone: Option<String>,
22 pub identification: Option<String>,
23 pub transactions: Option<Vec<TransactionStatusData>>,
24 pub subscriptions: Option<Vec<Subscription>>,
25 pub authorizations: Option<Vec<Authorization>>,
26 #[serde(rename = "createdAt")]
27 pub created_at: Option<String>,
28 #[serde(rename = "updatedAt")]
29 pub updated_at: Option<String>,
30 pub total_transactions: Option<u16>,
31 pub total_transaction_value: Option<Vec<String>>,
32 pub dedicated_account: Option<String>,
33}
34
35#[derive(Debug, Clone, Serialize, Default, Deserialize, Builder)]
37pub struct CreateCustomerRequest {
38 pub email: String,
40 #[builder(setter(strip_option), default)]
42 pub first_name: Option<String>,
43 #[builder(setter(strip_option), default)]
45 pub last_name: Option<String>,
46 #[builder(setter(strip_option), default)]
48 pub phone: Option<String>,
49}
50
51#[derive(Debug, Clone, Serialize, Default, Deserialize, Builder)]
53pub struct UpdateCustomerRequest {
54 #[builder(setter(strip_option), default)]
56 pub first_name: Option<String>,
57 #[builder(setter(strip_option), default)]
59 pub last_name: Option<String>,
60 #[builder(setter(strip_option), default)]
62 pub phone: Option<String>,
63}
64
65#[derive(Debug, Clone, Serialize, Default, Deserialize, Builder)]
66pub struct ValidateCustomerRequest {
67 pub first_name: String,
69 pub last_name: String,
71 #[builder(setter(strip_option), default)]
73 pub middle_name: Option<String>,
74 #[serde(rename = "type")]
76 pub identification_type: IdentificationType,
77 #[builder(setter(strip_option), default)]
79 pub value: Option<String>,
80 pub country: String,
82 pub bvn: String,
84 pub bank_code: String,
86 #[builder(setter(strip_option), default)]
88 pub account_number: Option<String>,
89}
90
91#[derive(Debug, Serialize, Default, Deserialize, Clone, PartialEq)]
95#[serde(rename_all = "lowercase")]
96pub enum IdentificationType {
97 #[default]
98 #[serde(rename = "bank_account")]
99 BankAccount,
100}
101
102impl fmt::Display for IdentificationType {
103 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
104 let identification_type = match self {
105 IdentificationType::BankAccount => "bank_account",
106 };
107 write!(f, "{}", identification_type)
108 }
109}
110
111#[derive(Debug, Serialize, Default, Deserialize, Clone, PartialEq)]
112#[serde(rename_all = "lowercase")]
113pub enum RiskAction {
114 #[default]
115 Default,
116 Allow,
117 Deny,
118}
119
120impl fmt::Display for RiskAction {
121 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
122 let risk_action = match self {
123 RiskAction::Allow => "allow",
124 RiskAction::Default => "default",
125 RiskAction::Deny => "deny",
126 };
127 write!(f, "{}", risk_action)
128 }
129}
130
131#[cfg(test)]
132mod tests {
133 use super::*;
134
135 #[test]
136 fn can_build_customer() {
137 let customer = CreateCustomerRequestBuilder::default()
138 .email("customer@example.com".to_string())
139 .first_name("Zero".to_string())
140 .last_name("Sum".to_string())
141 .phone("+2348123456789".to_string())
142 .build()
143 .expect("unable to build customer request");
144
145 assert_eq!(customer.first_name, Some("Zero".to_string()));
146 assert_eq!(customer.last_name, Some("Sum".to_string()));
147 }
148
149 #[test]
150 fn build_customer_with_invalid_data_fails() {
151 let first_name = "Zero".to_string();
152 let last_name = "Sum".to_string();
153 let phone = "+2348123456789".to_string();
154
155 let body = CreateCustomerRequestBuilder::default()
156 .first_name(first_name)
157 .last_name(last_name)
158 .phone(phone)
159 .build();
160
161 assert!(body.is_err());
162 }
163
164 #[test]
165 fn can_use_identification_type() {
166 let identification = IdentificationType::BankAccount;
167
168 assert_eq!(identification.to_string(), "bank_account".to_string());
169 }
170}