use reqwest::Method;
use crate::client::Bkash;
use crate::config::Product;
use crate::error::Error;
use crate::models::checkout::{
CreatePaymentRequest, CreatePaymentResponse, ExecutePaymentRequest, ExecutePaymentResponse,
QueryPaymentRequest, QueryPaymentResponse, RefundRequest, RefundResponse, RefundStatusRequest,
RefundStatusResponse, SearchTransactionRequest, SearchTransactionResponse,
};
use crate::models::token::{GrantTokenRequest, RefreshTokenRequest, TokenResponse};
use crate::token::TokenTransport;
#[derive(Debug, Clone, Copy)]
pub struct CheckoutClient<'a> {
client: &'a Bkash,
}
impl<'a> CheckoutClient<'a> {
#[must_use]
pub(crate) fn new(client: &'a Bkash) -> Self {
Self { client }
}
pub async fn grant_token(&self, req: GrantTokenRequest) -> Result<TokenResponse, Error> {
self.client
.transport()
.execute_raw(
Product::Checkout,
Method::POST,
Product::Checkout.token_path(),
Some(&req),
)
.await
}
pub async fn refresh_token(&self, req: RefreshTokenRequest) -> Result<TokenResponse, Error> {
self.client
.transport()
.execute_raw(
Product::Checkout,
Method::POST,
Product::Checkout.token_refresh_path(),
Some(&req),
)
.await
}
pub async fn create_payment(
&self,
req: CreatePaymentRequest,
) -> Result<CreatePaymentResponse, Error> {
self.client
.transport()
.request(
Product::Checkout,
Method::POST,
"tokenized/checkout/create",
Some(&req),
)
.await
}
pub async fn execute_payment(&self, payment_id: &str) -> Result<ExecutePaymentResponse, Error> {
let req = ExecutePaymentRequest::new(payment_id);
self.client
.transport()
.request(
Product::Checkout,
Method::POST,
"tokenized/checkout/execute",
Some(&req),
)
.await
}
pub async fn query_payment(&self, payment_id: &str) -> Result<QueryPaymentResponse, Error> {
let req = QueryPaymentRequest::new(payment_id);
self.client
.transport()
.request(
Product::Checkout,
Method::POST,
"tokenized/checkout/payment/status",
Some(&req),
)
.await
}
pub async fn search_transaction(
&self,
trx_id: &str,
) -> Result<SearchTransactionResponse, Error> {
let req = SearchTransactionRequest::new(trx_id);
self.client
.transport()
.request(
Product::Checkout,
Method::POST,
"tokenized/checkout/general/searchTransaction",
Some(&req),
)
.await
}
pub async fn refund(&self, req: RefundRequest) -> Result<RefundResponse, Error> {
self.client
.transport()
.request(
Product::Checkout,
Method::POST,
"tokenized/checkout/payment/refund",
Some(&req),
)
.await
}
pub async fn refund_status(
&self,
payment_id: &str,
trx_id: &str,
) -> Result<RefundStatusResponse, Error> {
let req = RefundStatusRequest::new(payment_id, trx_id);
self.client
.transport()
.request(
Product::Checkout,
Method::POST,
"tokenized/checkout/payment/refund/status",
Some(&req),
)
.await
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn client_is_copy() {
fn assert_copy<T: Copy>() {}
assert_copy::<CheckoutClient<'_>>();
}
}