    }

    fn get_webhook_event_type(
        &self,
        request: &IncomingWebhookRequestDetails<'_>,
    ) -> CustomResult<IncomingWebhookEvent, errors::ConnectorError> {
        let details: airwallex::AirwallexWebhookData = request
            .body
            .parse_struct("airwallexWebhookData")
            .change_context(errors::ConnectorError::WebhookReferenceIdNotFound)?;
        Ok(IncomingWebhookEvent::try_from(details.name)?)
    }

    fn get_webhook_resource_object(
        &self,
        request: &IncomingWebhookRequestDetails<'_>,
    ) -> CustomResult<Box<dyn masking::ErasedMaskSerialize>, errors::ConnectorError> {
        let details: airwallex::AirwallexWebhookObjectResource = request
            .body
            .parse_struct("AirwallexWebhookObjectResource")
            .change_context(errors::ConnectorError::WebhookResourceObjectNotFound)?;

        Ok(Box::new(details.data.object))
    }

    fn get_dispute_details(
        &self,
        request: &IncomingWebhookRequestDetails<'_>,
    ) -> CustomResult<DisputePayload, errors::ConnectorError> {
        let details: airwallex::AirwallexWebhookData = request
            .body
            .parse_struct("airwallexWebhookData")
            .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?;
        let dispute_details: airwallex::AirwallexDisputeObject = details
            .data
            .object
            .parse_value("AirwallexDisputeObject")
            .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?;
        let amount = convert_amount(
            self.amount_converter_to_string_minor,
            dispute_details.dispute_amount,
            dispute_details.dispute_currency,
        )?;
        Ok(DisputePayload {
            amount,
            currency: dispute_details.dispute_currency,
            dispute_stage: api_models::enums::DisputeStage::from(dispute_details.stage.clone()),
            connector_dispute_id: dispute_details.dispute_id,
            connector_reason: dispute_details.dispute_reason_type,
            connector_reason_code: dispute_details.dispute_original_reason_code,
            challenge_required_by: None,
            connector_status: dispute_details.status.to_string(),
            created_at: dispute_details.created_at,
            updated_at: dispute_details.updated_at,
        })
    }
}

impl ConnectorRedirectResponse for Airwallex {
    fn get_flow_type(
        &self,
        _query_params: &str,
        _json_payload: Option<serde_json::Value>,
        action: PaymentAction,
    ) -> CustomResult<CallConnectorAction, errors::ConnectorError> {
        match action {
            PaymentAction::PSync
            | PaymentAction::CompleteAuthorize
            | PaymentAction::PaymentAuthenticateCompleteAuthorize => {
                Ok(CallConnectorAction::Trigger)
            }
        }
    }
}

static AIRWALLEX_SUPPORTED_PAYMENT_METHODS: LazyLock<SupportedPaymentMethods> =
    LazyLock::new(|| {
        let supported_capture_methods = vec![
            enums::CaptureMethod::Automatic,
            enums::CaptureMethod::Manual,
            enums::CaptureMethod::SequentialAutomatic,
        ];

        let supported_capture_methods_redirect = vec![
            enums::CaptureMethod::Automatic,
            enums::CaptureMethod::SequentialAutomatic,
        ];

        let supported_card_network = vec![
            common_enums::CardNetwork::Visa,
            common_enums::CardNetwork::Mastercard,
            common_enums::CardNetwork::AmericanExpress,
            common_enums::CardNetwork::JCB,
            common_enums::CardNetwork::DinersClub,
            common_enums::CardNetwork::UnionPay,
            common_enums::CardNetwork::Discover,
        ];

        let mut airwallex_supported_payment_methods = SupportedPaymentMethods::new();

        airwallex_supported_payment_methods.add(
            enums::PaymentMethod::Card,
            enums::PaymentMethodType::Credit,
            PaymentMethodDetails {
                mandates: enums::FeatureStatus::NotSupported,
                refunds: enums::FeatureStatus::Supported,
                supported_capture_methods: supported_capture_methods.clone(),
                specific_features: Some(
                    api_models::feature_matrix::PaymentMethodSpecificFeatures::Card({
                        api_models::feature_matrix::CardSpecificFeatures {
                            three_ds: common_enums::FeatureStatus::Supported,
                            no_three_ds: common_enums::FeatureStatus::Supported,
                            supported_card_networks: supported_card_network.clone(),
                        }
                    }),
                ),
            },
        );

        airwallex_supported_payment_methods.add(
            enums::PaymentMethod::Card,
            enums::PaymentMethodType::Debit,
            PaymentMethodDetails {
                mandates: enums::FeatureStatus::NotSupported,
                refunds: enums::FeatureStatus::Supported,
                supported_capture_methods: supported_capture_methods.clone(),
                specific_features: Some(
                    api_models::feature_matrix::PaymentMethodSpecificFeatures::Card({
                        api_models::feature_matrix::CardSpecificFeatures {
                            three_ds: common_enums::FeatureStatus::Supported,
                            no_three_ds: common_enums::FeatureStatus::Supported,
                            supported_card_networks: supported_card_network.clone(),
                        }
                    }),
                ),
            },
        );

        airwallex_supported_payment_methods.add(
            enums::PaymentMethod::Wallet,
            enums::PaymentMethodType::GooglePay,
            PaymentMethodDetails {
                mandates: enums::FeatureStatus::NotSupported,
                refunds: enums::FeatureStatus::Supported,
                supported_capture_methods: supported_capture_methods.clone(),
                specific_features: None,
            },
        );

        airwallex_supported_payment_methods.add(
            enums::PaymentMethod::Wallet,
            enums::PaymentMethodType::Paypal,
            PaymentMethodDetails {
                mandates: enums::FeatureStatus::NotSupported,
                refunds: enums::FeatureStatus::Supported,
                supported_capture_methods: supported_capture_methods_redirect.clone(),
                specific_features: None,
            },
        );

        airwallex_supported_payment_methods.add(
            enums::PaymentMethod::Wallet,
            enums::PaymentMethodType::Skrill,
            PaymentMethodDetails {
                mandates: enums::FeatureStatus::NotSupported,
                refunds: enums::FeatureStatus::Supported,
                supported_capture_methods: supported_capture_methods_redirect.clone(),
                specific_features: None,
            },
        );

        airwallex_supported_payment_methods.add(
            enums::PaymentMethod::PayLater,
            enums::PaymentMethodType::Klarna,
            PaymentMethodDetails {
                mandates: enums::FeatureStatus::NotSupported,
                refunds: enums::FeatureStatus::Supported,
                supported_capture_methods: supported_capture_methods.clone(),
                specific_features: None,
            },
        );

        airwallex_supported_payment_methods.add(
            enums::PaymentMethod::PayLater,
            enums::PaymentMethodType::Atome,
            PaymentMethodDetails {
                mandates: enums::FeatureStatus::NotSupported,
                refunds: enums::FeatureStatus::Supported,
                supported_capture_methods: supported_capture_methods_redirect.clone(),
                specific_features: None,
            },
        );

        airwallex_supported_payment_methods.add(
            enums::PaymentMethod::BankRedirect,
            enums::PaymentMethodType::Trustly,
            PaymentMethodDetails {
                mandates: enums::FeatureStatus::NotSupported,
                refunds: enums::FeatureStatus::Supported,
                supported_capture_methods: supported_capture_methods_redirect.clone(),
                specific_features: None,
            },
        );

        airwallex_supported_payment_methods.add(
            enums::PaymentMethod::BankRedirect,
            enums::PaymentMethodType::Blik,
            PaymentMethodDetails {
                mandates: enums::FeatureStatus::NotSupported,
                refunds: enums::FeatureStatus::Supported,
                supported_capture_methods: supported_capture_methods_redirect.clone(),
                specific_features: None,
            },
        );

        airwallex_supported_payment_methods.add(
            enums::PaymentMethod::BankRedirect,
            enums::PaymentMethodType::Ideal,
            PaymentMethodDetails {
                mandates: enums::FeatureStatus::NotSupported,
                refunds: enums::FeatureStatus::Supported,
                supported_capture_methods: supported_capture_methods_redirect.clone(),
                specific_features: None,
            },
        );

        airwallex_supported_payment_methods.add(
            enums::PaymentMethod::BankTransfer,
            enums::PaymentMethodType::IndonesianBankTransfer,
            PaymentMethodDetails {
                mandates: enums::FeatureStatus::NotSupported,
                refunds: enums::FeatureStatus::NotSupported,
                supported_capture_methods: supported_capture_methods_redirect.clone(),
                specific_features: None,
            },
        );

        airwallex_supported_payment_methods
    });

static AIRWALLEX_CONNECTOR_INFO: ConnectorInfo = ConnectorInfo {
    display_name: "Airwallex",
    description: "Airwallex is a multinational financial technology company offering financial services and software as a service (SaaS)",
    connector_type: enums::HyperswitchConnectorCategory::PaymentGateway,
    integration_status: enums::ConnectorIntegrationStatus::Sandbox,
};

static AIRWALLEX_SUPPORTED_WEBHOOK_FLOWS: [enums::EventClass; 3] = [
    enums::EventClass::Payments,
    enums::EventClass::Refunds,
    enums::EventClass::Disputes,
];

impl ConnectorSpecifications for Airwallex {
    fn get_connector_about(&self) -> Option<&'static ConnectorInfo> {
        Some(&AIRWALLEX_CONNECTOR_INFO)
    }

    fn get_supported_payment_methods(&self) -> Option<&'static SupportedPaymentMethods> {
        Some(&*AIRWALLEX_SUPPORTED_PAYMENT_METHODS)
    }

    fn get_supported_webhook_flows(&self) -> Option<&'static [enums::EventClass]> {
        Some(&AIRWALLEX_SUPPORTED_WEBHOOK_FLOWS)
    }
}


OpenAPI Block Path: components.schemas.PayoutRetrieveBody
{
  "type": "object",
  "properties": {
    "force_sync": {
      "type": "boolean",
      "nullable": true
    },
    "merchant_id": {
      "type": "string",
      "nullable": true
    }
  }
}


OpenAPI Block Path: components.schemas.CardTokenResponse
{
  "allOf": [
    {
      "allOf": [
        {
          "$ref": "#/components/schemas/CardTokenAdditionalData"
        }
      ],
      "nullable": true
    },
    {
      "type": "object"
    }
  ]
}


pub struct SessionState {
    pub store: Box<dyn StorageInterface>,
    /// Global store is used for global schema operations in tables like Users and Tenants
    pub global_store: Box<dyn GlobalStorageInterface>,
    pub accounts_store: Box<dyn AccountsStorageInterface>,
    pub conf: Arc<settings::Settings<RawSecret>>,
    pub api_client: Box<dyn crate::services::ApiClient>,
    pub event_handler: EventsHandler,
    #[cfg(feature = "email")]
    pub email_client: Arc<Box<dyn EmailService>>,
    #[cfg(feature = "olap")]
    pub pool: AnalyticsProvider,
    pub file_storage_client: Arc<dyn FileStorageInterface>,
    pub request_id: Option<RequestId>,
    pub base_url: String,
    pub tenant: Tenant,
    #[cfg(feature = "olap")]
    pub opensearch_client: Option<Arc<OpenSearchClient>>,
    pub grpc_client: Arc<GrpcClients>,
    pub theme_storage_client: Arc<dyn FileStorageInterface>,
    pub locale: String,
    pub crm_client: Arc<dyn CrmInterface>,
    pub infra_components: Option<serde_json::Value>,
    pub enhancement: Option<HashMap<String, String>>,
}


