File: crates/router/tests/connectors/getnet.rs

use hyperswitch_domain_models::payment_method_data::{Card, PaymentMethodData};
use masking::Secret;
use router::types::{self, api, storage::enums};
use test_utils::connector_auth;

use crate::utils::{self, ConnectorActions};

#[derive(Clone, Copy)]
struct GetnetTest;
impl ConnectorActions for GetnetTest {}
impl utils::Connector for GetnetTest {
    fn get_data(&self) -> api::ConnectorData {
        use router::connector::Getnet;
        utils::construct_connector_data_old(
            Box::new(Getnet::new()),
            types::Connector::Plaid,
            api::GetToken::Connector,
            None,
        )
    }

    fn get_auth_token(&self) -> types::ConnectorAuthType {
        utils::to_connector_auth_type(
            connector_auth::ConnectorAuthentication::new()
                .getnet
                .expect("Missing connector authentication configuration")
                .into(),
        )
    }

    fn get_name(&self) -> String {
        "getnet".to_string()
    }
}

static CONNECTOR: GetnetTest = GetnetTest {};

fn get_default_payment_info() -> Option<utils::PaymentInfo> {
    None
}

fn payment_method_details() -> Option<types::PaymentsAuthorizeData> {
    None
}

// Cards Positive Tests
// Creates a payment using the manual capture flow (Non 3DS).
#[actix_web::test]
async fn should_only_authorize_payment() {
    let response = CONNECTOR
        .authorize_payment(payment_method_details(), get_default_payment_info())
        .await
        .expect("Authorize payment response");
    assert_eq!(response.status, enums::AttemptStatus::Authorized);
}

// Captures a payment using the manual capture flow (Non 3DS).
#[actix_web::test]
async fn should_capture_authorized_payment() {
    let response = CONNECTOR
        .authorize_and_capture_payment(payment_method_details(), None, get_default_payment_info())
        .await
        .expect("Capture payment response");
    assert_eq!(response.status, enums::AttemptStatus::Charged);
}

// Partially captures a payment using the manual capture flow (Non 3DS).
#[actix_web::test]
async fn should_partially_capture_authorized_payment() {
    let response = CONNECTOR
        .authorize_and_capture_payment(
            payment_method_details(),
            Some(types::PaymentsCaptureData {
                amount_to_capture: 50,
                ..utils::PaymentCaptureType::default().0
            }),
            get_default_payment_info(),
        )
        .await
        .expect("Capture payment response");
    assert_eq!(response.status, enums::AttemptStatus::Charged);
}

// Synchronizes a payment using the manual capture flow (Non 3DS).
#[actix_web::test]
async fn should_sync_authorized_payment() {
    let authorize_response = CONNECTOR
        .authorize_payment(payment_method_details(), get_default_payment_info())
        .await
        .expect("Authorize payment response");
    let txn_id = utils::get_connector_transaction_id(authorize_response.response);
    let response = CONNECTOR
        .psync_retry_till_status_matches(
            enums::AttemptStatus::Authorized,
            Some(types::PaymentsSyncData {
                connector_transaction_id: types::ResponseId::ConnectorTransactionId(
                    txn_id.unwrap(),
                ),
                ..Default::default()
            }),
            get_default_payment_info(),
        )
        .await
        .expect("PSync response");
    assert_eq!(response.status, enums::AttemptStatus::Authorized,);
}

// Voids a payment using the manual capture flow (Non 3DS).
#[actix_web::test]
async fn should_void_authorized_payment() {
    let response = CONNECTOR
        .authorize_and_void_payment(
            payment_method_details(),
            Some(types::PaymentsCancelData {
                connector_transaction_id: String::from(""),
                cancellation_reason: Some("requested_by_customer".to_string()),
                ..Default::default()
            }),
            get_default_payment_info(),
        )
        .await
        .expect("Void payment response");
    assert_eq!(response.status, enums::AttemptStatus::Voided);
}

// Refunds a payment using the manual capture flow (Non 3DS).
#[actix_web::test]
async fn should_refund_manually_captured_payment() {
    let response = CONNECTOR
        .capture_payment_and_refund(
            payment_method_details(),
            None,
            None,
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap().refund_status,
        enums::RefundStatus::Success,
    );
}

// Partially refunds a payment using the manual capture flow (Non 3DS).
#[actix_web::test]
async fn should_partially_refund_manually_captured_payment() {
    let response = CONNECTOR
        .capture_payment_and_refund(
            payment_method_details(),
            None,
            Some(types::RefundsData {
                refund_amount: 50,
                ..utils::PaymentRefundType::default().0
            }),
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap().refund_status,
        enums::RefundStatus::Success,
    );
}

// Synchronizes a refund using the manual capture flow (Non 3DS).
#[actix_web::test]
async fn should_sync_manually_captured_refund() {
    let refund_response = CONNECTOR
        .capture_payment_and_refund(
            payment_method_details(),
            None,
            None,
            get_default_payment_info(),
        )
        .await
        .unwrap();
    let response = CONNECTOR
        .rsync_retry_till_status_matches(
            enums::RefundStatus::Success,
            refund_response.response.unwrap().connector_refund_id,
            None,
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap().refund_status,
        enums::RefundStatus::Success,
    );
}

// Creates a payment using the automatic capture flow (Non 3DS).
#[actix_web::test]
async fn should_make_payment() {
    let authorize_response = CONNECTOR
        .make_payment(payment_method_details(), get_default_payment_info())
        .await
        .unwrap();
    assert_eq!(authorize_response.status, enums::AttemptStatus::Charged);
}

// Synchronizes a payment using the automatic capture flow (Non 3DS).
#[actix_web::test]
async fn should_sync_auto_captured_payment() {
    let authorize_response = CONNECTOR
        .make_payment(payment_method_details(), get_default_payment_info())
        .await
        .unwrap();
    assert_eq!(authorize_response.status, enums::AttemptStatus::Charged);
    let txn_id = utils::get_connector_transaction_id(authorize_response.response);
    assert_ne!(txn_id, None, "Empty connector transaction id");
    let response = CONNECTOR
        .psync_retry_till_status_matches(
            enums::AttemptStatus::Charged,
            Some(types::PaymentsSyncData {
                connector_transaction_id: types::ResponseId::ConnectorTransactionId(
                    txn_id.unwrap(),
                ),
                capture_method: Some(enums::CaptureMethod::Automatic),
                ..Default::default()
            }),
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(response.status, enums::AttemptStatus::Charged,);
}

// Refunds a payment using the automatic capture flow (Non 3DS).
#[actix_web::test]
async fn should_refund_auto_captured_payment() {
    let response = CONNECTOR
        .make_payment_and_refund(payment_method_details(), None, get_default_payment_info())
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap().refund_status,
        enums::RefundStatus::Success,
    );
}

// Partially refunds a payment using the automatic capture flow (Non 3DS).
#[actix_web::test]
async fn should_partially_refund_succeeded_payment() {
    let refund_response = CONNECTOR
        .make_payment_and_refund(
            payment_method_details(),
            Some(types::RefundsData {
                refund_amount: 50,
                ..utils::PaymentRefundType::default().0
            }),
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        refund_response.response.unwrap().refund_status,
        enums::RefundStatus::Success,
    );
}

// Creates multiple refunds against a payment using the automatic capture flow (Non 3DS).
#[actix_web::test]
async fn should_refund_succeeded_payment_multiple_times() {
    CONNECTOR
        .make_payment_and_multiple_refund(
            payment_method_details(),
            Some(types::RefundsData {
                refund_amount: 50,
                ..utils::PaymentRefundType::default().0
            }),
            get_default_payment_info(),
        )
        .await;
}

// Synchronizes a refund using the automatic capture flow (Non 3DS).
#[actix_web::test]
async fn should_sync_refund() {
    let refund_response = CONNECTOR
        .make_payment_and_refund(payment_method_details(), None, get_default_payment_info())
        .await
        .unwrap();
    let response = CONNECTOR
        .rsync_retry_till_status_matches(
            enums::RefundStatus::Success,
            refund_response.response.unwrap().connector_refund_id,
            None,
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap().refund_status,
        enums::RefundStatus::Success,
    );
}

