impl MerchantDefaultConfigUpdate<'_> {
    async fn retrieve_and_update_default_fallback_routing_algorithm_if_routable_connector_exists(
        &self,
    ) -> RouterResult<()> {
        let mut default_routing_config = routing::helpers::get_merchant_default_config(
            self.store,
            self.merchant_id.get_string_repr(),
            self.transaction_type,
        )
        .await?;

        let mut default_routing_config_for_profile = routing::helpers::get_merchant_default_config(
            self.store,
            self.profile_id.get_string_repr(),
            self.transaction_type,
        )
        .await?;

        if let Some(routable_connector_val) = self.routable_connector {
            let choice = routing_types::RoutableConnectorChoice {
                choice_kind: routing_types::RoutableChoiceKind::FullStruct,
                connector: *routable_connector_val,
                merchant_connector_id: Some(self.merchant_connector_id.clone()),
            };
            if !default_routing_config.contains(&choice) {
                default_routing_config.push(choice.clone());
                routing::helpers::update_merchant_default_config(
                    self.store,
                    self.merchant_id.get_string_repr(),
                    default_routing_config.clone(),
                    self.transaction_type,
                )
                .await?;
            }
            if !default_routing_config_for_profile.contains(&choice.clone()) {
                default_routing_config_for_profile.push(choice);
                routing::helpers::update_merchant_default_config(
                    self.store,
                    self.profile_id.get_string_repr(),
                    default_routing_config_for_profile.clone(),
                    self.transaction_type,
                )
                .await?;
            }
        }
        Ok(())
    }

    async fn retrieve_and_delete_from_default_fallback_routing_algorithm_if_routable_connector_exists(
        &self,
    ) -> RouterResult<()> {
        let mut default_routing_config = routing::helpers::get_merchant_default_config(
            self.store,
            self.merchant_id.get_string_repr(),
            self.transaction_type,
        )
        .await?;

        let mut default_routing_config_for_profile = routing::helpers::get_merchant_default_config(
            self.store,
            self.profile_id.get_string_repr(),
            self.transaction_type,
        )
        .await?;

        if let Some(routable_connector_val) = self.routable_connector {
            let choice = routing_types::RoutableConnectorChoice {
                choice_kind: routing_types::RoutableChoiceKind::FullStruct,
                connector: *routable_connector_val,
                merchant_connector_id: Some(self.merchant_connector_id.clone()),
            };
            if default_routing_config.contains(&choice) {
                default_routing_config.retain(|mca| {
                    mca.merchant_connector_id.as_ref() != Some(self.merchant_connector_id)
                });
                routing::helpers::update_merchant_default_config(
                    self.store,
                    self.merchant_id.get_string_repr(),
                    default_routing_config.clone(),
                    self.transaction_type,
                )
                .await?;
            }
            if default_routing_config_for_profile.contains(&choice.clone()) {
                default_routing_config_for_profile.retain(|mca| {
                    mca.merchant_connector_id.as_ref() != Some(self.merchant_connector_id)
                });
                routing::helpers::update_merchant_default_config(
                    self.store,
                    self.profile_id.get_string_repr(),
                    default_routing_config_for_profile.clone(),
                    self.transaction_type,
                )
                .await?;
            }
        }
        Ok(())
    }
}


impl api::PaymentVoid for Adyen {}


File: crates/hyperswitch_domain_models/src/refunds.rs
 Public structs: 2

#[cfg(feature = "v2")]
use crate::business_profile::Profile;
#[cfg(feature = "v1")]
use crate::errors;

#[cfg(feature = "v1")]
pub struct RefundListConstraints {
    pub payment_id: Option<common_utils::id_type::PaymentId>,
    pub refund_id: Option<String>,
    pub profile_id: Option<Vec<common_utils::id_type::ProfileId>>,
    pub limit: Option<i64>,
    pub offset: Option<i64>,
    pub time_range: Option<common_utils::types::TimeRange>,
    pub amount_filter: Option<api_models::payments::AmountFilter>,
    pub connector: Option<Vec<String>>,
    pub merchant_connector_id: Option<Vec<common_utils::id_type::MerchantConnectorAccountId>>,
    pub currency: Option<Vec<common_enums::Currency>>,
    pub refund_status: Option<Vec<common_enums::RefundStatus>>,
}

#[cfg(feature = "v2")]
pub struct RefundListConstraints {
    pub payment_id: Option<common_utils::id_type::GlobalPaymentId>,
    pub refund_id: Option<common_utils::id_type::GlobalRefundId>,
    pub profile_id: common_utils::id_type::ProfileId,
    pub limit: Option<i64>,
    pub offset: Option<i64>,
    pub time_range: Option<common_utils::types::TimeRange>,
    pub amount_filter: Option<api_models::payments::AmountFilter>,
    pub connector: Option<Vec<String>>,
    pub connector_id_list: Option<Vec<common_utils::id_type::MerchantConnectorAccountId>>,
    pub currency: Option<Vec<common_enums::Currency>>,
    pub refund_status: Option<Vec<common_enums::RefundStatus>>,
}

#[cfg(feature = "v1")]
impl
    TryFrom<(
        api_models::refunds::RefundListRequest,
        Option<Vec<common_utils::id_type::ProfileId>>,
    )> for RefundListConstraints
{
    type Error = error_stack::Report<errors::api_error_response::ApiErrorResponse>;

    fn try_from(
        (value, auth_profile_id_list): (
            api_models::refunds::RefundListRequest,
            Option<Vec<common_utils::id_type::ProfileId>>,
        ),
    ) -> Result<Self, Self::Error> {
        let api_models::refunds::RefundListRequest {
            connector,
            currency,
            refund_status,
            payment_id,
            refund_id,
            profile_id,
            limit,
            offset,
            time_range,
            amount_filter,
            merchant_connector_id,
        } = value;
        let profile_id_from_request_body = profile_id;
        let profile_id_list = match (profile_id_from_request_body, auth_profile_id_list) {
            (None, None) => None,
            (None, Some(auth_profile_id_list)) => Some(auth_profile_id_list),
            (Some(profile_id_from_request_body), None) => Some(vec![profile_id_from_request_body]),
            (Some(profile_id_from_request_body), Some(auth_profile_id_list)) => {
                let profile_id_from_request_body_is_available_in_auth_profile_id_list =
                    auth_profile_id_list.contains(&profile_id_from_request_body);

                if profile_id_from_request_body_is_available_in_auth_profile_id_list {
                    Some(vec![profile_id_from_request_body])
                } else {
                    // This scenario is very unlikely to happen
                    return Err(error_stack::Report::new(
                        errors::api_error_response::ApiErrorResponse::PreconditionFailed {
                            message: format!(
                                "Access not available for the given profile_id {profile_id_from_request_body:?}",

                            ),
                        },
                    ));
                }
            }
        };
        Ok(Self {
            payment_id,
            refund_id,
            profile_id: profile_id_list,
            limit,
            offset,
            time_range,
            amount_filter,
            connector,
            merchant_connector_id,
            currency,
            refund_status,
        })
    }
}

#[cfg(feature = "v2")]
impl From<(api_models::refunds::RefundListRequest, Profile)> for RefundListConstraints {
    fn from((value, profile): (api_models::refunds::RefundListRequest, Profile)) -> Self {
        let api_models::refunds::RefundListRequest {
            payment_id,
            refund_id,
            connector,
            currency,
            refund_status,
            limit,
            offset,
            time_range,
            amount_filter,
            connector_id_list,
        } = value;

        Self {
            payment_id,
            refund_id,
            profile_id: profile.get_id().to_owned(),
            limit,
            offset,
            time_range,
            amount_filter,
            connector,
            connector_id_list,
            currency,
            refund_status,
        }
    }
}


pub fn attempt_status_from_transaction_state(
    transaction_state: JpmorganTransactionState,
) -> common_enums::AttemptStatus {
    match transaction_state {
        JpmorganTransactionState::Authorized => common_enums::AttemptStatus::Authorized,
        JpmorganTransactionState::Closed => common_enums::AttemptStatus::Charged,
        JpmorganTransactionState::Declined | JpmorganTransactionState::Error => {
            common_enums::AttemptStatus::Failure
        }
        JpmorganTransactionState::Pending => common_enums::AttemptStatus::Pending,
        JpmorganTransactionState::Voided => common_enums::AttemptStatus::Voided,
    }
}


impl api::PaymentAuthorize for Prophetpay {}

impl api::PaymentAuthorize for for Prophetpay


impl IncomingWebhook for Archipel {
    fn get_webhook_object_reference_id(
        &self,
        _request: &IncomingWebhookRequestDetails<'_>,
    ) -> CustomResult<ObjectReferenceId, errors::ConnectorError> {
        Err(report!(errors::ConnectorError::WebhooksNotImplemented))
    }

    fn get_webhook_event_type(
        &self,
        _request: &IncomingWebhookRequestDetails<'_>,
    ) -> CustomResult<IncomingWebhookEvent, errors::ConnectorError> {
        Err(report!(errors::ConnectorError::WebhooksNotImplemented))
    }

    fn get_webhook_resource_object(
        &self,
        _request: &IncomingWebhookRequestDetails<'_>,
    ) -> CustomResult<Box<dyn masking::ErasedMaskSerialize>, errors::ConnectorError> {
        Err(report!(errors::ConnectorError::WebhooksNotImplemented))
    }
}


pub async fn accept_dispute(
    state: SessionState,
    merchant_context: domain::MerchantContext,
    profile_id: Option<common_utils::id_type::ProfileId>,
    req: disputes::DisputeId,
) -> RouterResponse<dispute_models::DisputeResponse> {
    todo!()
}


pub struct EligiblePaymentMethods {
    #[serde(deserialize_with = "deserialize_hashset")]
    pub sdk_eligible_payment_methods: HashSet<String>,
}


