extern crate reqwest;
extern crate serde_json;
use crate::{
Charge, PaystackResult, RequestNotSuccessful, Transaction, TransactionResponse,
TransactionStatus, TransactionStatusList,
};
static BASE_URL: &str = "https://api.paystack.co";
#[derive(Clone, Debug)]
pub struct PaystackClient {
client: reqwest::Client,
api_key: String,
}
impl PaystackClient {
pub fn new(key: impl Into<String>) -> Self {
Self {
client: reqwest::Client::new(),
api_key: key.into(),
}
}
pub async fn initialize_transaction(
&self,
transaction_body: Transaction,
) -> PaystackResult<TransactionResponse> {
let url = format!("{}/transaction/initialize", BASE_URL);
let response = self
.client
.post(url)
.bearer_auth(&self.api_key)
.header("Content-Type", "application/json")
.json(&transaction_body)
.send()
.await?;
if response.error_for_status_ref().is_err() {
return Err(
RequestNotSuccessful::new(response.status(), response.text().await?).into(),
);
}
let content = response.json::<TransactionResponse>().await?;
Ok(content)
}
pub async fn verify_transaction(&self, reference: String) -> PaystackResult<TransactionStatus> {
let url = format!("{}/transaction/verify/{}", BASE_URL, reference);
let response = self
.client
.get(url)
.bearer_auth(&self.api_key)
.header("Content-Type", "application/json")
.send()
.await?;
if response.error_for_status_ref().is_err() {
return Err(
RequestNotSuccessful::new(response.status(), response.text().await?).into(),
);
}
let content = response.json::<TransactionStatus>().await?;
Ok(content)
}
pub async fn list_transactions(
&self,
number_of_transactions: Option<u32>,
) -> PaystackResult<TransactionStatusList> {
let url = format!("{}/transaction", BASE_URL);
let query = vec![("perPage", number_of_transactions.unwrap_or(10))];
let response = self
.client
.get(url)
.query(&query)
.bearer_auth(&self.api_key)
.header("Content-Type", "application.json")
.send()
.await?;
if response.error_for_status_ref().is_err() {
return Err(
RequestNotSuccessful::new(response.status(), response.text().await?).into(),
);
}
let contents = response.json::<TransactionStatusList>().await?;
Ok(contents)
}
pub async fn fetch_transactions(
&self,
transaction_id: u32,
) -> PaystackResult<TransactionStatus> {
let url = format!("{}/transaction/{}", BASE_URL, transaction_id);
let response = self
.client
.get(url)
.bearer_auth(&self.api_key)
.header("Content-Type", "application/json")
.send()
.await?;
if response.error_for_status_ref().is_err() {
return Err(
RequestNotSuccessful::new(response.status(), response.text().await?).into(),
);
}
let content = response.json::<TransactionStatus>().await?;
Ok(content)
}
pub async fn charge_authorization(&self, charge: Charge) -> PaystackResult<TransactionStatus> {
let url = format!("{}/transaction/charge_authorization", BASE_URL);
let response = self
.client
.post(url)
.bearer_auth(&self.api_key)
.header("Content-Type", "application/json")
.json(&charge)
.send()
.await?;
if response.error_for_status_ref().is_err() {
return Err(
RequestNotSuccessful::new(response.status(), response.text().await?).into(),
);
}
let content = response.json::<TransactionStatus>().await?;
Ok(content)
}
}