// Cards Negative scenarios
// Creates a payment with incorrect CVC.
#[actix_web::test]
async fn should_fail_payment_for_incorrect_cvc() {
    let response = CONNECTOR
        .make_payment(
            Some(types::PaymentsAuthorizeData {
                payment_method_data: PaymentMethodData::Card(Card {
                    card_cvc: Secret::new("12345".to_string()),
                    ..utils::CCardType::default().0
                }),
                ..utils::PaymentAuthorizeType::default().0
            }),
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap_err().message,
        "Your card's security code is invalid.".to_string(),
    );
}

// Creates a payment with incorrect expiry month.
#[actix_web::test]
async fn should_fail_payment_for_invalid_exp_month() {
    let response = CONNECTOR
        .make_payment(
            Some(types::PaymentsAuthorizeData {
                payment_method_data: PaymentMethodData::Card(Card {
                    card_exp_month: Secret::new("20".to_string()),
                    ..utils::CCardType::default().0
                }),
                ..utils::PaymentAuthorizeType::default().0
            }),
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap_err().message,
        "Your card's expiration month is invalid.".to_string(),
    );
}

// Creates a payment with incorrect expiry year.
#[actix_web::test]
async fn should_fail_payment_for_incorrect_expiry_year() {
    let response = CONNECTOR
        .make_payment(
            Some(types::PaymentsAuthorizeData {
                payment_method_data: PaymentMethodData::Card(Card {
                    card_exp_year: Secret::new("2000".to_string()),
                    ..utils::CCardType::default().0
                }),
                ..utils::PaymentAuthorizeType::default().0
            }),
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap_err().message,
        "Your card's expiration year is invalid.".to_string(),
    );
}

// Voids a payment using automatic capture flow (Non 3DS).
#[actix_web::test]
async fn should_fail_void_payment_for_auto_capture() {
    let authorize_response = CONNECTOR
        .make_payment(payment_method_details(), get_default_payment_info())
        .await
        .unwrap();
    assert_eq!(authorize_response.status, enums::AttemptStatus::Charged);
    let txn_id = utils::get_connector_transaction_id(authorize_response.response);
    assert_ne!(txn_id, None, "Empty connector transaction id");
    let void_response = CONNECTOR
        .void_payment(txn_id.unwrap(), None, get_default_payment_info())
        .await
        .unwrap();
    assert_eq!(
        void_response.response.unwrap_err().message,
        "You cannot cancel this PaymentIntent because it has a status of succeeded."
    );
}

// Captures a payment using invalid connector payment id.
#[actix_web::test]
async fn should_fail_capture_for_invalid_payment() {
    let capture_response = CONNECTOR
        .capture_payment("123456789".to_string(), None, get_default_payment_info())
        .await
        .unwrap();
    assert_eq!(
        capture_response.response.unwrap_err().message,
        String::from("No such payment_intent: '123456789'")
    );
}

// Refunds a payment with refund amount higher than payment amount.
#[actix_web::test]
async fn should_fail_for_refund_amount_higher_than_payment_amount() {
    let response = CONNECTOR
        .make_payment_and_refund(
            payment_method_details(),
            Some(types::RefundsData {
                refund_amount: 150,
                ..utils::PaymentRefundType::default().0
            }),
            get_default_payment_info(),
        )
        .await
        .unwrap();
    assert_eq!(
        response.response.unwrap_err().message,
        "Refund amount (₹1.50) is greater than charge amount (₹1.00)",
    );
}

// Connector dependent test cases goes here

// [#478]: add unit tests for non 3DS, wallets & webhooks in connector tests


pub struct PaymentElement {
    pub net: CoinbaseProcessingFee,
    pub block: Block,
    pub value: CoinbaseProcessingFee,
    pub status: String,
    pub network: String,
    pub deposited: Deposited,
    pub payment_id: String,
    pub detected_at: String,
    pub transaction_id: String,
    pub coinbase_processing_fee: CoinbaseProcessingFee,
}


pub async fn list_metadata_by_merchant_id(
        conn: &PgPooledConn,
        merchant_id: &common_utils::id_type::MerchantId,
        limit: i64,
        offset: i64,
    ) -> StorageResult<Vec<RoutingProfileMetadata>> {
        Ok(Self::table()
            .select((
                dsl::profile_id,
                dsl::algorithm_id,
                dsl::name,
                dsl::description,
                dsl::kind,
                dsl::created_at,
                dsl::modified_at,
                dsl::algorithm_for,
            ))
            .filter(dsl::merchant_id.eq(merchant_id.to_owned()))
            .limit(limit)
            .offset(offset)
            .order(dsl::modified_at.desc())
            .load_async::<(
                common_utils::id_type::ProfileId,
                common_utils::id_type::RoutingId,
                String,
                Option<String>,
                enums::RoutingAlgorithmKind,
                PrimitiveDateTime,
                PrimitiveDateTime,
                enums::TransactionType,
            )>(conn)
            .await
            .change_context(DatabaseError::Others)?
            .into_iter()
            .map(
                |(
                    profile_id,
                    algorithm_id,
                    name,
                    description,
                    kind,
                    created_at,
                    modified_at,
                    algorithm_for,
                )| {
                    RoutingProfileMetadata {
                        profile_id,
                        algorithm_id,
                        name,
                        description,
                        kind,
                        created_at,
                        modified_at,
                        algorithm_for,
                    }
                },
            )
            .collect())
    }


pub fn permission_groups_to_parent_group_info(
    permission_groups: &[PermissionGroup],
    entity_type: EntityType,
) -> Vec<role_api::ParentGroupInfo> {
    let parent_groups_map: HashMap<ParentGroup, Vec<common_enums::PermissionScope>> =
        permission_groups
            .iter()
            .fold(HashMap::new(), |mut acc, group| {
                let parent = group.parent();
                let scope = group.scope();
                acc.entry(parent).or_default().push(scope);
                acc
            });

    parent_groups_map
        .into_iter()
        .filter_map(|(name, scopes)| {
            let unique_scopes = scopes
                .into_iter()
                .collect::<HashSet<_>>()
                .into_iter()
                .collect();

            let description =
                ParentGroup::get_descriptions_for_groups(entity_type, permission_groups.to_vec())
                    .and_then(|descriptions| descriptions.get(&name).cloned())?;

            Some(role_api::ParentGroupInfo {
                name,
                description,
                scopes: unique_scopes,
            })
        })
        .collect()
}


