paystack/endpoints/
transaction_split.rs

1//! Transaction Split
2//! =================
3//! The Transaction Splits API enables merchants split the settlement for a
4//! transaction across their payout account, and one or more subaccounts.
5
6use crate::{
7    DeleteSubAccountBody, HttpClient, PaystackAPIError, PaystackResult, Response, SubaccountBody,
8    TransactionSplitRequest, TransactionSplitResponseData, UpdateTransactionSplitRequest,
9};
10use std::sync::Arc;
11
12/// A struct to hold all the functions of the transaction split API endpoint
13#[derive(Debug, Clone)]
14pub struct TransactionSplitEndpoints<T: HttpClient + Default> {
15    /// Paystack API Key
16    key: String,
17    /// Base URL for the transaction route
18    base_url: String,
19    /// Http client for the route
20    http: Arc<T>,
21}
22
23impl<T: HttpClient + Default> TransactionSplitEndpoints<T> {
24    /// Constructor
25    pub fn new(key: Arc<String>, http: Arc<T>) -> TransactionSplitEndpoints<T> {
26        let base_url = String::from("https://api.paystack.co/split");
27        TransactionSplitEndpoints {
28            key: key.to_string(),
29            base_url,
30            http,
31        }
32    }
33
34    /// Create a split payment on your integration.
35    ///
36    /// This method takes a `TransactionSplitRequest` object as a parameter.
37    pub async fn create_transaction_split(
38        &self,
39        split_body: TransactionSplitRequest,
40    ) -> PaystackResult<TransactionSplitResponseData> {
41        let url = self.base_url.to_string();
42        let body = serde_json::to_value(split_body)
43            .map_err(|e| PaystackAPIError::TransactionSplit(e.to_string()))?;
44
45        let response = self.http.post(&url, &self.key, &body).await;
46
47        match response {
48            Ok(response) => {
49                let parsed_response: Response<TransactionSplitResponseData> =
50                    serde_json::from_str(&response)
51                        .map_err(|e| PaystackAPIError::TransactionSplit(e.to_string()))?;
52                Ok(parsed_response)
53            }
54            Err(e) => Err(PaystackAPIError::TransactionSplit(e.to_string())),
55        }
56    }
57
58    /// List the transaction splits available on your integration
59    ///
60    /// Takes in the following parameters:
61    ///     - `split_name`: (Optional) name of the split to retrieve.
62    ///     - `split_active`: (Optional) status of the split to retrieve.
63    pub async fn list_transaction_splits(
64        &self,
65        split_name: Option<&str>,
66        split_active: Option<bool>,
67    ) -> PaystackResult<Vec<TransactionSplitResponseData>> {
68        let url = self.base_url.to_string();
69
70        // Specify a default option for active splits
71        let split_active = match split_active {
72            Some(active) => active.to_string(),
73            None => "".to_string(),
74        };
75
76        let query = vec![
77            ("name", split_name.unwrap_or("")),
78            ("active", &split_active),
79        ];
80
81        let response = self.http.get(&url, &self.key, Some(&query)).await;
82
83        match response {
84            Ok(response) => {
85                let parsed_response: Response<Vec<TransactionSplitResponseData>> =
86                    serde_json::from_str(&response)
87                        .map_err(|e| PaystackAPIError::TransactionSplit(e.to_string()))?;
88
89                Ok(parsed_response)
90            }
91            Err(e) => Err(PaystackAPIError::TransactionSplit(e.to_string())),
92        }
93    }
94
95    /// Get details of a split on your integration.
96    ///
97    /// Takes in the following parameter:
98    ///     - `split_id`:  ID of the transaction split.
99    pub async fn fetch_transaction_split(
100        &self,
101        split_id: &str,
102    ) -> PaystackResult<TransactionSplitResponseData> {
103        let url = format!("{}/{}", self.base_url, split_id);
104
105        let response = self.http.get(&url, &self.key, None).await;
106
107        match response {
108            Ok(response) => {
109                let parsed_response: Response<TransactionSplitResponseData> =
110                    serde_json::from_str(&response)
111                        .map_err(|e| PaystackAPIError::TransactionSplit(e.to_string()))?;
112
113                Ok(parsed_response)
114            }
115            Err(e) => Err(PaystackAPIError::TransactionSplit(e.to_string())),
116        }
117    }
118
119    /// Update a transaction split details on your integration.
120    ///
121    /// Takes in a
122    /// - `update_body` as a `UpdateTransactionSplitRequest` struct which is created from the `UpdateTransactionSplitRequestBuilder` struct
123    /// - `split_id`, the ID of the split to update
124    pub async fn update_transaction_split(
125        &self,
126        split_id: &str,
127        update_body: UpdateTransactionSplitRequest,
128    ) -> PaystackResult<TransactionSplitResponseData> {
129        let url = format!("{}/{}", self.base_url, split_id);
130        let body = serde_json::to_value(update_body)
131            .map_err(|e| PaystackAPIError::TransactionSplit(e.to_string()))?;
132
133        let response = self.http.put(&url, &self.key, &body).await;
134
135        match response {
136            Ok(response) => {
137                let parsed_response: Response<TransactionSplitResponseData> =
138                    serde_json::from_str(&response)
139                        .map_err(|e| PaystackAPIError::TransactionSplit(e.to_string()))?;
140                Ok(parsed_response)
141            }
142            Err(e) => Err(PaystackAPIError::TransactionSplit(e.to_string())),
143        }
144    }
145
146    /// Add a Subaccount to a Transaction Split, or update the share of an existing Subaccount in a Transaction Split
147    ///
148    /// Takes in the following parameters:
149    ///     - `split_id`: Id of the transaction split to update.
150    ///     - `body`: Subaccount to add to the transaction split.
151    pub async fn add_or_update_subaccount_split(
152        &self,
153        split_id: &str,
154        body: SubaccountBody,
155    ) -> PaystackResult<TransactionSplitResponseData> {
156        let url = format!("{}/{}/subaccount/add", self.base_url, split_id);
157        let body = serde_json::to_value(body)
158            .map_err(|e| PaystackAPIError::TransactionSplit(e.to_string()))?;
159
160        let response = self.http.post(&url, &self.key, &body).await;
161
162        match response {
163            Ok(response) => {
164                let parsed_response: Response<TransactionSplitResponseData> =
165                    serde_json::from_str(&response)
166                        .map_err(|e| PaystackAPIError::TransactionSplit(e.to_string()))?;
167
168                Ok(parsed_response)
169            }
170            Err(e) => Err(PaystackAPIError::TransactionSplit(e.to_string())),
171        }
172    }
173
174    /// Remove a subaccount from a transaction split.
175    ///
176    /// Takes in the following parameters
177    ///     - split_id: Id of the transaction split
178    ///     - subaccount: subaccount code to remove
179    pub async fn remove_subaccount_from_transaction_split(
180        &self,
181        split_id: &str,
182        subaccount: DeleteSubAccountBody,
183    ) -> PaystackResult<String> {
184        let url = format!("{}/{}/subaccount/remove", self.base_url, split_id);
185        let body = serde_json::to_value(subaccount)
186            .map_err(|e| PaystackAPIError::TransactionSplit(e.to_string()))?;
187
188        let response = self.http.post(&url, &self.key, &body).await;
189
190        match response {
191            Ok(response) => {
192                let parsed_response: Response<String> = serde_json::from_str(&response)
193                    .map_err(|e| PaystackAPIError::TransactionSplit(e.to_string()))?;
194
195                Ok(parsed_response)
196            }
197            Err(e) => Err(PaystackAPIError::TransactionSplit(e.to_string())),
198        }
199    }
200}