pub struct MandateToken {
    pub href: Secret<String>,
    pub token_id: String,
    pub token_expiry_date_time: String,
}


impl CycleCheck {
    pub fn new() -> Self {
        Self(FxHashMap::default())
    }
}


File: crates/euclid_macros/src/inner/knowledge.rs

use std::{
    fmt::{Display, Formatter},
    hash::Hash,
    rc::Rc,
};

use proc_macro2::{Span, TokenStream};
use quote::{format_ident, quote};
use rustc_hash::{FxHashMap, FxHashSet};
use syn::{parse::Parse, Token};

mod strength {
    syn::custom_punctuation!(Normal, ->);
    syn::custom_punctuation!(Strong, ->>);
}

mod kw {
    syn::custom_keyword!(any);
    syn::custom_keyword!(not);
}

#[derive(Clone, PartialEq, Eq, Hash)]
enum Comparison {
    LessThan,
    Equal,
    GreaterThan,
    GreaterThanEqual,
    LessThanEqual,
}

impl Display for Comparison {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        let symbol = match self {
            Self::LessThan => "< ",
            Self::Equal => return Ok(()),
            Self::GreaterThanEqual => ">= ",
            Self::LessThanEqual => "<= ",
            Self::GreaterThan => "> ",
        };
        write!(f, "{symbol}")
    }
}

impl Parse for Comparison {
    fn parse(input: syn::parse::ParseStream<'_>) -> syn::Result<Self> {
        if input.peek(Token![>]) {
            input.parse::<Token![>]>()?;
            Ok(Self::GreaterThan)
        } else if input.peek(Token![<]) {
            input.parse::<Token![<]>()?;
            Ok(Self::LessThan)
        } else if input.peek(Token!(<=)) {
            input.parse::<Token![<=]>()?;
            Ok(Self::LessThanEqual)
        } else if input.peek(Token!(>=)) {
            input.parse::<Token![>=]>()?;
            Ok(Self::GreaterThanEqual)
        } else {
            Ok(Self::Equal)
        }
    }
}

#[derive(Clone, PartialEq, Eq, Hash)]
enum ValueType {
    Any,
    EnumVariant(String),
    Number { number: i64, comparison: Comparison },
}

impl ValueType {
    fn to_string(&self, key: &str) -> String {
        match self {
            Self::Any => format!("{key}(any)"),
            Self::EnumVariant(s) => format!("{key}({s})"),
            Self::Number { number, comparison } => {
                format!("{key}({comparison}{number})")
            }
        }
    }
}

impl Parse for ValueType {
    fn parse(input: syn::parse::ParseStream<'_>) -> syn::Result<Self> {
        let lookahead = input.lookahead1();
        if lookahead.peek(syn::Ident) {
            let ident: syn::Ident = input.parse()?;
            Ok(Self::EnumVariant(ident.to_string()))
        } else if lookahead.peek(Token![>])
            || lookahead.peek(Token![<])
            || lookahead.peek(syn::LitInt)
        {
            let comparison: Comparison = input.parse()?;
            let number: syn::LitInt = input.parse()?;
            let num_val = number.base10_parse::<i64>()?;
            Ok(Self::Number {
                number: num_val,
                comparison,
            })
        } else {
            Err(lookahead.error())
        }
    }
}

#[derive(Clone, PartialEq, Eq, Hash)]
struct Atom {
    key: String,
    value: ValueType,
}

impl Display for Atom {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", self.value.to_string(&self.key))
    }
}

impl Parse for Atom {
    fn parse(input: syn::parse::ParseStream<'_>) -> syn::Result<Self> {
        let maybe_any: syn::Ident = input.parse()?;
        if maybe_any == "any" {
            let actual_key: syn::Ident = input.parse()?;
            Ok(Self {
                key: actual_key.to_string(),
                value: ValueType::Any,
            })
        } else {
            let content;
            syn::parenthesized!(content in input);
            let value: ValueType = content.parse()?;
            Ok(Self {
                key: maybe_any.to_string(),
                value,
            })
        }
    }
}

#[derive(Clone, PartialEq, Eq, Hash, strum::Display)]
enum Strength {
    Normal,
    Strong,
}

impl Parse for Strength {
    fn parse(input: syn::parse::ParseStream<'_>) -> syn::Result<Self> {
        let lookahead = input.lookahead1();
        if lookahead.peek(strength::Strong) {
            input.parse::<strength::Strong>()?;
            Ok(Self::Strong)
        } else if lookahead.peek(strength::Normal) {
            input.parse::<strength::Normal>()?;
            Ok(Self::Normal)
        } else {
            Err(lookahead.error())
        }
    }
}

#[derive(Clone, PartialEq, Eq, Hash, strum::Display)]
enum Relation {
    Positive,
    Negative,
}

enum AtomType {
    Value {
        relation: Relation,
        atom: Rc<Atom>,
    },

    InAggregator {
        key: String,
        values: Vec<String>,
        relation: Relation,
    },
}

fn parse_atom_type_inner(
    input: syn::parse::ParseStream<'_>,
    key: syn::Ident,
    relation: Relation,
) -> syn::Result<AtomType> {
    let result = if input.peek(Token![in]) {
        input.parse::<Token![in]>()?;

        let bracketed;
        syn::bracketed!(bracketed in input);

        let mut values = Vec::<String>::new();
        let first: syn::Ident = bracketed.parse()?;
        values.push(first.to_string());
        while !bracketed.is_empty() {
            bracketed.parse::<Token![,]>()?;
            let next: syn::Ident = bracketed.parse()?;
            values.push(next.to_string());
        }

        AtomType::InAggregator {
            key: key.to_string(),
            values,
            relation,
        }
    } else if input.peek(kw::any) {
        input.parse::<kw::any>()?;
        AtomType::Value {
            relation,
            atom: Rc::new(Atom {
                key: key.to_string(),
                value: ValueType::Any,
            }),
        }
    } else {
        let value: ValueType = input.parse()?;
        AtomType::Value {
            relation,
            atom: Rc::new(Atom {
                key: key.to_string(),
                value,
            }),
        }
    };

    Ok(result)
}

impl Parse for AtomType {
    fn parse(input: syn::parse::ParseStream<'_>) -> syn::Result<Self> {
        let key: syn::Ident = input.parse()?;
        let content;
        syn::parenthesized!(content in input);

        let relation = if content.peek(kw::not) {
            content.parse::<kw::not>()?;
            Relation::Negative
        } else {
            Relation::Positive
        };

        let result = parse_atom_type_inner(&content, key, relation)?;

        if !content.is_empty() {
            Err(content.error("Unexpected input received after atom value"))
        } else {
            Ok(result)
        }
    }
}

fn parse_rhs_atom(input: syn::parse::ParseStream<'_>) -> syn::Result<Atom> {
    let key: syn::Ident = input.parse()?;
    let content;
    syn::parenthesized!(content in input);

    let lookahead = content.lookahead1();

    let value_type = if lookahead.peek(kw::any) {
        content.parse::<kw::any>()?;
        ValueType::Any
    } else if lookahead.peek(syn::Ident) {
        let variant = content.parse::<syn::Ident>()?;
        ValueType::EnumVariant(variant.to_string())
    } else {
        return Err(lookahead.error());
    };

    if !content.is_empty() {
        Err(content.error("Unexpected input received after atom value"))
    } else {
        Ok(Atom {
            key: key.to_string(),
            value: value_type,
        })
    }
}

struct Rule {
    lhs: Vec<AtomType>,
    strength: Strength,
    rhs: Rc<Atom>,
}

impl Parse for Rule {
    fn parse(input: syn::parse::ParseStream<'_>) -> syn::Result<Self> {
        let first_atom: AtomType = input.parse()?;
        let mut lhs: Vec<AtomType> = vec![first_atom];

        while input.peek(Token![&]) {
            input.parse::<Token![&]>()?;
            let and_atom: AtomType = input.parse()?;
            lhs.push(and_atom);
        }

        let strength: Strength = input.parse()?;

        let rhs: Rc<Atom> = Rc::new(parse_rhs_atom(input)?);

        input.parse::<Token![;]>()?;

        Ok(Self { lhs, strength, rhs })
    }
}

#[derive(Clone)]
struct Program {
    rules: Vec<Rc<Rule>>,
}

impl Parse for Program {
    fn parse(input: syn::parse::ParseStream<'_>) -> syn::Result<Self> {
        let mut rules: Vec<Rc<Rule>> = Vec::new();

        while !input.is_empty() {
            rules.push(Rc::new(input.parse::<Rule>()?));
        }

        Ok(Self { rules })
    }
}

struct GenContext {
    next_idx: usize,
    next_node_idx: usize,
    idx2atom: FxHashMap<usize, Rc<Atom>>,
    atom2idx: FxHashMap<Rc<Atom>, usize>,
    edges: FxHashMap<usize, FxHashSet<usize>>,
    compiled_atoms: FxHashMap<Rc<Atom>, proc_macro2::Ident>,
}

impl GenContext {
    fn new() -> Self {
        Self {
            next_idx: 1,
            next_node_idx: 1,
            idx2atom: FxHashMap::default(),
            atom2idx: FxHashMap::default(),
            edges: FxHashMap::default(),
            compiled_atoms: FxHashMap::default(),
        }
    }

    fn register_node(&mut self, atom: Rc<Atom>) -> usize {
        if let Some(idx) = self.atom2idx.get(&atom) {
            *idx
        } else {
            let this_idx = self.next_idx;
            self.next_idx += 1;

            self.idx2atom.insert(this_idx, Rc::clone(&atom));
            self.atom2idx.insert(atom, this_idx);

            this_idx
        }
    }

    fn register_edge(&mut self, from: usize, to: usize) -> Result<(), String> {
        let node_children = self.edges.entry(from).or_default();
        if node_children.contains(&to) {
            Err("Duplicate edge detected".to_string())
        } else {
            node_children.insert(to);
            self.edges.entry(to).or_default();
            Ok(())
        }
    }

    fn register_rule(&mut self, rule: &Rule) -> Result<(), String> {
        let to_idx = self.register_node(Rc::clone(&rule.rhs));

        for atom_type in &rule.lhs {
            if let AtomType::Value { atom, .. } = atom_type {
                let from_idx = self.register_node(Rc::clone(atom));
                self.register_edge(from_idx, to_idx)?;
            }
        }

        Ok(())
    }

    fn cycle_dfs(
        &self,
        node_id: usize,
        explored: &mut FxHashSet<usize>,
        visited: &mut FxHashSet<usize>,
        order: &mut Vec<usize>,
    ) -> Result<Option<Vec<usize>>, String> {
        if explored.contains(&node_id) {
            let position = order
                .iter()
                .position(|v| *v == node_id)
                .ok_or_else(|| "Error deciding cycle order".to_string())?;

            let cycle_order = order
                .get(position..)
                .ok_or_else(|| "Error getting cycle order".to_string())?
                .to_vec();
            Ok(Some(cycle_order))
        } else if visited.contains(&node_id) {
            Ok(None)
        } else {
            visited.insert(node_id);
            explored.insert(node_id);
            order.push(node_id);
            let dests = self
                .edges
                .get(&node_id)
                .ok_or_else(|| "Error getting edges of node".to_string())?;

            for dest in dests.iter().copied() {
                if let Some(cycle) = self.cycle_dfs(dest, explored, visited, order)? {
                    return Ok(Some(cycle));
                }
            }

            order.pop();

            Ok(None)
        }
    }