pub async fn call_connector_service<F, RouterDReq, ApiRequest, D>(
    state: &SessionState,
    req_state: ReqState,
    merchant_context: &domain::MerchantContext,
    connector: api::ConnectorData,
    operation: &BoxedOperation<'_, F, ApiRequest, D>,
    payment_data: &mut D,
    customer: &Option<domain::Customer>,
    call_connector_action: CallConnectorAction,
    validate_result: &operations::ValidateResult,
    schedule_time: Option<time::PrimitiveDateTime>,
    header_payload: HeaderPayload,
    frm_suggestion: Option<storage_enums::FrmSuggestion>,
    business_profile: &domain::Profile,
    is_retry_payment: bool,
    return_raw_connector_response: Option<bool>,
    merchant_connector_account: helpers::MerchantConnectorAccountType,
    mut router_data: RouterData<F, RouterDReq, router_types::PaymentsResponseData>,
    tokenization_action: TokenizationAction,
) -> RouterResult<(
    RouterData<F, RouterDReq, router_types::PaymentsResponseData>,
    helpers::MerchantConnectorAccountType,
)>
where
    F: Send + Clone + Sync,
    RouterDReq: Send + Sync,

    // To create connector flow specific interface data
    D: OperationSessionGetters<F> + OperationSessionSetters<F> + Send + Sync + Clone,
    D: ConstructFlowSpecificData<F, RouterDReq, router_types::PaymentsResponseData>,
    RouterData<F, RouterDReq, router_types::PaymentsResponseData>: Feature<F, RouterDReq> + Send,
    // To construct connector flow specific api
    dyn api::Connector:
        services::api::ConnectorIntegration<F, RouterDReq, router_types::PaymentsResponseData>,
{
    let add_access_token_result = router_data
        .add_access_token(
            state,
            &connector,
            merchant_context,
            payment_data.get_creds_identifier(),
        )
        .await?;

    router_data = router_data.add_session_token(state, &connector).await?;

    let should_continue_further = access_token::update_router_data_with_access_token_result(
        &add_access_token_result,
        &mut router_data,
        &call_connector_action,
    );

    let should_continue_further = match router_data
        .create_order_at_connector(state, &connector, should_continue_further)
        .await?
    {
        Some(create_order_response) => {
            if let Ok(order_id) = create_order_response.clone().create_order_result {
                payment_data.set_connector_response_reference_id(Some(order_id.clone()))
            }

            // Set the response in routerdata response to carry forward
            router_data
                .update_router_data_with_create_order_response(create_order_response.clone());
            create_order_response.create_order_result.ok().is_some()
        }
        // If create order is not required, then we can proceed with further processing
        None => true,
    };

    let updated_customer = call_create_connector_customer_if_required(
        state,
        customer,
        merchant_context,
        &merchant_connector_account,
        payment_data,
        router_data.access_token.as_ref(),
    )
    .await?;

    #[cfg(feature = "v1")]
    if let Some(connector_customer_id) = payment_data.get_connector_customer_id() {
        router_data.connector_customer = Some(connector_customer_id);
    }

    router_data.payment_method_token = payment_data.get_payment_method_token().cloned();

    let payment_method_token_response = router_data
        .add_payment_method_token(
            state,
            &connector,
            &tokenization_action,
            should_continue_further,
        )
        .await?;

    let mut should_continue_further =
        tokenization::update_router_data_with_payment_method_token_result(
            payment_method_token_response,
            &mut router_data,
            is_retry_payment,
            should_continue_further,
        );

    (router_data, should_continue_further) = complete_preprocessing_steps_if_required(
        state,
        &connector,
        payment_data,
        router_data,
        operation,
        should_continue_further,
    )
    .await?;

    if let Ok(router_types::PaymentsResponseData::PreProcessingResponse {
        session_token: Some(session_token),
        ..
    }) = router_data.response.to_owned()
    {
        payment_data.push_sessions_token(session_token);
    };

    // In case of authorize flow, pre-task and post-tasks are being called in build request
    // if we do not want to proceed further, then the function will return Ok(None, false)
    let (connector_request, should_continue_further) = if should_continue_further {
        // Check if the actual flow specific request can be built with available data
        router_data
            .build_flow_specific_connector_request(state, &connector, call_connector_action.clone())
            .await?
    } else {
        (None, false)
    };

    if should_add_task_to_process_tracker(payment_data) {
        operation
            .to_domain()?
            .add_task_to_process_tracker(
                state,
                payment_data.get_payment_attempt(),
                validate_result.requeue,
                schedule_time,
            )
            .await
            .map_err(|error| logger::error!(process_tracker_error=?error))
            .ok();
    }

    // Update the payment trackers just before calling the connector
    // Since the request is already built in the previous step,
    // there should be no error in request construction from hyperswitch end
    (_, *payment_data) = operation
        .to_update_tracker()?
        .update_trackers(
            state,
            req_state,
            payment_data.clone(),
            customer.clone(),
            merchant_context.get_merchant_account().storage_scheme,
            updated_customer,
            merchant_context.get_merchant_key_store(),
            frm_suggestion,
            header_payload.clone(),
        )
        .await?;

    let router_data = if should_continue_further {
        // The status of payment_attempt and intent will be updated in the previous step
        // update this in router_data.
        // This is added because few connector integrations do not update the status,
        // and rely on previous status set in router_data
        router_data.status = payment_data.get_payment_attempt().status;
        router_data
            .decide_flows(
                state,
                &connector,
                call_connector_action,
                connector_request,
                business_profile,
                header_payload.clone(),
                return_raw_connector_response,
            )
            .await
    } else {
        Ok(router_data)
    }?;

    Ok((router_data, merchant_connector_account))
}


pub fn get_id(&self) -> &masking::Secret<String> {
        &self.0
    }


pub struct CheckoutPaymentsRequest {
    order: FiservOrder,
    payment_method: FiservPaymentMethod,
    interactions: FiservInteractions,
    transaction_details: TransactionDetails,
}


pub struct HandlerInner {
    shutdown_interval: Duration,
    loop_interval: Duration,
    active_tasks: Arc<atomic::AtomicU64>,
    conf: DrainerSettings,
    stores: HashMap<id_type::TenantId, Arc<Store>>,
    running: Arc<atomic::AtomicBool>,
}


pub struct Iter<'a, K, V> {
    inner: iter::Enumerate<slice::Iter<'a, V>>,
    _marker: PhantomData<K>,
}


pub fn get_three_ds_keys() -> JsResult {
    let keys = <common_types::payments::ConditionalConfigs as EuclidDirFilter>::ALLOWED;
    Ok(serde_wasm_bindgen::to_value(keys)?)
}


pub fn update_surcharge_config_id(&mut self, ids: String) {
        self.surcharge_config_algo_id = Some(ids);
        self.timestamp = common_utils::date_time::now_unix_timestamp();
    }


pub struct ApplepayPaymentMethod {
    pub display_name: String,
    pub network: String,
    pub pm_type: String,
}


pub struct PayonePayoutFulfillResponse {
    id: String,
    payout_output: PayoutOutput,
    status: PayoneStatus,
}


pub struct TrustpaymentsRouterData<T> {
    pub amount: StringMinorUnit, // The type of amount that a connector accepts, for example, String, i64, f64, etc.
    pub router_data: T,
}


pub fn network_token_migrated(&mut self, network_token_migrated: Option<bool>) {
        self.network_token_migrated = network_token_migrated;
    }


File: crates/kgraph_utils/src/transformers.rs
 Public functions: 3

use api_models::enums as api_enums;
use euclid::{
    backend::BackendInput,
    dirval,
    dssa::types::AnalysisErrorType,
    frontend::{ast, dir},
    types::{NumValue, StrValue},
};

use crate::error::KgraphError;

pub trait IntoContext {
    fn into_context(self) -> Result<Vec<dir::DirValue>, KgraphError>;
}

impl IntoContext for BackendInput {
    fn into_context(self) -> Result<Vec<dir::DirValue>, KgraphError> {
        let mut ctx: Vec<dir::DirValue> = Vec::new();

        ctx.push(dir::DirValue::PaymentAmount(NumValue {
            number: self.payment.amount,
            refinement: None,
        }));

        ctx.push(dir::DirValue::PaymentCurrency(self.payment.currency));

        if let Some(auth_type) = self.payment.authentication_type {
            ctx.push(dir::DirValue::AuthenticationType(auth_type));
        }

        if let Some(capture_method) = self.payment.capture_method {
            ctx.push(dir::DirValue::CaptureMethod(capture_method));
        }

        if let Some(business_country) = self.payment.business_country {
            ctx.push(dir::DirValue::BusinessCountry(business_country));
        }
        if let Some(business_label) = self.payment.business_label {
            ctx.push(dir::DirValue::BusinessLabel(StrValue {
                value: business_label,
            }));
        }
        if let Some(billing_country) = self.payment.billing_country {
            ctx.push(dir::DirValue::BillingCountry(billing_country));
        }

        if let Some(payment_method) = self.payment_method.payment_method {
            ctx.push(dir::DirValue::PaymentMethod(payment_method));
        }

        if let (Some(pm_type), Some(payment_method)) = (
            self.payment_method.payment_method_type,
            self.payment_method.payment_method,
        ) {
            ctx.push((pm_type, payment_method).into_dir_value()?)
        }

        if let Some(card_network) = self.payment_method.card_network {
            ctx.push(dir::DirValue::CardNetwork(card_network));
        }
        if let Some(setup_future_usage) = self.payment.setup_future_usage {
            ctx.push(dir::DirValue::SetupFutureUsage(setup_future_usage));
        }
        if let Some(mandate_acceptance_type) = self.mandate.mandate_acceptance_type {
            ctx.push(dir::DirValue::MandateAcceptanceType(
                mandate_acceptance_type,
            ));
        }
        if let Some(mandate_type) = self.mandate.mandate_type {
            ctx.push(dir::DirValue::MandateType(mandate_type));
        }
        if let Some(payment_type) = self.mandate.payment_type {
            ctx.push(dir::DirValue::PaymentType(payment_type));
        }

        Ok(ctx)
    }
}