OpenAPI Block Path: components.schemas.PayLaterData
{
  "oneOf": [
    {
      "type": "object",
      "required": [
        "klarna_redirect"
      ],
      "properties": {
        "klarna_redirect": {
          "type": "object",
          "description": "For KlarnaRedirect as PayLater Option",
          "properties": {
            "billing_email": {
              "type": "string",
              "description": "The billing email",
              "nullable": true
            },
            "billing_country": {
              "allOf": [
                {
                  "$ref": "#/components/schemas/CountryAlpha2"
                }
              ],
              "nullable": true
            }
          }
        }
      }
    },
    {
      "type": "object",
      "required": [
        "klarna_sdk"
      ],
      "properties": {
        "klarna_sdk": {
          "type": "object",
          "description": "For Klarna Sdk as PayLater Option",
          "required": [
            "token"
          ],
          "properties": {
            "token": {
              "type": "string",
              "description": "The token for the sdk workflow"
            }
          }
        }
      }
    },
    {
      "type": "object",
      "required": [
        "affirm_redirect"
      ],
      "properties": {
        "affirm_redirect": {
          "type": "object",
          "description": "For Affirm redirect as PayLater Option"
        }
      }
    },
    {
      "type": "object",
      "required": [
        "afterpay_clearpay_redirect"
      ],
      "properties": {
        "afterpay_clearpay_redirect": {
          "type": "object",
          "description": "For AfterpayClearpay redirect as PayLater Option",
          "properties": {
            "billing_email": {
              "type": "string",
              "description": "The billing email",
              "nullable": true
            },
            "billing_name": {
              "type": "string",
              "description": "The billing name",
              "nullable": true
            }
          }
        }
      }
    },
    {
      "type": "object",
      "required": [
        "pay_bright_redirect"
      ],
      "properties": {
        "pay_bright_redirect": {
          "type": "object",
          "description": "For PayBright Redirect as PayLater Option"
        }
      }
    },
    {
      "type": "object",
      "required": [
        "flexiti_redirect"
      ],
      "properties": {
        "flexiti_redirect": {
          "type": "object",
          "description": "For Flexiti Redirect as PayLater long term finance Option"
        }
      }
    },
    {
      "type": "object",
      "required": [
        "walley_redirect"
      ],
      "properties": {
        "walley_redirect": {
          "type": "object",
          "description": "For WalleyRedirect as PayLater Option"
        }
      }
    },
    {
      "type": "object",
      "required": [
        "alma_redirect"
      ],
      "properties": {
        "alma_redirect": {
          "type": "object",
          "description": "For Alma Redirection as PayLater Option"
        }
      }
    },
    {
      "type": "object",
      "required": [
        "atome_redirect"
      ],
      "properties": {
        "atome_redirect": {
          "type": "object"
        }
      }
    },
    {
      "type": "object",
      "required": [
        "breadpay_redirect"
      ],
      "properties": {
        "breadpay_redirect": {
          "type": "object"
        }
      }
    }
  ]
}


File: crates/diesel_models/src/routing_algorithm.rs
 Public functions: 1
 Public structs: 3

use common_utils::id_type;
use diesel::{Identifiable, Insertable, Queryable, Selectable};
use serde::{Deserialize, Serialize};

use crate::{enums, schema::routing_algorithm};

#[derive(Clone, Debug, Identifiable, Insertable, Queryable, Selectable, Serialize, Deserialize)]
#[diesel(table_name = routing_algorithm, primary_key(algorithm_id), check_for_backend(diesel::pg::Pg))]
pub struct RoutingAlgorithm {
    pub algorithm_id: id_type::RoutingId,
    pub profile_id: id_type::ProfileId,
    pub merchant_id: id_type::MerchantId,
    pub name: String,
    pub description: Option<String>,
    pub kind: enums::RoutingAlgorithmKind,
    pub algorithm_data: serde_json::Value,
    pub created_at: time::PrimitiveDateTime,
    pub modified_at: time::PrimitiveDateTime,
    pub algorithm_for: enums::TransactionType,
    pub decision_engine_routing_id: Option<String>,
}

pub struct RoutingAlgorithmMetadata {
    pub algorithm_id: id_type::RoutingId,
    pub name: String,
    pub description: Option<String>,
    pub kind: enums::RoutingAlgorithmKind,
    pub created_at: time::PrimitiveDateTime,
    pub modified_at: time::PrimitiveDateTime,
    pub algorithm_for: enums::TransactionType,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct RoutingProfileMetadata {
    pub profile_id: id_type::ProfileId,
    pub algorithm_id: id_type::RoutingId,
    pub name: String,
    pub description: Option<String>,
    pub kind: enums::RoutingAlgorithmKind,
    pub created_at: time::PrimitiveDateTime,
    pub modified_at: time::PrimitiveDateTime,
    pub algorithm_for: enums::TransactionType,
}

impl RoutingProfileMetadata {
    pub fn metadata_is_advanced_rule_for_payments(&self) -> bool {
        matches!(self.kind, enums::RoutingAlgorithmKind::Advanced)
            && matches!(self.algorithm_for, enums::TransactionType::Payment)
    }
}


pub struct IncrementalAuthorization;


pub struct PaymentMethodIntentConfirmInternal {
    pub id: id_type::GlobalPaymentMethodId,
    pub request: PaymentMethodIntentConfirm,
}


impl api::PaymentCapture for Worldpayxml {}

impl api::PaymentCapture for for Worldpayxml


OpenAPI Block Path: components.schemas.UpdateScoreResponse
{
  "type": "object",
  "required": [
    "message"
  ],
  "properties": {
    "message": {
      "type": "string"
    }
  }
}


pub fn get_wait_screen_metadata() -> CustomResult<Option<serde_json::Value>, errors::ConnectorError>
{
    let current_time = OffsetDateTime::now_utc().unix_timestamp_nanos();
    Ok(Some(serde_json::json!(WaitScreenData {
        display_from_timestamp: current_time,
        display_to_timestamp: Some(current_time + Duration::minutes(5).whole_nanoseconds()),
        poll_config: Some(PollConfig {
            delay_in_secs: 5,
            frequency: 5,
        }),
    })))
}


impl ConnectorValidation for Gpayments {
    //TODO: implement functions when support enabled
}

impl ConnectorValidation for for Gpayments


pub struct KafkaPaymentAttemptEvent<'a> {
    pub payment_id: &'a id_type::GlobalPaymentId,
    pub merchant_id: &'a id_type::MerchantId,
    pub attempt_id: &'a id_type::GlobalAttemptId,
    pub status: storage_enums::AttemptStatus,
    pub amount: MinorUnit,
    pub connector: Option<&'a String>,
    pub error_message: Option<&'a String>,
    pub surcharge_amount: Option<MinorUnit>,
    pub tax_amount: Option<MinorUnit>,
    pub payment_method_id: Option<&'a id_type::GlobalPaymentMethodId>,
    pub payment_method: storage_enums::PaymentMethod,
    pub connector_transaction_id: Option<&'a String>,
    pub authentication_type: storage_enums::AuthenticationType,
    #[serde(with = "time::serde::timestamp::nanoseconds")]
    pub created_at: OffsetDateTime,
    #[serde(with = "time::serde::timestamp::nanoseconds")]
    pub modified_at: OffsetDateTime,
    #[serde(default, with = "time::serde::timestamp::nanoseconds::option")]
    pub last_synced: Option<OffsetDateTime>,
    pub cancellation_reason: Option<&'a String>,
    pub amount_to_capture: Option<MinorUnit>,
    pub browser_info: Option<&'a types::BrowserInformation>,
    pub error_code: Option<&'a String>,
    pub connector_metadata: Option<String>,
    // TODO: These types should implement copy ideally
    pub payment_experience: Option<&'a storage_enums::PaymentExperience>,
    pub payment_method_type: &'a storage_enums::PaymentMethodType,
    pub payment_method_data: Option<String>,
    pub error_reason: Option<&'a String>,
    pub multiple_capture_count: Option<i16>,
    pub amount_capturable: MinorUnit,
    pub merchant_connector_id: Option<&'a id_type::MerchantConnectorAccountId>,
    pub net_amount: MinorUnit,
    pub unified_code: Option<&'a String>,
    pub unified_message: Option<&'a String>,
    pub client_source: Option<&'a String>,
    pub client_version: Option<&'a String>,
    pub profile_id: &'a id_type::ProfileId,
    pub organization_id: &'a id_type::OrganizationId,
    pub card_network: Option<String>,
    pub card_discovery: Option<String>,

    pub connector_payment_id: Option<types::ConnectorTransactionId>,
    pub payment_token: Option<String>,
    pub preprocessing_step_id: Option<String>,
    pub connector_response_reference_id: Option<String>,
    pub updated_by: &'a String,
    pub encoded_data: Option<&'a masking::Secret<String>>,
    pub external_three_ds_authentication_attempted: Option<bool>,
    pub authentication_connector: Option<String>,
    pub authentication_id: Option<String>,
    pub fingerprint_id: Option<String>,
    pub customer_acceptance: Option<&'a masking::Secret<payments::CustomerAcceptance>>,
    pub shipping_cost: Option<MinorUnit>,
    pub order_tax_amount: Option<MinorUnit>,
    pub charges: Option<payments::ConnectorChargeResponseData>,
    pub processor_merchant_id: &'a id_type::MerchantId,
    pub created_by: Option<&'a types::CreatedBy>,
    pub payment_method_type_v2: storage_enums::PaymentMethod,
    pub payment_method_subtype: storage_enums::PaymentMethodType,
    pub routing_result: Option<serde_json::Value>,
    pub authentication_applied: Option<common_enums::AuthenticationType>,
    pub external_reference_id: Option<String>,
    pub tax_on_surcharge: Option<MinorUnit>,
    pub payment_method_billing_address: Option<masking::Secret<&'a address::Address>>, // adjusted from Encryption
    pub redirection_data: Option<&'a RedirectForm>,
    pub connector_payment_data: Option<String>,
    pub connector_token_details: Option<&'a payment_attempt::ConnectorTokenDetails>,
    pub feature_metadata: Option<&'a PaymentAttemptFeatureMetadata>,
    pub network_advice_code: Option<String>,
    pub network_decline_code: Option<String>,
    pub network_error_message: Option<String>,
    pub connector_request_reference_id: Option<String>,
}


pub struct ApplePayHeader {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub application_data_hash: Option<Secret<String>>,
    pub ephemeral_public_key: Secret<String>,
    pub public_key_hash: Secret<String>,
    pub transaction_id: Secret<String>,
}


pub fn fetch_qr_code_url_next_steps_check(
    payment_attempt: storage::PaymentAttempt,
) -> RouterResult<Option<api_models::payments::FetchQrCodeInformation>> {
    let qr_code_steps: Option<Result<api_models::payments::FetchQrCodeInformation, _>> =
        payment_attempt
            .connector_metadata
            .map(|metadata| metadata.parse_value("FetchQrCodeInformation"));

    let qr_code_fetch_url = qr_code_steps.transpose().ok().flatten();
    Ok(qr_code_fetch_url)
}


pub struct AdyenAddress {
    line1: Secret<String>,
    line2: Secret<String>,
    postal_code: Option<Secret<String>>,
    state_or_province: Option<Secret<String>>,
    city: String,
    country: enums::CountryAlpha2,
}


