1use std::{marker::PhantomData, sync::Arc};
6
7use serde_json::json;
8
9use crate::{
10 DestinationRequest, DestinationResponse, HttpClient, PaystackAPIError, PaystackResult,
11 Response, TransactionSplitResponseData, VirtualTerminalRequestData,
12 VirtualTerminalResponseData, VirtualTerminalStatus,
13};
14
15#[derive(Debug, Clone)]
16pub struct VirtualTerminalEndpoints<T: HttpClient + Default> {
17 key: String,
19 base_url: String,
21 http: Arc<T>,
23}
24
25impl<T: HttpClient + Default> VirtualTerminalEndpoints<T> {
26 pub fn new(key: Arc<String>, http: Arc<T>) -> VirtualTerminalEndpoints<T> {
28 let base_url = String::from("https://api.paystack.co/virtual_terminal");
29 VirtualTerminalEndpoints {
30 key: key.to_string(),
31 base_url,
32 http,
33 }
34 }
35
36 pub async fn create_virtual_terminal(
41 &self,
42 virtual_terminal_request: VirtualTerminalRequestData,
43 ) -> PaystackResult<VirtualTerminalResponseData> {
44 let url = format!("{}", self.base_url);
45 let body = serde_json::to_value(virtual_terminal_request)
46 .map_err(|e| PaystackAPIError::VirtualTerminal(e.to_string()))?;
47
48 let response = self.http.post(&url, &self.key, &body).await;
49
50 match response {
51 Ok(response) => {
52 let parsed_response: Response<VirtualTerminalResponseData> =
53 serde_json::from_str(&response)
54 .map_err(|e| PaystackAPIError::VirtualTerminal(e.to_string()))?;
55
56 Ok(parsed_response)
57 }
58 Err(e) => Err(PaystackAPIError::VirtualTerminal(e.to_string())),
59 }
60 }
61
62 pub async fn list_virtual_terminals(
68 &self,
69 status: VirtualTerminalStatus,
70 per_page: i32,
71 ) -> PaystackResult<Vec<VirtualTerminalResponseData>> {
72 let url = format!("{}", self.base_url);
73 let status = status.to_string();
74 let per_page = per_page.to_string();
75
76 let query = vec![("status", status.as_str()), ("perPage", per_page.as_str())];
77
78 let response = self.http.get(&url, &self.key, Some(&query)).await;
79
80 match response {
81 Ok(response) => {
82 let parsed_response: Response<Vec<VirtualTerminalResponseData>> =
83 serde_json::from_str(&response)
84 .map_err(|e| PaystackAPIError::VirtualTerminal(e.to_string()))?;
85
86 Ok(parsed_response)
87 }
88 Err(e) => Err(PaystackAPIError::VirtualTerminal(e.to_string())),
89 }
90 }
91
92 pub async fn fetch_virtual_terminal(
97 self,
98 code: String,
99 ) -> PaystackResult<VirtualTerminalResponseData> {
100 let url = format!("{}/{}", self.base_url, code);
101
102 let response = self.http.get(&url, &self.key, None).await;
103
104 match response {
105 Ok(response) => {
106 let parsed_response: Response<VirtualTerminalResponseData> =
107 serde_json::from_str(&response)
108 .map_err(|e| PaystackAPIError::VirtualTerminal(e.to_string()))?;
109
110 Ok(parsed_response)
111 }
112 Err(e) => Err(PaystackAPIError::VirtualTerminal(e.to_string())),
113 }
114 }
115
116 pub async fn update_virtual_terminal(
122 &self,
123 code: String,
124 name: String,
125 ) -> PaystackResult<PhantomData<String>> {
126 let url = format!("{}/{}", self.base_url, code);
127 let body = json!({
128 "name": name
129 });
130
131 let response = self.http.put(&url, &self.key, &body).await;
132
133 match response {
134 Ok(response) => {
135 let parsed_response: Response<PhantomData<String>> =
136 serde_json::from_str(&response)
137 .map_err(|e| PaystackAPIError::VirtualTerminal(e.to_string()))?;
138
139 Ok(parsed_response)
140 }
141 Err(e) => Err(PaystackAPIError::VirtualTerminal(e.to_string())),
142 }
143 }
144
145 pub async fn deactivate_virtual_terminal(
150 &self,
151 code: String,
152 ) -> PaystackResult<PhantomData<String>> {
153 let url = format!("{}/{}/deactivate", self.base_url, code);
154 let body = json!({}); let response = self.http.put(&url, &self.key, &body).await;
157
158 match response {
159 Ok(response) => {
160 let parsed_response: Response<PhantomData<String>> =
161 serde_json::from_str(&response)
162 .map_err(|e| PaystackAPIError::VirtualTerminal(e.to_string()))?;
163
164 Ok(parsed_response)
165 }
166 Err(e) => Err(PaystackAPIError::VirtualTerminal(e.to_string())),
167 }
168 }
169
170 pub async fn assign_virtual_terminal_destination(
176 &self,
177 code: String,
178 destinations: Vec<DestinationRequest>,
179 ) -> PaystackResult<Vec<DestinationResponse>> {
180 let url = format!("{}/{}/destination/assign", self.base_url, code);
181 let body = json!({
182 "destinations": destinations
183 });
184
185 let response = self.http.post(&url, &self.key, &body).await;
186
187 match response {
188 Ok(response) => {
189 let parsed_response: Response<Vec<DestinationResponse>> =
190 serde_json::from_str(&response)
191 .map_err(|e| PaystackAPIError::VirtualTerminal(e.to_string()))?;
192
193 Ok(parsed_response)
194 }
195 Err(e) => Err(PaystackAPIError::VirtualTerminal(e.to_string())),
196 }
197 }
198
199 pub async fn unassign_virtual_terminal_destination(
205 &self,
206 code: String,
207 targets: Vec<String>,
208 ) -> PaystackResult<PhantomData<String>> {
209 let url = format!("{}/{}/destination/unassign", self.base_url, code);
210 let body = json!({
211 "targets": targets
212 });
213
214 let response = self.http.post(&url, &self.key, &body).await;
215
216 match response {
217 Ok(response) => {
218 let parsed_response: Response<PhantomData<String>> =
219 serde_json::from_str(&response)
220 .map_err(|e| PaystackAPIError::VirtualTerminal(e.to_string()))?;
221
222 Ok(parsed_response)
223 }
224 Err(e) => Err(PaystackAPIError::VirtualTerminal(e.to_string())),
225 }
226 }
227
228 pub async fn add_split_code_to_virtual_terminal(
234 &self,
235 code: String,
236 split_code: String,
237 ) -> PaystackResult<TransactionSplitResponseData> {
238 let url = format!("{}/{}/split_code", self.base_url, code);
239 let body = json!({
240 "split_code": split_code
241 });
242
243 let response = self.http.put(&url, &self.key, &body).await;
244
245 match response {
246 Ok(response) => {
247 let parsed_response: Response<TransactionSplitResponseData> =
248 serde_json::from_str(&response)
249 .map_err(|e| PaystackAPIError::VirtualTerminal(e.to_string()))?;
250
251 Ok(parsed_response)
252 }
253 Err(e) => Err(PaystackAPIError::VirtualTerminal(e.to_string())),
254 }
255 }
256
257 pub async fn remove_split_code_from_virtual_terminal(
263 &self,
264 code: String,
265 split_code: String,
266 ) -> PaystackResult<PhantomData<String>> {
267 let url = format!("{}/{}/split_code", self.base_url, code);
268 let body = json!({
269 "split_code": split_code
270 });
271
272 let response = self.http.delete(&url, &self.key, &body).await;
273
274 match response {
275 Ok(response) => {
276 let parsed_response: Response<PhantomData<String>> =
277 serde_json::from_str(&response)
278 .map_err(|e| PaystackAPIError::VirtualTerminal(e.to_string()))?;
279
280 Ok(parsed_response)
281 }
282 Err(e) => Err(PaystackAPIError::VirtualTerminal(e.to_string())),
283 }
284 }
285}