pub trait IntoDirValue {
    fn into_dir_value(self) -> Result<dir::DirValue, KgraphError>;
}

impl IntoDirValue for ast::ConnectorChoice {
    fn into_dir_value(self) -> Result<dir::DirValue, KgraphError> {
        Ok(dir::DirValue::Connector(Box::new(self)))
    }
}

impl IntoDirValue for api_enums::PaymentMethod {
    fn into_dir_value(self) -> Result<dir::DirValue, KgraphError> {
        match self {
            Self::Card => Ok(dirval!(PaymentMethod = Card)),
            Self::Wallet => Ok(dirval!(PaymentMethod = Wallet)),
            Self::PayLater => Ok(dirval!(PaymentMethod = PayLater)),
            Self::BankRedirect => Ok(dirval!(PaymentMethod = BankRedirect)),
            Self::Crypto => Ok(dirval!(PaymentMethod = Crypto)),
            Self::BankDebit => Ok(dirval!(PaymentMethod = BankDebit)),
            Self::BankTransfer => Ok(dirval!(PaymentMethod = BankTransfer)),
            Self::Reward => Ok(dirval!(PaymentMethod = Reward)),
            Self::RealTimePayment => Ok(dirval!(PaymentMethod = RealTimePayment)),
            Self::Upi => Ok(dirval!(PaymentMethod = Upi)),
            Self::Voucher => Ok(dirval!(PaymentMethod = Voucher)),
            Self::GiftCard => Ok(dirval!(PaymentMethod = GiftCard)),
            Self::CardRedirect => Ok(dirval!(PaymentMethod = CardRedirect)),
            Self::OpenBanking => Ok(dirval!(PaymentMethod = OpenBanking)),
            Self::MobilePayment => Ok(dirval!(PaymentMethod = MobilePayment)),
        }
    }
}

impl IntoDirValue for api_enums::AuthenticationType {
    fn into_dir_value(self) -> Result<dir::DirValue, KgraphError> {
        match self {
            Self::ThreeDs => Ok(dirval!(AuthenticationType = ThreeDs)),
            Self::NoThreeDs => Ok(dirval!(AuthenticationType = NoThreeDs)),
        }
    }
}

impl IntoDirValue for api_enums::FutureUsage {
    fn into_dir_value(self) -> Result<dir::DirValue, KgraphError> {
        match self {
            Self::OnSession => Ok(dirval!(SetupFutureUsage = OnSession)),
            Self::OffSession => Ok(dirval!(SetupFutureUsage = OffSession)),
        }
    }
}