    fn detect_graph_cycles(&self) -> Result<(), String> {
        let start_nodes = self.edges.keys().copied().collect::<Vec<usize>>();

        let mut total_visited = FxHashSet::<usize>::default();

        for node_id in start_nodes.iter().copied() {
            let mut explored = FxHashSet::<usize>::default();
            let mut order = Vec::<usize>::new();

            match self.cycle_dfs(node_id, &mut explored, &mut total_visited, &mut order)? {
                None => {}
                Some(order) => {
                    let mut display_strings = Vec::<String>::with_capacity(order.len() + 1);

                    for cycle_node_id in order {
                        let node = self.idx2atom.get(&cycle_node_id).ok_or_else(|| {
                            "Failed to find node during cycle display creation".to_string()
                        })?;

                        display_strings.push(node.to_string());
                    }

                    let first = display_strings
                        .first()
                        .cloned()
                        .ok_or("Unable to fill cycle display array")?;

                    display_strings.push(first);

                    return Err(format!("Found cycle: {}", display_strings.join(" -> ")));
                }
            }
        }

        Ok(())
    }

    fn next_node_ident(&mut self) -> (proc_macro2::Ident, usize) {
        let this_idx = self.next_node_idx;
        self.next_node_idx += 1;
        (format_ident!("_node_{this_idx}"), this_idx)
    }