pub struct MonerisAuthRequest {
    client_id: Secret<String>,
    client_secret: Secret<String>,
    grant_type: String,
}


OpenAPI Block Path: components.schemas.PaymentMethodUpdate
{
  "type": "object",
  "properties": {
    "card": {
      "allOf": [
        {
          "$ref": "#/components/schemas/CardDetailUpdate"
        }
      ],
      "nullable": true
    },
    "client_secret": {
      "type": "string",
      "description": "This is a 15 minute expiry token which shall be used from the client to authenticate and perform sessions from the SDK",
      "example": "secret_k2uj3he2893eiu2d",
      "nullable": true,
      "maxLength": 30,
      "minLength": 30
    }
  },
  "additionalProperties": false
}


pub struct DeutschebankThreeDSInitializeRequestAmountTotal {
    amount: MinorUnit,
    currency: api_models::enums::Currency,
}


File: crates/analytics/src/disputes/metrics/sessionized_metrics/dispute_status_metric.rs

use std::collections::HashSet;

use api_models::analytics::{
    disputes::{DisputeDimensions, DisputeFilters, DisputeMetricsBucketIdentifier},
    Granularity, TimeRange,
};
use common_utils::errors::ReportSwitchExt;
use error_stack::ResultExt;
use time::PrimitiveDateTime;

use super::DisputeMetricRow;
use crate::{
    enums::AuthInfo,
    query::{Aggregate, GroupByClause, QueryBuilder, QueryFilter, SeriesBucket, ToSql, Window},
    types::{AnalyticsCollection, AnalyticsDataSource, MetricsError, MetricsResult},
};
#[derive(Default)]
pub(crate) struct DisputeStatusMetric {}

#[async_trait::async_trait]
impl<T> super::DisputeMetric<T> for DisputeStatusMetric
where
    T: AnalyticsDataSource + super::DisputeMetricAnalytics,
    PrimitiveDateTime: ToSql<T>,
    AnalyticsCollection: ToSql<T>,
    Granularity: GroupByClause<T>,
    Aggregate<&'static str>: ToSql<T>,
    Window<&'static str>: ToSql<T>,
{
    async fn load_metrics(
        &self,
        dimensions: &[DisputeDimensions],
        auth: &AuthInfo,
        filters: &DisputeFilters,
        granularity: Option<Granularity>,
        time_range: &TimeRange,
        pool: &T,
    ) -> MetricsResult<HashSet<(DisputeMetricsBucketIdentifier, DisputeMetricRow)>>
    where
        T: AnalyticsDataSource + super::DisputeMetricAnalytics,
    {
        let mut query_builder = QueryBuilder::new(AnalyticsCollection::DisputeSessionized);

        for dim in dimensions {
            query_builder.add_select_column(dim).switch()?;
        }

        query_builder.add_select_column("dispute_status").switch()?;

        query_builder
            .add_select_column(Aggregate::Count {
                field: None,
                alias: Some("count"),
            })
            .switch()?;
        query_builder
            .add_select_column(Aggregate::Min {
                field: "created_at",
                alias: Some("start_bucket"),
            })
            .switch()?;
        query_builder
            .add_select_column(Aggregate::Max {
                field: "created_at",
                alias: Some("end_bucket"),
            })
            .switch()?;

        filters.set_filter_clause(&mut query_builder).switch()?;

        auth.set_filter_clause(&mut query_builder).switch()?;

        time_range.set_filter_clause(&mut query_builder).switch()?;

        for dim in dimensions {
            query_builder.add_group_by_clause(dim).switch()?;
        }

        query_builder
            .add_group_by_clause("dispute_status")
            .switch()?;

        if let Some(granularity) = granularity {
            granularity
                .set_group_by_clause(&mut query_builder)
                .switch()?;
        }

        query_builder
            .execute_query::<DisputeMetricRow, _>(pool)
            .await
            .change_context(MetricsError::QueryBuildingError)?
            .change_context(MetricsError::QueryExecutionFailure)?
            .into_iter()
            .map(|i| {
                Ok((
                    DisputeMetricsBucketIdentifier::new(
                        i.dispute_stage.as_ref().map(|i| i.0),
                        i.connector.clone(),
                        i.currency.as_ref().map(|i| i.0),
                        TimeRange {
                            start_time: match (granularity, i.start_bucket) {
                                (Some(g), Some(st)) => g.clip_to_start(st)?,
                                _ => time_range.start_time,
                            },
                            end_time: granularity.as_ref().map_or_else(
                                || Ok(time_range.end_time),
                                |g| i.end_bucket.map(|et| g.clip_to_end(et)).transpose(),
                            )?,
                        },
                    ),
                    i,
                ))
            })
            .collect::<error_stack::Result<
                HashSet<(DisputeMetricsBucketIdentifier, DisputeMetricRow)>,
                crate::query::PostProcessingError,
            >>()
            .change_context(MetricsError::PostProcessingFailure)
    }
}


pub fn generate_id(length: usize, prefix: &str) -> String {
    format!("{}_{}", prefix, nanoid!(length, &consts::ALPHABETS))
}


pub struct PaymentMethodIntentCreate {
    /// You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. Metadata is useful for storing additional, structured information on an object.
    #[schema(value_type = Option<Object>,example = json!({ "city": "NY", "unit": "245" }))]
    pub metadata: Option<pii::SecretSerdeValue>,

    /// The billing details of the payment method
    #[schema(value_type = Option<Address>)]
    pub billing: Option<payments::Address>,

    /// The unique identifier of the customer.
    #[schema(
        min_length = 32,
        max_length = 64,
        example = "12345_cus_01926c58bc6e77c09e809964e72af8c8",
        value_type = String
    )]
    pub customer_id: id_type::GlobalCustomerId,
}


pub async fn payments_operation_core<F, Req, Op, FData, D>(
    state: &SessionState,
    req_state: ReqState,
    merchant_context: domain::MerchantContext,
    profile: &domain::Profile,
    operation: Op,
    req: Req,
    get_tracker_response: operations::GetTrackerResponse<D>,
    call_connector_action: CallConnectorAction,
    header_payload: HeaderPayload,
) -> RouterResult<(
    D,
    Req,
    Option<domain::Customer>,
    Option<u16>,
    Option<u128>,
    common_types::domain::ConnectorResponseData,
)>
where
    F: Send + Clone + Sync,
    Req: Send + Sync + Authenticate,
    Op: Operation<F, Req, Data = D> + Send + Sync,
    D: OperationSessionGetters<F> + OperationSessionSetters<F> + Send + Sync + Clone,

    // To create connector flow specific interface data
    D: ConstructFlowSpecificData<F, FData, router_types::PaymentsResponseData>,
    RouterData<F, FData, router_types::PaymentsResponseData>: Feature<F, FData>,

    // To construct connector flow specific api
    dyn api::Connector:
        services::api::ConnectorIntegration<F, FData, router_types::PaymentsResponseData>,

    RouterData<F, FData, router_types::PaymentsResponseData>:
        hyperswitch_domain_models::router_data::TrackerPostUpdateObjects<F, FData, D>,

    // To perform router related operation for PaymentResponse
    PaymentResponse: Operation<F, FData, Data = D>,
    FData: Send + Sync + Clone,
{
    let operation: BoxedOperation<'_, F, Req, D> = Box::new(operation);

    // Get the trackers related to track the state of the payment
    let operations::GetTrackerResponse { mut payment_data } = get_tracker_response;

    operation
        .to_domain()?
        .create_or_fetch_payment_method(state, &merchant_context, profile, &mut payment_data)
        .await?;

    let (_operation, customer) = operation
        .to_domain()?
        .get_customer_details(
            state,
            &mut payment_data,
            merchant_context.get_merchant_key_store(),
            merchant_context.get_merchant_account().storage_scheme,
        )
        .await
        .to_not_found_response(errors::ApiErrorResponse::CustomerNotFound)
        .attach_printable("Failed while fetching/creating customer")?;

    operation
        .to_domain()?
        .run_decision_manager(state, &mut payment_data, profile)
        .await
        .change_context(errors::ApiErrorResponse::InternalServerError)
        .attach_printable("Failed to run decision manager")?;

    let connector = operation
        .to_domain()?
        .perform_routing(&merchant_context, profile, state, &mut payment_data)
        .await?;

    let mut connector_http_status_code = None;
    let (payment_data, connector_response_data) = match connector {
        ConnectorCallType::PreDetermined(connector_data) => {
            let (mca_type_details, updated_customer, router_data) =
                call_connector_service_prerequisites(
                    state,
                    req_state.clone(),
                    &merchant_context,
                    connector_data.connector_data.clone(),
                    &operation,
                    &mut payment_data,
                    &customer,
                    call_connector_action.clone(),
                    None,
                    header_payload.clone(),
                    None,
                    profile,
                    false,
                    false, //should_retry_with_pan is set to false in case of PreDetermined ConnectorCallType
                    req.should_return_raw_response(),
                )
                .await?;

            let router_data = decide_unified_connector_service_call(
                state,
                req_state.clone(),
                &merchant_context,
                connector_data.connector_data.clone(),
                &operation,
                &mut payment_data,
                &customer,
                call_connector_action.clone(),
                None, // schedule_time is not used in PreDetermined ConnectorCallType
                header_payload.clone(),
                #[cfg(feature = "frm")]
                None,
                profile,
                false,
                false, //should_retry_with_pan is set to false in case of PreDetermined ConnectorCallType
                req.should_return_raw_response(),
                mca_type_details,
                router_data,
                updated_customer,
            )
            .await?;

            let connector_response_data = common_types::domain::ConnectorResponseData {
                raw_connector_response: router_data.raw_connector_response.clone(),
            };

            let payments_response_operation = Box::new(PaymentResponse);

            connector_http_status_code = router_data.connector_http_status_code;
            add_connector_http_status_code_metrics(connector_http_status_code);

            payments_response_operation
                .to_post_update_tracker()?
                .save_pm_and_mandate(
                    state,
                    &router_data,
                    &merchant_context,
                    &mut payment_data,
                    profile,
                )
                .await?;

            let payment_data = payments_response_operation
                .to_post_update_tracker()?
                .update_tracker(
                    state,
                    payment_data,
                    router_data,
                    merchant_context.get_merchant_key_store(),
                    merchant_context.get_merchant_account().storage_scheme,
                )
                .await?;

            (payment_data, connector_response_data)
        }
        ConnectorCallType::Retryable(connectors) => {
            let mut connectors = connectors.clone().into_iter();
            let connector_data = get_connector_data(&mut connectors)?;

            let (mca_type_details, updated_customer, router_data) =
                call_connector_service_prerequisites(
                    state,
                    req_state.clone(),
                    &merchant_context,
                    connector_data.connector_data.clone(),
                    &operation,
                    &mut payment_data,
                    &customer,
                    call_connector_action.clone(),
                    None,
                    header_payload.clone(),
                    None,
                    profile,
                    false,
                    false, //should_retry_with_pan is set to false in case of Retryable ConnectorCallType
                    req.should_return_raw_response(),
                )
                .await?;

            let router_data = decide_unified_connector_service_call(
                state,
                req_state.clone(),
                &merchant_context,
                connector_data.connector_data.clone(),
                &operation,
                &mut payment_data,
                &customer,
                call_connector_action.clone(),
                None, // schedule_time is not used in Retryable ConnectorCallType
                header_payload.clone(),
                #[cfg(feature = "frm")]
                None,
                profile,
                true,
                false, //should_retry_with_pan is set to false in case of PreDetermined ConnectorCallType
                req.should_return_raw_response(),
                mca_type_details,
                router_data,
                updated_customer,
            )
            .await?;

            let connector_response_data = common_types::domain::ConnectorResponseData {
                raw_connector_response: router_data.raw_connector_response.clone(),
            };

            let payments_response_operation = Box::new(PaymentResponse);

            connector_http_status_code = router_data.connector_http_status_code;
            add_connector_http_status_code_metrics(connector_http_status_code);

            payments_response_operation
                .to_post_update_tracker()?
                .save_pm_and_mandate(
                    state,
                    &router_data,
                    &merchant_context,
                    &mut payment_data,
                    profile,
                )
                .await?;

            let payment_data = payments_response_operation
                .to_post_update_tracker()?
                .update_tracker(
                    state,
                    payment_data,
                    router_data,
                    merchant_context.get_merchant_key_store(),
                    merchant_context.get_merchant_account().storage_scheme,
                )
                .await?;

            (payment_data, connector_response_data)
        }
        ConnectorCallType::SessionMultiple(vec) => todo!(),
        ConnectorCallType::Skip => (
            payment_data,
            common_types::domain::ConnectorResponseData {
                raw_connector_response: None,
            },
        ),
    };

    let payment_intent_status = payment_data.get_payment_intent().status;

    // Delete the tokens after payment
    payment_data
        .get_payment_attempt()
        .payment_token
        .as_ref()
        .zip(Some(payment_data.get_payment_attempt().payment_method_type))
        .map(ParentPaymentMethodToken::return_key_for_token)
        .async_map(|key_for_token| async move {
            let _ = vault::delete_payment_token(state, &key_for_token, payment_intent_status)
                .await
                .inspect_err(|err| logger::error!("Failed to delete payment_token: {:?}", err));
        })
        .await;

    Ok((
        payment_data,
        req,
        customer,
        connector_http_status_code,
        None,
        connector_response_data,
    ))
}


