use reqwest::Method;
use crate::client::Bkash;
use crate::config::Product;
use crate::error::Error;
use crate::models::token::{GrantTokenRequest, RefreshTokenRequest, TokenResponse};
use crate::models::tokenized::{
AgreementStatusResponse, CancelAgreementResponse, CreateAgreementRequest,
CreateAgreementResponse, CreatePaymentRequest, CreatePaymentResponse, ExecuteAgreementResponse,
ExecutePaymentResponse, QueryPaymentResponse, RefundRequest, RefundResponse,
RefundStatusResponse, SearchTransactionResponse,
};
use crate::token::TokenTransport;
#[derive(Debug, Clone, Copy)]
pub struct TokenizedCheckoutClient<'a> {
client: &'a Bkash,
}
impl<'a> TokenizedCheckoutClient<'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::Tokenized,
Method::POST,
Product::Tokenized.token_path(),
Some(&req),
)
.await
}
pub async fn refresh_token(&self, req: RefreshTokenRequest) -> Result<TokenResponse, Error> {
self.client
.transport()
.execute_raw(
Product::Tokenized,
Method::POST,
Product::Tokenized.token_refresh_path(),
Some(&req),
)
.await
}
pub async fn create_agreement(
&self,
req: CreateAgreementRequest,
) -> Result<CreateAgreementResponse, Error> {
self.client
.transport()
.request(
Product::Tokenized,
Method::POST,
"tokenized/checkout/create",
Some(&req),
)
.await
}
pub async fn execute_agreement(
&self,
payment_id: &str,
) -> Result<ExecuteAgreementResponse, Error> {
let req = crate::models::tokenized::ExecuteAgreementRequest::new(payment_id);
self.client
.transport()
.request(
Product::Tokenized,
Method::POST,
"tokenized/checkout/execute",
Some(&req),
)
.await
}
pub async fn query_agreement(
&self,
agreement_id: &str,
) -> Result<AgreementStatusResponse, Error> {
let req = crate::models::tokenized::QueryAgreementRequest::new(agreement_id);
self.client
.transport()
.request(
Product::Tokenized,
Method::POST,
"tokenized/checkout/agreement/status",
Some(&req),
)
.await
}
pub async fn cancel_agreement(
&self,
agreement_id: &str,
) -> Result<CancelAgreementResponse, Error> {
let req = crate::models::tokenized::CancelAgreementRequest::new(agreement_id);
self.client
.transport()
.request(
Product::Tokenized,
Method::POST,
"tokenized/checkout/agreement/cancel",
Some(&req),
)
.await
}
pub async fn create_payment(
&self,
req: CreatePaymentRequest,
) -> Result<CreatePaymentResponse, Error> {
self.client
.transport()
.request(
Product::Tokenized,
Method::POST,
"tokenized/checkout/create",
Some(&req),
)
.await
}
pub async fn execute_payment(&self, payment_id: &str) -> Result<ExecutePaymentResponse, Error> {
let req = crate::models::tokenized::ExecutePaymentRequest::new(payment_id);
self.client
.transport()
.request(
Product::Tokenized,
Method::POST,
"tokenized/checkout/execute",
Some(&req),
)
.await
}
pub async fn query_payment(&self, payment_id: &str) -> Result<QueryPaymentResponse, Error> {
let req = crate::models::tokenized::QueryPaymentRequest::new(payment_id);
self.client
.transport()
.request(
Product::Tokenized,
Method::POST,
"tokenized/checkout/payment/status",
Some(&req),
)
.await
}
pub async fn search_transaction(
&self,
trx_id: &str,
) -> Result<SearchTransactionResponse, Error> {
let req = crate::models::tokenized::SearchTransactionRequest::new(trx_id);
self.client
.transport()
.request(
Product::Tokenized,
Method::POST,
"tokenized/checkout/general/searchTransaction",
Some(&req),
)
.await
}
pub async fn refund(&self, req: RefundRequest) -> Result<RefundResponse, Error> {
self.client
.transport()
.request(
Product::Tokenized,
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 = crate::models::tokenized::RefundStatusRequest::new(payment_id, trx_id);
self.client
.transport()
.request(
Product::Tokenized,
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::<TokenizedCheckoutClient<'_>>();
}
}