use serde::de::DeserializeOwned;
use serde::Serialize;
use crate::checkout::Checkout;
use crate::context::Context;
use crate::error::{new_not_found_error, Error};
use crate::internal_context::InternalContext;
use crate::money::Money;
use super::{cancel, new, process, Initiator, InitiatorId, Payment, PaymentProcessor};
pub async fn get_handler<C: Context + Send>(
ctx: &mut C,
id: &str,
) -> Result<Payment<<C as PaymentProcessor>::Data>, Error> {
let maybe_payment = ctx.get_payment(id).await?;
if maybe_payment.is_none() {
return Err(new_not_found_error(
"the requested payment could not be found",
));
}
Ok(maybe_payment.unwrap())
}
pub async fn create_handler<
'a,
C: Context + Send,
P: Sync + Send + Serialize + DeserializeOwned,
>(
ctx: &mut C,
initiator: Initiator<'a, P>,
charge_amount: Money,
args: <C as PaymentProcessor>::InitArgs,
) -> Result<Payment<<C as PaymentProcessor>::Data>, Error> {
new(ctx, initiator, charge_amount, args).await
}
pub async fn step_handler<C: Context + Send>(
internal_ctx: &InternalContext,
ctx: &mut C,
id: &str,
args: <C as PaymentProcessor>::ProcessArgs,
) -> Result<Payment<<C as PaymentProcessor>::Data>, Error> {
let maybe_payment = ctx.get_payment_for_update(id).await?;
if maybe_payment.is_none() {
return Err(new_not_found_error("the payment could not be found"));
}
let mut payment: Payment<<C as PaymentProcessor>::Data> = maybe_payment.unwrap();
match &payment.initiator_id {
InitiatorId::Checkout(co_id) => {
let maybe_co: Option<Checkout<Payment<<C as PaymentProcessor>::Data>>> =
ctx.get_checkout_for_update(co_id).await?;
if maybe_co.is_none() {
return Err(new_not_found_error(
"the associated checkout could not be found",
));
}
let mut checkout = maybe_co.unwrap();
process(
internal_ctx,
ctx,
&mut payment,
Initiator::Checkout(&mut checkout),
args,
)
.await?;
}
InitiatorId::Order(od_id) => {
let maybe_od = ctx.get_order_for_update(od_id).await?;
if maybe_od.is_none() {
return Err(new_not_found_error(
"the associated order could not be found",
));
}
let mut order = maybe_od.unwrap();
process(
internal_ctx,
ctx,
&mut payment,
Initiator::<Payment<<C as PaymentProcessor>::Data>>::Order(&mut order),
args,
)
.await?;
}
}
Ok(payment)
}
pub async fn callback_handler<C: Context + Send>(
internal_ctx: &InternalContext,
ctx: &mut C,
correlation_id: &str,
args: <C as PaymentProcessor>::ProcessArgs,
) -> Result<Payment<<C as PaymentProcessor>::Data>, Error> {
let maybe_payment = ctx
.get_payment_for_update_by_correlation_id(correlation_id)
.await?;
if maybe_payment.is_none() {
return Err(new_not_found_error("the payment could not be found"));
}
let mut payment: Payment<<C as PaymentProcessor>::Data> = maybe_payment.unwrap();
match &payment.initiator_id {
InitiatorId::Checkout(co_id) => {
let maybe_co: Option<Checkout<Payment<<C as PaymentProcessor>::Data>>> =
ctx.get_checkout_for_update(co_id).await?;
if maybe_co.is_none() {
return Err(new_not_found_error(
"the associated checkout could not be found",
));
}
let mut checkout = maybe_co.unwrap();
process(
internal_ctx,
ctx,
&mut payment,
Initiator::Checkout(&mut checkout),
args,
)
.await?;
}
InitiatorId::Order(od_id) => {
let maybe_od = ctx.get_order_for_update(od_id).await?;
if maybe_od.is_none() {
return Err(new_not_found_error(
"the associated order could not be found",
));
}
let mut order = maybe_od.unwrap();
process(
internal_ctx,
ctx,
&mut payment,
Initiator::<Payment<<C as PaymentProcessor>::Data>>::Order(&mut order),
args,
)
.await?;
}
}
Ok(payment)
}
pub async fn cancel_handler<C: Context + Send>(
internal_ctx: &InternalContext,
ctx: &mut C,
id: &str,
) -> Result<Payment<<C as PaymentProcessor>::Data>, Error> {
let maybe_payment: Option<Payment<<C as PaymentProcessor>::Data>> =
ctx.get_payment_for_update(id).await?;
if maybe_payment.is_none() {
return Err(new_not_found_error("the payment could not be found"));
}
let mut payment = maybe_payment.unwrap();
match &payment.initiator_id {
InitiatorId::Checkout(co_id) => {
let maybe_co: Option<Checkout<Payment<<C as PaymentProcessor>::Data>>> =
ctx.get_checkout_for_update(co_id).await?;
if maybe_co.is_none() {
return Err(new_not_found_error("the checkout could not be found"));
}
let mut checkout = maybe_co.unwrap();
cancel(
internal_ctx,
ctx,
&mut payment,
Initiator::<Payment<<C as PaymentProcessor>::Data>>::Checkout(&mut checkout),
)
.await?;
}
InitiatorId::Order(od_id) => {
let maybe_od = ctx.get_order_for_update(od_id).await?;
if maybe_od.is_none() {
return Err(new_not_found_error("the order could not be found"));
}
let mut order = maybe_od.unwrap();
cancel(
internal_ctx,
ctx,
&mut payment,
Initiator::<Payment<<C as PaymentProcessor>::Data>>::Order(&mut order),
)
.await?;
}
}
Ok(payment)
}