impl MandateSetup for Checkout {}


pub async fn create_gsm_rule() {}


pub struct FiuuSyncStatus {
    pub stat_name: StatName,
    pub stat_code: StatCode,
}


impl ConnectorValidation for Paybox {
    fn validate_mandate_payment(
        &self,
        pm_type: Option<enums::PaymentMethodType>,
        pm_data: PaymentMethodData,
    ) -> CustomResult<(), errors::ConnectorError> {
        let mandate_supported_pmd = std::collections::HashSet::from([PaymentMethodDataType::Card]);
        is_mandate_supported(pm_data, pm_type, mandate_supported_pmd, self.id())
    }
}


pub struct ConfiguredRouting {
    pub routing_id: String,
}


impl Responder {
        let index = index.into_inner();
        let flow = AnalyticsFlow::GetSearchResults;
        let indexed_req = GetSearchRequestWithIndex {
            search_req: json_payload.into_inner(),
            index,
        };
        Box::pin(api::server_wrap(
            flow,
            state.clone(),
            &req,
            indexed_req,
            |state, auth: UserFromToken, req, _| async move {
                let role_id = auth.role_id;
                let role_info = RoleInfo::from_role_id_org_id_tenant_id(
                    &state,
                    &role_id,
                    &auth.org_id,
                    auth.tenant_id.as_ref().unwrap_or(&state.tenant.tenant_id),
                )
                .await
                .change_context(UserErrors::InternalServerError)
                .change_context(OpenSearchError::UnknownError)?;
                let permission_groups = role_info.get_permission_groups();
                if !permission_groups.contains(&common_enums::PermissionGroup::OperationsView) {
                    return Err(OpenSearchError::AccessForbiddenError)?;
                }
                let user_roles: HashSet<UserRole> = match role_info.get_entity_type() {
                    EntityType::Tenant => state
                        .global_store
                        .list_user_roles_by_user_id(ListUserRolesByUserIdPayload {
                            user_id: &auth.user_id,
                            tenant_id: auth.tenant_id.as_ref().unwrap_or(&state.tenant.tenant_id),
                            org_id: None,
                            merchant_id: None,
                            profile_id: None,
                            entity_id: None,
                            version: None,
                            status: None,
                            limit: None,
                        })
                        .await
                        .change_context(UserErrors::InternalServerError)
                        .change_context(OpenSearchError::UnknownError)?
                        .into_iter()
                        .collect(),
                    EntityType::Organization | EntityType::Merchant | EntityType::Profile => state
                        .global_store
                        .list_user_roles_by_user_id(ListUserRolesByUserIdPayload {
                            user_id: &auth.user_id,
                            tenant_id: auth.tenant_id.as_ref().unwrap_or(&state.tenant.tenant_id),
                            org_id: Some(&auth.org_id),
                            merchant_id: None,
                            profile_id: None,
                            entity_id: None,
                            version: None,
                            status: None,
                            limit: None,
                        })
                        .await
                        .change_context(UserErrors::InternalServerError)
                        .change_context(OpenSearchError::UnknownError)?
                        .into_iter()
                        .collect(),
                };
                let state = Arc::new(state);
                let role_info_map: HashMap<String, RoleInfo> = user_roles
                    .iter()
                    .map(|user_role| {
                        let state = Arc::clone(&state);
                        let role_id = user_role.role_id.clone();
                        let org_id = user_role.org_id.clone().unwrap_or_default();
                        let tenant_id = &user_role.tenant_id;
                        async move {
                            RoleInfo::from_role_id_org_id_tenant_id(
                                &state, &role_id, &org_id, tenant_id,
                            )
                            .await
                            .change_context(UserErrors::InternalServerError)
                            .change_context(OpenSearchError::UnknownError)
                            .map(|role_info| (role_id, role_info))
                        }
                    })
                    .collect::<FuturesUnordered<_>>()
                    .collect::<Vec<_>>()
                    .await
                    .into_iter()
                    .collect::<Result<HashMap<_, _>, _>>()?;

                let filtered_user_roles: Vec<&UserRole> = user_roles
                    .iter()
                    .filter(|user_role| {
                        let user_role_id = &user_role.role_id;
                        if let Some(role_info) = role_info_map.get(user_role_id) {
                            let permissions = role_info.get_permission_groups();
                            permissions.contains(&common_enums::PermissionGroup::OperationsView)
                        } else {
                            false
                        }
                    })
                    .collect();

                let search_params: Vec<AuthInfo> = filtered_user_roles
                    .iter()
                    .filter_map(|user_role| {
                        user_role
                            .get_entity_id_and_type()
                            .and_then(|(_, entity_type)| match entity_type {
                                EntityType::Profile => Some(AuthInfo::ProfileLevel {
                                    org_id: user_role.org_id.clone()?,
                                    merchant_id: user_role.merchant_id.clone()?,
                                    profile_ids: vec![user_role.profile_id.clone()?],
                                }),
                                EntityType::Merchant => Some(AuthInfo::MerchantLevel {
                                    org_id: user_role.org_id.clone()?,
                                    merchant_ids: vec![user_role.merchant_id.clone()?],
                                }),
                                EntityType::Organization => Some(AuthInfo::OrgLevel {
                                    org_id: user_role.org_id.clone()?,
                                }),
                                EntityType::Tenant => Some(AuthInfo::OrgLevel {
                                    org_id: auth.org_id.clone(),
                                }),
                            })
                    })
                    .collect();
                analytics::search::search_results(
                    state
                        .opensearch_client
                        .as_ref()
                        .ok_or_else(|| error_stack::report!(OpenSearchError::NotEnabled))?,
                    req,
                    search_params,
                )
                .await
                .map(ApplicationResponse::Json)
            },
            &auth::JWTAuth {
                permission: Permission::ProfileAnalyticsRead,
            },
            api_locking::LockAction::NotApplicable,
        ))
        .await
    }


pub struct Sale;


File: crates/router/src/core/user_role/role.rs
 Public functions: 9

use std::{cmp, collections::HashSet};

use api_models::user_role::role as role_api;
use common_enums::{EntityType, ParentGroup, PermissionGroup};
use common_utils::generate_id_with_default_len;
use diesel_models::role::{ListRolesByEntityPayload, RoleNew, RoleUpdate};
use error_stack::{report, ResultExt};

use crate::{
    core::errors::{StorageErrorExt, UserErrors, UserResponse},
    routes::{app::ReqState, SessionState},
    services::{
        authentication::{blacklist, UserFromToken},
        authorization::{
            permission_groups::{ParentGroupExt, PermissionGroupExt},
            roles::{self, predefined_roles::PREDEFINED_ROLES},
        },
        ApplicationResponse,
    },
    types::domain::user::RoleName,
    utils,
};

pub async fn get_role_from_token_with_groups(
    state: SessionState,
    user_from_token: UserFromToken,
) -> UserResponse<Vec<PermissionGroup>> {
    let role_info = user_from_token
        .get_role_info_from_db(&state)
        .await
        .attach_printable("Invalid role_id in JWT")?;

    let permissions = role_info.get_permission_groups().to_vec();

    Ok(ApplicationResponse::Json(permissions))
}

pub async fn get_groups_and_resources_for_role_from_token(
    state: SessionState,
    user_from_token: UserFromToken,
) -> UserResponse<role_api::GroupsAndResources> {
    let role_info = user_from_token.get_role_info_from_db(&state).await?;

    let groups = role_info
        .get_permission_groups()
        .into_iter()
        .collect::<Vec<_>>();
    let resources = groups
        .iter()
        .flat_map(|group| group.resources())
        .collect::<HashSet<_>>()
        .into_iter()
        .collect();

    Ok(ApplicationResponse::Json(role_api::GroupsAndResources {
        groups,
        resources,
    }))
}

