use crate::client::Client;
use crate::envelope::Envelope;
use crate::error::Result;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct BillPackage {
pub id: i64,
pub biller_id: i64,
pub name: String,
pub is_amount_editable: bool,
pub amount: f64,
pub min_amount: f64,
pub max_amount: f64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Biller {
pub id: i64,
pub name: String,
pub identifier: Option<String>,
pub short_code: Option<String>,
#[serde(rename = "isAquired")]
pub is_acquired: bool,
pub required_validation: bool,
pub charge: f64,
pub flow: i64,
#[serde(default)]
pub packages: Vec<BillPackage>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct BillCategory {
pub id: i64,
pub name: String,
#[serde(default)]
pub billers: Vec<Biller>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ValidateCustomerRequest {
pub channel_id: String,
pub identifier: String,
pub package_id: i64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CustomerValidation {
pub is_validated: bool,
pub customer_name: Option<String>,
pub message: Option<String>,
pub validation_info: Option<String>,
pub credit_limit: Option<f64>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct PayBillRequest {
pub client_id: String,
pub customer_account: String,
pub amount: f64,
pub charge: f64,
pub transaction_reference: String,
pub package_id: i64,
pub customer_identifier: String,
pub customer_email: String,
pub customer_phone_number: String,
pub customer_name: String,
pub security_info: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct PaymentResult {
pub status: Option<String>,
pub message: Option<String>,
pub narration: Option<String>,
pub transaction_reference: Option<String>,
pub platform_transaction_reference: Option<String>,
pub transaction_stan: Option<String>,
pub value: Option<String>,
#[serde(rename = "orinalTxnTransactionDate")]
pub original_transaction_date: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CheckTransactionStatusRequest {
pub transaction_reference: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct TransactionStatus {
pub transaction_reference: Option<String>,
pub transaction_status: i64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct DataPackage {
pub id: i64,
pub name: String,
pub amount: f64,
pub data_plan: Option<String>,
#[serde(rename = "validity_Period")]
pub validity_period: Option<String>,
pub enabled_for_bnpl: Option<bool>,
pub description: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct DataPlanCategory {
pub id: i64,
pub network_provider: String,
#[serde(default)]
pub data_packages: Vec<DataPackage>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct PurchaseAirtimeRequest {
pub transaction_reference: String,
pub account_number: String,
pub network: String,
pub phone_number: String,
pub amount: f64,
pub security_info: String,
pub client_id: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct PurchaseDataRequest {
pub transaction_reference: String,
pub account_number: String,
pub phone_number: String,
pub package_code: i64,
pub amount: f64,
pub network: String,
pub security_info: String,
pub client_id: String,
}
impl Client {
pub async fn get_all_bills(&self) -> Result<Vec<BillCategory>> {
let headers = self.access_headers(true)?;
self.get_json::<Envelope<Vec<BillCategory>>>(
"bills-payment/api/BillsPayment/GetAllBills",
&[],
&headers,
)
.await?
.into_result()
}
pub async fn validate_customer(
&self,
request: &ValidateCustomerRequest,
) -> Result<CustomerValidation> {
let headers = self.access_headers(true)?;
self.post_json::<_, Envelope<CustomerValidation>>(
"bills-payment/api/BillsPayment/ValidateCustomer",
request,
&headers,
)
.await?
.into_result()
}
pub async fn pay_bill(&self, request: &PayBillRequest) -> Result<PaymentResult> {
let headers = self.access_headers(true)?;
self.post_json::<_, Envelope<PaymentResult>>(
"bills-payment/api/Shared/PayBill",
request,
&headers,
)
.await?
.into_result()
}
pub async fn check_bill_transaction_status(
&self,
request: &CheckTransactionStatusRequest,
) -> Result<TransactionStatus> {
let headers = self.access_headers(true)?;
self.post_json::<_, Envelope<TransactionStatus>>(
"bills-payment/api/PartnerPayment/checktransactionstatus",
request,
&headers,
)
.await?
.into_result()
}
pub async fn get_data_plans(&self) -> Result<Vec<DataPlanCategory>> {
let headers = self.access_headers(false)?;
self.get_json::<Envelope<Vec<DataPlanCategory>>>(
"airtime-data/api/Data/GetDataPlans",
&[],
&headers,
)
.await?
.into_result()
}
pub async fn purchase_airtime(&self, request: &PurchaseAirtimeRequest) -> Result<PaymentResult> {
let headers = self.access_headers(true)?;
self.post_json::<_, Envelope<PaymentResult>>(
"airtime-data/api/Airtime/Client/PurchaseAirtime",
request,
&headers,
)
.await?
.into_result()
}
pub async fn purchase_data(&self, request: &PurchaseDataRequest) -> Result<PaymentResult> {
let headers = self.access_headers(false)?;
self.post_json::<_, Envelope<PaymentResult>>(
"airtime-data/api/Data/Client/PurchaseData",
request,
&headers,
)
.await?
.into_result()
}
}