impl IntoDirValue for (api_enums::PaymentMethodType, api_enums::PaymentMethod) {
    fn into_dir_value(self) -> Result<dir::DirValue, KgraphError> {
        match self.0 {
            api_enums::PaymentMethodType::AmazonPay => Ok(dirval!(WalletType = AmazonPay)),
            api_enums::PaymentMethodType::Paysera => Ok(dirval!(WalletType = Paysera)),
            api_enums::PaymentMethodType::Skrill => Ok(dirval!(WalletType = Skrill)),
            api_enums::PaymentMethodType::Credit => Ok(dirval!(CardType = Credit)),
            api_enums::PaymentMethodType::Debit => Ok(dirval!(CardType = Debit)),
            #[cfg(feature = "v2")]
            api_enums::PaymentMethodType::Card => Ok(dirval!(CardType = Card)),
            api_enums::PaymentMethodType::Giropay => Ok(dirval!(BankRedirectType = Giropay)),
            api_enums::PaymentMethodType::Ideal => Ok(dirval!(BankRedirectType = Ideal)),
            api_enums::PaymentMethodType::Sofort => Ok(dirval!(BankRedirectType = Sofort)),
            api_enums::PaymentMethodType::Eft => Ok(dirval!(BankRedirectType = Eft)),
            api_enums::PaymentMethodType::Eps => Ok(dirval!(BankRedirectType = Eps)),
            api_enums::PaymentMethodType::Klarna => Ok(dirval!(PayLaterType = Klarna)),
            api_enums::PaymentMethodType::Affirm => Ok(dirval!(PayLaterType = Affirm)),
            api_enums::PaymentMethodType::AfterpayClearpay => {
                Ok(dirval!(PayLaterType = AfterpayClearpay))
            }
            api_enums::PaymentMethodType::GooglePay => Ok(dirval!(WalletType = GooglePay)),
            api_enums::PaymentMethodType::Bluecode => Ok(dirval!(WalletType = Bluecode)),
            api_enums::PaymentMethodType::ApplePay => Ok(dirval!(WalletType = ApplePay)),
            api_enums::PaymentMethodType::Paypal => Ok(dirval!(WalletType = Paypal)),
            api_enums::PaymentMethodType::CryptoCurrency => {
                Ok(dirval!(CryptoType = CryptoCurrency))
            }
            api_enums::PaymentMethodType::RevolutPay => Ok(dirval!(WalletType = RevolutPay)),
            api_enums::PaymentMethodType::Ach => match self.1 {
                api_enums::PaymentMethod::BankDebit => Ok(dirval!(BankDebitType = Ach)),
                api_enums::PaymentMethod::BankTransfer => Ok(dirval!(BankTransferType = Ach)),
                api_enums::PaymentMethod::BankRedirect
                | api_enums::PaymentMethod::Card
                | api_enums::PaymentMethod::CardRedirect
                | api_enums::PaymentMethod::PayLater
                | api_enums::PaymentMethod::Wallet
                | api_enums::PaymentMethod::Crypto
                | api_enums::PaymentMethod::Reward
                | api_enums::PaymentMethod::RealTimePayment
                | api_enums::PaymentMethod::Upi
                | api_enums::PaymentMethod::MobilePayment
                | api_enums::PaymentMethod::Voucher
                | api_enums::PaymentMethod::OpenBanking
                | api_enums::PaymentMethod::GiftCard => Err(KgraphError::ContextConstructionError(
                    Box::new(AnalysisErrorType::NotSupported),
                )),
            },
            api_enums::PaymentMethodType::Bacs => match self.1 {
                api_enums::PaymentMethod::BankDebit => Ok(dirval!(BankDebitType = Bacs)),
                api_enums::PaymentMethod::BankTransfer => Ok(dirval!(BankTransferType = Bacs)),
                api_enums::PaymentMethod::BankRedirect
                | api_enums::PaymentMethod::Card
                | api_enums::PaymentMethod::CardRedirect
                | api_enums::PaymentMethod::PayLater
                | api_enums::PaymentMethod::Wallet
                | api_enums::PaymentMethod::Crypto
                | api_enums::PaymentMethod::Reward
                | api_enums::PaymentMethod::RealTimePayment
                | api_enums::PaymentMethod::Upi
                | api_enums::PaymentMethod::MobilePayment
                | api_enums::PaymentMethod::Voucher
                | api_enums::PaymentMethod::OpenBanking
                | api_enums::PaymentMethod::GiftCard => Err(KgraphError::ContextConstructionError(
                    Box::new(AnalysisErrorType::NotSupported),
                )),
            },
            api_enums::PaymentMethodType::Becs => Ok(dirval!(BankDebitType = Becs)),
            api_enums::PaymentMethodType::Sepa => Ok(dirval!(BankDebitType = Sepa)),
            api_enums::PaymentMethodType::SepaBankTransfer => {
                Ok(dirval!(BankTransferType = SepaBankTransfer))
            }
            api_enums::PaymentMethodType::AliPay => Ok(dirval!(WalletType = AliPay)),
            api_enums::PaymentMethodType::AliPayHk => Ok(dirval!(WalletType = AliPayHk)),
            api_enums::PaymentMethodType::BancontactCard => {
                Ok(dirval!(BankRedirectType = BancontactCard))
            }
            api_enums::PaymentMethodType::Blik => Ok(dirval!(BankRedirectType = Blik)),
            api_enums::PaymentMethodType::MbWay => Ok(dirval!(WalletType = MbWay)),
            api_enums::PaymentMethodType::MobilePay => Ok(dirval!(WalletType = MobilePay)),
            api_enums::PaymentMethodType::Cashapp => Ok(dirval!(WalletType = Cashapp)),
            api_enums::PaymentMethodType::Multibanco => Ok(dirval!(BankTransferType = Multibanco)),
            api_enums::PaymentMethodType::Pix => Ok(dirval!(BankTransferType = Pix)),
            api_enums::PaymentMethodType::Pse => Ok(dirval!(BankTransferType = Pse)),
            api_enums::PaymentMethodType::Interac => Ok(dirval!(BankRedirectType = Interac)),
            api_enums::PaymentMethodType::OnlineBankingCzechRepublic => {
                Ok(dirval!(BankRedirectType = OnlineBankingCzechRepublic))
            }
            api_enums::PaymentMethodType::OnlineBankingFinland => {
                Ok(dirval!(BankRedirectType = OnlineBankingFinland))
            }
            api_enums::PaymentMethodType::OnlineBankingPoland => {
                Ok(dirval!(BankRedirectType = OnlineBankingPoland))
            }
            api_enums::PaymentMethodType::OnlineBankingSlovakia => {
                Ok(dirval!(BankRedirectType = OnlineBankingSlovakia))
            }
            api_enums::PaymentMethodType::Swish => Ok(dirval!(WalletType = Swish)),
            api_enums::PaymentMethodType::Trustly => Ok(dirval!(BankRedirectType = Trustly)),
            api_enums::PaymentMethodType::Bizum => Ok(dirval!(BankRedirectType = Bizum)),
            api_enums::PaymentMethodType::PayBright => Ok(dirval!(PayLaterType = PayBright)),
            api_enums::PaymentMethodType::Flexiti => Ok(dirval!(PayLaterType = Flexiti)),
            api_enums::PaymentMethodType::Walley => Ok(dirval!(PayLaterType = Walley)),
            api_enums::PaymentMethodType::Breadpay => Ok(dirval!(PayLaterType = Breadpay)),
            api_enums::PaymentMethodType::Przelewy24 => Ok(dirval!(BankRedirectType = Przelewy24)),
            api_enums::PaymentMethodType::WeChatPay => Ok(dirval!(WalletType = WeChatPay)),
            api_enums::PaymentMethodType::ClassicReward => Ok(dirval!(RewardType = ClassicReward)),
            api_enums::PaymentMethodType::Evoucher => Ok(dirval!(RewardType = Evoucher)),
            api_enums::PaymentMethodType::UpiCollect => Ok(dirval!(UpiType = UpiCollect)),
            api_enums::PaymentMethodType::UpiIntent => Ok(dirval!(UpiType = UpiIntent)),
            api_enums::PaymentMethodType::SamsungPay => Ok(dirval!(WalletType = SamsungPay)),
            api_enums::PaymentMethodType::GoPay => Ok(dirval!(WalletType = GoPay)),
            api_enums::PaymentMethodType::KakaoPay => Ok(dirval!(WalletType = KakaoPay)),
            api_enums::PaymentMethodType::Twint => Ok(dirval!(WalletType = Twint)),
            api_enums::PaymentMethodType::Gcash => Ok(dirval!(WalletType = Gcash)),
            api_enums::PaymentMethodType::Vipps => Ok(dirval!(WalletType = Vipps)),
            api_enums::PaymentMethodType::Momo => Ok(dirval!(WalletType = Momo)),
            api_enums::PaymentMethodType::Alma => Ok(dirval!(PayLaterType = Alma)),
            api_enums::PaymentMethodType::Dana => Ok(dirval!(WalletType = Dana)),
            api_enums::PaymentMethodType::OnlineBankingFpx => {
                Ok(dirval!(BankRedirectType = OnlineBankingFpx))
            }
            api_enums::PaymentMethodType::LocalBankRedirect => {
                Ok(dirval!(BankRedirectType = LocalBankRedirect))
            }
            api_enums::PaymentMethodType::OnlineBankingThailand => {
                Ok(dirval!(BankRedirectType = OnlineBankingThailand))
            }
            api_enums::PaymentMethodType::TouchNGo => Ok(dirval!(WalletType = TouchNGo)),
            api_enums::PaymentMethodType::Atome => Ok(dirval!(PayLaterType = Atome)),
            api_enums::PaymentMethodType::Boleto => Ok(dirval!(VoucherType = Boleto)),
            api_enums::PaymentMethodType::Efecty => Ok(dirval!(VoucherType = Efecty)),
            api_enums::PaymentMethodType::PagoEfectivo => Ok(dirval!(VoucherType = PagoEfectivo)),
            api_enums::PaymentMethodType::RedCompra => Ok(dirval!(VoucherType = RedCompra)),
            api_enums::PaymentMethodType::RedPagos => Ok(dirval!(VoucherType = RedPagos)),
            api_enums::PaymentMethodType::Alfamart => Ok(dirval!(VoucherType = Alfamart)),
            api_enums::PaymentMethodType::BcaBankTransfer => {
                Ok(dirval!(BankTransferType = BcaBankTransfer))
            }
            api_enums::PaymentMethodType::BniVa => Ok(dirval!(BankTransferType = BniVa)),
            api_enums::PaymentMethodType::BriVa => Ok(dirval!(BankTransferType = BriVa)),
            api_enums::PaymentMethodType::CimbVa => Ok(dirval!(BankTransferType = CimbVa)),
            api_enums::PaymentMethodType::DanamonVa => Ok(dirval!(BankTransferType = DanamonVa)),
            api_enums::PaymentMethodType::Indomaret => Ok(dirval!(VoucherType = Indomaret)),
            api_enums::PaymentMethodType::MandiriVa => Ok(dirval!(BankTransferType = MandiriVa)),
            api_enums::PaymentMethodType::LocalBankTransfer => {
                Ok(dirval!(BankTransferType = LocalBankTransfer))
            }
            api_enums::PaymentMethodType::InstantBankTransfer => {
                Ok(dirval!(BankTransferType = InstantBankTransfer))
            }
            api_enums::PaymentMethodType::InstantBankTransferFinland => {
                Ok(dirval!(BankTransferType = InstantBankTransferFinland))
            }
            api_enums::PaymentMethodType::InstantBankTransferPoland => {
                Ok(dirval!(BankTransferType = InstantBankTransferPoland))
            }
            api_enums::PaymentMethodType::PermataBankTransfer => {
                Ok(dirval!(BankTransferType = PermataBankTransfer))
            }
            api_enums::PaymentMethodType::PaySafeCard => Ok(dirval!(GiftCardType = PaySafeCard)),
            api_enums::PaymentMethodType::SevenEleven => Ok(dirval!(VoucherType = SevenEleven)),
            api_enums::PaymentMethodType::Lawson => Ok(dirval!(VoucherType = Lawson)),
            api_enums::PaymentMethodType::MiniStop => Ok(dirval!(VoucherType = MiniStop)),
            api_enums::PaymentMethodType::FamilyMart => Ok(dirval!(VoucherType = FamilyMart)),
            api_enums::PaymentMethodType::Seicomart => Ok(dirval!(VoucherType = Seicomart)),
            api_enums::PaymentMethodType::PayEasy => Ok(dirval!(VoucherType = PayEasy)),
            api_enums::PaymentMethodType::Givex => Ok(dirval!(GiftCardType = Givex)),
            api_enums::PaymentMethodType::BhnCardNetwork => {
                Ok(dirval!(GiftCardType = BhnCardNetwork))
            }
            api_enums::PaymentMethodType::Benefit => Ok(dirval!(CardRedirectType = Benefit)),
            api_enums::PaymentMethodType::Knet => Ok(dirval!(CardRedirectType = Knet)),
            api_enums::PaymentMethodType::OpenBankingUk => {
                Ok(dirval!(BankRedirectType = OpenBankingUk))
            }
            api_enums::PaymentMethodType::MomoAtm => Ok(dirval!(CardRedirectType = MomoAtm)),
            api_enums::PaymentMethodType::Oxxo => Ok(dirval!(VoucherType = Oxxo)),
            api_enums::PaymentMethodType::CardRedirect => {
                Ok(dirval!(CardRedirectType = CardRedirect))
            }
            api_enums::PaymentMethodType::Venmo => Ok(dirval!(WalletType = Venmo)),
            api_enums::PaymentMethodType::Mifinity => Ok(dirval!(WalletType = Mifinity)),
            api_enums::PaymentMethodType::Fps => Ok(dirval!(RealTimePaymentType = Fps)),
            api_enums::PaymentMethodType::DuitNow => Ok(dirval!(RealTimePaymentType = DuitNow)),
            api_enums::PaymentMethodType::PromptPay => Ok(dirval!(RealTimePaymentType = PromptPay)),
            api_enums::PaymentMethodType::VietQr => Ok(dirval!(RealTimePaymentType = VietQr)),
            api_enums::PaymentMethodType::OpenBankingPIS => {
                Ok(dirval!(OpenBankingType = OpenBankingPIS))
            }
            api_enums::PaymentMethodType::Paze => Ok(dirval!(WalletType = Paze)),
            api_enums::PaymentMethodType::DirectCarrierBilling => {
                Ok(dirval!(MobilePaymentType = DirectCarrierBilling))
            }
            api_enums::PaymentMethodType::IndonesianBankTransfer => {
                Ok(dirval!(BankTransferType = IndonesianBankTransfer))
            }
        }
    }
}

