paystack/endpoints/
transaction_splits.rs

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