    fn compile_atom(
        &mut self,
        atom: &Rc<Atom>,
        tokens: &mut TokenStream,
    ) -> Result<proc_macro2::Ident, String> {
        let maybe_ident = self.compiled_atoms.get(atom);

        if let Some(ident) = maybe_ident {
            Ok(ident.clone())
        } else {
            let (identifier, _) = self.next_node_ident();
            let key = format_ident!("{}", &atom.key);
            let the_value = match &atom.value {
                ValueType::Any => quote! {
                    cgraph::NodeValue::Key(DirKey::new(DirKeyKind::#key,None))
                },
                ValueType::EnumVariant(variant) => {
                    let variant = format_ident!("{}", variant);
                    quote! {
                        cgraph::NodeValue::Value(DirValue::#key(#key::#variant))
                    }
                }
                ValueType::Number { number, comparison } => {
                    let comp_type = match comparison {
                        Comparison::Equal => quote! {
                            None
                        },
                        Comparison::LessThan => quote! {
                            Some(NumValueRefinement::LessThan)
                        },
                        Comparison::GreaterThan => quote! {
                            Some(NumValueRefinement::GreaterThan)
                        },
                        Comparison::GreaterThanEqual => quote! {
                            Some(NumValueRefinement::GreaterThanEqual)
                        },
                        Comparison::LessThanEqual => quote! {
                            Some(NumValueRefinement::LessThanEqual)
                        },
                    };

                    quote! {
                        cgraph::NodeValue::Value(DirValue::#key(NumValue {
                            number: #number,
                            refinement: #comp_type,
                        }))
                    }
                }
            };

            let compiled = quote! {
                let #identifier = graph.make_value_node(#the_value, None, None::<()>);
            };

            tokens.extend(compiled);
            self.compiled_atoms
                .insert(Rc::clone(atom), identifier.clone());

            Ok(identifier)
        }
    }

    fn compile_atom_type(
        &mut self,
        atom_type: &AtomType,
        tokens: &mut TokenStream,
    ) -> Result<(proc_macro2::Ident, Relation), String> {
        match atom_type {
            AtomType::Value { relation, atom } => {
                let node_ident = self.compile_atom(atom, tokens)?;

                Ok((node_ident, relation.clone()))
            }

            AtomType::InAggregator {
                key,
                values,
                relation,
            } => {
                let key_ident = format_ident!("{key}");
                let mut values_tokens: Vec<TokenStream> = Vec::new();

                for value in values {
                    let value_ident = format_ident!("{value}");
                    values_tokens.push(quote! { DirValue::#key_ident(#key_ident::#value_ident) });
                }

                let (node_ident, _) = self.next_node_ident();
                let node_code = quote! {
                    let #node_ident = graph.make_in_aggregator(
                        Vec::from_iter([#(#values_tokens),*]),
                        None,
                        None::<()>,
                    ).expect("Failed to make In aggregator");
                };

                tokens.extend(node_code);

                Ok((node_ident, relation.clone()))
            }
        }
    }

    fn compile_rule(&mut self, rule: &Rule, tokens: &mut TokenStream) -> Result<(), String> {
        let rhs_ident = self.compile_atom(&rule.rhs, tokens)?;
        let mut node_details: Vec<(proc_macro2::Ident, Relation)> =
            Vec::with_capacity(rule.lhs.len());
        for lhs_atom_type in &rule.lhs {
            let details = self.compile_atom_type(lhs_atom_type, tokens)?;
            node_details.push(details);
        }

        if node_details.len() <= 1 {
            let strength = format_ident!("{}", rule.strength.to_string());
            for (from_node, relation) in &node_details {
                let relation = format_ident!("{}", relation.to_string());
                tokens.extend(quote! {
                    graph.make_edge(#from_node, #rhs_ident, cgraph::Strength::#strength, cgraph::Relation::#relation, None::<cgraph::DomainId>)
                        .expect("Failed to make edge");
                });
            }
        } else {
            let mut all_agg_nodes: Vec<TokenStream> = Vec::with_capacity(node_details.len());
            for (from_node, relation) in &node_details {
                let relation = format_ident!("{}", relation.to_string());
                all_agg_nodes.push(
                    quote! { (#from_node, cgraph::Relation::#relation, cgraph::Strength::Strong) },
                );
            }

            let strength = format_ident!("{}", rule.strength.to_string());
            let (agg_node_ident, _) = self.next_node_ident();
            tokens.extend(quote! {
                let #agg_node_ident = graph.make_all_aggregator(&[#(#all_agg_nodes),*], None, None::<()>, None)
                    .expect("Failed to make all aggregator node");

                graph.make_edge(#agg_node_ident, #rhs_ident, cgraph::Strength::#strength, cgraph::Relation::Positive, None::<cgraph::DomainId>)
                    .expect("Failed to create all aggregator edge");

            });
        }

        Ok(())
    }

    fn compile(&mut self, program: Program) -> Result<TokenStream, String> {
        let mut tokens = TokenStream::new();
        for rule in &program.rules {
            self.compile_rule(rule, &mut tokens)?;
        }

        let compiled = quote! {{
            use euclid_graph_prelude::*;

            let mut graph = cgraph::ConstraintGraphBuilder::new();

            #tokens

            graph.build()
        }};

        Ok(compiled)
    }
}

pub(crate) fn knowledge_inner(ts: TokenStream) -> syn::Result<TokenStream> {
    let program = syn::parse::<Program>(ts.into())?;
    let mut gen_context = GenContext::new();

    for rule in &program.rules {
        gen_context
            .register_rule(rule)
            .map_err(|msg| syn::Error::new(Span::call_site(), msg))?;
    }

    gen_context
        .detect_graph_cycles()
        .map_err(|msg| syn::Error::new(Span::call_site(), msg))?;

    gen_context
        .compile(program)
        .map_err(|msg| syn::Error::new(Span::call_site(), msg))
}


pub async fn get_theme_lineage_from_user_token(
    user_from_token: &UserFromToken,
    state: &SessionState,
    request_entity_type: &EntityType,
) -> UserResult<ThemeLineage> {
    let tenant_id = user_from_token
        .tenant_id
        .clone()
        .unwrap_or(state.tenant.tenant_id.clone());
    let org_id = user_from_token.org_id.clone();
    let merchant_id = user_from_token.merchant_id.clone();
    let profile_id = user_from_token.profile_id.clone();

    Ok(ThemeLineage::new(
        *request_entity_type,
        tenant_id,
        org_id,
        merchant_id,
        profile_id,
    ))
}


pub fn as_bool(self) -> bool {
        match self {
            Self::Skip => false,
            Self::Calculate => true,
        }
    }


pub async fn get_total_count_of_payouts(
        conn: &PgPooledConn,
        merchant_id: &common_utils::id_type::MerchantId,
        active_payout_ids: &[common_utils::id_type::PayoutId],
        connector: Option<Vec<String>>,
        currency: Option<Vec<enums::Currency>>,
        status: Option<Vec<enums::PayoutStatus>>,
        payout_type: Option<Vec<enums::PayoutType>>,
    ) -> StorageResult<i64> {
        let mut filter = <Self as HasTable>::table()
            .inner_join(payout_attempt::table.on(payout_attempt::dsl::payout_id.eq(dsl::payout_id)))
            .count()
            .filter(dsl::merchant_id.eq(merchant_id.to_owned()))
            .filter(dsl::payout_id.eq_any(active_payout_ids.to_vec()))
            .into_boxed();

        if let Some(connector) = connector {
            filter = filter.filter(payout_attempt::dsl::connector.eq_any(connector));
        }
        if let Some(currency) = currency {
            filter = filter.filter(dsl::destination_currency.eq_any(currency));
        }
        if let Some(status) = status {
            filter = filter.filter(dsl::status.eq_any(status));
        }
        if let Some(payout_type) = payout_type {
            filter = filter.filter(dsl::payout_type.eq_any(payout_type));
        }
        router_env::logger::debug!(query = %debug_query::<Pg, _>(&filter).to_string());

        db_metrics::track_database_call::<<Self as HasTable>::Table, _, _>(
            filter.get_result_async::<i64>(conn),
            db_metrics::DatabaseOperation::Filter,
        )
        .await
        .change_context(errors::DatabaseError::Others)
        .attach_printable("Error filtering count of payouts")
    }


pub async fn routing_link_config() {}


Documentation: api-reference/v1/payments/payments--post-session-tokens.mdx
# Type: Doc File

---
openapi: post /payments/{payment_id}/post_session_tokens
---


impl api::RefundExecute for Worldpay {}

impl api::RefundExecute for for Worldpay


pub struct ResponseRouterData<Flow, R, Request, Response> {
    pub response: R,
    pub data: PaymentAuthRouterData<Flow, Request, Response>,
    pub http_code: u16,
}


pub struct FacilitapaySubject {
    pub social_name: Secret<String>,
    pub document_type: DocumentType,
    pub document_number: Secret<String>,
    // In documentation, both CountryAlpha2 and String are used. We cannot rely on CountryAlpha2.
    pub fiscal_country: String,
    pub updated_at: Option<String>,
    pub status: SubjectKycStatus,
    #[serde(rename = "id")]
    pub customer_id: Secret<String>,
    pub birth_date: Option<time::Date>,
    pub email: Option<pii::Email>,
    pub phone_country_code: Option<Secret<String>>,
    pub phone_area_code: Option<Secret<String>>,
    pub phone_number: Option<Secret<String>>,
    pub address_street: Option<Secret<String>>,
    pub address_number: Option<Secret<String>>,
    pub address_complement: Option<Secret<String>>,
    pub address_city: Option<String>,
    pub address_state: Option<String>,
    pub address_postal_code: Option<Secret<String>>,
    pub address_country: Option<String>,
    pub address_neighborhood: Option<Secret<String>>,
    pub net_monthly_average_income: Option<StringMajorUnit>,
    pub clearance_level: Option<i32>,
    pub required_clearance_level: Option<i32>,
    pub inserted_at: Option<String>,
    pub references: Option<Vec<serde_json::Value>>,
    pub rfc_pf: Option<Secret<String>>, // 13-digit RFC, specific to Mexico users
    pub documents: Option<Vec<serde_json::Value>>,
}


pub struct Shift4RouterData<T> {
    pub amount: MinorUnit,
    pub router_data: T,
}


pub fn collect(self) -> DisputeMetricsBucketValue {
        let (challenge_rate, won_rate, lost_rate, total_dispute) =
            self.disputes_status_rate.collect().unwrap_or_default();
        DisputeMetricsBucketValue {
            disputes_challenged: challenge_rate,
            disputes_won: won_rate,
            disputes_lost: lost_rate,
            disputed_amount: self.disputed_amount.collect(),
            dispute_lost_amount: self.dispute_lost_amount.collect(),
            total_dispute,
        }
    }


impl Responder {
    let flow = Flow::UpdateDynamicRoutingConfigs;
    let routing_payload_wrapper = routing_types::ContractBasedRoutingPayloadWrapper {
        updated_config: json_payload.into_inner(),
        algorithm_id: path.algorithm_id.clone(),
        profile_id: path.profile_id.clone(),
    };
    Box::pin(oss_api::server_wrap(
        flow,
        state,
        &req,
        routing_payload_wrapper.clone(),
        |state,
         auth: auth::AuthenticationData,
         wrapper: routing_types::ContractBasedRoutingPayloadWrapper,
         _| async {
            let merchant_context = domain::MerchantContext::NormalMerchant(Box::new(
                domain::Context(auth.merchant_account, auth.key_store),
            ));
            Box::pin(routing::contract_based_routing_update_configs(
                state,
                wrapper.updated_config,
                merchant_context,
                wrapper.algorithm_id,
                wrapper.profile_id,
            ))
            .await
        },
        auth::auth_type(
            &auth::HeaderAuth(auth::ApiKeyAuth {
                is_connected_allowed: false,
                is_platform_allowed: false,
            }),
            &auth::JWTAuthProfileFromRoute {
                profile_id: routing_payload_wrapper.profile_id,
                required_permission: Permission::ProfileRoutingWrite,
            },
            req.headers(),
        ),
        api_locking::LockAction::NotApplicable,
    ))
    .await
}


pub async fn generate_profile_refund_report(
        state: web::Data<AppState>,
        req: actix_web::HttpRequest,
        json_payload: web::Json<ReportRequest>,
    ) -> impl Responder {
        let flow = AnalyticsFlow::GenerateRefundReport;
        Box::pin(api::server_wrap(
            flow,
            state.clone(),
            &req,
            json_payload.into_inner(),
            |state, (auth, user_id): auth::AuthenticationDataWithUserId, payload, _| async move {
                let user = UserInterface::find_user_by_id(&*state.global_store, &user_id)
                    .await
                    .change_context(AnalyticsError::UnknownError)?;

                let user_email = UserEmail::from_pii_email(user.email)
                    .change_context(AnalyticsError::UnknownError)?
                    .get_secret();

                let org_id = auth.merchant_account.get_org_id();
                let merchant_id = auth.merchant_account.get_id();
                let profile_id = auth
                    .profile_id
                    .ok_or(report!(UserErrors::JwtProfileIdMissing))
                    .change_context(AnalyticsError::AccessForbiddenError)?;
                let lambda_req = GenerateReportRequest {
                    request: payload,
                    merchant_id: Some(merchant_id.clone()),
                    auth: AuthInfo::ProfileLevel {
                        org_id: org_id.clone(),
                        merchant_id: merchant_id.clone(),
                        profile_ids: vec![profile_id.clone()],
                    },
                    email: user_email,
                };

                let json_bytes =
                    serde_json::to_vec(&lambda_req).map_err(|_| AnalyticsError::UnknownError)?;
                invoke_lambda(
                    &state.conf.report_download_config.refund_function,
                    &state.conf.report_download_config.region,
                    &json_bytes,
                )
                .await
                .map(ApplicationResponse::Json)
            },
            &auth::JWTAuth {
                permission: Permission::ProfileReportRead,
            },
            api_locking::LockAction::NotApplicable,
        ))
        .await
    }


impl utils::MultipleCaptureSyncResponse for ActionResponse {
    fn get_connector_capture_id(&self) -> String {
        self.action_id.clone()
    }

    fn get_capture_attempt_status(&self) -> AttemptStatus {
        match self.approved {
            Some(true) => AttemptStatus::Charged,
            Some(false) => AttemptStatus::Failure,
            None => AttemptStatus::Pending,
        }
    }

    fn get_connector_reference_id(&self) -> Option<String> {
        self.reference.clone()
    }

    fn is_capture_response(&self) -> bool {
        self.action_type == ActionType::Capture
    }

    fn get_amount_captured(&self) -> Result<Option<MinorUnit>, error_stack::Report<ParsingError>> {
        Ok(Some(self.amount))
    }
}

impl utils::MultipleCaptureSyncResponse for for ActionResponse


File: crates/hyperswitch_interfaces/src/conversion_impls.rs

use common_utils::{errors::CustomResult, id_type};
use error_stack::ResultExt;
#[cfg(feature = "frm")]
use hyperswitch_domain_models::router_data_v2::flow_common_types::FrmFlowData;
#[cfg(feature = "payouts")]
use hyperswitch_domain_models::router_data_v2::flow_common_types::PayoutFlowData;
use hyperswitch_domain_models::{
    payment_address::PaymentAddress,
    router_data::{self, RouterData},
    router_data_v2::{
        flow_common_types::{
            AccessTokenFlowData, AuthenticationTokenFlowData, BillingConnectorInvoiceSyncFlowData,
            BillingConnectorPaymentsSyncFlowData, DisputesFlowData, ExternalAuthenticationFlowData,
            ExternalVaultProxyFlowData, FilesFlowData, MandateRevokeFlowData, PaymentFlowData,
            RefundFlowData, RevenueRecoveryRecordBackData, UasFlowData, VaultConnectorFlowData,
            WebhookSourceVerifyData,
        },
        RouterDataV2,
    },
};

use crate::{connector_integration_interface::RouterDataConversion, errors::ConnectorError};

fn get_irrelevant_id_string(id_name: &str, flow_name: &str) -> String {
    format!("irrelevant {id_name} in {flow_name} flow")
}
fn get_default_router_data<F, Req, Resp>(
    tenant_id: id_type::TenantId,
    flow_name: &str,
    request: Req,
    response: Result<Resp, router_data::ErrorResponse>,
) -> RouterData<F, Req, Resp> {
    RouterData {
        tenant_id,
        flow: std::marker::PhantomData,
        merchant_id: id_type::MerchantId::get_irrelevant_merchant_id(),
        customer_id: None,
        connector_customer: None,
        connector: get_irrelevant_id_string("connector", flow_name),
        payment_id: id_type::PaymentId::get_irrelevant_id(flow_name)
            .get_string_repr()
            .to_owned(),
        attempt_id: get_irrelevant_id_string("attempt_id", flow_name),
        status: common_enums::AttemptStatus::default(),
        payment_method: common_enums::PaymentMethod::default(),
        connector_auth_type: router_data::ConnectorAuthType::default(),
        description: None,
        address: PaymentAddress::default(),
        auth_type: common_enums::AuthenticationType::default(),
        connector_meta_data: None,
        connector_wallets_details: None,
        amount_captured: None,
        access_token: None,
        session_token: None,
        reference_id: None,
        payment_method_token: None,
        recurring_mandate_payment_data: None,
        preprocessing_id: None,
        payment_method_balance: None,
        connector_api_version: None,
        request,
        response,
        connector_request_reference_id: get_irrelevant_id_string(
            "connector_request_reference_id",
            flow_name,
        ),
        #[cfg(feature = "payouts")]
        payout_method_data: None,
        #[cfg(feature = "payouts")]
        quote_id: None,
        test_mode: None,
        connector_http_status_code: None,
        external_latency: None,
        apple_pay_flow: None,
        frm_metadata: None,
        dispute_id: None,
        refund_id: None,
        connector_response: None,
        payment_method_status: None,
        minor_amount_captured: None,
        integrity_check: Ok(()),
        additional_merchant_data: None,
        header_payload: None,
        connector_mandate_request_reference_id: None,
        authentication_id: None,
        psd2_sca_exemption_type: None,
        raw_connector_response: None,
        is_payment_id_from_merchant: None,
        l2_l3_data: None,
        minor_amount_capturable: None,
    }
}

impl<T, Req: Clone, Resp: Clone> RouterDataConversion<T, Req, Resp>
    for AuthenticationTokenFlowData
{
    fn from_old_router_data(
        old_router_data: &RouterData<T, Req, Resp>,
    ) -> CustomResult<RouterDataV2<T, Self, Req, Resp>, ConnectorError>
    where
        Self: Sized,
    {
        let resource_common_data = Self {};
        Ok(RouterDataV2 {
            flow: std::marker::PhantomData,
            tenant_id: old_router_data.tenant_id.clone(),
            resource_common_data,
            connector_auth_type: old_router_data.connector_auth_type.clone(),
            request: old_router_data.request.clone(),
            response: old_router_data.response.clone(),
        })
    }

    fn to_old_router_data(
        new_router_data: RouterDataV2<T, Self, Req, Resp>,
    ) -> CustomResult<RouterData<T, Req, Resp>, ConnectorError>
    where
        Self: Sized,
    {
        let Self {} = new_router_data.resource_common_data;
        let request = new_router_data.request.clone();
        let response = new_router_data.response.clone();
        let router_data = get_default_router_data(
            new_router_data.tenant_id.clone(),
            "authentication token",
            request,
            response,
        );
        Ok(router_data)
    }
}

impl<T, Req: Clone, Resp: Clone> RouterDataConversion<T, Req, Resp> for AccessTokenFlowData {
    fn from_old_router_data(
        old_router_data: &RouterData<T, Req, Resp>,
    ) -> CustomResult<RouterDataV2<T, Self, Req, Resp>, ConnectorError>
    where
        Self: Sized,
    {
        let resource_common_data = Self {};
        Ok(RouterDataV2 {
            flow: std::marker::PhantomData,
            tenant_id: old_router_data.tenant_id.clone(),
            resource_common_data,
            connector_auth_type: old_router_data.connector_auth_type.clone(),
            request: old_router_data.request.clone(),
            response: old_router_data.response.clone(),
        })
    }

    fn to_old_router_data(
        new_router_data: RouterDataV2<T, Self, Req, Resp>,
    ) -> CustomResult<RouterData<T, Req, Resp>, ConnectorError>
    where
        Self: Sized,
    {
        let Self {} = new_router_data.resource_common_data;
        let request = new_router_data.request.clone();
        let response = new_router_data.response.clone();
        let router_data = get_default_router_data(
            new_router_data.tenant_id.clone(),
            "access token",
            request,
            response,
        );
        Ok(router_data)
    }
}

impl<T, Req: Clone, Resp: Clone> RouterDataConversion<T, Req, Resp> for PaymentFlowData {
    fn from_old_router_data(
        old_router_data: &RouterData<T, Req, Resp>,
    ) -> CustomResult<RouterDataV2<T, Self, Req, Resp>, ConnectorError>
    where
        Self: Sized,
    {
        let resource_common_data = Self {
            merchant_id: old_router_data.merchant_id.clone(),
            customer_id: old_router_data.customer_id.clone(),
            connector_customer: old_router_data.connector_customer.clone(),
            payment_id: old_router_data.payment_id.clone(),
            attempt_id: old_router_data.attempt_id.clone(),
            status: old_router_data.status,
            payment_method: old_router_data.payment_method,
            description: old_router_data.description.clone(),
            address: old_router_data.address.clone(),
            auth_type: old_router_data.auth_type,
            connector_meta_data: old_router_data.connector_meta_data.clone(),
            amount_captured: old_router_data.amount_captured,
            minor_amount_captured: old_router_data.minor_amount_captured,
            access_token: old_router_data.access_token.clone(),
            session_token: old_router_data.session_token.clone(),
            reference_id: old_router_data.reference_id.clone(),
            payment_method_token: old_router_data.payment_method_token.clone(),
            recurring_mandate_payment_data: old_router_data.recurring_mandate_payment_data.clone(),
            preprocessing_id: old_router_data.preprocessing_id.clone(),
            payment_method_balance: old_router_data.payment_method_balance.clone(),
            connector_api_version: old_router_data.connector_api_version.clone(),
            connector_request_reference_id: old_router_data.connector_request_reference_id.clone(),
            test_mode: old_router_data.test_mode,
            connector_http_status_code: old_router_data.connector_http_status_code,
            external_latency: old_router_data.external_latency,
            apple_pay_flow: old_router_data.apple_pay_flow.clone(),
            connector_response: old_router_data.connector_response.clone(),
            payment_method_status: old_router_data.payment_method_status,
        };
        Ok(RouterDataV2 {
            flow: std::marker::PhantomData,
            tenant_id: old_router_data.tenant_id.clone(),
            resource_common_data,
            connector_auth_type: old_router_data.connector_auth_type.clone(),
            request: old_router_data.request.clone(),
            response: old_router_data.response.clone(),
        })
    }

    fn to_old_router_data(
        new_router_data: RouterDataV2<T, Self, Req, Resp>,
    ) -> CustomResult<RouterData<T, Req, Resp>, ConnectorError>
    where
        Self: Sized,
    {
        let Self {
            merchant_id,
            customer_id,
            connector_customer,
            payment_id,
            attempt_id,
            status,
            payment_method,
            description,
            address,
            auth_type,
            connector_meta_data,
            amount_captured,
            minor_amount_captured,
            access_token,
            session_token,
            reference_id,
            payment_method_token,
            recurring_mandate_payment_data,
            preprocessing_id,
            payment_method_balance,
            connector_api_version,
            connector_request_reference_id,
            test_mode,
            connector_http_status_code,
            external_latency,
            apple_pay_flow,
            connector_response,
            payment_method_status,
        } = new_router_data.resource_common_data;
        let mut router_data = get_default_router_data(
            new_router_data.tenant_id.clone(),
            "payment",
            new_router_data.request,
            new_router_data.response,
        );
        router_data.merchant_id = merchant_id;
        router_data.customer_id = customer_id;
        router_data.connector_customer = connector_customer;
        router_data.payment_id = payment_id;
        router_data.attempt_id = attempt_id;
        router_data.status = status;
        router_data.payment_method = payment_method;
        router_data.description = description;
        router_data.address = address;
        router_data.auth_type = auth_type;
        router_data.connector_meta_data = connector_meta_data;
        router_data.amount_captured = amount_captured;
        router_data.minor_amount_captured = minor_amount_captured;
        router_data.access_token = access_token;
        router_data.session_token = session_token;
        router_data.reference_id = reference_id;
        router_data.payment_method_token = payment_method_token;
        router_data.recurring_mandate_payment_data = recurring_mandate_payment_data;
        router_data.preprocessing_id = preprocessing_id;
        router_data.payment_method_balance = payment_method_balance;
        router_data.connector_api_version = connector_api_version;
        router_data.connector_request_reference_id = connector_request_reference_id;
        router_data.test_mode = test_mode;
        router_data.connector_http_status_code = connector_http_status_code;
        router_data.external_latency = external_latency;
        router_data.apple_pay_flow = apple_pay_flow;
        router_data.connector_response = connector_response;
        router_data.payment_method_status = payment_method_status;
        Ok(router_data)
    }
}

impl<T, Req: Clone, Resp: Clone> RouterDataConversion<T, Req, Resp> for RefundFlowData {
    fn from_old_router_data(
        old_router_data: &RouterData<T, Req, Resp>,
    ) -> CustomResult<RouterDataV2<T, Self, Req, Resp>, ConnectorError>
    where
        Self: Sized,
    {
        let resource_common_data = Self {
            merchant_id: old_router_data.merchant_id.clone(),
            customer_id: old_router_data.customer_id.clone(),
            payment_id: old_router_data.payment_id.clone(),
            attempt_id: old_router_data.attempt_id.clone(),
            status: old_router_data.status,
            payment_method: old_router_data.payment_method,
            connector_meta_data: old_router_data.connector_meta_data.clone(),
            amount_captured: old_router_data.amount_captured,
            minor_amount_captured: old_router_data.minor_amount_captured,
            connector_request_reference_id: old_router_data.connector_request_reference_id.clone(),
            refund_id: old_router_data.refund_id.clone().ok_or(
                ConnectorError::MissingRequiredField {
                    field_name: "refund_id",
                },
            )?,
        };
        Ok(RouterDataV2 {
            flow: std::marker::PhantomData,
            tenant_id: old_router_data.tenant_id.clone(),
            resource_common_data,
            connector_auth_type: old_router_data.connector_auth_type.clone(),
            request: old_router_data.request.clone(),
            response: old_router_data.response.clone(),
        })
    }

    fn to_old_router_data(
        new_router_data: RouterDataV2<T, Self, Req, Resp>,
    ) -> CustomResult<RouterData<T, Req, Resp>, ConnectorError>
    where
        Self: Sized,
    {
        let Self {
            merchant_id,
            customer_id,
            payment_id,
            attempt_id,
            status,
            payment_method,
            connector_meta_data,
            amount_captured,
            minor_amount_captured,
            connector_request_reference_id,
            refund_id,
        } = new_router_data.resource_common_data;
        let mut router_data = get_default_router_data(
            new_router_data.tenant_id.clone(),
            "refund",
            new_router_data.request,
            new_router_data.response,
        );
        router_data.merchant_id = merchant_id;
        router_data.customer_id = customer_id;
        router_data.payment_id = payment_id;
        router_data.attempt_id = attempt_id;
        router_data.status = status;
        router_data.payment_method = payment_method;
        router_data.connector_meta_data = connector_meta_data;
        router_data.amount_captured = amount_captured;
        router_data.minor_amount_captured = minor_amount_captured;
        router_data.connector_request_reference_id = connector_request_reference_id;
        router_data.refund_id = Some(refund_id);
        Ok(router_data)
    }
}

impl<T, Req: Clone, Resp: Clone> RouterDataConversion<T, Req, Resp> for DisputesFlowData {
    fn from_old_router_data(
        old_router_data: &RouterData<T, Req, Resp>,
    ) -> CustomResult<RouterDataV2<T, Self, Req, Resp>, ConnectorError>
    where
        Self: Sized,
    {
        let resource_common_data = Self {
            merchant_id: old_router_data.merchant_id.clone(),
            payment_id: old_router_data.payment_id.clone(),
            attempt_id: old_router_data.attempt_id.clone(),
            payment_method: old_router_data.payment_method,
            connector_meta_data: old_router_data.connector_meta_data.clone(),
            amount_captured: old_router_data.amount_captured,
            minor_amount_captured: old_router_data.minor_amount_captured,
            connector_request_reference_id: old_router_data.connector_request_reference_id.clone(),
            dispute_id: old_router_data.dispute_id.clone().ok_or(
                ConnectorError::MissingRequiredField {
                    field_name: "dispute_id",
                },
            )?,
        };
        Ok(RouterDataV2 {
            flow: std::marker::PhantomData,
            tenant_id: old_router_data.tenant_id.clone(),
            resource_common_data,
            connector_auth_type: old_router_data.connector_auth_type.clone(),
            request: old_router_data.request.clone(),
            response: old_router_data.response.clone(),
        })
    }

    fn to_old_router_data(
        new_router_data: RouterDataV2<T, Self, Req, Resp>,
    ) -> CustomResult<RouterData<T, Req, Resp>, ConnectorError>
    where
        Self: Sized,
    {
        let Self {
            merchant_id,
            payment_id,
            attempt_id,
            payment_method,
            connector_meta_data,
            amount_captured,
            minor_amount_captured,
            connector_request_reference_id,
            dispute_id,
        } = new_router_data.resource_common_data;
        let mut router_data = get_default_router_data(
            new_router_data.tenant_id.clone(),
            "Disputes",
            new_router_data.request,
            new_router_data.response,
        );
        router_data.merchant_id = merchant_id;
        router_data.payment_id = payment_id;
        router_data.attempt_id = attempt_id;
        router_data.payment_method = payment_method;
        router_data.connector_meta_data = connector_meta_data;
        router_data.amount_captured = amount_captured;
        router_data.minor_amount_captured = minor_amount_captured;
        router_data.connector_request_reference_id = connector_request_reference_id;
        router_data.dispute_id = Some(dispute_id);
        Ok(router_data)
    }
}

#[cfg(feature = "frm")]
impl<T, Req: Clone, Resp: Clone> RouterDataConversion<T, Req, Resp> for FrmFlowData {
    fn from_old_router_data(
        old_router_data: &RouterData<T, Req, Resp>,
    ) -> CustomResult<RouterDataV2<T, Self, Req, Resp>, ConnectorError>
    where
        Self: Sized,
    {
        let resource_common_data = Self {
            merchant_id: old_router_data.merchant_id.clone(),
            payment_id: old_router_data.payment_id.clone(),
            attempt_id: old_router_data.attempt_id.clone(),
            payment_method: old_router_data.payment_method,
            connector_request_reference_id: old_router_data.connector_request_reference_id.clone(),
            auth_type: old_router_data.auth_type,
            connector_wallets_details: old_router_data.connector_wallets_details.clone(),
            connector_meta_data: old_router_data.connector_meta_data.clone(),
            amount_captured: old_router_data.amount_captured,
            minor_amount_captured: old_router_data.minor_amount_captured,
        };
        Ok(RouterDataV2 {
            tenant_id: old_router_data.tenant_id.clone(),
            flow: std::marker::PhantomData,
            resource_common_data,
            connector_auth_type: old_router_data.connector_auth_type.clone(),
            request: old_router_data.request.clone(),
            response: old_router_data.response.clone(),
        })
    }

    fn to_old_router_data(
        new_router_data: RouterDataV2<T, Self, Req, Resp>,
    ) -> CustomResult<RouterData<T, Req, Resp>, ConnectorError>
    where
        Self: Sized,
    {
        let Self {
            merchant_id,
            payment_id,
            attempt_id,
            payment_method,
            connector_request_reference_id,
            auth_type,
            connector_wallets_details,
            connector_meta_data,
            amount_captured,
            minor_amount_captured,
        } = new_router_data.resource_common_data;
        let mut router_data = get_default_router_data(
            new_router_data.tenant_id.clone(),
            "frm",
            new_router_data.request,
            new_router_data.response,
        );

        router_data.merchant_id = merchant_id;
        router_data.payment_id = payment_id;
        router_data.attempt_id = attempt_id;
        router_data.payment_method = payment_method;
        router_data.connector_request_reference_id = connector_request_reference_id;
        router_data.auth_type = auth_type;
        router_data.connector_wallets_details = connector_wallets_details;
        router_data.connector_meta_data = connector_meta_data;
        router_data.amount_captured = amount_captured;
        router_data.minor_amount_captured = minor_amount_captured;

        Ok(router_data)
    }
}

impl<T, Req: Clone, Resp: Clone> RouterDataConversion<T, Req, Resp> for FilesFlowData {
    fn from_old_router_data(
        old_router_data: &RouterData<T, Req, Resp>,
    ) -> CustomResult<RouterDataV2<T, Self, Req, Resp>, ConnectorError>
    where
        Self: Sized,
    {
        let resource_common_data = Self {
            merchant_id: old_router_data.merchant_id.clone(),
            payment_id: old_router_data.payment_id.clone(),
            attempt_id: old_router_data.attempt_id.clone(),
            connector_meta_data: old_router_data.connector_meta_data.clone(),
            connector_request_reference_id: old_router_data.connector_request_reference_id.clone(),
        };
        Ok(RouterDataV2 {
            flow: std::marker::PhantomData,
            tenant_id: old_router_data.tenant_id.clone(),
            resource_common_data,
            connector_auth_type: old_router_data.connector_auth_type.clone(),
            request: old_router_data.request.clone(),
            response: old_router_data.response.clone(),
        })
    }

    fn to_old_router_data(
        new_router_data: RouterDataV2<T, Self, Req, Resp>,
    ) -> CustomResult<RouterData<T, Req, Resp>, ConnectorError>
    where
        Self: Sized,
    {
        let Self {
            merchant_id,
            payment_id,
            attempt_id,
            connector_meta_data,
            connector_request_reference_id,
        } = new_router_data.resource_common_data;
        let mut router_data = get_default_router_data(
            new_router_data.tenant_id.clone(),
            "files",
            new_router_data.request,
            new_router_data.response,
        );
        router_data.merchant_id = merchant_id;
        router_data.payment_id = payment_id;
        router_data.attempt_id = attempt_id;
        router_data.connector_meta_data = connector_meta_data;
        router_data.connector_request_reference_id = connector_request_reference_id;

        Ok(router_data)
    }
}

impl<T, Req: Clone, Resp: Clone> RouterDataConversion<T, Req, Resp> for WebhookSourceVerifyData {
    fn from_old_router_data(
        old_router_data: &RouterData<T, Req, Resp>,
    ) -> CustomResult<RouterDataV2<T, Self, Req, Resp>, ConnectorError>
    where
        Self: Sized,
    {
        let resource_common_data = Self {
            merchant_id: old_router_data.merchant_id.clone(),
        };
        Ok(RouterDataV2 {
            tenant_id: old_router_data.tenant_id.clone(),
            flow: std::marker::PhantomData,
            resource_common_data,
            connector_auth_type: old_router_data.connector_auth_type.clone(),
            request: old_router_data.request.clone(),
            response: old_router_data.response.clone(),
        })
    }

    fn to_old_router_data(
        new_router_data: RouterDataV2<T, Self, Req, Resp>,
    ) -> CustomResult<RouterData<T, Req, Resp>, ConnectorError>
    where
        Self: Sized,
    {
        let Self { merchant_id } = new_router_data.resource_common_data;
        let mut router_data = get_default_router_data(
            new_router_data.tenant_id.clone(),
            "webhook source verify",
            new_router_data.request,
            new_router_data.response,
        );
        router_data.merchant_id = merchant_id;
        Ok(router_data)
    }
}

impl<T, Req: Clone, Resp: Clone> RouterDataConversion<T, Req, Resp> for MandateRevokeFlowData {
    fn from_old_router_data(
        old_router_data: &RouterData<T, Req, Resp>,
    ) -> CustomResult<RouterDataV2<T, Self, Req, Resp>, ConnectorError>
    where
        Self: Sized,
    {
        let resource_common_data = Self {
            merchant_id: old_router_data.merchant_id.clone(),
            customer_id: old_router_data.customer_id.clone().ok_or(
                ConnectorError::MissingRequiredField {
                    field_name: "customer_id",
                },
            )?,
            payment_id: Some(old_router_data.payment_id.clone()),
        };
        Ok(RouterDataV2 {
            flow: std::marker::PhantomData,
            tenant_id: old_router_data.tenant_id.clone(),
            resource_common_data,
            connector_auth_type: old_router_data.connector_auth_type.clone(),
            request: old_router_data.request.clone(),
            response: old_router_data.response.clone(),
        })
    }

    fn to_old_router_data(
        new_router_data: RouterDataV2<T, Self, Req, Resp>,
    ) -> CustomResult<RouterData<T, Req, Resp>, ConnectorError>
    where
        Self: Sized,
    {
        let Self {
            merchant_id,
            customer_id,
            payment_id,
        } = new_router_data.resource_common_data;
        let mut router_data = get_default_router_data(
            new_router_data.tenant_id.clone(),
            "mandate revoke",
            new_router_data.request,
            new_router_data.response,
        );
        router_data.merchant_id = merchant_id;
        router_data.customer_id = Some(customer_id);
        router_data.payment_id = payment_id
            .unwrap_or_else(|| {
                id_type::PaymentId::get_irrelevant_id("mandate revoke")
                    .get_string_repr()
                    .to_owned()
            })
            .to_owned();
        Ok(router_data)
    }
}

#[cfg(feature = "payouts")]
impl<T, Req: Clone, Resp: Clone> RouterDataConversion<T, Req, Resp> for PayoutFlowData {
    fn from_old_router_data(
        old_router_data: &RouterData<T, Req, Resp>,
    ) -> CustomResult<RouterDataV2<T, Self, Req, Resp>, ConnectorError>
    where
        Self: Sized,
    {
        let resource_common_data = Self {
            merchant_id: old_router_data.merchant_id.clone(),
            customer_id: old_router_data.customer_id.clone(),
            connector_customer: old_router_data.connector_customer.clone(),
            address: old_router_data.address.clone(),
            connector_meta_data: old_router_data.connector_meta_data.clone(),
            connector_wallets_details: old_router_data.connector_wallets_details.clone(),
            connector_request_reference_id: old_router_data.connector_request_reference_id.clone(),
            payout_method_data: old_router_data.payout_method_data.clone(),
            quote_id: old_router_data.quote_id.clone(),
        };
        Ok(RouterDataV2 {
            tenant_id: old_router_data.tenant_id.clone(),
            flow: std::marker::PhantomData,
            resource_common_data,
            connector_auth_type: old_router_data.connector_auth_type.clone(),
            request: old_router_data.request.clone(),
            response: old_router_data.response.clone(),
        })
    }

    fn to_old_router_data(
        new_router_data: RouterDataV2<T, Self, Req, Resp>,
    ) -> CustomResult<RouterData<T, Req, Resp>, ConnectorError>
    where
        Self: Sized,
    {
        let Self {
            merchant_id,
            customer_id,
            connector_customer,
            address,
            connector_meta_data,
            connector_wallets_details,
            connector_request_reference_id,
            payout_method_data,
            quote_id,
        } = new_router_data.resource_common_data;
        let mut router_data = get_default_router_data(
            new_router_data.tenant_id.clone(),
            "payout",
            new_router_data.request,
            new_router_data.response,
        );
        router_data.merchant_id = merchant_id;
        router_data.customer_id = customer_id;
        router_data.connector_customer = connector_customer;
        router_data.address = address;
        router_data.connector_meta_data = connector_meta_data;
        router_data.connector_wallets_details = connector_wallets_details;
        router_data.connector_request_reference_id = connector_request_reference_id;
        router_data.payout_method_data = payout_method_data;
        router_data.quote_id = quote_id;
        Ok(router_data)
    }
}
impl<T, Req: Clone, Resp: Clone> RouterDataConversion<T, Req, Resp>
    for ExternalAuthenticationFlowData
{
    fn from_old_router_data(
        old_router_data: &RouterData<T, Req, Resp>,
    ) -> CustomResult<RouterDataV2<T, Self, Req, Resp>, ConnectorError>
    where
        Self: Sized,
    {
        let resource_common_data = Self {
            merchant_id: old_router_data.merchant_id.clone(),
            connector_meta_data: old_router_data.connector_meta_data.clone(),
            address: old_router_data.address.clone(),
        };
        Ok(RouterDataV2 {
            tenant_id: old_router_data.tenant_id.clone(),
            flow: std::marker::PhantomData,
            resource_common_data,
            connector_auth_type: old_router_data.connector_auth_type.clone(),
            request: old_router_data.request.clone(),
            response: old_router_data.response.clone(),
        })
    }

    fn to_old_router_data(
        new_router_data: RouterDataV2<T, Self, Req, Resp>,
    ) -> CustomResult<RouterData<T, Req, Resp>, ConnectorError>
    where
        Self: Sized,
    {
        let Self {
            merchant_id,
            connector_meta_data,
            address,
        } = new_router_data.resource_common_data;
        let mut router_data = get_default_router_data(
            new_router_data.tenant_id.clone(),
            "external authentication",
            new_router_data.request,
            new_router_data.response,
        );
        router_data.merchant_id = merchant_id;
        router_data.connector_meta_data = connector_meta_data;
        router_data.address = address;
        Ok(router_data)
    }
}

impl<T, Req: Clone, Resp: Clone> RouterDataConversion<T, Req, Resp>
    for RevenueRecoveryRecordBackData
{
    fn from_old_router_data(
        old_router_data: &RouterData<T, Req, Resp>,
    ) -> CustomResult<RouterDataV2<T, Self, Req, Resp>, ConnectorError>
    where
        Self: Sized,
    {
        let resource_common_data = Self {};
        Ok(RouterDataV2 {
            flow: std::marker::PhantomData,
            tenant_id: old_router_data.tenant_id.clone(),
            resource_common_data,
            connector_auth_type: old_router_data.connector_auth_type.clone(),
            request: old_router_data.request.clone(),
            response: old_router_data.response.clone(),
        })
    }

    fn to_old_router_data(
        new_router_data: RouterDataV2<T, Self, Req, Resp>,
    ) -> CustomResult<RouterData<T, Req, Resp>, ConnectorError>
    where
        Self: Sized,
    {
        let router_data = get_default_router_data(
            new_router_data.tenant_id.clone(),
            "recovery_record_back",
            new_router_data.request,
            new_router_data.response,
        );
        Ok(RouterData {
            connector_auth_type: new_router_data.connector_auth_type.clone(),
            ..router_data
        })
    }
}

impl<T, Req: Clone, Resp: Clone> RouterDataConversion<T, Req, Resp> for UasFlowData {
    fn from_old_router_data(
        old_router_data: &RouterData<T, Req, Resp>,
    ) -> CustomResult<RouterDataV2<T, Self, Req, Resp>, ConnectorError>
    where
        Self: Sized,
    {
        let resource_common_data = Self {
            authenticate_by: old_router_data.connector.clone(),
            source_authentication_id: old_router_data
                .authentication_id
                .clone()
                .ok_or(ConnectorError::MissingRequiredField {
                    field_name: "source_authentication_id",
                })
                .attach_printable("missing authentication id for uas")?,
        };
        Ok(RouterDataV2 {
            flow: std::marker::PhantomData,
            tenant_id: old_router_data.tenant_id.clone(),
            resource_common_data,
            connector_auth_type: old_router_data.connector_auth_type.clone(),
            request: old_router_data.request.clone(),
            response: old_router_data.response.clone(),
        })
    }

    fn to_old_router_data(
        new_router_data: RouterDataV2<T, Self, Req, Resp>,
    ) -> CustomResult<RouterData<T, Req, Resp>, ConnectorError>
    where
        Self: Sized,
    {
        let Self {
            authenticate_by,
            source_authentication_id,
        } = new_router_data.resource_common_data;
        let mut router_data = get_default_router_data(
            new_router_data.tenant_id.clone(),
            "uas",
            new_router_data.request,
            new_router_data.response,
        );
        router_data.connector = authenticate_by;
        router_data.authentication_id = Some(source_authentication_id);
        Ok(router_data)
    }
}

impl<T, Req: Clone, Resp: Clone> RouterDataConversion<T, Req, Resp>
    for BillingConnectorPaymentsSyncFlowData
{
    fn from_old_router_data(
        old_router_data: &RouterData<T, Req, Resp>,
    ) -> CustomResult<RouterDataV2<T, Self, Req, Resp>, ConnectorError>
    where
        Self: Sized,
    {
        let resource_common_data = Self {};
        Ok(RouterDataV2 {
            flow: std::marker::PhantomData,
            tenant_id: old_router_data.tenant_id.clone(),
            resource_common_data,
            connector_auth_type: old_router_data.connector_auth_type.clone(),
            request: old_router_data.request.clone(),
            response: old_router_data.response.clone(),
        })
    }

    fn to_old_router_data(
        new_router_data: RouterDataV2<T, Self, Req, Resp>,
    ) -> CustomResult<RouterData<T, Req, Resp>, ConnectorError>
    where
        Self: Sized,
    {
        let router_data = get_default_router_data(
            new_router_data.tenant_id.clone(),
            "BillingConnectorPaymentsSync",
            new_router_data.request,
            new_router_data.response,
        );
        Ok(RouterData {
            connector_auth_type: new_router_data.connector_auth_type.clone(),
            ..router_data
        })
    }
}

impl<T, Req: Clone, Resp: Clone> RouterDataConversion<T, Req, Resp>
    for BillingConnectorInvoiceSyncFlowData
{
    fn from_old_router_data(
        old_router_data: &RouterData<T, Req, Resp>,
    ) -> CustomResult<RouterDataV2<T, Self, Req, Resp>, ConnectorError>
    where
        Self: Sized,
    {
        let resource_common_data = Self {};
        Ok(RouterDataV2 {
            flow: std::marker::PhantomData,
            tenant_id: old_router_data.tenant_id.clone(),
            resource_common_data,
            connector_auth_type: old_router_data.connector_auth_type.clone(),
            request: old_router_data.request.clone(),
            response: old_router_data.response.clone(),
        })
    }

    fn to_old_router_data(
        new_router_data: RouterDataV2<T, Self, Req, Resp>,
    ) -> CustomResult<RouterData<T, Req, Resp>, ConnectorError>
    where
        Self: Sized,
    {
        let router_data = get_default_router_data(
            new_router_data.tenant_id.clone(),
            "BillingConnectorInvoiceSync",
            new_router_data.request,
            new_router_data.response,
        );
        Ok(RouterData {
            connector_auth_type: new_router_data.connector_auth_type.clone(),
            ..router_data
        })
    }
}

impl<T, Req: Clone, Resp: Clone> RouterDataConversion<T, Req, Resp> for VaultConnectorFlowData {
    fn from_old_router_data(
        old_router_data: &RouterData<T, Req, Resp>,
    ) -> CustomResult<RouterDataV2<T, Self, Req, Resp>, ConnectorError>
    where
        Self: Sized,
    {
        let resource_common_data = Self {
            merchant_id: old_router_data.merchant_id.clone(),
        };
        Ok(RouterDataV2 {
            flow: std::marker::PhantomData,
            tenant_id: old_router_data.tenant_id.clone(),
            resource_common_data,
            connector_auth_type: old_router_data.connector_auth_type.clone(),
            request: old_router_data.request.clone(),
            response: old_router_data.response.clone(),
        })
    }

    fn to_old_router_data(
        new_router_data: RouterDataV2<T, Self, Req, Resp>,
    ) -> CustomResult<RouterData<T, Req, Resp>, ConnectorError>
    where
        Self: Sized,
    {
        let router_data = get_default_router_data(
            new_router_data.tenant_id.clone(),
            "VaultConnector",
            new_router_data.request,
            new_router_data.response,
        );
        Ok(RouterData {
            connector_auth_type: new_router_data.connector_auth_type.clone(),
            ..router_data
        })
    }
}

impl<T, Req: Clone, Resp: Clone> RouterDataConversion<T, Req, Resp> for ExternalVaultProxyFlowData {
    fn from_old_router_data(
        old_router_data: &RouterData<T, Req, Resp>,
    ) -> CustomResult<RouterDataV2<T, Self, Req, Resp>, ConnectorError>
    where
        Self: Sized,
    {
        let resource_common_data = Self {
            merchant_id: old_router_data.merchant_id.clone(),
            customer_id: old_router_data.customer_id.clone(),
            connector_customer: old_router_data.connector_customer.clone(),
            payment_id: old_router_data.payment_id.clone(),
            attempt_id: old_router_data.attempt_id.clone(),
            status: old_router_data.status,
            payment_method: old_router_data.payment_method,
            description: old_router_data.description.clone(),
            address: old_router_data.address.clone(),
            auth_type: old_router_data.auth_type,
            connector_meta_data: old_router_data.connector_meta_data.clone(),
            amount_captured: old_router_data.amount_captured,
            minor_amount_captured: old_router_data.minor_amount_captured,
            access_token: old_router_data.access_token.clone(),
            session_token: old_router_data.session_token.clone(),
            reference_id: old_router_data.reference_id.clone(),
            payment_method_token: old_router_data.payment_method_token.clone(),
            recurring_mandate_payment_data: old_router_data.recurring_mandate_payment_data.clone(),
            preprocessing_id: old_router_data.preprocessing_id.clone(),
            payment_method_balance: old_router_data.payment_method_balance.clone(),
            connector_api_version: old_router_data.connector_api_version.clone(),
            connector_request_reference_id: old_router_data.connector_request_reference_id.clone(),
            test_mode: old_router_data.test_mode,
            connector_http_status_code: old_router_data.connector_http_status_code,
            external_latency: old_router_data.external_latency,
            apple_pay_flow: old_router_data.apple_pay_flow.clone(),
            connector_response: old_router_data.connector_response.clone(),
            payment_method_status: old_router_data.payment_method_status,
        };
        Ok(RouterDataV2 {
            flow: std::marker::PhantomData,
            tenant_id: old_router_data.tenant_id.clone(),
            resource_common_data,
            connector_auth_type: old_router_data.connector_auth_type.clone(),
            request: old_router_data.request.clone(),
            response: old_router_data.response.clone(),
        })
    }

    fn to_old_router_data(
        new_router_data: RouterDataV2<T, Self, Req, Resp>,
    ) -> CustomResult<RouterData<T, Req, Resp>, ConnectorError>
    where
        Self: Sized,
    {
        let Self {
            merchant_id,
            customer_id,
            connector_customer,
            payment_id,
            attempt_id,
            status,
            payment_method,
            description,
            address,
            auth_type,
            connector_meta_data,
            amount_captured,


pub struct RefundErrorMessageDistributionRow {
    pub count: i64,
    pub total: i64,
    pub refund_error_message: String,
}


pub struct PaysafeConnectorMetadataObject {
    pub account_id: Secret<String>,
}


pub struct AirwallexObjectData {
    pub object: serde_json::Value,
}


impl Responder {
    use api_models::payments::PaymentsGetIntentRequest;
    use hyperswitch_domain_models::payments::PaymentIntentData;

    let flow = Flow::PaymentsGetIntent;
    let header_payload = match HeaderPayload::foreign_try_from(req.headers()) {
        Ok(headers) => headers,
        Err(err) => {
            return api::log_and_return_error_response(err);
        }
    };

    let payload = PaymentsGetIntentRequest {
        id: path.into_inner(),
    };

    let global_payment_id = payload.id.clone();

    Box::pin(api::server_wrap(
        flow,
        state,
        &req,
        payload,
        |state, auth: auth::AuthenticationData, req, req_state| {
            let merchant_context = domain::MerchantContext::NormalMerchant(Box::new(
                domain::Context(auth.merchant_account, auth.key_store),
            ));
            payments::payments_intent_core::<
                api_types::PaymentGetIntent,
                payment_types::PaymentsIntentResponse,
                _,
                _,
                PaymentIntentData<api_types::PaymentGetIntent>,
            >(
                state,
                req_state,
                merchant_context,
                auth.profile,
                payments::operations::PaymentGetIntent,
                req,
                global_payment_id.clone(),
                header_payload.clone(),
            )
        },
        auth::api_or_client_or_jwt_auth(
            &auth::V2ApiKeyAuth {
                is_connected_allowed: false,
                is_platform_allowed: false,
            },
            &auth::V2ClientAuth(common_utils::types::authentication::ResourceId::Payment(
                global_payment_id.clone(),
            )),
            &auth::JWTAuth {
                permission: Permission::ProfileRevenueRecoveryRead,
            },
            req.headers(),
        ),
        api_locking::LockAction::NotApplicable,
    ))
    .await
}


impl Responder {
    let routing_payload_wrapper = routing_types::RoutingPayloadWrapper {
        updated_config: json_payload.into_inner(),
        profile_id: path.into_inner(),
    };
    Box::pin(oss_api::server_wrap(
        Flow::RoutingUpdateDefaultConfig,
        state,
        &req,
        routing_payload_wrapper.clone(),
        |state, auth: auth::AuthenticationData, wrapper, _| {
            let merchant_context = domain::MerchantContext::NormalMerchant(Box::new(
                domain::Context(auth.merchant_account, auth.key_store),
            ));
            routing::update_default_routing_config_for_profile(
                state,
                merchant_context,
                wrapper.updated_config,
                wrapper.profile_id,
                transaction_type,
            )
        },
        auth::auth_type(
            &auth::HeaderAuth(auth::ApiKeyAuth {
                is_connected_allowed: false,
                is_platform_allowed: false,
            }),
            &auth::JWTAuthProfileFromRoute {
                profile_id: routing_payload_wrapper.profile_id,
                required_permission: Permission::ProfileRoutingWrite,
            },
            req.headers(),
        ),
        api_locking::LockAction::NotApplicable,
    ))
    .await
}


OpenAPI Block Path: components.schemas.MobilePaymentConsent
{
  "type": "string",
  "enum": [
    "consent_required",
    "consent_not_required",
    "consent_optional"
  ]
}


pub struct NetceteraPreAuthenticationRequest {
    cardholder_account_number: cards::CardNumber,
    scheme_id: Option<netcetera_types::SchemeId>,
}


impl Mandate {
    pub async fn find_by_merchant_id_mandate_id(
        conn: &PgPooledConn,
        merchant_id: &common_utils::id_type::MerchantId,
        mandate_id: &str,
    ) -> StorageResult<Self> {
        generics::generic_find_one::<<Self as HasTable>::Table, _, _>(
            conn,
            dsl::merchant_id
                .eq(merchant_id.to_owned())
                .and(dsl::mandate_id.eq(mandate_id.to_owned())),
        )
        .await
    }

    pub async fn find_by_merchant_id_connector_mandate_id(
        conn: &PgPooledConn,
        merchant_id: &common_utils::id_type::MerchantId,
        connector_mandate_id: &str,
    ) -> StorageResult<Self> {
        generics::generic_find_one::<<Self as HasTable>::Table, _, _>(
            conn,
            dsl::merchant_id
                .eq(merchant_id.to_owned())
                .and(dsl::connector_mandate_id.eq(connector_mandate_id.to_owned())),
        )
        .await
    }

    pub async fn find_by_merchant_id_customer_id(
        conn: &PgPooledConn,
        merchant_id: &common_utils::id_type::MerchantId,
        customer_id: &common_utils::id_type::CustomerId,
    ) -> StorageResult<Vec<Self>> {
        generics::generic_filter::<
            <Self as HasTable>::Table,
            _,
            <<Self as HasTable>::Table as Table>::PrimaryKey,
            _,
        >(
            conn,
            dsl::merchant_id
                .eq(merchant_id.to_owned())
                .and(dsl::customer_id.eq(customer_id.to_owned())),
            None,
            None,
            None,
        )
        .await
    }

    //Fix this function once V2 mandate is schema is being built
    #[cfg(feature = "v2")]
    pub async fn find_by_global_customer_id(
        conn: &PgPooledConn,
        customer_id: &common_utils::id_type::GlobalCustomerId,
    ) -> StorageResult<Vec<Self>> {
        generics::generic_filter::<
            <Self as HasTable>::Table,
            _,
            <<Self as HasTable>::Table as Table>::PrimaryKey,
            _,
        >(
            conn,
            dsl::customer_id.eq(customer_id.to_owned()),
            None,
            None,
            None,
        )
        .await
    }

    pub async fn update_by_merchant_id_mandate_id(
        conn: &PgPooledConn,
        merchant_id: &common_utils::id_type::MerchantId,
        mandate_id: &str,
        mandate: MandateUpdateInternal,
    ) -> StorageResult<Self> {
        generics::generic_update_with_results::<<Self as HasTable>::Table, _, _, _>(
            conn,
            dsl::merchant_id
                .eq(merchant_id.to_owned())
                .and(dsl::mandate_id.eq(mandate_id.to_owned())),
            mandate,
        )
        .await?
        .first()
        .cloned()
        .ok_or_else(|| {
            report!(errors::DatabaseError::NotFound)
                .attach_printable("Error while updating mandate")
        })
    }
}


Documentation: api-reference/v2/connector-account/connector-account--create.mdx
# Type: Doc File

---
openapi: post /v2/connector-accounts
---


pub fn lower_program<O>(
    dir_program: dir::DirProgram<O>,
) -> Result<vir::ValuedProgram<O>, AnalysisError> {
    Ok(vir::ValuedProgram {
        default_selection: dir_program.default_selection,
        rules: dir_program
            .rules
            .into_iter()
            .map(lower_rule)
            .collect::<Result<_, _>>()
            .map_err(|e| AnalysisError {
                error_type: e,
                metadata: Default::default(),
            })?,
        metadata: dir_program.metadata,
    })
}


impl TokenioErrorResponse {
    pub fn from_bytes(bytes: &[u8]) -> Self {
        // First try to parse as JSON
        if let Ok(json_response) = serde_json::from_slice::<Self>(bytes) {
            json_response
        } else {
            // If JSON parsing fails, treat as plain text
            let text = String::from_utf8_lossy(bytes).to_string();
            Self::Text(text)
        }
    }
    pub fn get_message(&self) -> String {
        match self {
            Self::Json {
                message,
                error_code,
            } => message
                .as_deref()
                .or(error_code.as_deref())
                .unwrap_or(NO_ERROR_MESSAGE)
                .to_string(),
            Self::Text(text) => text.clone(),
        }
    }

    pub fn get_error_code(&self) -> String {
        match self {
            Self::Json { error_code, .. } => {
                error_code.as_deref().unwrap_or(NO_ERROR_CODE).to_string()
            }
            Self::Text(_) => NO_ERROR_CODE.to_string(),
        }
    }
}


File: crates/router/src/core/payments/conditional_configs.rs
 Public functions: 3

use api_models::{conditional_configs::DecisionManagerRecord, routing};
use common_utils::ext_traits::StringExt;
use error_stack::ResultExt;
use euclid::backend::{self, inputs as dsl_inputs, EuclidBackend};
use router_env::{instrument, tracing};
use storage_impl::redis::cache::{self, DECISION_MANAGER_CACHE};

use super::routing::make_dsl_input;
#[cfg(feature = "v2")]
use crate::{core::errors::RouterResult, types::domain};
use crate::{
    core::{errors, errors::ConditionalConfigError as ConfigError, routing as core_routing},
    routes,
};
pub type ConditionalConfigResult<O> = errors::CustomResult<O, ConfigError>;

#[instrument(skip_all)]
#[cfg(feature = "v1")]
pub async fn perform_decision_management(
    state: &routes::SessionState,
    algorithm_ref: routing::RoutingAlgorithmRef,
    merchant_id: &common_utils::id_type::MerchantId,
    payment_data: &core_routing::PaymentsDslInput<'_>,
) -> ConditionalConfigResult<common_types::payments::ConditionalConfigs> {
    let algorithm_id = if let Some(id) = algorithm_ref.config_algo_id {
        id
    } else {
        return Ok(common_types::payments::ConditionalConfigs::default());
    };
    let db = &*state.store;

    let key = merchant_id.get_dsl_config();

    let find_key_from_db = || async {
        let config = db.find_config_by_key(&algorithm_id).await?;

        let rec: DecisionManagerRecord = config
            .config
            .parse_struct("Program")
            .change_context(errors::StorageError::DeserializationFailed)
            .attach_printable("Error parsing routing algorithm from configs")?;

        backend::VirInterpreterBackend::with_program(rec.program)
            .change_context(errors::StorageError::ValueNotFound("Program".to_string()))
            .attach_printable("Error initializing DSL interpreter backend")
    };

    let interpreter = cache::get_or_populate_in_memory(
        db.get_cache_store().as_ref(),
        &key,
        find_key_from_db,
        &DECISION_MANAGER_CACHE,
    )
    .await
    .change_context(ConfigError::DslCachePoisoned)?;

    let backend_input =
        make_dsl_input(payment_data).change_context(ConfigError::InputConstructionError)?;

    execute_dsl_and_get_conditional_config(backend_input, &interpreter)
}

#[cfg(feature = "v2")]
pub fn perform_decision_management(
    record: common_types::payments::DecisionManagerRecord,
    payment_data: &core_routing::PaymentsDslInput<'_>,
) -> RouterResult<common_types::payments::ConditionalConfigs> {
    let interpreter = backend::VirInterpreterBackend::with_program(record.program)
        .change_context(errors::ApiErrorResponse::InternalServerError)
        .attach_printable("Error initializing DSL interpreter backend")?;

    let backend_input = make_dsl_input(payment_data)
        .change_context(errors::ApiErrorResponse::InternalServerError)
        .attach_printable("Error constructing DSL input")?;
    execute_dsl_and_get_conditional_config(backend_input, &interpreter)
        .change_context(errors::ApiErrorResponse::InternalServerError)
        .attach_printable("Error executing DSL")
}

pub fn execute_dsl_and_get_conditional_config(
    backend_input: dsl_inputs::BackendInput,
    interpreter: &backend::VirInterpreterBackend<common_types::payments::ConditionalConfigs>,
) -> ConditionalConfigResult<common_types::payments::ConditionalConfigs> {
    let routing_output = interpreter
        .execute(backend_input)
        .map(|out| out.connector_selection)
        .change_context(ConfigError::DslExecutionError)?;
    Ok(routing_output)
}


impl api::PaymentSession for Razorpay {}

impl api::PaymentSession for for Razorpay


pub struct NoonSubscriptionObject {
    identifier: Secret<String>,
}


pub struct PaymentLinkBackgroundImageConfig {
    /// URL of the image
    #[schema(value_type = String, example = "https://hyperswitch.io/favicon.ico")]
    pub url: common_utils::types::Url,
    /// Position of the image in the UI
    #[schema(value_type = Option<ElementPosition>, example = "top-left")]
    pub position: Option<api_enums::ElementPosition>,
    /// Size of the image in the UI
    #[schema(value_type = Option<ElementSize>, example = "contain")]
    pub size: Option<api_enums::ElementSize>,
}


pub async fn elimination_routing_update_configs(
    state: web::Data<AppState>,
    req: HttpRequest,
    path: web::Path<routing_types::DynamicRoutingUpdateConfigQuery>,
    json_payload: web::Json<routing_types::EliminationRoutingConfig>,
) -> impl Responder {
    let flow = Flow::UpdateDynamicRoutingConfigs;
    let routing_payload_wrapper = routing_types::EliminationRoutingPayloadWrapper {
        updated_config: json_payload.into_inner(),
        algorithm_id: path.clone().algorithm_id,
        profile_id: path.clone().profile_id,
    };
    Box::pin(oss_api::server_wrap(
        flow,
        state,
        &req,
        routing_payload_wrapper.clone(),
        |state, _, wrapper: routing_types::EliminationRoutingPayloadWrapper, _| async {
            Box::pin(routing::elimination_routing_update_configs(
                state,
                wrapper.updated_config,
                wrapper.algorithm_id,
                wrapper.profile_id,
            ))
            .await
        },
        auth::auth_type(
            &auth::HeaderAuth(auth::ApiKeyAuth {
                is_connected_allowed: false,
                is_platform_allowed: false,
            }),
            &auth::JWTAuthProfileFromRoute {
                profile_id: routing_payload_wrapper.profile_id,
                required_permission: Permission::ProfileRoutingWrite,
            },
            req.headers(),
        ),
        api_locking::LockAction::NotApplicable,
    ))
    .await
}


pub struct SamsungPayWalletCredentials {
    pub method: Option<String>,
    pub recurring_payment: Option<bool>,
    pub card_brand: common_enums::SamsungPayCardBrand,
    pub dpan_last_four_digits: Option<String>,
    #[serde(rename = "card_last4digits")]
    pub card_last_four_digits: String,
    #[serde(rename = "3_d_s")]
    pub token_data: SamsungPayTokenData,
}


pub fn get_payment_method_collect_data(&self) -> Result<&PaymentMethodCollectLinkData, String> {
        match self {
            Self::PaymentMethodCollect(pm) => Ok(pm),
            _ => Err("Invalid link type for fetching payment method collect data".to_string()),
        }
    }