paystack/endpoints/
customers.rs1use super::PAYSTACK_BASE_URL;
6use crate::{
7    CreateCustomerRequest, CustomerResponseData, HttpClient, PaystackAPIError, PaystackResult,
8    Response, RiskAction, UpdateCustomerRequest, ValidateCustomerRequest,
9};
10use serde_json::json;
11use std::{marker::PhantomData, sync::Arc};
12
13#[derive(Debug, Clone)]
15pub struct CustomersEndpoints<T: HttpClient + Default> {
16    key: String,
18    base_url: String,
20    http: Arc<T>,
22}
23
24impl<T: HttpClient + Default> CustomersEndpoints<T> {
25    pub fn new(key: Arc<String>, http: Arc<T>) -> CustomersEndpoints<T> {
34        let base_url = format!("{PAYSTACK_BASE_URL}/customer");
35        CustomersEndpoints {
36            key: key.to_string(),
37            base_url,
38            http,
39        }
40    }
41
42    pub async fn create_customer(
51        &self,
52        create_customer_request: CreateCustomerRequest,
53    ) -> PaystackResult<CustomerResponseData> {
54        let url = &self.base_url;
55        let body = serde_json::to_value(create_customer_request)
56            .map_err(|e| PaystackAPIError::Customer(e.to_string()))?;
57
58        let response = self
59            .http
60            .post(url, &self.key, &body)
61            .await
62            .map_err(|e| PaystackAPIError::Customer(e.to_string()))?;
63
64        let parsed_response: Response<CustomerResponseData> = serde_json::from_str(&response)
65            .map_err(|e| PaystackAPIError::Customer(e.to_string()))?;
66
67        Ok(parsed_response)
68    }
69
70    pub async fn list_customers(
79        &self,
80        per_page: Option<u8>,
81        page: Option<u8>,
82    ) -> PaystackResult<Vec<CustomerResponseData>> {
83        let url = &self.base_url;
84
85        let per_page = per_page.unwrap_or(50).to_string();
86        let page = page.unwrap_or(1).to_string();
87        let query = vec![("perPage", per_page.as_str()), ("page", page.as_str())];
88
89        let response = self
90            .http
91            .get(url, &self.key, Some(&query))
92            .await
93            .map_err(|e| PaystackAPIError::Customer(e.to_string()))?;
94
95        let parsed_response: Response<Vec<CustomerResponseData>> = serde_json::from_str(&response)
96            .map_err(|e| PaystackAPIError::Customer(e.to_string()))?;
97
98        Ok(parsed_response)
99    }
100
101    pub async fn fetch_customer(
109        &self,
110        email_or_code: String,
111    ) -> PaystackResult<CustomerResponseData> {
112        let url = format!("{}/{}", self.base_url, email_or_code);
113
114        let response = self
115            .http
116            .get(&url, &self.key, None)
117            .await
118            .map_err(|e| PaystackAPIError::Customer(e.to_string()))?;
119
120        let parsed_response: Response<CustomerResponseData> = serde_json::from_str(&response)
121            .map_err(|e| PaystackAPIError::Customer(e.to_string()))?;
122
123        Ok(parsed_response)
124    }
125
126    pub async fn update_customer(
136        &self,
137        customer_code: String,
138        update_customer_request: UpdateCustomerRequest,
139    ) -> PaystackResult<CustomerResponseData> {
140        let url = format!("{}/{}", self.base_url, customer_code);
141        let body = serde_json::to_value(update_customer_request)
142            .map_err(|e| PaystackAPIError::Customer(e.to_string()))?;
143
144        let response = self
145            .http
146            .put(&url, &self.key, &body)
147            .await
148            .map_err(|e| PaystackAPIError::Customer(e.to_string()))?;
149
150        let parsed_response: Response<CustomerResponseData> = serde_json::from_str(&response)
151            .map_err(|e| PaystackAPIError::Customer(e.to_string()))?;
152
153        Ok(parsed_response)
154    }
155
156    pub async fn validate_customer(
166        &self,
167        customer_code: String,
168        customer_validation_request: ValidateCustomerRequest,
169    ) -> PaystackResult<PhantomData<String>> {
170        let url = format!("{}/{}/identification", self.base_url, customer_code);
171        let body = serde_json::to_value(customer_validation_request)
172            .map_err(|e| PaystackAPIError::Customer(e.to_string()))?;
173
174        let response = self
175            .http
176            .post(&url, &self.key, &body)
177            .await
178            .map_err(|e| PaystackAPIError::Customer(e.to_string()))?;
179
180        let parsed_response: Response<PhantomData<String>> = serde_json::from_str(&response)
181            .map_err(|e| PaystackAPIError::Customer(e.to_string()))?;
182
183        Ok(parsed_response)
184    }
185
186    pub async fn whitelist_or_blacklist_customer(
195        &self,
196        customer_code: String,
197        risk_action: RiskAction,
198    ) -> PaystackResult<CustomerResponseData> {
199        let url = format!("{}/set_risk_action", self.base_url);
200        let body = json!({
201            "customer": customer_code,
202            "risk_action": risk_action
203        });
204
205        let response = self
206            .http
207            .post(&url, &self.key, &body)
208            .await
209            .map_err(|e| PaystackAPIError::Customer(e.to_string()))?;
210
211        let parsed_response: Response<CustomerResponseData> = serde_json::from_str(&response)
212            .map_err(|e| PaystackAPIError::Customer(e.to_string()))?;
213
214        Ok(parsed_response)
215    }
216
217    pub async fn deactivate_authorization(
225        &self,
226        authorization_code: String,
227    ) -> PaystackResult<PhantomData<String>> {
228        let url = format!("{}/authorization/deactivate", self.base_url);
229        let body = json!({
230            "authorization_code": authorization_code
231        });
232
233        let response = self
234            .http
235            .post(&url, &self.key, &body)
236            .await
237            .map_err(|e| PaystackAPIError::Customer(e.to_string()))?;
238
239        let parsed_response: Response<PhantomData<String>> = serde_json::from_str(&response)
240            .map_err(|e| PaystackAPIError::Customer(e.to_string()))?;
241
242        Ok(parsed_response)
243    }
244}