pub async fn create_role(
    state: SessionState,
    user_from_token: UserFromToken,
    req: role_api::CreateRoleRequest,
    _req_state: ReqState,
) -> UserResponse<role_api::RoleInfoWithGroupsResponse> {
    let now = common_utils::date_time::now();

    let user_entity_type = user_from_token
        .get_role_info_from_db(&state)
        .await
        .attach_printable("Invalid role_id in JWT")?
        .get_entity_type();

    let role_entity_type = req.entity_type.unwrap_or(EntityType::Merchant);

    if matches!(role_entity_type, EntityType::Organization) {
        return Err(report!(UserErrors::InvalidRoleOperation))
            .attach_printable("User trying to create org level custom role");
    }
    let requestor_entity_from_role_scope = EntityType::from(req.role_scope);

    if requestor_entity_from_role_scope < role_entity_type {
        return Err(report!(UserErrors::InvalidRoleOperation)).attach_printable(format!(
            "User is trying to create role of type {role_entity_type} and scope {requestor_entity_from_role_scope}",

        ));
    }
    let max_from_scope_and_entity = cmp::max(requestor_entity_from_role_scope, role_entity_type);

    if user_entity_type < max_from_scope_and_entity {
        return Err(report!(UserErrors::InvalidRoleOperation)).attach_printable(format!(
            "{user_entity_type} is trying to create of scope {requestor_entity_from_role_scope} and of type {role_entity_type}",

        ));
    }

    let role_name = RoleName::new(req.role_name)?;

    utils::user_role::validate_role_groups(&req.groups)?;
    utils::user_role::validate_role_name(
        &state,
        &role_name,
        &user_from_token.merchant_id,
        &user_from_token.org_id,
        user_from_token
            .tenant_id
            .as_ref()
            .unwrap_or(&state.tenant.tenant_id),
        &user_from_token.profile_id,
        &role_entity_type,
    )
    .await?;

    let (org_id, merchant_id, profile_id) = match role_entity_type {
        EntityType::Organization | EntityType::Tenant => (user_from_token.org_id, None, None),
        EntityType::Merchant => (
            user_from_token.org_id,
            Some(user_from_token.merchant_id),
            None,
        ),
        EntityType::Profile => (
            user_from_token.org_id,
            Some(user_from_token.merchant_id),
            Some(user_from_token.profile_id),
        ),
    };

    let role = state
        .global_store
        .insert_role(RoleNew {
            role_id: generate_id_with_default_len("role"),
            role_name: role_name.get_role_name(),
            merchant_id,
            org_id,
            groups: req.groups,
            scope: req.role_scope,
            entity_type: role_entity_type,
            created_by: user_from_token.user_id.clone(),
            last_modified_by: user_from_token.user_id,
            created_at: now,
            last_modified_at: now,
            profile_id,
            tenant_id: user_from_token.tenant_id.unwrap_or(state.tenant.tenant_id),
        })
        .await
        .to_duplicate_response(UserErrors::RoleNameAlreadyExists)?;

    Ok(ApplicationResponse::Json(
        role_api::RoleInfoWithGroupsResponse {
            groups: role.groups,
            role_id: role.role_id,
            role_name: role.role_name,
            role_scope: role.scope,
            entity_type: role.entity_type,
        },
    ))
}

pub async fn create_role_v2(
    state: SessionState,
    user_from_token: UserFromToken,
    req: role_api::CreateRoleV2Request,
    _req_state: ReqState,
) -> UserResponse<role_api::RoleInfoResponseWithParentsGroup> {
    let now = common_utils::date_time::now();

    let user_entity_type = user_from_token
        .get_role_info_from_db(&state)
        .await
        .attach_printable("Invalid role_id in JWT")?
        .get_entity_type();

    let role_entity_type = req.entity_type.unwrap_or(EntityType::Merchant);

    if matches!(role_entity_type, EntityType::Organization) {
        return Err(report!(UserErrors::InvalidRoleOperation))
            .attach_printable("User trying to create org level custom role");
    }

    let requestor_entity_from_role_scope = EntityType::from(req.role_scope);

    if requestor_entity_from_role_scope < role_entity_type {
        return Err(report!(UserErrors::InvalidRoleOperation)).attach_printable(format!(
            "User is trying to create role of type {role_entity_type} and scope {requestor_entity_from_role_scope}",
        ));
    }

    let max_from_scope_and_entity = cmp::max(requestor_entity_from_role_scope, role_entity_type);

    if user_entity_type < max_from_scope_and_entity {
        return Err(report!(UserErrors::InvalidRoleOperation)).attach_printable(format!(
            "{user_entity_type} is trying to create of scope {requestor_entity_from_role_scope} and of type {role_entity_type}",
        ));
    }

    let role_name = RoleName::new(req.role_name.clone())?;

    let permission_groups =
        utils::user_role::parent_group_info_request_to_permission_groups(&req.parent_groups)?;

    utils::user_role::validate_role_groups(&permission_groups)?;
    utils::user_role::validate_role_name(
        &state,
        &role_name,
        &user_from_token.merchant_id,
        &user_from_token.org_id,
        user_from_token
            .tenant_id
            .as_ref()
            .unwrap_or(&state.tenant.tenant_id),
        &user_from_token.profile_id,
        &role_entity_type,
    )
    .await?;

    let (org_id, merchant_id, profile_id) = match role_entity_type {
        EntityType::Organization | EntityType::Tenant => (user_from_token.org_id, None, None),
        EntityType::Merchant => (
            user_from_token.org_id,
            Some(user_from_token.merchant_id),
            None,
        ),
        EntityType::Profile => (
            user_from_token.org_id,
            Some(user_from_token.merchant_id),
            Some(user_from_token.profile_id),
        ),
    };

    let role = state
        .global_store
        .insert_role(RoleNew {
            role_id: generate_id_with_default_len("role"),
            role_name: role_name.get_role_name(),
            merchant_id,
            org_id,
            groups: permission_groups,
            scope: req.role_scope,
            entity_type: role_entity_type,
            created_by: user_from_token.user_id.clone(),
            last_modified_by: user_from_token.user_id,
            created_at: now,
            last_modified_at: now,
            profile_id,
            tenant_id: user_from_token.tenant_id.unwrap_or(state.tenant.tenant_id),
        })
        .await
        .to_duplicate_response(UserErrors::RoleNameAlreadyExists)?;

    let response_parent_groups =
        utils::user_role::permission_groups_to_parent_group_info(&role.groups, role.entity_type);

    Ok(ApplicationResponse::Json(
        role_api::RoleInfoResponseWithParentsGroup {
            role_id: role.role_id,
            role_name: role.role_name,
            role_scope: role.scope,
            entity_type: role.entity_type,
            parent_groups: response_parent_groups,
        },
    ))
}

pub async fn get_role_with_groups(
    state: SessionState,
    user_from_token: UserFromToken,
    role: role_api::GetRoleRequest,
) -> UserResponse<role_api::RoleInfoWithGroupsResponse> {
    let role_info = roles::RoleInfo::from_role_id_org_id_tenant_id(
        &state,
        &role.role_id,
        &user_from_token.org_id,
        user_from_token
            .tenant_id
            .as_ref()
            .unwrap_or(&state.tenant.tenant_id),
    )
    .await
    .to_not_found_response(UserErrors::InvalidRoleId)?;

    if role_info.is_internal() {
        return Err(UserErrors::InvalidRoleId.into());
    }

    Ok(ApplicationResponse::Json(
        role_api::RoleInfoWithGroupsResponse {
            groups: role_info.get_permission_groups().to_vec(),
            role_id: role.role_id,
            role_name: role_info.get_role_name().to_string(),
            role_scope: role_info.get_scope(),
            entity_type: role_info.get_entity_type(),
        },
    ))
}

pub async fn get_parent_info_for_role(
    state: SessionState,
    user_from_token: UserFromToken,
    role: role_api::GetRoleRequest,
) -> UserResponse<role_api::RoleInfoWithParents> {
    let role_info = roles::RoleInfo::from_role_id_org_id_tenant_id(
        &state,
        &role.role_id,
        &user_from_token.org_id,
        user_from_token
            .tenant_id
            .as_ref()
            .unwrap_or(&state.tenant.tenant_id),
    )
    .await
    .to_not_found_response(UserErrors::InvalidRoleId)?;

    if role_info.is_internal() {
        return Err(UserErrors::InvalidRoleId.into());
    }

    let parent_groups = ParentGroup::get_descriptions_for_groups(
        role_info.get_entity_type(),
        role_info.get_permission_groups().to_vec(),
    )
    .ok_or(UserErrors::InternalServerError)
    .attach_printable(format!(
        "No group descriptions found for role_id: {}",
        role.role_id
    ))?
    .into_iter()
    .map(|(parent_group, description)| role_api::ParentGroupInfo {
        name: parent_group.clone(),
        description,
        scopes: role_info
            .get_permission_groups()
            .iter()
            .filter_map(|group| (group.parent() == parent_group).then_some(group.scope()))
            // TODO: Remove this hashset conversion when merchant access
            // and organization access groups are removed
            .collect::<HashSet<_>>()
            .into_iter()
            .collect(),
    })
    .collect();

    Ok(ApplicationResponse::Json(role_api::RoleInfoWithParents {
        role_id: role.role_id,
        parent_groups,
        role_name: role_info.get_role_name().to_string(),
        role_scope: role_info.get_scope(),
    }))
}

