use crate::{
get_request, post_request, put_request, BearerType, Currency, Error, PaystackResult,
ResponseWithoutData, SplitType, TransactionSplitListResponse, TransactionSplitResponse,
};
use derive_builder::Builder;
use reqwest::StatusCode;
use serde::Serialize;
#[derive(Serialize, Debug, Default, Builder)]
pub struct CreateTransactionSplitBody {
name: String,
#[serde(rename = "type")]
split_type: SplitType,
currency: Currency,
subaccounts: Vec<SubaccountBody>,
bearer_type: BearerType,
bearer_subaccount: String,
}
#[derive(Serialize, Debug, Clone, Builder)]
pub struct SubaccountBody {
pub subaccount: String,
pub share: u32,
}
#[derive(Serialize, Debug, Builder)]
pub struct UpdateTransactionSplitBody {
pub name: String,
pub active: bool,
#[builder(default = "None")]
pub bearer_type: Option<BearerType>,
#[builder(default = "None")]
pub bearer_subaccount: Option<SubaccountBody>,
}
#[derive(Debug, Clone)]
pub struct TransactionSplit {
api_key: String,
}
static BASE_URL: &str = "https://api.paystack.co";
impl TransactionSplit {
pub fn new(key: String) -> Self {
TransactionSplit { api_key: key }
}
pub async fn create_transaction_split(
&self,
split_body: CreateTransactionSplitBody,
) -> PaystackResult<TransactionSplitResponse> {
let url = format!("{}/split", BASE_URL);
match post_request(&self.api_key, &url, split_body).await {
Ok(response) => match response.status() {
StatusCode::OK => match response.json::<TransactionSplitResponse>().await {
Ok(content) => Ok(content),
Err(err) => Err(Error::TransactionSplit(err.to_string())),
},
_ => Err(Error::RequestNotSuccessful(
response.status().to_string(),
response.text().await?,
)),
},
Err(err) => Err(Error::FailedRequest(err.to_string())),
}
}
pub async fn list_transaction_splits(
&self,
split_name: Option<String>,
split_active: Option<bool>,
) -> PaystackResult<TransactionSplitListResponse> {
let url = format!("{}/split", BASE_URL);
let split_active = match split_active {
Some(active) => active.to_string(),
None => String::from(""),
};
let query = vec![
("name", split_name.unwrap_or("".to_string())),
("active", split_active),
];
match get_request(&self.api_key, &url, Some(query)).await {
Ok(response) => match response.status() {
StatusCode::OK => match response.json::<TransactionSplitListResponse>().await {
Ok(content) => Ok(content),
Err(err) => Err(Error::TransactionSplit(err.to_string())),
},
_ => Err(Error::RequestNotSuccessful(
response.status().to_string(),
response.text().await?,
)),
},
Err(err) => Err(Error::FailedRequest(err.to_string())),
}
}
pub async fn fetch_transaction_split(
&self,
split_id: String,
) -> PaystackResult<TransactionSplitResponse> {
let url = format!("{}/split{}", BASE_URL, split_id);
match get_request(&self.api_key, &url, None).await {
Ok(response) => match response.status() {
StatusCode::OK => match response.json::<TransactionSplitResponse>().await {
Ok(content) => Ok(content),
Err(err) => Err(Error::TransactionSplit(err.to_string())),
},
_ => Err(Error::RequestNotSuccessful(
response.status().to_string(),
response.text().await?,
)),
},
Err(err) => Err(Error::FailedRequest(err.to_string())),
}
}
pub async fn update_transaction_split(
&self,
split_id: String,
body: UpdateTransactionSplitBody,
) -> PaystackResult<TransactionSplitResponse> {
let url = format!("{}/split/{}", BASE_URL, split_id);
match put_request(&self.api_key, &url, body).await {
Ok(response) => match response.status() {
StatusCode::OK => match response.json::<TransactionSplitResponse>().await {
Ok(content) => Ok(content),
Err(err) => Err(Error::TransactionSplit(err.to_string())),
},
_ => Err(Error::RequestNotSuccessful(
response.status().to_string(),
response.text().await?,
)),
},
Err(err) => Err(Error::FailedRequest(err.to_string())),
}
}
pub async fn add_or_update_subaccount_split(
&self,
split_id: String,
body: SubaccountBody,
) -> PaystackResult<TransactionSplitResponse> {
let url = format!("{}/split/{}/subaccount/add", BASE_URL, split_id);
match post_request(&self.api_key, &url, body).await {
Ok(response) => match response.status() {
StatusCode::OK => match response.json::<TransactionSplitResponse>().await {
Ok(content) => Ok(content),
Err(err) => Err(Error::TransactionSplit(err.to_string())),
},
_ => Err(Error::RequestNotSuccessful(
response.status().to_string(),
response.text().await?,
)),
},
Err(err) => Err(Error::FailedRequest(err.to_string())),
}
}
pub async fn remove_subaccount_from_transaction_split(
&self,
split_id: &String,
subaccount: &String,
) -> PaystackResult<ResponseWithoutData> {
let url = format!("{}/split/{}/subaccount/remove", BASE_URL, split_id);
match post_request(&self.api_key, &url, subaccount).await {
Ok(response) => match response.status() {
StatusCode::OK => match response.json::<ResponseWithoutData>().await {
Ok(content) => Ok(content),
Err(err) => Err(Error::TransactionSplit(err.to_string())),
},
_ => Err(Error::RequestNotSuccessful(
response.status().to_string(),
response.text().await?,
)),
},
Err(err) => Err(Error::FailedRequest(err.to_string())),
}
}
}