use crate::error::Result;
use crate::modules::validators::Validators;
use crate::types::{
ApiResponse, CreatePaymentRequest, PaginatedResponse, PaginationParams, Payment,
PaymentResponse,
};
use std::sync::Arc;
pub struct PaymentModule {
client: Arc<crate::client::TapsilatClient>,
}
impl PaymentModule {
pub fn new(client: Arc<crate::client::TapsilatClient>) -> Self {
Self { client }
}
pub fn create(&self, request: CreatePaymentRequest) -> Result<PaymentResponse> {
Validators::validate_amount(request.amount)?;
let response = self
.client
.make_request("POST", "payments", Some(&request))?;
let api_response: ApiResponse<PaymentResponse> = serde_json::from_value(response)?;
match api_response.data {
Some(payment_response) => Ok(payment_response),
None => Err(crate::error::TapsilatError::InvalidResponse(
api_response
.message
.unwrap_or("No payment data in response".to_string()),
)),
}
}
pub fn get(&self, payment_id: &str) -> Result<Payment> {
if payment_id.is_empty() {
return Err(crate::error::TapsilatError::ValidationError(
"Payment ID cannot be empty".to_string(),
));
}
let endpoint = format!("payments/{}", payment_id);
let response = self.client.make_request::<()>("GET", &endpoint, None)?;
let api_response: ApiResponse<Payment> = serde_json::from_value(response)?;
match api_response.data {
Some(payment) => Ok(payment),
None => Err(crate::error::TapsilatError::InvalidResponse(
api_response
.message
.unwrap_or("No payment data in response".to_string()),
)),
}
}
pub fn list(&self, pagination: Option<PaginationParams>) -> Result<PaginatedResponse<Payment>> {
let mut endpoint = "payments".to_string();
if let Some(params) = pagination {
let mut query_params = Vec::new();
if let Some(page) = params.page {
query_params.push(format!("page={}", page));
}
if let Some(per_page) = params.per_page {
query_params.push(format!("per_page={}", per_page));
}
if !query_params.is_empty() {
endpoint.push('?');
endpoint.push_str(&query_params.join("&"));
}
}
let response = self.client.make_request::<()>("GET", &endpoint, None)?;
let api_response: ApiResponse<PaginatedResponse<Payment>> =
serde_json::from_value(response)?;
match api_response.data {
Some(paginated_payments) => Ok(paginated_payments),
None => Err(crate::error::TapsilatError::InvalidResponse(
api_response
.message
.unwrap_or("No payments data in response".to_string()),
)),
}
}
pub fn cancel(&self, payment_id: &str) -> Result<Payment> {
if payment_id.is_empty() {
return Err(crate::error::TapsilatError::ValidationError(
"Payment ID cannot be empty".to_string(),
));
}
let endpoint = format!("payments/{}/cancel", payment_id);
let response = self.client.make_request::<()>("POST", &endpoint, None)?;
let api_response: ApiResponse<Payment> = serde_json::from_value(response)?;
match api_response.data {
Some(payment) => Ok(payment),
None => Err(crate::error::TapsilatError::InvalidResponse(
api_response
.message
.unwrap_or("No payment data in response".to_string()),
)),
}
}
}