pub async fn update_role(
    state: SessionState,
    user_from_token: UserFromToken,
    req: role_api::UpdateRoleRequest,
    role_id: &str,
) -> UserResponse<role_api::RoleInfoWithGroupsResponse> {
    let role_name = req.role_name.map(RoleName::new).transpose()?;

    let role_info = roles::RoleInfo::from_role_id_in_lineage(
        &state,
        role_id,
        &user_from_token.merchant_id,
        &user_from_token.org_id,
        &user_from_token.profile_id,
        user_from_token
            .tenant_id
            .as_ref()
            .unwrap_or(&state.tenant.tenant_id),
    )
    .await
    .to_not_found_response(UserErrors::InvalidRoleOperation)?;

    let user_role_info = user_from_token.get_role_info_from_db(&state).await?;

    let requested_entity_from_role_scope = EntityType::from(role_info.get_scope());
    let requested_role_entity_type = role_info.get_entity_type();
    let max_from_scope_and_entity =
        cmp::max(requested_entity_from_role_scope, requested_role_entity_type);

    if user_role_info.get_entity_type() < max_from_scope_and_entity {
        return Err(report!(UserErrors::InvalidRoleOperation)).attach_printable(format!(
            "{} is trying to update of scope {} and of type {}",
            user_role_info.get_entity_type(),
            requested_entity_from_role_scope,
            requested_role_entity_type
        ));
    }

    if let Some(ref role_name) = role_name {
        utils::user_role::validate_role_name(
            &state,
            role_name,
            &user_from_token.merchant_id,
            &user_from_token.org_id,
            user_from_token
                .tenant_id
                .as_ref()
                .unwrap_or(&state.tenant.tenant_id),
            &user_from_token.profile_id,
            &role_info.get_entity_type(),
        )
        .await?;
    }

    if let Some(ref groups) = req.groups {
        utils::user_role::validate_role_groups(groups)?;
    }

    let updated_role = state
        .global_store
        .update_role_by_role_id(
            role_id,
            RoleUpdate::UpdateDetails {
                groups: req.groups,
                role_name: role_name.map(RoleName::get_role_name),
                last_modified_at: common_utils::date_time::now(),
                last_modified_by: user_from_token.user_id,
            },
        )
        .await
        .to_duplicate_response(UserErrors::RoleNameAlreadyExists)?;

    blacklist::insert_role_in_blacklist(&state, role_id).await?;

    Ok(ApplicationResponse::Json(
        role_api::RoleInfoWithGroupsResponse {
            groups: updated_role.groups,
            role_id: updated_role.role_id,
            role_name: updated_role.role_name,
            role_scope: updated_role.scope,
            entity_type: updated_role.entity_type,
        },
    ))
}

pub async fn list_roles_with_info(
    state: SessionState,
    user_from_token: UserFromToken,
    request: role_api::ListRolesQueryParams,
) -> UserResponse<role_api::ListRolesResponse> {
    let user_role_info = user_from_token
        .get_role_info_from_db(&state)
        .await
        .attach_printable("Invalid role_id in JWT")?;

    if user_role_info.is_internal() {
        return Err(UserErrors::InvalidRoleOperationWithMessage(
            "Internal roles are not allowed for this operation".to_string(),
        )
        .into());
    }

    let mut role_info_vec = PREDEFINED_ROLES.values().cloned().collect::<Vec<_>>();

    let user_role_entity = user_role_info.get_entity_type();
    let is_lineage_data_required = request.entity_type.is_none();
    let tenant_id = user_from_token
        .tenant_id
        .as_ref()
        .unwrap_or(&state.tenant.tenant_id)
        .to_owned();
    let custom_roles =
        match utils::user_role::get_min_entity(user_role_entity, request.entity_type)? {
            EntityType::Tenant | EntityType::Organization => state
                .global_store
                .generic_list_roles_by_entity_type(
                    ListRolesByEntityPayload::Organization,
                    is_lineage_data_required,
                    tenant_id,
                    user_from_token.org_id,
                )
                .await
                .change_context(UserErrors::InternalServerError)
                .attach_printable("Failed to get roles")?,
            EntityType::Merchant => state
                .global_store
                .generic_list_roles_by_entity_type(
                    ListRolesByEntityPayload::Merchant(user_from_token.merchant_id),
                    is_lineage_data_required,
                    tenant_id,
                    user_from_token.org_id,
                )
                .await
                .change_context(UserErrors::InternalServerError)
                .attach_printable("Failed to get roles")?,

            EntityType::Profile => state
                .global_store
                .generic_list_roles_by_entity_type(
                    ListRolesByEntityPayload::Profile(
                        user_from_token.merchant_id,
                        user_from_token.profile_id,
                    ),
                    is_lineage_data_required,
                    tenant_id,
                    user_from_token.org_id,
                )
                .await
                .change_context(UserErrors::InternalServerError)
                .attach_printable("Failed to get roles")?,
        };

    role_info_vec.extend(custom_roles.into_iter().map(roles::RoleInfo::from));

    if request.groups == Some(true) {
        let list_role_info_response = role_info_vec
            .into_iter()
            .filter_map(|role_info| {
                let is_lower_entity = user_role_entity >= role_info.get_entity_type();
                let request_filter = request.entity_type.map_or(true, |entity_type| {
                    entity_type == role_info.get_entity_type()
                });

                (is_lower_entity && request_filter).then_some({
                    let permission_groups = role_info.get_permission_groups();
                    let parent_groups = utils::user_role::permission_groups_to_parent_group_info(
                        &permission_groups,
                        role_info.get_entity_type(),
                    );

                    role_api::RoleInfoResponseWithParentsGroup {
                        role_id: role_info.get_role_id().to_string(),
                        role_name: role_info.get_role_name().to_string(),
                        entity_type: role_info.get_entity_type(),
                        parent_groups,
                        role_scope: role_info.get_scope(),
                    }
                })
            })
            .collect::<Vec<_>>();

        Ok(ApplicationResponse::Json(
            role_api::ListRolesResponse::WithParentGroups(list_role_info_response),
        ))
    }
    // TODO: To be deprecated
    else {
        let list_role_info_response = role_info_vec
            .into_iter()
            .filter_map(|role_info| {
                let is_lower_entity = user_role_entity >= role_info.get_entity_type();
                let request_filter = request.entity_type.map_or(true, |entity_type| {
                    entity_type == role_info.get_entity_type()
                });

                (is_lower_entity && request_filter).then_some(role_api::RoleInfoResponseNew {
                    role_id: role_info.get_role_id().to_string(),
                    role_name: role_info.get_role_name().to_string(),
                    groups: role_info.get_permission_groups().to_vec(),
                    entity_type: role_info.get_entity_type(),
                    scope: role_info.get_scope(),
                })
            })
            .collect::<Vec<_>>();

        Ok(ApplicationResponse::Json(
            role_api::ListRolesResponse::WithGroups(list_role_info_response),
        ))
    }
}

pub async fn list_roles_at_entity_level(
    state: SessionState,
    user_from_token: UserFromToken,
    req: role_api::ListRolesAtEntityLevelRequest,
    check_type: role_api::RoleCheckType,
) -> UserResponse<Vec<role_api::MinimalRoleInfo>> {
    let user_entity_type = user_from_token
        .get_role_info_from_db(&state)
        .await
        .attach_printable("Invalid role_id in JWT")?
        .get_entity_type();

    if req.entity_type > user_entity_type {
        return Err(UserErrors::InvalidRoleOperationWithMessage(
            "User is attempting to request list roles above the current entity level".to_string(),
        )
        .into());
    }
    let mut role_info_vec = PREDEFINED_ROLES.values().cloned().collect::<Vec<_>>();

    let tenant_id = user_from_token
        .tenant_id
        .as_ref()
        .unwrap_or(&state.tenant.tenant_id)
        .to_owned();

    let is_lineage_data_required = false;
    let custom_roles = match req.entity_type {
        EntityType::Tenant | EntityType::Organization => state
            .global_store
            .generic_list_roles_by_entity_type(
                ListRolesByEntityPayload::Organization,
                is_lineage_data_required,
                tenant_id,
                user_from_token.org_id,
            )
            .await
            .change_context(UserErrors::InternalServerError)
            .attach_printable("Failed to get roles")?,

        EntityType::Merchant => state
            .global_store
            .generic_list_roles_by_entity_type(
                ListRolesByEntityPayload::Merchant(user_from_token.merchant_id),
                is_lineage_data_required,
                tenant_id,
                user_from_token.org_id,
            )
            .await
            .change_context(UserErrors::InternalServerError)
            .attach_printable("Failed to get roles")?,

        EntityType::Profile => state
            .global_store
            .generic_list_roles_by_entity_type(
                ListRolesByEntityPayload::Profile(
                    user_from_token.merchant_id,
                    user_from_token.profile_id,
                ),
                is_lineage_data_required,
                tenant_id,
                user_from_token.org_id,
            )
            .await
            .change_context(UserErrors::InternalServerError)
            .attach_printable("Failed to get roles")?,
    };

    role_info_vec.extend(custom_roles.into_iter().map(roles::RoleInfo::from));

    let list_minimal_role_info = role_info_vec
        .into_iter()
        .filter_map(|role_info| {
            let check_type = match check_type {
                role_api::RoleCheckType::Invite => role_info.is_invitable(),
                role_api::RoleCheckType::Update => role_info.is_updatable(),
            };
            if check_type && role_info.get_entity_type() == req.entity_type {
                Some(role_api::MinimalRoleInfo {
                    role_id: role_info.get_role_id().to_string(),
                    role_name: role_info.get_role_name().to_string(),
                })
            } else {
                None
            }
        })
        .collect::<Vec<_>>();

    Ok(ApplicationResponse::Json(list_minimal_role_info))
}


OpenAPI Block Path: components.schemas.GooglePayAssuranceDetails
{
  "type": "object",
  "required": [
    "card_holder_authenticated",
    "account_verified"
  ],
  "properties": {
    "card_holder_authenticated": {
      "type": "boolean",
      "description": "indicates that Cardholder possession validation has been performed"
    },
    "account_verified": {
      "type": "boolean",
      "description": "indicates that identification and verifications (ID&V) was performed"
    }
  }
}


pub fn get_connector_params(
        &self,
        connector: connector_enums::Connector,
    ) -> CustomResult<ConnectorParams, api_error_response::ApiErrorResponse> {
        match connector {
            connector_enums::Connector::Recurly => Ok(self.recurly.clone()),
            connector_enums::Connector::Stripebilling => Ok(self.stripebilling.clone()),
            connector_enums::Connector::Chargebee => Ok(self.chargebee.clone()),
            _ => Err(api_error_response::ApiErrorResponse::IncorrectConnectorNameGiven.into()),
        }
    }


impl webhooks::IncomingWebhook for Vgs {
    fn get_webhook_object_reference_id(
        &self,
        _request: &webhooks::IncomingWebhookRequestDetails<'_>,
    ) -> CustomResult<api_models::webhooks::ObjectReferenceId, errors::ConnectorError> {
        Err(report!(errors::ConnectorError::WebhooksNotImplemented))
    }

    fn get_webhook_event_type(
        &self,
        _request: &webhooks::IncomingWebhookRequestDetails<'_>,
    ) -> CustomResult<api_models::webhooks::IncomingWebhookEvent, errors::ConnectorError> {
        Err(report!(errors::ConnectorError::WebhooksNotImplemented))
    }

    fn get_webhook_resource_object(
        &self,
        _request: &webhooks::IncomingWebhookRequestDetails<'_>,
    ) -> CustomResult<Box<dyn masking::ErasedMaskSerialize>, errors::ConnectorError> {
        Err(report!(errors::ConnectorError::WebhooksNotImplemented))
    }
}

impl webhooks::IncomingWebhook for for Vgs


Documentation: api-reference/v1/payments/payments--incremental-authorization.mdx
# Type: Doc File

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