impl IntoDirValue for api_enums::CardNetwork {
    fn into_dir_value(self) -> Result<dir::DirValue, KgraphError> {
        match self {
            Self::Visa => Ok(dirval!(CardNetwork = Visa)),
            Self::Mastercard => Ok(dirval!(CardNetwork = Mastercard)),
            Self::AmericanExpress => Ok(dirval!(CardNetwork = AmericanExpress)),
            Self::JCB => Ok(dirval!(CardNetwork = JCB)),
            Self::DinersClub => Ok(dirval!(CardNetwork = DinersClub)),
            Self::Discover => Ok(dirval!(CardNetwork = Discover)),
            Self::CartesBancaires => Ok(dirval!(CardNetwork = CartesBancaires)),
            Self::UnionPay => Ok(dirval!(CardNetwork = UnionPay)),
            Self::Interac => Ok(dirval!(CardNetwork = Interac)),
            Self::RuPay => Ok(dirval!(CardNetwork = RuPay)),
            Self::Maestro => Ok(dirval!(CardNetwork = Maestro)),
            Self::Star => Ok(dirval!(CardNetwork = Star)),
            Self::Accel => Ok(dirval!(CardNetwork = Accel)),
            Self::Pulse => Ok(dirval!(CardNetwork = Pulse)),
            Self::Nyce => Ok(dirval!(CardNetwork = Nyce)),
        }
    }
}

