use derive_builder::Builder;
use reqwest::StatusCode;
use serde::Serialize;
use crate::{
get_request, post_request, put_request, CreateSubaccountResponse, Error,
FetchSubaccountResponse, ListSubaccountsResponse, PaystackResult,
};
#[derive(Serialize, Debug, Builder)]
pub struct CreateSubaccountBody {
business_name: String,
settlement_bank: String,
account_number: String,
percentage_charge: f32,
description: String,
#[builder(default = "None")]
primary_contact_email: Option<String>,
#[builder(default = "None")]
primary_contact_name: Option<String>,
#[builder(default = "None")]
primary_contact_phone: Option<String>,
#[builder(default = "None")]
metadata: Option<String>,
}
#[derive(Debug, Clone)]
pub struct Subaccount {
api_key: String,
}
static BASE_URL: &str = "https://api.paystack.co";
impl Subaccount {
pub fn new(key: String) -> Self {
Subaccount { api_key: key }
}
pub async fn create_subaccount(
&self,
body: CreateSubaccountBody,
) -> PaystackResult<CreateSubaccountResponse> {
let url = format!("{}/subaccount", BASE_URL);
match post_request(&self.api_key, &url, body).await {
Ok(response) => match response.status() {
StatusCode::CREATED => match response.json::<CreateSubaccountResponse>().await {
Ok(content) => Ok(content),
Err(err) => Err(Error::Subaccount(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_subaccounts(
&self,
per_page: Option<u32>,
page: Option<u32>,
from: Option<String>,
to: Option<String>,
) -> PaystackResult<ListSubaccountsResponse> {
let url = format!("{}/subaccount", BASE_URL);
let query = vec![
("perPage", per_page.unwrap_or(50).to_string()),
("page", page.unwrap_or(1).to_string()),
("from", from.unwrap_or_default()),
("to", to.unwrap_or_default()),
];
match get_request(&self.api_key, &url, Some(query)).await {
Ok(response) => match response.status() {
StatusCode::OK => match response.json::<ListSubaccountsResponse>().await {
Ok(content) => Ok(content),
Err(err) => Err(Error::Subaccount(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_subaccount(
&self,
id_or_code: String,
) -> PaystackResult<FetchSubaccountResponse> {
let url = format!("{}/subaccount/{}", BASE_URL, id_or_code);
match get_request(&self.api_key, &url, None).await {
Ok(response) => match response.status() {
StatusCode::OK => match response.json::<FetchSubaccountResponse>().await {
Ok(content) => Ok(content),
Err(err) => Err(Error::Subaccount(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_subaccount(
&self,
id_or_code: String,
body: CreateSubaccountBody,
) -> PaystackResult<CreateSubaccountResponse> {
let url = format!("{}/subaccount/{}", BASE_URL, id_or_code);
match put_request(&self.api_key, &url, body).await {
Ok(response) => match response.status() {
StatusCode::OK => match response.json::<CreateSubaccountResponse>().await {
Ok(content) => Ok(content),
Err(err) => Err(Error::Subaccount(err.to_string())),
},
_ => Err(Error::RequestNotSuccessful(
response.status().to_string(),
response.text().await?,
)),
},
Err(err) => Err(Error::FailedRequest(err.to_string())),
}
}
}