File: crates/hyperswitch_connectors/src/constants.rs

/// Header Constants
pub(crate) mod headers {
    pub(crate) const ACCEPT: &str = "Accept";
    pub(crate) const API_KEY: &str = "API-KEY";
    pub(crate) const APIKEY: &str = "apikey";
    pub(crate) const API_TOKEN: &str = "Api-Token";
    pub(crate) const AUTHORIZATION: &str = "Authorization";
    pub(crate) const CONTENT_TYPE: &str = "Content-Type";
    pub(crate) const DATE: &str = "Date";
    pub(crate) const IDEMPOTENCY_KEY: &str = "Idempotency-Key";
    pub(crate) const MESSAGE_SIGNATURE: &str = "Message-Signature";
    pub(crate) const MERCHANT_ID: &str = "Merchant-ID";
    pub(crate) const REQUEST_ID: &str = "request-id";
    pub(crate) const NONCE: &str = "nonce";
    pub(crate) const TIMESTAMP: &str = "Timestamp";
    pub(crate) const TOKEN: &str = "token";
    pub(crate) const X_ACCEPT_VERSION: &str = "X-Accept-Version";
    pub(crate) const X_CC_API_KEY: &str = "X-CC-Api-Key";
    pub(crate) const X_CC_VERSION: &str = "X-CC-Version";
    pub(crate) const X_DATE: &str = "X-Date";
    pub(crate) const X_LOGIN: &str = "X-Login";
    pub(crate) const X_NN_ACCESS_KEY: &str = "X-NN-Access-Key";
    pub(crate) const X_TRANS_KEY: &str = "X-Trans-Key";
    pub(crate) const X_RANDOM_VALUE: &str = "X-RandomValue";
    pub(crate) const X_REQUEST_DATE: &str = "X-RequestDate";
    pub(crate) const X_VERSION: &str = "X-Version";
    pub(crate) const X_API_KEY: &str = "X-Api-Key";
    pub(crate) const CORRELATION_ID: &str = "Correlation-Id";
    pub(crate) const WP_API_VERSION: &str = "WP-Api-Version";
    pub(crate) const STRIPE_COMPATIBLE_CONNECT_ACCOUNT: &str = "Stripe-Account";
    pub(crate) const SOURCE: &str = "Source";
    pub(crate) const USER_AGENT: &str = "User-Agent";
    pub(crate) const KEY: &str = "key";
    pub(crate) const X_SIGNATURE: &str = "X-Signature";
    pub(crate) const SOAP_ACTION: &str = "SOAPAction";
    pub(crate) const X_PROFILE_ID: &str = "X-Profile-Id";
}

/// Unsupported response type error message
pub const UNSUPPORTED_ERROR_MESSAGE: &str = "Unsupported response type";

/// Error message for Authentication Error from the connector
pub const CONNECTOR_UNAUTHORIZED_ERROR: &str = "Authentication Error from the connector";

/// Error message when Refund request has been voided.
pub const REFUND_VOIDED: &str = "Refund request has been voided.";

pub const LOW_BALANCE_ERROR_MESSAGE: &str = "Insufficient balance in the payment method";

pub const DUIT_NOW_BRAND_COLOR: &str = "#ED2E67";

pub const DUIT_NOW_BRAND_TEXT: &str = "MALAYSIA NATIONAL QR";

pub(crate) const CANNOT_CONTINUE_AUTH: &str =
    "Cannot continue with Authorization due to failed Liability Shift.";

#[cfg(feature = "payouts")]
pub(crate) const DEFAULT_NOTIFICATION_SCRIPT_LANGUAGE: &str = "en-US";


pub fn update(&mut self, new_config: Self) {
        if let Some(threshold) = new_config.default_latency_threshold {
            self.default_latency_threshold = Some(threshold);
        }
        if let Some(bucket_size) = new_config.default_bucket_size {
            self.default_bucket_size = Some(bucket_size);
        }
        if let Some(hedging_percent) = new_config.default_hedging_percent {
            self.default_hedging_percent = Some(hedging_percent);
        }
        if let Some(lower_reset_factor) = new_config.default_lower_reset_factor {
            self.default_lower_reset_factor = Some(lower_reset_factor);
        }
        if let Some(upper_reset_factor) = new_config.default_upper_reset_factor {
            self.default_upper_reset_factor = Some(upper_reset_factor);
        }
        if let Some(gateway_extra_score) = new_config.default_gateway_extra_score {
            self.default_gateway_extra_score
                .as_mut()
                .map(|score| score.extend(gateway_extra_score));
        }
        if let Some(sub_level_input_config) = new_config.sub_level_input_config {
            self.sub_level_input_config.as_mut().map(|config| {
                config.extend(sub_level_input_config);
            });
        }
    }


pub fn process_payment_attempt(
        state: &SessionState,
        payment_attempt: types::DummyConnectorPaymentAttempt,
    ) -> types::DummyConnectorResult<Self> {
        let redirect_url = format!(
            "{}/dummy-connector/authorize/{}",
            state.base_url, payment_attempt.attempt_id
        );
        payment_attempt
            .clone()
            .payment_request
            .payment_method_data
            .build_payment_data_from_payment_attempt(payment_attempt, redirect_url)
    }


impl api::Payment for Payu {}


pub struct MerchantConnectorAccountNew {
    pub merchant_id: Option<id_type::MerchantId>,
    pub connector_type: Option<storage_enums::ConnectorType>,
    pub connector_name: Option<String>,
    pub connector_account_details: Option<Encryption>,
    pub test_mode: Option<bool>,
    pub disabled: Option<bool>,
    pub merchant_connector_id: id_type::MerchantConnectorAccountId,
    pub payment_methods_enabled: Option<Vec<pii::SecretSerdeValue>>,
    pub metadata: Option<pii::SecretSerdeValue>,
    pub connector_label: Option<String>,
    pub business_country: Option<storage_enums::CountryAlpha2>,
    pub business_label: Option<String>,
    pub business_sub_label: Option<String>,
    pub frm_configs: Option<pii::SecretSerdeValue>,
    pub created_at: time::PrimitiveDateTime,
    pub modified_at: time::PrimitiveDateTime,
    pub connector_webhook_details: Option<pii::SecretSerdeValue>,
    #[diesel(deserialize_as = super::OptionalDieselArray<pii::SecretSerdeValue>)]
    pub frm_config: Option<Vec<pii::SecretSerdeValue>>,
    pub profile_id: Option<id_type::ProfileId>,
    #[diesel(deserialize_as = super::OptionalDieselArray<String>)]
    pub applepay_verified_domains: Option<Vec<String>>,
    pub pm_auth_config: Option<pii::SecretSerdeValue>,
    pub status: storage_enums::ConnectorStatus,
    pub additional_merchant_data: Option<Encryption>,
    pub connector_wallets_details: Option<Encryption>,
    pub version: common_enums::ApiVersion,
    pub id: Option<id_type::MerchantConnectorAccountId>,
}


pub fn get_sdk_event_dimensions() -> Vec<NameDescription> {
    SdkEventDimensions::iter().map(Into::into).collect()
}


pub trait CheckingContext {
    type Value: ValueNode;

    fn from_node_values<L>(vals: impl IntoIterator<Item = L>) -> Self
    where
        L: Into<Self::Value>;

    fn check_presence(&self, value: &NodeValue<Self::Value>, strength: Strength) -> bool;

    fn get_values_by_key(
        &self,
        expected: &<Self::Value as ValueNode>::Key,
    ) -> Option<Vec<Self::Value>>;
}


pub struct CustomerAcceptance {
    #[serde(rename = "type")]
    pub acceptance_type: Option<AcceptanceType>,
    pub accepted_at: Option<PrimitiveDateTime>,
    pub online: Option<OnlineMandate>,
}


/// Get external authentication request poll id
    pub fn get_external_authentication_request_poll_id(&self) -> String {
        format!("external_authentication_{}", self.get_string_repr())
    }


OpenAPI Block Path: components.schemas.WalletAdditionalDataForCard
{
  "type": "object",
  "required": [
    "last4",
    "card_network"
  ],
  "properties": {
    "last4": {
      "type": "string",
      "description": "Last 4 digits of the card number"
    },
    "card_network": {
      "type": "string",
      "description": "The information of the payment method"
    },
    "type": {
      "type": "string",
      "description": "The type of payment method",
      "nullable": true
    }
  }
}


pub fn get_webhook_response(
    body: &[u8],
) -> CustomResult<GetnetWebhookNotificationResponse, errors::ConnectorError> {
    let body_bytes = bytes::Bytes::copy_from_slice(body);
    let parsed_param: GetnetWebhookNotificationResponse =
        parse_url_encoded_to_struct(body_bytes)
            .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?;
    Ok(parsed_param)
}


pub struct NetworkTokenExpiry {
    pub token_exp_month: Option<Secret<String>>,
    pub token_exp_year: Option<Secret<String>>,
}


impl GetPaymentMethodDetails for DummyConnectorPaymentMethodType {
    fn get_name(&self) -> &'static str {
        match self {
            Self::Card => "3D Secure",
            Self::Upi(upi_type) => upi_type.get_name(),
            Self::Wallet(wallet) => wallet.get_name(),
            Self::PayLater(pay_later) => pay_later.get_name(),
        }
    }

    fn get_image_link(&self, base_url: &str) -> String {
        match self {
            Self::Card => format!("{}{}", base_url, "CARD.svg"),
            Self::Upi(upi_type) => upi_type.get_image_link(base_url),
            Self::Wallet(wallet) => wallet.get_image_link(base_url),
            Self::PayLater(pay_later) => pay_later.get_image_link(base_url),
        }
    }
}

impl GetPaymentMethodDetails for for DummyConnectorPaymentMethodType


pub struct NomupayPaymentRequest {
    pub source_id: Secret<String>,
    pub destination_id: Secret<String>,
    pub payment_reference: String,
    pub amount: FloatMajorUnit,
    pub currency_code: Currency,
    pub purpose: String,
    pub description: Option<String>,
    pub internal_memo: Option<String>,
}


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


File: crates/analytics/src/auth_events/metrics/authentication_count.rs

use std::collections::HashSet;

use api_models::analytics::{
    auth_events::{AuthEventDimensions, AuthEventFilters, AuthEventMetricsBucketIdentifier},
    Granularity, TimeRange,
};
use common_utils::errors::ReportSwitchExt;
use error_stack::ResultExt;
use time::PrimitiveDateTime;

use super::AuthEventMetricRow;
use crate::{
    query::{Aggregate, GroupByClause, QueryBuilder, QueryFilter, SeriesBucket, ToSql, Window},
    types::{AnalyticsCollection, AnalyticsDataSource, MetricsError, MetricsResult},
    AuthInfo,
};