impl IntoDirValue for api_enums::Currency {
    fn into_dir_value(self) -> Result<dir::DirValue, KgraphError> {
        match self {
            Self::AED => Ok(dirval!(PaymentCurrency = AED)),
            Self::AFN => Ok(dirval!(PaymentCurrency = AFN)),
            Self::ALL => Ok(dirval!(PaymentCurrency = ALL)),
            Self::AMD => Ok(dirval!(PaymentCurrency = AMD)),
            Self::ANG => Ok(dirval!(PaymentCurrency = ANG)),
            Self::AOA => Ok(dirval!(PaymentCurrency = AOA)),
            Self::ARS => Ok(dirval!(PaymentCurrency = ARS)),
            Self::AUD => Ok(dirval!(PaymentCurrency = AUD)),
            Self::AWG => Ok(dirval!(PaymentCurrency = AWG)),
            Self::AZN => Ok(dirval!(PaymentCurrency = AZN)),
            Self::BAM => Ok(dirval!(PaymentCurrency = BAM)),
            Self::BBD => Ok(dirval!(PaymentCurrency = BBD)),
            Self::BDT => Ok(dirval!(PaymentCurrency = BDT)),
            Self::BGN => Ok(dirval!(PaymentCurrency = BGN)),
            Self::BHD => Ok(dirval!(PaymentCurrency = BHD)),
            Self::BIF => Ok(dirval!(PaymentCurrency = BIF)),
            Self::BMD => Ok(dirval!(PaymentCurrency = BMD)),
            Self::BND => Ok(dirval!(PaymentCurrency = BND)),
            Self::BOB => Ok(dirval!(PaymentCurrency = BOB)),
            Self::BRL => Ok(dirval!(PaymentCurrency = BRL)),
            Self::BSD => Ok(dirval!(PaymentCurrency = BSD)),
            Self::BTN => Ok(dirval!(PaymentCurrency = BTN)),
            Self::BWP => Ok(dirval!(PaymentCurrency = BWP)),
            Self::BYN => Ok(dirval!(PaymentCurrency = BYN)),
            Self::BZD => Ok(dirval!(PaymentCurrency = BZD)),
            Self::CAD => Ok(dirval!(PaymentCurrency = CAD)),
            Self::CDF => Ok(dirval!(PaymentCurrency = CDF)),
            Self::CHF => Ok(dirval!(PaymentCurrency = CHF)),
            Self::CLF => Ok(dirval!(PaymentCurrency = CLF)),
            Self::CLP => Ok(dirval!(PaymentCurrency = CLP)),
            Self::CNY => Ok(dirval!(PaymentCurrency = CNY)),
            Self::COP => Ok(dirval!(PaymentCurrency = COP)),
            Self::CRC => Ok(dirval!(PaymentCurrency = CRC)),
            Self::CUC => Ok(dirval!(PaymentCurrency = CUC)),
            Self::CUP => Ok(dirval!(PaymentCurrency = CUP)),
            Self::CVE => Ok(dirval!(PaymentCurrency = CVE)),
            Self::CZK => Ok(dirval!(PaymentCurrency = CZK)),
            Self::DJF => Ok(dirval!(PaymentCurrency = DJF)),
            Self::DKK => Ok(dirval!(PaymentCurrency = DKK)),
            Self::DOP => Ok(dirval!(PaymentCurrency = DOP)),
            Self::DZD => Ok(dirval!(PaymentCurrency = DZD)),
            Self::EGP => Ok(dirval!(PaymentCurrency = EGP)),
            Self::ERN => Ok(dirval!(PaymentCurrency = ERN)),
            Self::ETB => Ok(dirval!(PaymentCurrency = ETB)),
            Self::EUR => Ok(dirval!(PaymentCurrency = EUR)),
            Self::FJD => Ok(dirval!(PaymentCurrency = FJD)),
            Self::FKP => Ok(dirval!(PaymentCurrency = FKP)),
            Self::GBP => Ok(dirval!(PaymentCurrency = GBP)),
            Self::GEL => Ok(dirval!(PaymentCurrency = GEL)),
            Self::GHS => Ok(dirval!(PaymentCurrency = GHS)),
            Self::GIP => Ok(dirval!(PaymentCurrency = GIP)),
            Self::GMD => Ok(dirval!(PaymentCurrency = GMD)),
            Self::GNF => Ok(dirval!(PaymentCurrency = GNF)),
            Self::GTQ => Ok(dirval!(PaymentCurrency = GTQ)),
            Self::GYD => Ok(dirval!(PaymentCurrency = GYD)),
            Self::HKD => Ok(dirval!(PaymentCurrency = HKD)),
            Self::HNL => Ok(dirval!(PaymentCurrency = HNL)),
            Self::HRK => Ok(dirval!(PaymentCurrency = HRK)),
            Self::HTG => Ok(dirval!(PaymentCurrency = HTG)),
            Self::HUF => Ok(dirval!(PaymentCurrency = HUF)),
            Self::IDR => Ok(dirval!(PaymentCurrency = IDR)),
            Self::ILS => Ok(dirval!(PaymentCurrency = ILS)),
            Self::INR => Ok(dirval!(PaymentCurrency = INR)),
            Self::IQD => Ok(dirval!(PaymentCurrency = IQD)),
            Self::IRR => Ok(dirval!(PaymentCurrency = IRR)),
            Self::ISK => Ok(dirval!(PaymentCurrency = ISK)),
            Self::JMD => Ok(dirval!(PaymentCurrency = JMD)),
            Self::JOD => Ok(dirval!(PaymentCurrency = JOD)),
            Self::JPY => Ok(dirval!(PaymentCurrency = JPY)),
            Self::KES => Ok(dirval!(PaymentCurrency = KES)),
            Self::KGS => Ok(dirval!(PaymentCurrency = KGS)),
            Self::KHR => Ok(dirval!(PaymentCurrency = KHR)),
            Self::KMF => Ok(dirval!(PaymentCurrency = KMF)),
            Self::KPW => Ok(dirval!(PaymentCurrency = KPW)),
            Self::KRW => Ok(dirval!(PaymentCurrency = KRW)),
            Self::KWD => Ok(dirval!(PaymentCurrency = KWD)),
            Self::KYD => Ok(dirval!(PaymentCurrency = KYD)),
            Self::KZT => Ok(dirval!(PaymentCurrency = KZT)),
            Self::LAK => Ok(dirval!(PaymentCurrency = LAK)),
            Self::LBP => Ok(dirval!(PaymentCurrency = LBP)),
            Self::LKR => Ok(dirval!(PaymentCurrency = LKR)),
            Self::LRD => Ok(dirval!(PaymentCurrency = LRD)),
            Self::LSL => Ok(dirval!(PaymentCurrency = LSL)),
            Self::LYD => Ok(dirval!(PaymentCurrency = LYD)),
            Self::MAD => Ok(dirval!(PaymentCurrency = MAD)),
            Self::MDL => Ok(dirval!(PaymentCurrency = MDL)),
            Self::MGA => Ok(dirval!(PaymentCurrency = MGA)),
            Self::MKD => Ok(dirval!(PaymentCurrency = MKD)),
            Self::MMK => Ok(dirval!(PaymentCurrency = MMK)),
            Self::MNT => Ok(dirval!(PaymentCurrency = MNT)),
            Self::MOP => Ok(dirval!(PaymentCurrency = MOP)),
            Self::MRU => Ok(dirval!(PaymentCurrency = MRU)),
            Self::MUR => Ok(dirval!(PaymentCurrency = MUR)),
            Self::MVR => Ok(dirval!(PaymentCurrency = MVR)),
            Self::MWK => Ok(dirval!(PaymentCurrency = MWK)),
            Self::MXN => Ok(dirval!(PaymentCurrency = MXN)),
            Self::MYR => Ok(dirval!(PaymentCurrency = MYR)),
            Self::MZN => Ok(dirval!(PaymentCurrency = MZN)),
            Self::NAD => Ok(dirval!(PaymentCurrency = NAD)),
            Self::NGN => Ok(dirval!(PaymentCurrency = NGN)),
            Self::NIO => Ok(dirval!(PaymentCurrency = NIO)),
            Self::NOK => Ok(dirval!(PaymentCurrency = NOK)),
            Self::NPR => Ok(dirval!(PaymentCurrency = NPR)),
            Self::NZD => Ok(dirval!(PaymentCurrency = NZD)),
            Self::OMR => Ok(dirval!(PaymentCurrency = OMR)),
            Self::PAB => Ok(dirval!(PaymentCurrency = PAB)),
            Self::PEN => Ok(dirval!(PaymentCurrency = PEN)),
            Self::PGK => Ok(dirval!(PaymentCurrency = PGK)),
            Self::PHP => Ok(dirval!(PaymentCurrency = PHP)),
            Self::PKR => Ok(dirval!(PaymentCurrency = PKR)),
            Self::PLN => Ok(dirval!(PaymentCurrency = PLN)),
            Self::PYG => Ok(dirval!(PaymentCurrency = PYG)),
            Self::QAR => Ok(dirval!(PaymentCurrency = QAR)),
            Self::RON => Ok(dirval!(PaymentCurrency = RON)),
            Self::RSD => Ok(dirval!(PaymentCurrency = RSD)),
            Self::RUB => Ok(dirval!(PaymentCurrency = RUB)),
            Self::RWF => Ok(dirval!(PaymentCurrency = RWF)),
            Self::SAR => Ok(dirval!(PaymentCurrency = SAR)),
            Self::SBD => Ok(dirval!(PaymentCurrency = SBD)),
            Self::SCR => Ok(dirval!(PaymentCurrency = SCR)),
            Self::SDG => Ok(dirval!(PaymentCurrency = SDG)),
            Self::SEK => Ok(dirval!(PaymentCurrency = SEK)),
            Self::SGD => Ok(dirval!(PaymentCurrency = SGD)),
            Self::SHP => Ok(dirval!(PaymentCurrency = SHP)),
            Self::SLE => Ok(dirval!(PaymentCurrency = SLE)),
            Self::SLL => Ok(dirval!(PaymentCurrency = SLL)),
            Self::SOS => Ok(dirval!(PaymentCurrency = SOS)),
            Self::SRD => Ok(dirval!(PaymentCurrency = SRD)),
            Self::SSP => Ok(dirval!(PaymentCurrency = SSP)),
            Self::STD => Ok(dirval!(PaymentCurrency = STD)),
            Self::STN => Ok(dirval!(PaymentCurrency = STN)),
            Self::SVC => Ok(dirval!(PaymentCurrency = SVC)),
            Self::SYP => Ok(dirval!(PaymentCurrency = SYP)),
            Self::SZL => Ok(dirval!(PaymentCurrency = SZL)),
            Self::THB => Ok(dirval!(PaymentCurrency = THB)),
            Self::TJS => Ok(dirval!(PaymentCurrency = TJS)),
            Self::TMT => Ok(dirval!(PaymentCurrency = TMT)),
            Self::TND => Ok(dirval!(PaymentCurrency = TND)),
            Self::TOP => Ok(dirval!(PaymentCurrency = TOP)),
            Self::TRY => Ok(dirval!(PaymentCurrency = TRY)),
            Self::TTD => Ok(dirval!(PaymentCurrency = TTD)),
            Self::TWD => Ok(dirval!(PaymentCurrency = TWD)),
            Self::TZS => Ok(dirval!(PaymentCurrency = TZS)),
            Self::UAH => Ok(dirval!(PaymentCurrency = UAH)),
            Self::UGX => Ok(dirval!(PaymentCurrency = UGX)),
            Self::USD => Ok(dirval!(PaymentCurrency = USD)),
            Self::UYU => Ok(dirval!(PaymentCurrency = UYU)),
            Self::UZS => Ok(dirval!(PaymentCurrency = UZS)),
            Self::VES => Ok(dirval!(PaymentCurrency = VES)),
            Self::VND => Ok(dirval!(PaymentCurrency = VND)),
            Self::VUV => Ok(dirval!(PaymentCurrency = VUV)),
            Self::WST => Ok(dirval!(PaymentCurrency = WST)),
            Self::XAF => Ok(dirval!(PaymentCurrency = XAF)),
            Self::XCD => Ok(dirval!(PaymentCurrency = XCD)),
            Self::XOF => Ok(dirval!(PaymentCurrency = XOF)),
            Self::XPF => Ok(dirval!(PaymentCurrency = XPF)),
            Self::YER => Ok(dirval!(PaymentCurrency = YER)),
            Self::ZAR => Ok(dirval!(PaymentCurrency = ZAR)),
            Self::ZMW => Ok(dirval!(PaymentCurrency = ZMW)),
            Self::ZWL => Ok(dirval!(PaymentCurrency = ZWL)),
        }
    }
}

