checkout_core 0.0.147

core traits and structs for the checkout_controller crate
Documentation
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() {
                // this isn't supposed to happen.
                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() {
                // this isn't supposed to happen.
                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() {
                // this isn't supposed to happen.
                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() {
                // this isn't supposed to happen.
                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)
}