#[derive(Default)]
pub(super) struct AuthenticationCount;

#[async_trait::async_trait]
impl<T> super::AuthEventMetric<T> for AuthenticationCount
where
    T: AnalyticsDataSource + super::AuthEventMetricAnalytics,
    PrimitiveDateTime: ToSql<T>,
    AnalyticsCollection: ToSql<T>,
    Granularity: GroupByClause<T>,
    Aggregate<&'static str>: ToSql<T>,
    Window<&'static str>: ToSql<T>,
{
    async fn load_metrics(
        &self,
        auth: &AuthInfo,
        dimensions: &[AuthEventDimensions],
        filters: &AuthEventFilters,
        granularity: Option<Granularity>,
        time_range: &TimeRange,
        pool: &T,
    ) -> MetricsResult<HashSet<(AuthEventMetricsBucketIdentifier, AuthEventMetricRow)>> {
        let mut query_builder: QueryBuilder<T> =
            QueryBuilder::new(AnalyticsCollection::Authentications);
        for dim in dimensions.iter() {
            query_builder.add_select_column(dim).switch()?;
        }
        query_builder
            .add_select_column(Aggregate::Count {
                field: None,
                alias: Some("count"),
            })
            .switch()?;

        query_builder
            .add_select_column(Aggregate::Min {
                field: "created_at",
                alias: Some("start_bucket"),
            })
            .switch()?;

        query_builder
            .add_select_column(Aggregate::Max {
                field: "created_at",
                alias: Some("end_bucket"),
            })
            .switch()?;

        filters.set_filter_clause(&mut query_builder).switch()?;
        time_range
            .set_filter_clause(&mut query_builder)
            .attach_printable("Error filtering time range")
            .switch()?;
        auth.set_filter_clause(&mut query_builder).switch()?;

        for dim in dimensions.iter() {
            query_builder
                .add_group_by_clause(dim)
                .attach_printable("Error grouping by dimensions")
                .switch()?;
        }

        if let Some(granularity) = granularity {
            granularity
                .set_group_by_clause(&mut query_builder)
                .attach_printable("Error adding granularity")
                .switch()?;
        }

        query_builder
            .execute_query::<AuthEventMetricRow, _>(pool)
            .await
            .change_context(MetricsError::QueryBuildingError)?
            .change_context(MetricsError::QueryExecutionFailure)?
            .into_iter()
            .map(|i| {
                Ok((
                    AuthEventMetricsBucketIdentifier::new(
                        i.authentication_status.as_ref().map(|i| i.0),
                        i.trans_status.as_ref().map(|i| i.0.clone()),
                        i.authentication_type.as_ref().map(|i| i.0),
                        i.error_message.clone(),
                        i.authentication_connector.as_ref().map(|i| i.0),
                        i.message_version.clone(),
                        i.acs_reference_number.clone(),
                        i.mcc.clone(),
                        i.currency.as_ref().map(|i| i.0),
                        i.merchant_country.clone(),
                        i.billing_country.clone(),
                        i.shipping_country.clone(),
                        i.issuer_country.clone(),
                        i.earliest_supported_version.clone(),
                        i.latest_supported_version.clone(),
                        i.whitelist_decision,
                        i.device_manufacturer.clone(),
                        i.device_type.clone(),
                        i.device_brand.clone(),
                        i.device_os.clone(),
                        i.device_display.clone(),
                        i.browser_name.clone(),
                        i.browser_version.clone(),
                        i.issuer_id.clone(),
                        i.scheme_name.clone(),
                        i.exemption_requested,
                        i.exemption_accepted,
                        TimeRange {
                            start_time: match (granularity, i.start_bucket) {
                                (Some(g), Some(st)) => g.clip_to_start(st)?,
                                _ => time_range.start_time,
                            },
                            end_time: granularity.as_ref().map_or_else(
                                || Ok(time_range.end_time),
                                |g| i.end_bucket.map(|et| g.clip_to_end(et)).transpose(),
                            )?,
                        },
                    ),
                    i,
                ))
            })
            .collect::<error_stack::Result<
                HashSet<(AuthEventMetricsBucketIdentifier, AuthEventMetricRow)>,
                crate::query::PostProcessingError,
            >>()
            .change_context(MetricsError::PostProcessingFailure)
    }
}


pub struct ProxyClient {
    proxy_config: Proxy,
    client: reqwest::Client,
    request_id: Option<String>,
}


impl api::MandateSetup for Powertranz {}

impl api::MandateSetup for for Powertranz


File: crates/hyperswitch_connectors/src/connectors/payload/requests.rs
 Public structs: 7

use common_utils::types::StringMajorUnit;
use masking::Secret;
use serde::{Deserialize, Serialize};

use crate::connectors::payload::responses;

#[derive(Debug, Serialize, PartialEq)]
#[serde(untagged)]
pub enum PayloadPaymentsRequest {
    PayloadCardsRequest(Box<PayloadCardsRequestData>),
    PayloadMandateRequest(Box<PayloadMandateRequestData>),
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum TransactionTypes {
    Credit,
    Chargeback,
    ChargebackReversal,
    Deposit,
    Payment,
    Refund,
    Reversal,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct BillingAddress {
    #[serde(rename = "payment_method[billing_address][city]")]
    pub city: String,
    #[serde(rename = "payment_method[billing_address][country_code]")]
    pub country: common_enums::CountryAlpha2,
    #[serde(rename = "payment_method[billing_address][postal_code]")]
    pub postal_code: Secret<String>,
    #[serde(rename = "payment_method[billing_address][state_province]")]
    pub state_province: Secret<String>,
    #[serde(rename = "payment_method[billing_address][street_address]")]
    pub street_address: Secret<String>,
}

#[derive(Debug, Clone, Serialize, PartialEq)]
pub struct PayloadCardsRequestData {
    pub amount: StringMajorUnit,
    #[serde(flatten)]
    pub card: PayloadCard,
    #[serde(rename = "type")]
    pub transaction_types: TransactionTypes,
    // For manual capture, set status to "authorized", otherwise omit
    #[serde(skip_serializing_if = "Option::is_none")]
    pub status: Option<responses::PayloadPaymentStatus>,
    #[serde(rename = "payment_method[type]")]
    pub payment_method_type: String,
    // Billing address fields are for AVS validation
    #[serde(flatten)]
    pub billing_address: BillingAddress,
    pub processing_id: Option<Secret<String>>,
    /// Allows one-time payment by customer without saving their payment method
    /// This is true by default
    #[serde(rename = "payment_method[keep_active]")]
    pub keep_active: bool,
}

#[derive(Debug, Clone, Serialize, PartialEq)]
pub struct PayloadMandateRequestData {
    pub amount: StringMajorUnit,
    #[serde(rename = "type")]
    pub transaction_types: TransactionTypes,
    // Based on the connectors' response, we can do recurring payment either based on a default payment method id saved in the customer profile or a specific payment method id
    // Connector by default, saves every payment method
    pub payment_method_id: Secret<String>,
    // For manual capture, set status to "authorized", otherwise omit
    #[serde(skip_serializing_if = "Option::is_none")]
    pub status: Option<responses::PayloadPaymentStatus>,
}

#[derive(Default, Clone, Debug, Serialize, Eq, PartialEq)]
pub struct PayloadCard {
    #[serde(rename = "payment_method[card][card_number]")]
    pub number: cards::CardNumber,
    #[serde(rename = "payment_method[card][expiry]")]
    pub expiry: Secret<String>,
    #[serde(rename = "payment_method[card][card_code]")]
    pub cvc: Secret<String>,
}

#[derive(Clone, Debug, Serialize, PartialEq)]
pub struct PayloadCancelRequest {
    pub status: responses::PayloadPaymentStatus,
}

// Type definition for CaptureRequest
#[derive(Clone, Debug, Serialize, PartialEq)]
pub struct PayloadCaptureRequest {
    pub status: responses::PayloadPaymentStatus,
}

// Type definition for RefundRequest
#[derive(Debug, Serialize)]
pub struct PayloadRefundRequest {
    #[serde(rename = "type")]
    pub transaction_type: TransactionTypes,
    pub amount: StringMajorUnit,
    #[serde(rename = "ledger[0][assoc_transaction_id]")]
    pub ledger_assoc_transaction_id: String,
}


/// This is the url to which the customer will be redirected to, to complete the redirection flow
    pub fn create_start_redirection_url(
        &self,
        base_url: &str,
        publishable_key: String,
    ) -> CustomResult<url::Url, errors::api_error_response::ApiErrorResponse> {
        let start_redirection_url = &format!(
            "{}/v2/payments/{}/start-redirection?publishable_key={}&profile_id={}",
            base_url,
            self.get_id().get_string_repr(),
            publishable_key,
            self.profile_id.get_string_repr()
        );
        url::Url::parse(start_redirection_url)
            .change_context(errors::api_error_response::ApiErrorResponse::InternalServerError)
            .attach_printable("Error creating start redirection url")
    }


pub struct MultipleCaptureRequestData {
    pub capture_sequence: i16,
    pub capture_reference: String,
}


File: crates/router/src/types/domain/types.rs

use ::payment_methods::state as pm_state;
use common_utils::types::keymanager::KeyManagerState;
pub use hyperswitch_domain_models::type_encryption::{
    crypto_operation, AsyncLift, CryptoOperation, Lift, OptionalEncryptableJsonType,
};

use crate::routes::app;

impl From<&app::SessionState> for KeyManagerState {
    fn from(state: &app::SessionState) -> Self {
        let conf = state.conf.key_manager.get_inner();
        Self {
            global_tenant_id: state.conf.multitenancy.global_tenant.tenant_id.clone(),
            tenant_id: state.tenant.tenant_id.clone(),
            enabled: conf.enabled,
            url: conf.url.clone(),
            client_idle_timeout: state.conf.proxy.idle_pool_connection_timeout,
            #[cfg(feature = "km_forward_x_request_id")]
            request_id: state.request_id,
            #[cfg(feature = "keymanager_mtls")]
            cert: conf.cert.clone(),
            #[cfg(feature = "keymanager_mtls")]
            ca: conf.ca.clone(),
            infra_values: app::AppState::process_env_mappings(state.conf.infra_values.clone()),
        }
    }
}

impl From<&app::SessionState> for pm_state::PaymentMethodsState {
    fn from(state: &app::SessionState) -> Self {
        Self {
            store: state.store.get_payment_methods_store(),
            key_store: None,
            key_manager_state: state.into(),
        }
    }
}