pub fn get_dir_country_dir_value(c: api_enums::Country) -> dir::enums::Country {
    match c {
        api_enums::Country::Afghanistan => dir::enums::Country::Afghanistan,
        api_enums::Country::AlandIslands => dir::enums::Country::AlandIslands,
        api_enums::Country::Albania => dir::enums::Country::Albania,
        api_enums::Country::Algeria => dir::enums::Country::Algeria,
        api_enums::Country::AmericanSamoa => dir::enums::Country::AmericanSamoa,
        api_enums::Country::Andorra => dir::enums::Country::Andorra,
        api_enums::Country::Angola => dir::enums::Country::Angola,
        api_enums::Country::Anguilla => dir::enums::Country::Anguilla,
        api_enums::Country::Antarctica => dir::enums::Country::Antarctica,
        api_enums::Country::AntiguaAndBarbuda => dir::enums::Country::AntiguaAndBarbuda,
        api_enums::Country::Argentina => dir::enums::Country::Argentina,
        api_enums::Country::Armenia => dir::enums::Country::Armenia,
        api_enums::Country::Aruba => dir::enums::Country::Aruba,
        api_enums::Country::Australia => dir::enums::Country::Australia,
        api_enums::Country::Austria => dir::enums::Country::Austria,
        api_enums::Country::Azerbaijan => dir::enums::Country::Azerbaijan,
        api_enums::Country::Bahamas => dir::enums::Country::Bahamas,
        api_enums::Country::Bahrain => dir::enums::Country::Bahrain,
        api_enums::Country::Bangladesh => dir::enums::Country::Bangladesh,
        api_enums::Country::Barbados => dir::enums::Country::Barbados,
        api_enums::Country::Belarus => dir::enums::Country::Belarus,
        api_enums::Country::Belgium => dir::enums::Country::Belgium,
        api_enums::Country::Belize => dir::enums::Country::Belize,
        api_enums::Country::Benin => dir::enums::Country::Benin,
        api_enums::Country::Bermuda => dir::enums::Country::Bermuda,
        api_enums::Country::Bhutan => dir::enums::Country::Bhutan,
        api_enums::Country::BoliviaPlurinationalState => {
            dir::enums::Country::BoliviaPlurinationalState
        }
        api_enums::Country::BonaireSintEustatiusAndSaba => {
            dir::enums::Country::BonaireSintEustatiusAndSaba
        }
        api_enums::Country::BosniaAndHerzegovina => dir::enums::Country::BosniaAndHerzegovina,
        api_enums::Country::Botswana => dir::enums::Country::Botswana,
        api_enums::Country::BouvetIsland => dir::enums::Country::BouvetIsland,
        api_enums::Country::Brazil => dir::enums::Country::Brazil,
        api_enums::Country::BritishIndianOceanTerritory => {
            dir::enums::Country::BritishIndianOceanTerritory
        }
        api_enums::Country::BruneiDarussalam => dir::enums::Country::BruneiDarussalam,
        api_enums::Country::Bulgaria => dir::enums::Country::Bulgaria,
        api_enums::Country::BurkinaFaso => dir::enums::Country::BurkinaFaso,
        api_enums::Country::Burundi => dir::enums::Country::Burundi,
        api_enums::Country::CaboVerde => dir::enums::Country::CaboVerde,
        api_enums::Country::Cambodia => dir::enums::Country::Cambodia,
        api_enums::Country::Cameroon => dir::enums::Country::Cameroon,
        api_enums::Country::Canada => dir::enums::Country::Canada,
        api_enums::Country::CaymanIslands => dir::enums::Country::CaymanIslands,


impl api::RefundSync for Bankofamerica {}

impl api::RefundSync for for Bankofamerica


pub async fn execute(self, conn: &PgPooledConn) -> crate::StorageResult<DBResult> {
        Ok(match self {
            Self::Insert { insertable } => match *insertable {
                Insertable::PaymentIntent(a) => {
                    DBResult::PaymentIntent(Box::new(a.insert(conn).await?))
                }
                Insertable::PaymentAttempt(a) => {
                    DBResult::PaymentAttempt(Box::new(a.insert(conn).await?))
                }
                Insertable::Refund(a) => DBResult::Refund(Box::new(a.insert(conn).await?)),
                Insertable::Address(addr) => DBResult::Address(Box::new(addr.insert(conn).await?)),
                Insertable::Customer(cust) => {
                    DBResult::Customer(Box::new(cust.insert(conn).await?))
                }
                Insertable::ReverseLookUp(rev) => {
                    DBResult::ReverseLookUp(Box::new(rev.insert(conn).await?))
                }
                Insertable::Payouts(rev) => DBResult::Payouts(Box::new(rev.insert(conn).await?)),
                Insertable::PayoutAttempt(rev) => {
                    DBResult::PayoutAttempt(Box::new(rev.insert(conn).await?))
                }
                Insertable::PaymentMethod(rev) => {
                    DBResult::PaymentMethod(Box::new(rev.insert(conn).await?))
                }
                Insertable::Mandate(m) => DBResult::Mandate(Box::new(m.insert(conn).await?)),
            },
            Self::Update { updatable } => match *updatable {
                #[cfg(feature = "v1")]
                Updateable::PaymentIntentUpdate(a) => {
                    DBResult::PaymentIntent(Box::new(a.orig.update(conn, a.update_data).await?))
                }
                #[cfg(feature = "v2")]
                Updateable::PaymentIntentUpdate(a) => {
                    DBResult::PaymentIntent(Box::new(a.orig.update(conn, a.update_data).await?))
                }
                #[cfg(feature = "v1")]
                Updateable::PaymentAttemptUpdate(a) => DBResult::PaymentAttempt(Box::new(
                    a.orig.update_with_attempt_id(conn, a.update_data).await?,
                )),
                #[cfg(feature = "v2")]
                Updateable::PaymentAttemptUpdate(a) => DBResult::PaymentAttempt(Box::new(
                    a.orig.update_with_attempt_id(conn, a.update_data).await?,
                )),
                #[cfg(feature = "v1")]
                Updateable::RefundUpdate(a) => {
                    DBResult::Refund(Box::new(a.orig.update(conn, a.update_data).await?))
                }
                #[cfg(feature = "v2")]
                Updateable::RefundUpdate(a) => {
                    DBResult::Refund(Box::new(a.orig.update_with_id(conn, a.update_data).await?))
                }
                Updateable::AddressUpdate(a) => {
                    DBResult::Address(Box::new(a.orig.update(conn, a.update_data).await?))
                }
                Updateable::PayoutsUpdate(a) => {
                    DBResult::Payouts(Box::new(a.orig.update(conn, a.update_data).await?))
                }
                Updateable::PayoutAttemptUpdate(a) => DBResult::PayoutAttempt(Box::new(
                    a.orig.update_with_attempt_id(conn, a.update_data).await?,
                )),
                #[cfg(feature = "v1")]
                Updateable::PaymentMethodUpdate(v) => DBResult::PaymentMethod(Box::new(
                    v.orig
                        .update_with_payment_method_id(conn, v.update_data)
                        .await?,
                )),
                #[cfg(feature = "v2")]
                Updateable::PaymentMethodUpdate(v) => DBResult::PaymentMethod(Box::new(
                    v.orig.update_with_id(conn, v.update_data).await?,
                )),
                Updateable::MandateUpdate(m) => DBResult::Mandate(Box::new(
                    Mandate::update_by_merchant_id_mandate_id(
                        conn,
                        &m.orig.merchant_id,
                        &m.orig.mandate_id,
                        m.update_data,
                    )
                    .await?,
                )),
                #[cfg(feature = "v1")]
                Updateable::CustomerUpdate(cust) => DBResult::Customer(Box::new(
                    Customer::update_by_customer_id_merchant_id(
                        conn,
                        cust.orig.customer_id.clone(),
                        cust.orig.merchant_id.clone(),
                        cust.update_data,
                    )
                    .await?,
                )),
                #[cfg(feature = "v2")]
                Updateable::CustomerUpdate(cust) => DBResult::Customer(Box::new(
                    Customer::update_by_id(conn, cust.orig.id, cust.update_data).await?,
                )),
            },
        })
    }