}

#[cfg(feature = "v1")]
pub async fn save_in_locker_external(
    state: &SessionState,
    merchant_context: &domain::MerchantContext,
    payment_method_request: api::PaymentMethodCreate,
    card_detail: Option<api::CardDetail>,
    external_vault_connector_details: &ExternalVaultConnectorDetails,
) -> RouterResult<(
    api_models::payment_methods::PaymentMethodResponse,
    Option<payment_methods::transformers::DataDuplicationCheck>,
)> {
    let customer_id = payment_method_request
        .customer_id
        .clone()
        .get_required_value("customer_id")?;
    // For external vault, we need to convert the card data to PaymentMethodVaultingData
    if let Some(card) = card_detail {
        let payment_method_vaulting_data =
            hyperswitch_domain_models::vault::PaymentMethodVaultingData::Card(card.clone());

        let external_vault_mca_id = external_vault_connector_details.vault_connector_id.clone();

        let key_manager_state = &state.into();

        let merchant_connector_account_details = state
            .store
            .find_by_merchant_connector_account_merchant_id_merchant_connector_id(
                key_manager_state,
                merchant_context.get_merchant_account().get_id(),
                &external_vault_mca_id,
                merchant_context.get_merchant_key_store(),
            )
            .await
            .to_not_found_response(errors::ApiErrorResponse::MerchantConnectorAccountNotFound {
                id: external_vault_mca_id.get_string_repr().to_string(),
            })?;

        // Call vault_payment_method_external_v1
        let vault_response = vault_payment_method_external_v1(
            state,
            &payment_method_vaulting_data,
            merchant_context.get_merchant_account(),
            merchant_connector_account_details,
        )
        .await?;

        let payment_method_id = vault_response.vault_id.to_string().to_owned();
        let card_detail = CardDetailFromLocker::from(card);

        let pm_resp = api::PaymentMethodResponse {
            merchant_id: merchant_context.get_merchant_account().get_id().to_owned(),
            customer_id: Some(customer_id),
            payment_method_id,
            payment_method: payment_method_request.payment_method,
            payment_method_type: payment_method_request.payment_method_type,
            card: Some(card_detail),
            recurring_enabled: Some(false),
            installment_payment_enabled: Some(false),
            payment_experience: Some(vec![api_models::enums::PaymentExperience::RedirectToUrl]),
            metadata: None,
            created: Some(common_utils::date_time::now()),
            #[cfg(feature = "payouts")]
            bank_transfer: None,
            last_used_at: Some(common_utils::date_time::now()),
            client_secret: None,
        };

        Ok((pm_resp, None))
    } else {
        //Similar implementation is done for save in locker internal
        let pm_id = common_utils::generate_id(consts::ID_LENGTH, "pm");
        let payment_method_response = api::PaymentMethodResponse {
            merchant_id: merchant_context.get_merchant_account().get_id().to_owned(),
            customer_id: Some(customer_id),
            payment_method_id: pm_id,
            payment_method: payment_method_request.payment_method,
            payment_method_type: payment_method_request.payment_method_type,
            #[cfg(feature = "payouts")]
            bank_transfer: None,
            card: None,
            metadata: None,
            created: Some(common_utils::date_time::now()),
            recurring_enabled: Some(false),
            installment_payment_enabled: Some(false),
            payment_experience: Some(vec![api_models::enums::PaymentExperience::RedirectToUrl]), //[#219]
            last_used_at: Some(common_utils::date_time::now()),
            client_secret: None,
        };
        Ok((payment_method_response, None))
    }
}

#[cfg(feature = "v2")]
pub async fn save_in_locker_internal(
    _state: &SessionState,
    _merchant_context: &domain::MerchantContext,
    _payment_method_request: api::PaymentMethodCreate,
) -> RouterResult<(
    api_models::payment_methods::PaymentMethodResponse,
    Option<payment_methods::transformers::DataDuplicationCheck>,
)> {
    todo!()
}

#[cfg(feature = "v2")]
pub async fn save_network_token_in_locker(
    _state: &SessionState,
    _merchant_context: &domain::MerchantContext,
    _card_data: &domain::Card,
    _payment_method_request: api::PaymentMethodCreate,
) -> RouterResult<(
    Option<api_models::payment_methods::PaymentMethodResponse>,
    Option<payment_methods::transformers::DataDuplicationCheck>,
    Option<String>,
)> {
    todo!()
}

#[cfg(feature = "v1")]
pub async fn save_network_token_in_locker(
    state: &SessionState,
    merchant_context: &domain::MerchantContext,
    card_data: &payment_method_data::Card,
    network_token_data: Option<api::CardDetail>,
    payment_method_request: api::PaymentMethodCreate,
) -> RouterResult<(
    Option<api_models::payment_methods::PaymentMethodResponse>,
    Option<payment_methods::transformers::DataDuplicationCheck>,
    Option<String>,
)> {
    let customer_id = payment_method_request
        .customer_id
        .clone()
        .get_required_value("customer_id")?;
    let network_tokenization_supported_card_networks = &state
        .conf
        .network_tokenization_supported_card_networks
        .card_networks;

    match network_token_data {
        Some(nt_data) => {
            let (res, dc) = Box::pin(
                PmCards {
                    state,
                    merchant_context,
                }
                .add_card_to_locker(
                    payment_method_request,
                    &nt_data,
                    &customer_id,
                    None,
                ),
            )
            .await
            .change_context(errors::ApiErrorResponse::InternalServerError)
            .attach_printable("Add Network Token Failed")?;

            Ok((Some(res), dc, None))
        }
        None => {
            if card_data
                .card_network
                .as_ref()
                .filter(|cn| network_tokenization_supported_card_networks.contains(cn))
                .is_some()
            {
                let optional_card_cvc = Some(card_data.card_cvc.clone());
                match network_tokenization::make_card_network_tokenization_request(
                    state,
                    &domain::CardDetail::from(card_data),
                    optional_card_cvc,
                    &customer_id,
                )
                .await
                {
                    Ok((token_response, network_token_requestor_ref_id)) => {
                        // Only proceed if the tokenization was successful
                        let network_token_data = api::CardDetail {
                            card_number: token_response.token.clone(),
                            card_exp_month: token_response.token_expiry_month.clone(),
                            card_exp_year: token_response.token_expiry_year.clone(),
                            card_holder_name: None,
                            nick_name: None,
                            card_issuing_country: None,
                            card_network: Some(token_response.card_brand.clone()),
                            card_issuer: None,
                            card_type: None,
                        };

                        let (res, dc) = Box::pin(
                            PmCards {
                                state,
                                merchant_context,
                            }
                            .add_card_to_locker(
                                payment_method_request,
                                &network_token_data,
                                &customer_id,
                                None,
                            ),
                        )
                        .await
                        .change_context(errors::ApiErrorResponse::InternalServerError)
                        .attach_printable("Add Network Token Failed")?;

                        Ok((Some(res), dc, network_token_requestor_ref_id))
                    }
                    Err(err) => {
                        logger::error!("Failed to tokenize card: {:?}", err);
                        Ok((None, None, None)) //None will be returned in case of error when calling network tokenization service
                    }
                }
            } else {
                Ok((None, None, None)) //None will be returned in case of unsupported card network.
            }
        }
    }
}

pub fn handle_tokenization_response<F, Req>(
    resp: &mut types::RouterData<F, Req, types::PaymentsResponseData>,
) {
    let response = resp.response.clone();
    if let Err(err) = response {
        if let Some(secret_metadata) = &err.connector_metadata {
            let metadata = secret_metadata.clone().expose();
            if let Some(token) = metadata
                .get("payment_method_token")
                .and_then(|t| t.as_str())
            {
                resp.response = Ok(types::PaymentsResponseData::TokenizationResponse {
                    token: token.to_string(),
                });
            }
        }
    }
}

pub fn create_payment_method_metadata(
    metadata: Option<&pii::SecretSerdeValue>,
    connector_token: Option<(String, String)>,
) -> RouterResult<Option<serde_json::Value>> {
    let mut meta = match metadata {
        None => serde_json::Map::new(),
        Some(meta) => {
            let metadata = meta.clone().expose();
            let existing_metadata: serde_json::Map<String, serde_json::Value> = metadata
                .parse_value("Map<String, Value>")
                .change_context(errors::ApiErrorResponse::InternalServerError)
                .attach_printable("Failed to parse the metadata")?;
            existing_metadata
        }
    };
    Ok(connector_token.and_then(|connector_and_token| {
        meta.insert(
            connector_and_token.0,
            serde_json::Value::String(connector_and_token.1),
        )
    }))
}

pub async fn add_payment_method_token<F: Clone, T: types::Tokenizable + Clone>(
    state: &SessionState,
    connector: &api::ConnectorData,
    tokenization_action: &payments::TokenizationAction,
    router_data: &mut types::RouterData<F, T, types::PaymentsResponseData>,
    pm_token_request_data: types::PaymentMethodTokenizationData,
    should_continue_payment: bool,
) -> RouterResult<types::PaymentMethodTokenResult> {
    if should_continue_payment {
        match tokenization_action {
            payments::TokenizationAction::TokenizeInConnector => {
                let connector_integration: services::BoxedPaymentConnectorIntegrationInterface<
                    api::PaymentMethodToken,
                    types::PaymentMethodTokenizationData,
                    types::PaymentsResponseData,
                > = connector.connector.get_connector_integration();

                let pm_token_response_data: Result<
                    types::PaymentsResponseData,
                    types::ErrorResponse,
                > = Err(types::ErrorResponse::default());

                let pm_token_router_data =
                    helpers::router_data_type_conversion::<_, api::PaymentMethodToken, _, _, _, _>(
                        router_data.clone(),
                        pm_token_request_data,
                        pm_token_response_data,
                    );

                router_data
                    .request
                    .set_session_token(pm_token_router_data.session_token.clone());

                let mut resp = services::execute_connector_processing_step(
                    state,
                    connector_integration,
                    &pm_token_router_data,
                    payments::CallConnectorAction::Trigger,
                    None,
                    None,
                )
                .await
                .to_payment_failed_response()?;

                // checks for metadata in the ErrorResponse, if present bypasses it and constructs an Ok response
                handle_tokenization_response(&mut resp);

                metrics::CONNECTOR_PAYMENT_METHOD_TOKENIZATION.add(
                    1,
                    router_env::metric_attributes!(
                        ("connector", connector.connector_name.to_string()),
                        ("payment_method", router_data.payment_method.to_string()),
                    ),
                );

                let payment_token_resp = resp.response.map(|res| {
                    if let types::PaymentsResponseData::TokenizationResponse { token } = res {
                        Some(token)
                    } else {
                        None
                    }
                });

                Ok(types::PaymentMethodTokenResult {
                    payment_method_token_result: payment_token_resp,
                    is_payment_method_tokenization_performed: true,
                    connector_response: resp.connector_response.clone(),
                })
            }
            _ => Ok(types::PaymentMethodTokenResult {
                payment_method_token_result: Ok(None),
                is_payment_method_tokenization_performed: false,
                connector_response: None,
            }),
        }
    } else {
        logger::debug!("Skipping connector tokenization based on should_continue_payment flag");
        Ok(types::PaymentMethodTokenResult {
            payment_method_token_result: Ok(None),
            is_payment_method_tokenization_performed: false,
            connector_response: None,
        })
    }
}

pub fn update_router_data_with_payment_method_token_result<F: Clone, T>(
    payment_method_token_result: types::PaymentMethodTokenResult,
    router_data: &mut types::RouterData<F, T, types::PaymentsResponseData>,
    is_retry_payment: bool,
    should_continue_further: bool,
) -> bool {
    if payment_method_token_result.is_payment_method_tokenization_performed {
        match payment_method_token_result.payment_method_token_result {
            Ok(pm_token_result) => {
                router_data.payment_method_token = pm_token_result.map(|pm_token| {
                    hyperswitch_domain_models::router_data::PaymentMethodToken::Token(Secret::new(
                        pm_token,
                    ))
                });
                if router_data.connector_response.is_none() {
                    router_data.connector_response =
                        payment_method_token_result.connector_response.clone();
                }
                true
            }
            Err(err) => {
                if is_retry_payment {
                    router_data.response = Err(err);
                    false
                } else {
                    logger::debug!(payment_method_tokenization_error=?err);
                    true
                }
            }
        }
    } else {
        should_continue_further
    }
}

#[cfg(feature = "v1")]
pub fn add_connector_mandate_details_in_payment_method(
    payment_method_type: Option<storage_enums::PaymentMethodType>,
    authorized_amount: Option<i64>,
    authorized_currency: Option<storage_enums::Currency>,
    merchant_connector_id: Option<id_type::MerchantConnectorAccountId>,
    connector_mandate_id: Option<String>,
    mandate_metadata: Option<Secret<serde_json::Value>>,
    connector_mandate_request_reference_id: Option<String>,
) -> Option<CommonMandateReference> {
    let mut mandate_details = HashMap::new();

    if let Some((mca_id, connector_mandate_id)) =
        merchant_connector_id.clone().zip(connector_mandate_id)
    {
        mandate_details.insert(
            mca_id,
            PaymentsMandateReferenceRecord {
                connector_mandate_id,
                payment_method_type,
                original_payment_authorized_amount: authorized_amount,
                original_payment_authorized_currency: authorized_currency,
                mandate_metadata,
                connector_mandate_status: Some(ConnectorMandateStatus::Active),
                connector_mandate_request_reference_id,
            },
        );
        Some(CommonMandateReference {
            payments: Some(PaymentsMandateReference(mandate_details)),
            payouts: None,
        })
    } else {
        None
    }
}

#[allow(clippy::too_many_arguments)]
#[cfg(feature = "v1")]
pub fn update_connector_mandate_details(
    mandate_details: Option<CommonMandateReference>,
    payment_method_type: Option<storage_enums::PaymentMethodType>,
    authorized_amount: Option<i64>,
    authorized_currency: Option<storage_enums::Currency>,
    merchant_connector_id: Option<id_type::MerchantConnectorAccountId>,
    connector_mandate_id: Option<String>,
    mandate_metadata: Option<Secret<serde_json::Value>>,
    connector_mandate_request_reference_id: Option<String>,
) -> RouterResult<Option<CommonMandateReference>> {
    let mandate_reference = match mandate_details
        .as_ref()
        .and_then(|common_mandate| common_mandate.payments.clone())
    {
        Some(mut payment_mandate_reference) => {
            if let Some((mca_id, connector_mandate_id)) =
                merchant_connector_id.clone().zip(connector_mandate_id)
            {
                let updated_record = PaymentsMandateReferenceRecord {
                    connector_mandate_id: connector_mandate_id.clone(),
                    payment_method_type,
                    original_payment_authorized_amount: authorized_amount,
                    original_payment_authorized_currency: authorized_currency,
                    mandate_metadata: mandate_metadata.clone(),
                    connector_mandate_status: Some(ConnectorMandateStatus::Active),
                    connector_mandate_request_reference_id: connector_mandate_request_reference_id
                        .clone(),
                };

                payment_mandate_reference
                    .entry(mca_id)
                    .and_modify(|pm| *pm = updated_record)
                    .or_insert(PaymentsMandateReferenceRecord {
                        connector_mandate_id,
                        payment_method_type,
                        original_payment_authorized_amount: authorized_amount,
                        original_payment_authorized_currency: authorized_currency,
                        mandate_metadata: mandate_metadata.clone(),
                        connector_mandate_status: Some(ConnectorMandateStatus::Active),
                        connector_mandate_request_reference_id,
                    });

                let payout_data = mandate_details.and_then(|common_mandate| common_mandate.payouts);

                Some(CommonMandateReference {
                    payments: Some(payment_mandate_reference),
                    payouts: payout_data,
                })
            } else {
                None
            }
        }
        None => add_connector_mandate_details_in_payment_method(
            payment_method_type,
            authorized_amount,
            authorized_currency,
            merchant_connector_id,
            connector_mandate_id,
            mandate_metadata,
            connector_mandate_request_reference_id,
        ),
    };
    Ok(mandate_reference)
}

#[cfg(feature = "v1")]
pub fn update_connector_mandate_details_status(
    merchant_connector_id: id_type::MerchantConnectorAccountId,
    mut payment_mandate_reference: PaymentsMandateReference,
    status: ConnectorMandateStatus,
) -> RouterResult<Option<CommonMandateReference>> {
    let mandate_reference = {
        payment_mandate_reference
            .entry(merchant_connector_id)
            .and_modify(|pm| {
                let update_rec = PaymentsMandateReferenceRecord {
                    connector_mandate_id: pm.connector_mandate_id.clone(),
                    payment_method_type: pm.payment_method_type,
                    original_payment_authorized_amount: pm.original_payment_authorized_amount,
                    original_payment_authorized_currency: pm.original_payment_authorized_currency,
                    mandate_metadata: pm.mandate_metadata.clone(),
                    connector_mandate_status: Some(status),
                    connector_mandate_request_reference_id: pm
                        .connector_mandate_request_reference_id
                        .clone(),
                };
                *pm = update_rec
            });
        Some(payment_mandate_reference)
    };

    Ok(Some(CommonMandateReference {
        payments: mandate_reference,
        payouts: None,
    }))
}

#[cfg(feature = "v2")]
pub async fn add_token_for_payment_method(
    router_data: &mut types::RouterData<
        api::PaymentMethodToken,
        types::PaymentMethodTokenizationData,
        types::PaymentsResponseData,
    >,
    payment_method_data_request: types::PaymentMethodTokenizationData,
    state: SessionState,
    merchant_connector_account_details: &hyperswitch_domain_models::merchant_connector_account::MerchantConnectorAccount,
) -> RouterResult<types::PspTokenResult> {
    let connector_id = merchant_connector_account_details.id.clone();
    let connector_data = api::ConnectorData::get_connector_by_name(
        &(state.conf.connectors),
        &merchant_connector_account_details
            .connector_name
            .to_string(),
        api::GetToken::Connector,
        Some(connector_id.clone()),
    )?;

    let connector_integration: services::BoxedPaymentConnectorIntegrationInterface<
        api::PaymentMethodToken,
        types::PaymentMethodTokenizationData,
        types::PaymentsResponseData,
    > = connector_data.connector.get_connector_integration();

    let payment_method_token_response_data_type: Result<
        types::PaymentsResponseData,
        types::ErrorResponse,
    > = Err(types::ErrorResponse::default());

    let payment_method_token_router_data =
        helpers::router_data_type_conversion::<_, api::PaymentMethodToken, _, _, _, _>(
            router_data.clone(),
            payment_method_data_request.clone(),
            payment_method_token_response_data_type,
        );

    let connector_integration_response = services::execute_connector_processing_step(
        &state,
        connector_integration,
        &payment_method_token_router_data,
        payments::CallConnectorAction::Trigger,
        None,
        None,
    )
    .await
    .to_payment_failed_response()?;
    let payment_token_response = connector_integration_response.response.map(|res| {
        if let types::PaymentsResponseData::TokenizationResponse { token } = res {
            Ok(token)
        } else {
            Err(errors::ApiErrorResponse::InternalServerError)
                .attach_printable("Failed to get token from connector")
        }
    });

    match payment_token_response {
        Ok(token) => Ok(types::PspTokenResult { token: Ok(token?) }),
        Err(error_response) => Ok(types::PspTokenResult {
            token: Err(error_response),
        }),
    }
}

#[cfg(feature = "v1")]
#[allow(clippy::too_many_arguments)]
pub async fn save_card_and_network_token_in_locker(
    state: &SessionState,
    customer_id: id_type::CustomerId,
    payment_method_status: common_enums::PaymentMethodStatus,
    payment_method_data: domain::PaymentMethodData,
    vault_operation: Option<hyperswitch_domain_models::payments::VaultOperation>,
    payment_method_info: Option<domain::PaymentMethod>,
    merchant_context: &domain::MerchantContext,
    payment_method_create_request: api::PaymentMethodCreate,
    is_network_tokenization_enabled: bool,
    business_profile: &domain::Profile,
) -> RouterResult<(
    (
        api_models::payment_methods::PaymentMethodResponse,
        Option<payment_methods::transformers::DataDuplicationCheck>,
        Option<String>,
    ),
    Option<api_models::payment_methods::PaymentMethodResponse>,
)> {
    let network_token_requestor_reference_id = payment_method_info
        .and_then(|pm_info| pm_info.network_token_requestor_reference_id.clone());

    match vault_operation {
        Some(hyperswitch_domain_models::payments::VaultOperation::SaveCardData(card)) => {
            let card_data = api::CardDetail::from(card.card_data.clone());
            if let (Some(nt_ref_id), Some(tokenization_service)) = (
                card.network_token_req_ref_id.clone(),
                &state.conf.network_tokenization_service,
            ) {
                let _ = record_operation_time(
                    async {
                        network_tokenization::delete_network_token_from_tokenization_service(
                            state,
                            nt_ref_id.clone(),
                            &customer_id,
                            tokenization_service.get_inner(),
                        )
                        .await
                    },
                    &metrics::DELETE_NETWORK_TOKEN_TIME,
                    &[],
                )
                .await;
            }
            let (res, dc) = Box::pin(save_in_locker(
                state,
                merchant_context,
                payment_method_create_request.to_owned(),
                Some(card_data),
                business_profile,
            ))
            .await
            .change_context(errors::ApiErrorResponse::InternalServerError)
            .attach_printable("Add Card In Locker Failed")?;

            Ok(((res, dc, None), None))
        }
        Some(hyperswitch_domain_models::payments::VaultOperation::SaveCardAndNetworkTokenData(
            save_card_and_network_token_data,
        )) => {
            let card_data =
                api::CardDetail::from(save_card_and_network_token_data.card_data.clone());

            let network_token_data = api::CardDetail::from(
                save_card_and_network_token_data
                    .network_token
                    .network_token_data
                    .clone(),
            );

            if payment_method_status == common_enums::PaymentMethodStatus::Active {
                let (res, dc) = Box::pin(save_in_locker_internal(
                    state,
                    merchant_context,
                    payment_method_create_request.to_owned(),
                    Some(card_data),
                ))
                .await
                .change_context(errors::ApiErrorResponse::InternalServerError)
                .attach_printable("Add Card In Locker Failed")?;

                let (network_token_resp, _dc, _) = Box::pin(save_network_token_in_locker(
                    state,
                    merchant_context,
                    &save_card_and_network_token_data.card_data,
                    Some(network_token_data),
                    payment_method_create_request.clone(),
                ))
                .await
                .change_context(errors::ApiErrorResponse::InternalServerError)
                .attach_printable("Add Network Token In Locker Failed")?;

                Ok((
                    (res, dc, network_token_requestor_reference_id),
                    network_token_resp,
                ))
            } else {
                if let (Some(nt_ref_id), Some(tokenization_service)) = (
                    network_token_requestor_reference_id.clone(),
                    &state.conf.network_tokenization_service,
                ) {
                    let _ = record_operation_time(
                        async {
                            network_tokenization::delete_network_token_from_tokenization_service(
                                state,
                                nt_ref_id.clone(),
                                &customer_id,
                                tokenization_service.get_inner(),
                            )
                            .await
                        },
                        &metrics::DELETE_NETWORK_TOKEN_TIME,
                        &[],
                    )
                    .await;
                }
                let (res, dc) = Box::pin(save_in_locker_internal(
                    state,
                    merchant_context,
                    payment_method_create_request.to_owned(),
                    Some(card_data),
                ))
                .await
                .change_context(errors::ApiErrorResponse::InternalServerError)
                .attach_printable("Add Card In Locker Failed")?;

                Ok(((res, dc, None), None))
            }
        }
        _ => {
            let card_data = payment_method_create_request.card.clone();
            let (res, dc) = Box::pin(save_in_locker(
                state,
                merchant_context,
                payment_method_create_request.to_owned(),
                card_data,
                business_profile,
            ))
            .await
            .change_context(errors::ApiErrorResponse::InternalServerError)
            .attach_printable("Add Card In Locker Failed")?;

            if is_network_tokenization_enabled {
                match &payment_method_data {
                    domain::PaymentMethodData::Card(card) => {
                        let (
                            network_token_resp,
                            _network_token_duplication_check, //the duplication check is discarded, since each card has only one token, handling card duplication check will be suffice
                            network_token_requestor_ref_id,
                        ) = Box::pin(save_network_token_in_locker(
                            state,
                            merchant_context,
                            card,
                            None,
                            payment_method_create_request.clone(),
                        ))
                        .await?;

                        Ok((
                            (res, dc, network_token_requestor_ref_id),
                            network_token_resp,
                        ))
                    }
                    _ => Ok(((res, dc, None), None)), //network_token_resp is None in case of other payment methods
                }
            } else {
                Ok(((res, dc, None), None))
            }
        }
    }
}


// Function: new
// File: crates/hyperswitch_connectors/src/connectors/bamboraapac.rs
// Module: hyperswitch_connectors

pub fn new() -> &'static Self


// Implementation: impl api::PaymentSession for for Nomupay
// File: crates/hyperswitch_connectors/src/connectors/nomupay.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl api::PaymentSession for for Nomupay


// Struct: Mistercash
// File: crates/hyperswitch_connectors/src/connectors/multisafepay/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct Mistercash


// Function: get_vault_data
// File: crates/router/src/core/proxy/utils.rs
// Module: router

pub fn get_vault_data(
        &self,
        state: &SessionState,
        merchant_context: domain::MerchantContext,
    ) -> RouterResult<Value>


// Function: call_decision_manager
// File: crates/router/src/core/payments.rs
// Module: router

pub fn call_decision_manager<F, D>(
    state: &SessionState,
    merchant_context: &domain::MerchantContext,
    _business_profile: &domain::Profile,
    payment_data: &D,
) -> RouterResult<Option<enums::AuthenticationType>>
where
    F: Clone,
    D: OperationSessionGetters<F>,


// Function: refund_payment
// File: crates/router/src/routes/dummy_connector/core.rs
// Module: router

pub fn refund_payment(
    state: SessionState,
    req: types::DummyConnectorRefundRequest,
) -> types::DummyConnectorResponse<types::DummyConnectorRefundResponse>


// Struct: EnhancedAuthResponse
// File: crates/hyperswitch_connectors/src/connectors/worldpayvantiv/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct EnhancedAuthResponse


// Struct: References
// File: crates/hyperswitch_connectors/src/connectors/trustpay/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct References


// Struct: PaymentIntentMetricRow
// File: crates/analytics/src/payment_intents/metrics.rs
// Module: analytics
// Implementations: 0

pub struct PaymentIntentMetricRow


// Implementation: impl api::PaymentToken for for Gpayments
// File: crates/hyperswitch_connectors/src/connectors/gpayments.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl api::PaymentToken for for Gpayments


// Function: get_header_value_by_key
// File: crates/router/src/services/authentication.rs
// Module: router

pub fn get_header_value_by_key(key: String, headers: &HeaderMap) -> RouterResult<Option<&str>>


            maud::html! {
            (maud::DOCTYPE)
            html {
                head {
                    meta name="viewport" content="width=device-width, initial-scale=1";
                }
                    body style="background-color: #ffffff; padding: 20px; font-family: Arial, Helvetica, Sans-Serif;" {

                        div id="loader1" class="lottie" style="height: 150px; display: block; position: relative; margin-top: 150px; margin-left: auto; margin-right: auto;" { "" }

                        (PreEscaped(r#"<script src="https://cdnjs.cloudflare.com/ajax/libs/bodymovin/5.7.4/lottie.min.js"></script>"#))

                        (PreEscaped(r#"
                            <script>
                            var anime = bodymovin.loadAnimation({
                                container: document.getElementById('loader1'),
                                renderer: 'svg',
                                loop: true,
                                autoplay: true,
                                name: 'hyperswitch loader',
                                animationData: {"v":"4.8.0","meta":{"g":"LottieFiles AE 3.1.1","a":"","k":"","d":"","tc":""},"fr":29.9700012207031,"ip":0,"op":31.0000012626559,"w":400,"h":250,"nm":"loader_shape","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"circle 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[278.25,202.671,0],"ix":2},"a":{"a":0,"k":[23.72,23.72,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[12.935,0],[0,-12.936],[-12.935,0],[0,12.935]],"o":[[-12.952,0],[0,12.935],[12.935,0],[0,-12.936]],"v":[[0,-23.471],[-23.47,0.001],[0,23.471],[23.47,0.001]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0.427451010311,0.976470648074,1],"ix":4},"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":10,"s":[10]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":19.99,"s":[100]},{"t":29.9800012211104,"s":[10]}],"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[23.72,23.721],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":48.0000019550801,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"square 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[196.25,201.271,0],"ix":2},"a":{"a":0,"k":[22.028,22.03,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.914,0],[0,0],[0,-1.914],[0,0],[-1.914,0],[0,0],[0,1.914],[0,0]],"o":[[0,0],[-1.914,0],[0,0],[0,1.914],[0,0],[1.914,0],[0,0],[0,-1.914]],"v":[[18.313,-21.779],[-18.312,-21.779],[-21.779,-18.313],[-21.779,18.314],[-18.312,21.779],[18.313,21.779],[21.779,18.314],[21.779,-18.313]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0.427451010311,0.976470648074,1],"ix":4},"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":5,"s":[10]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":14.99,"s":[100]},{"t":24.9800010174563,"s":[10]}],"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[22.028,22.029],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":47.0000019143492,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Triangle 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[116.25,200.703,0],"ix":2},"a":{"a":0,"k":[27.11,21.243,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0.558,-0.879],[0,0],[-1.133,0],[0,0],[0.609,0.947],[0,0]],"o":[[-0.558,-0.879],[0,0],[-0.609,0.947],[0,0],[1.133,0],[0,0],[0,0]],"v":[[1.209,-20.114],[-1.192,-20.114],[-26.251,18.795],[-25.051,20.993],[25.051,20.993],[26.251,18.795],[1.192,-20.114]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0.427451010311,0.976470648074,1],"ix":4},"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[10]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":9.99,"s":[100]},{"t":19.9800008138021,"s":[10]}],"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[27.11,21.243],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":48.0000019550801,"st":0,"bm":0}],"markers":[]}
                            })
                            </script>
                            "#))

                        h3 style="text-align: center;" { "Please wait while we process your payment..." }
                    }

                // This is the iframe recommended by cybersource but the redirection happens inside this iframe once otp
                // is received and we lose control of the redirection on user client browser, so to avoid that we have removed this iframe and directly consumed it.
                // (PreEscaped(r#"<iframe id="step_up_iframe" style="border: none; margin-left: auto; margin-right: auto; display: block" height="800px" width="400px" name="stepUpIframe"></iframe>"#))
                (PreEscaped(format!("<form id=\"step-up-form\" method=\"POST\" action=\"{step_up_url}\">
                <input type=\"hidden\" name=\"JWT\" value=\"{access_token}\">
              </form>")))
              (PreEscaped(format!("<script>
              {logging_template}
              window.onload = function() {{
              var stepUpForm = document.querySelector('#step-up-form'); if(stepUpForm) stepUpForm.submit();
              }}
              </script>")))
            }}
        }
        RedirectForm::BlueSnap {
            payment_fields_token,
        } => {
            let card_details = if let Some(PaymentMethodData::Card(ccard)) = payment_method_data {
                format!(
                    "var saveCardDirectly={{cvv: \"{}\",amount: {},currency: \"{}\"}};",
                    ccard.card_cvc.peek(),
                    amount,
                    currency
                )
            } else {
                "".to_string()
            };
            let bluesnap_sdk_url = config.connectors.bluesnap.secondary_base_url;
            maud::html! {
            (maud::DOCTYPE)
            html {
                head {
                    meta name="viewport" content="width=device-width, initial-scale=1";
                    (PreEscaped(format!("<script src=\"{bluesnap_sdk_url}web-sdk/5/bluesnap.js\"></script>")))
                }
                    body style="background-color: #ffffff; padding: 20px; font-family: Arial, Helvetica, Sans-Serif;" {

                        div id="loader1" class="lottie" style="height: 150px; display: block; position: relative; margin-top: 150px; margin-left: auto; margin-right: auto;" { "" }

                        (PreEscaped(r#"<script src="https://cdnjs.cloudflare.com/ajax/libs/bodymovin/5.7.4/lottie.min.js"></script>"#))

                        (PreEscaped(r#"
                        <script>
                        var anime = bodymovin.loadAnimation({
                            container: document.getElementById('loader1'),
                            renderer: 'svg',
                            loop: true,
                            autoplay: true,
                            name: 'hyperswitch loader',
                            animationData: {"v":"4.8.0","meta":{"g":"LottieFiles AE 3.1.1","a":"","k":"","d":"","tc":""},"fr":29.9700012207031,"ip":0,"op":31.0000012626559,"w":400,"h":250,"nm":"loader_shape","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"circle 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[278.25,202.671,0],"ix":2},"a":{"a":0,"k":[23.72,23.72,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[12.935,0],[0,-12.936],[-12.935,0],[0,12.935]],"o":[[-12.952,0],[0,12.935],[12.935,0],[0,-12.936]],"v":[[0,-23.471],[-23.47,0.001],[0,23.471],[23.47,0.001]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0.427451010311,0.976470648074,1],"ix":4},"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":10,"s":[10]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":19.99,"s":[100]},{"t":29.9800012211104,"s":[10]}],"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[23.72,23.721],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":48.0000019550801,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"square 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[196.25,201.271,0],"ix":2},"a":{"a":0,"k":[22.028,22.03,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.914,0],[0,0],[0,-1.914],[0,0],[-1.914,0],[0,0],[0,1.914],[0,0]],"o":[[0,0],[-1.914,0],[0,0],[0,1.914],[0,0],[1.914,0],[0,0],[0,-1.914]],"v":[[18.313,-21.779],[-18.312,-21.779],[-21.779,-18.313],[-21.779,18.314],[-18.312,21.779],[18.313,21.779],[21.779,18.314],[21.779,-18.313]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0.427451010311,0.976470648074,1],"ix":4},"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":5,"s":[10]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":14.99,"s":[100]},{"t":24.9800010174563,"s":[10]}],"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[22.028,22.029],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":47.0000019143492,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Triangle 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[116.25,200.703,0],"ix":2},"a":{"a":0,"k":[27.11,21.243,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0.558,-0.879],[0,0],[-1.133,0],[0,0],[0.609,0.947],[0,0]],"o":[[-0.558,-0.879],[0,0],[-0.609,0.947],[0,0],[1.133,0],[0,0],[0,0]],"v":[[1.209,-20.114],[-1.192,-20.114],[-26.251,18.795],[-25.051,20.993],[25.051,20.993],[26.251,18.795],[1.192,-20.114]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0.427451010311,0.976470648074,1],"ix":4},"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[10]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":9.99,"s":[100]},{"t":19.9800008138021,"s":[10]}],"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[27.11,21.243],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":48.0000019550801,"st":0,"bm":0}],"markers":[]}
                        })
                        </script>
                        "#))

                        h3 style="text-align: center;" { "Please wait while we process your payment..." }
                    }

                (PreEscaped(format!("<script>
                    {logging_template}
                    bluesnap.threeDsPaymentsSetup(\"{payment_fields_token}\",
                    function(sdkResponse) {{
                        // console.log(sdkResponse);
                        var f = document.createElement('form');
                        f.action=window.location.pathname.replace(/payments\\/redirect\\/(\\w+)\\/(\\w+)\\/\\w+/, \"payments/$1/$2/redirect/complete/bluesnap?paymentToken={payment_fields_token}\");
                        f.method='POST';
                        var i=document.createElement('input');
                        i.type='hidden';
                        i.name='authentication_response';
                        i.value=JSON.stringify(sdkResponse);
                        f.appendChild(i);
                        document.body.appendChild(f);
                        f.submit();
                    }});
                    {card_details}
                    bluesnap.threeDsPaymentsSubmitData(saveCardDirectly);
                </script>
                ")))
                }}
        }
        RedirectForm::CybersourceAuthSetup {
            access_token,
            ddc_url,
            reference_id,
        } => {
            maud::html! {
            (maud::DOCTYPE)
            html {
                head {
                    meta name="viewport" content="width=device-width, initial-scale=1";
                }
                    body style="background-color: #ffffff; padding: 20px; font-family: Arial, Helvetica, Sans-Serif;" {

                        div id="loader1" class="lottie" style="height: 150px; display: block; position: relative; margin-top: 150px; margin-left: auto; margin-right: auto;" { "" }

                        (PreEscaped(r#"<script src="https://cdnjs.cloudflare.com/ajax/libs/bodymovin/5.7.4/lottie.min.js"></script>"#))

                        (PreEscaped(r#"
                            <script>
                            var anime = bodymovin.loadAnimation({
                                container: document.getElementById('loader1'),
                                renderer: 'svg',
                                loop: true,
                                autoplay: true,
                                name: 'hyperswitch loader',


// Implementation: impl api::PaymentCapture for for Sift
// File: crates/hyperswitch_connectors/src/connectors/sift.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl api::PaymentCapture for for Sift


// Implementation: impl Default for for ZeroMandates
// File: crates/payment_methods/src/configs/payment_connector_required_fields.rs
// Module: payment_methods
// Methods: 1 total (0 public)

impl Default for for ZeroMandates


// Function: parse_and_log_keys_in_url_encoded_response
// File: crates/hyperswitch_connectors/src/connectors/fiuu.rs
// Module: hyperswitch_connectors

pub fn parse_and_log_keys_in_url_encoded_response<T>(data: &[u8])


// File: crates/hyperswitch_connectors/src/connectors/finix/transformers.rs
// Module: hyperswitch_connectors
// Public structs: 8

use common_enums::enums;
use common_utils::types::MinorUnit;
use hyperswitch_domain_models::{
    payment_method_data::PaymentMethodData,
    router_data::{ConnectorAuthType, RouterData},
    router_flow_types::refunds::{Execute, RSync},
    router_request_types::ResponseId,
    router_response_types::{PaymentsResponseData, RefundsResponseData},
    types::{PaymentsAuthorizeRouterData, RefundsRouterData},
};
use hyperswitch_interfaces::errors;
use masking::Secret;
use serde::{Deserialize, Serialize};

use crate::types::{RefundsResponseRouterData, ResponseRouterData};

//TODO: Fill the struct with respective fields
pub struct FinixRouterData<T> {
    pub amount: MinorUnit, // The type of amount that a connector accepts, for example, String, i64, f64, etc.
    pub router_data: T,
}

impl<T> From<(MinorUnit, T)> for FinixRouterData<T> {
    fn from((amount, item): (MinorUnit, T)) -> Self {
        //Todo :  use utils to convert the amount to the type of amount that a connector accepts
        Self {
            amount,
            router_data: item,
        }
    }
}

//TODO: Fill the struct with respective fields
#[derive(Default, Debug, Serialize, PartialEq)]
pub struct FinixPaymentsRequest {
    amount: MinorUnit,
    card: FinixCard,
}

#[derive(Default, Debug, Serialize, Eq, PartialEq)]
pub struct FinixCard {
    number: cards::CardNumber,
    expiry_month: Secret<String>,
    expiry_year: Secret<String>,
    cvc: Secret<String>,
    complete: bool,
}

impl TryFrom<&FinixRouterData<&PaymentsAuthorizeRouterData>> for FinixPaymentsRequest {
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(item: &FinixRouterData<&PaymentsAuthorizeRouterData>) -> Result<Self, Self::Error> {
        match item.router_data.request.payment_method_data.clone() {
            PaymentMethodData::Card(_) => Err(errors::ConnectorError::NotImplemented(
                "Card payment method not implemented".to_string(),
            )
            .into()),
            _ => Err(errors::ConnectorError::NotImplemented("Payment method".to_string()).into()),
        }
    }
}

//TODO: Fill the struct with respective fields
// Auth Struct
pub struct FinixAuthType {
    pub(super) api_key: Secret<String>,
}

impl TryFrom<&ConnectorAuthType> for FinixAuthType {
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(auth_type: &ConnectorAuthType) -> Result<Self, Self::Error> {
        match auth_type {
            ConnectorAuthType::HeaderKey { api_key } => Ok(Self {
                api_key: api_key.to_owned(),
            }),
            _ => Err(errors::ConnectorError::FailedToObtainAuthType.into()),
        }
    }
}
// PaymentsResponse
//TODO: Append the remaining status flags
#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum FinixPaymentStatus {
    Succeeded,
    Failed,
    #[default]
    Processing,
}

impl From<FinixPaymentStatus> for common_enums::AttemptStatus {
    fn from(item: FinixPaymentStatus) -> Self {
        match item {
            FinixPaymentStatus::Succeeded => Self::Charged,
            FinixPaymentStatus::Failed => Self::Failure,
            FinixPaymentStatus::Processing => Self::Authorizing,
        }
    }
}

//TODO: Fill the struct with respective fields
#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct FinixPaymentsResponse {
    status: FinixPaymentStatus,
    id: String,
}

impl<F, T> TryFrom<ResponseRouterData<F, FinixPaymentsResponse, T, PaymentsResponseData>>
    for RouterData<F, T, PaymentsResponseData>
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: ResponseRouterData<F, FinixPaymentsResponse, T, PaymentsResponseData>,
    ) -> Result<Self, Self::Error> {
        Ok(Self {
            status: common_enums::AttemptStatus::from(item.response.status),
            response: Ok(PaymentsResponseData::TransactionResponse {
                resource_id: ResponseId::ConnectorTransactionId(item.response.id),
                redirection_data: Box::new(None),
                mandate_reference: Box::new(None),
                connector_metadata: None,
                network_txn_id: None,
                connector_response_reference_id: None,
                incremental_authorization_allowed: None,
                charges: None,
            }),
            ..item.data
        })
    }
}

//TODO: Fill the struct with respective fields
// REFUND :
// Type definition for RefundRequest
#[derive(Default, Debug, Serialize)]
pub struct FinixRefundRequest {
    pub amount: MinorUnit,
}

impl<F> TryFrom<&FinixRouterData<&RefundsRouterData<F>>> for FinixRefundRequest {
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(item: &FinixRouterData<&RefundsRouterData<F>>) -> Result<Self, Self::Error> {
        Ok(Self {
            amount: item.amount.to_owned(),
        })
    }
}

// Type definition for Refund Response

#[allow(dead_code)]
#[derive(Debug, Copy, Serialize, Default, Deserialize, Clone)]
pub enum RefundStatus {
    Succeeded,
    Failed,
    #[default]
    Processing,
}

impl From<RefundStatus> for enums::RefundStatus {
    fn from(item: RefundStatus) -> Self {
        match item {
            RefundStatus::Succeeded => Self::Success,
            RefundStatus::Failed => Self::Failure,
            RefundStatus::Processing => Self::Pending,
            //TODO: Review mapping
        }
    }
}

//TODO: Fill the struct with respective fields
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
pub struct RefundResponse {
    id: String,
    status: RefundStatus,
}

impl TryFrom<RefundsResponseRouterData<Execute, RefundResponse>> for RefundsRouterData<Execute> {
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: RefundsResponseRouterData<Execute, RefundResponse>,
    ) -> Result<Self, Self::Error> {
        Ok(Self {
            response: Ok(RefundsResponseData {
                connector_refund_id: item.response.id.to_string(),
                refund_status: enums::RefundStatus::from(item.response.status),
            }),
            ..item.data
        })
    }
}

impl TryFrom<RefundsResponseRouterData<RSync, RefundResponse>> for RefundsRouterData<RSync> {
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: RefundsResponseRouterData<RSync, RefundResponse>,
    ) -> Result<Self, Self::Error> {
        Ok(Self {
            response: Ok(RefundsResponseData {
                connector_refund_id: item.response.id.to_string(),
                refund_status: enums::RefundStatus::from(item.response.status),
            }),
            ..item.data
        })
    }
}

//TODO: Fill the struct with respective fields
#[derive(Default, Debug, Serialize, Deserialize, PartialEq)]
pub struct FinixErrorResponse {
    pub status_code: u16,
    pub code: String,
    pub message: String,
    pub reason: Option<String>,
    pub network_advice_code: Option<String>,
    pub network_decline_code: Option<String>,
    pub network_error_message: Option<String>,
}


// Function: get_payment_status_for_sync
// File: crates/hyperswitch_connectors/src/connectors/trustpayments/transformers.rs
// Module: hyperswitch_connectors

pub fn get_payment_status_for_sync(&self) -> common_enums::AttemptStatus


// Implementation: impl Hash for for ApiEventMetricsBucketIdentifier
// File: crates/api_models/src/analytics/api_event.rs
// Module: api_models
// Methods: 1 total (0 public)

impl Hash for for ApiEventMetricsBucketIdentifier


// Implementation: impl api::PaymentsCompleteAuthorize for for Payme
// File: crates/hyperswitch_connectors/src/connectors/payme.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl api::PaymentsCompleteAuthorize for for Payme


// Function: insert_org_in_db
// File: crates/router/src/types/domain/user.rs
// Module: router

pub fn insert_org_in_db(self, state: SessionState) -> UserResult<Organization>


// Struct: CybersourceAuthValidateRequest
// File: crates/hyperswitch_connectors/src/connectors/cybersource/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct CybersourceAuthValidateRequest


// Function: get_should_call_gsm_key
// File: crates/common_utils/src/id_type/merchant.rs
// Module: common_utils

// Documentation: Get should call gsm key for payment

pub fn get_should_call_gsm_key(&self) -> String


// Struct: BankOfAmericaRouterData
// File: crates/hyperswitch_connectors/src/connectors/bankofamerica/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct BankOfAmericaRouterData<T>


// Struct: GsmDeleteResponse
// File: crates/api_models/src/gsm.rs
// Module: api_models
// Implementations: 0

pub struct GsmDeleteResponse


// Function: check_two_factor_auth_status
// File: crates/router/src/routes/user.rs
// Module: router

pub fn check_two_factor_auth_status(
    state: web::Data<AppState>,
    req: HttpRequest,
) -> HttpResponse


// Function: contract_based_routing_update_configs
// File: crates/router/src/core/routing.rs
// Module: router

pub fn contract_based_routing_update_configs(
    state: SessionState,
    request: routing_types::ContractBasedRoutingConfig,
    merchant_context: domain::MerchantContext,
    algorithm_id: common_utils::id_type::RoutingId,
    profile_id: common_utils::id_type::ProfileId,
) -> RouterResponse<routing_types::RoutingDictionaryRecord>


// Module Structure
// File: crates/hyperswitch_connectors/src/connectors/payload.rs
// Module: hyperswitch_connectors

// Public submodules:
pub mod transformers;


// File: crates/api_models/src/blocklist.rs
// Module: api_models
// Public structs: 7

use common_enums::enums;
use common_utils::events::ApiEventMetric;
use masking::StrongSecret;
use utoipa::ToSchema;

#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ToSchema)]
#[serde(rename_all = "snake_case", tag = "type", content = "data")]
pub enum BlocklistRequest {
    CardBin(String),
    Fingerprint(String),
    ExtendedCardBin(String),
}

#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ToSchema)]
pub struct GenerateFingerprintRequest {
    pub card: Card,
    pub hash_key: StrongSecret<String>,
}
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
pub struct Card {
    pub card_number: StrongSecret<String>,
}
pub type AddToBlocklistRequest = BlocklistRequest;
pub type DeleteFromBlocklistRequest = BlocklistRequest;

#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ToSchema)]
pub struct BlocklistResponse {
    pub fingerprint_id: String,
    #[schema(value_type = BlocklistDataKind)]
    pub data_kind: enums::BlocklistDataKind,
    #[serde(with = "common_utils::custom_serde::iso8601")]
    pub created_at: time::PrimitiveDateTime,
}

#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "snake_case")]
pub struct GenerateFingerprintResponsePayload {
    pub card_fingerprint: String,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ToSchema)]
pub struct ToggleBlocklistResponse {
    pub blocklist_guard_status: String,
}

pub type AddToBlocklistResponse = BlocklistResponse;
pub type DeleteFromBlocklistResponse = BlocklistResponse;

#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ToSchema)]
pub struct ListBlocklistQuery {
    #[schema(value_type = BlocklistDataKind)]
    pub data_kind: enums::BlocklistDataKind,
    #[serde(default = "default_list_limit")]
    pub limit: u16,
    #[serde(default)]
    pub offset: u16,
    pub client_secret: Option<String>,
}

fn default_list_limit() -> u16 {
    10
}

#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ToSchema)]
pub struct ToggleBlocklistQuery {
    #[schema(value_type = BlocklistDataKind)]
    pub status: bool,
}

impl ApiEventMetric for BlocklistRequest {}
impl ApiEventMetric for BlocklistResponse {}
impl ApiEventMetric for ToggleBlocklistResponse {}
impl ApiEventMetric for ListBlocklistQuery {}
impl ApiEventMetric for GenerateFingerprintRequest {}
impl ApiEventMetric for ToggleBlocklistQuery {}
impl ApiEventMetric for GenerateFingerprintResponsePayload {}
impl ApiEventMetric for Card {}


// Function: handle_unified_connector_service_response_for_payment_get
// File: crates/router/src/core/unified_connector_service.rs
// Module: router

pub fn handle_unified_connector_service_response_for_payment_get(
    response: payments_grpc::PaymentServiceGetResponse,
) -> UnifiedConnectorServiceResult


// Struct: Address
// File: crates/hyperswitch_connectors/src/connectors/shift4/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct Address


// Implementation: impl DisputeMetricAccumulator for for DisputedAmountAccumulator
// File: crates/analytics/src/disputes/accumulators.rs
// Module: analytics
// Methods: 2 total (0 public)

impl DisputeMetricAccumulator for for DisputedAmountAccumulator


// Implementation: impl api::RefundExecute for for Rapyd
// File: crates/hyperswitch_connectors/src/connectors/rapyd.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl api::RefundExecute for for Rapyd


// Function: create_merchant_account
// File: crates/router/src/core/admin.rs
// Module: router

pub fn create_merchant_account(
    state: SessionState,
    req: api::MerchantAccountCreate,
    org_data_from_auth: Option<authentication::AuthenticationDataWithOrg>,
) -> RouterResponse<api::MerchantAccountResponse>


// Struct: PaypalRedirectionStruct
// File: crates/hyperswitch_connectors/src/connectors/paypal/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct PaypalRedirectionStruct


// Implementation: impl IncomingWebhook for for Adyenplatform
// File: crates/hyperswitch_connectors/src/connectors/adyenplatform.rs
// Module: hyperswitch_connectors
// Methods: 8 total (0 public)

impl IncomingWebhook for for Adyenplatform


// Function: get_api_key
// File: crates/router/src/services/authentication.rs
// Module: router

pub fn get_api_key(headers: &HeaderMap) -> RouterResult<&str>


// Struct: PaypalAdditionalData
// File: crates/common_utils/src/payout_method_utils.rs
// Module: common_utils
// Implementations: 0

pub struct PaypalAdditionalData


// Implementation: impl api::PaymentToken for for Digitalvirgo
// File: crates/hyperswitch_connectors/src/connectors/digitalvirgo.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl api::PaymentToken for for Digitalvirgo


// Struct: Customer
// File: crates/hyperswitch_domain_models/src/customer.rs
// Module: hyperswitch_domain_models
// Implementations: 3
// Traits: behaviour::Conversion, behaviour::Conversion

pub struct Customer


// Implementation: impl RecoveryPaymentTuple
// File: crates/router/src/core/webhooks/recovery_incoming.rs
// Module: router
// Methods: 2 total (1 public)

impl RecoveryPaymentTuple


// Struct: Log
// File: crates/router_env/src/logger/config.rs
// Module: router_env
// Implementations: 0

pub struct Log


// File: crates/hyperswitch_interfaces/src/webhooks.rs
// Module: hyperswitch_interfaces
// Public structs: 1

//! Webhooks interface

use common_utils::{crypto, errors::CustomResult, ext_traits::ValueExt};
use error_stack::ResultExt;
use hyperswitch_domain_models::{
    api::ApplicationResponse, errors::api_error_response::ApiErrorResponse,
};
use masking::{ExposeInterface, Secret};

use crate::{api::ConnectorCommon, errors};

/// struct IncomingWebhookRequestDetails
#[derive(Debug)]
pub struct IncomingWebhookRequestDetails<'a> {
    /// method
    pub method: http::Method,
    /// uri
    pub uri: http::Uri,
    /// headers
    pub headers: &'a actix_web::http::header::HeaderMap,
    /// body
    pub body: &'a [u8],
    /// query_params
    pub query_params: String,
}

/// IncomingWebhookFlowError enum defining the error type for incoming webhook
#[derive(Debug)]
pub enum IncomingWebhookFlowError {
    /// Resource not found for the webhook
    ResourceNotFound,
    /// Internal error for the webhook
    InternalError,
}

impl From<&ApiErrorResponse> for IncomingWebhookFlowError {
    fn from(api_error_response: &ApiErrorResponse) -> Self {
        match api_error_response {
            ApiErrorResponse::WebhookResourceNotFound
            | ApiErrorResponse::DisputeNotFound { .. }
            | ApiErrorResponse::PayoutNotFound
            | ApiErrorResponse::MandateNotFound
            | ApiErrorResponse::PaymentNotFound
            | ApiErrorResponse::RefundNotFound
            | ApiErrorResponse::AuthenticationNotFound { .. } => Self::ResourceNotFound,
            _ => Self::InternalError,
        }
    }
}

/// Trait defining incoming webhook
#[async_trait::async_trait]
pub trait IncomingWebhook: ConnectorCommon + Sync {
    /// fn get_webhook_body_decoding_algorithm
    fn get_webhook_body_decoding_algorithm(
        &self,
        _request: &IncomingWebhookRequestDetails<'_>,
    ) -> CustomResult<Box<dyn crypto::DecodeMessage + Send>, errors::ConnectorError> {
        Ok(Box::new(crypto::NoAlgorithm))
    }

    /// fn get_webhook_body_decoding_message
    fn get_webhook_body_decoding_message(
        &self,
        request: &IncomingWebhookRequestDetails<'_>,
    ) -> CustomResult<Vec<u8>, errors::ConnectorError> {
        Ok(request.body.to_vec())
    }

    /// fn decode_webhook_body
    async fn decode_webhook_body(
        &self,
        request: &IncomingWebhookRequestDetails<'_>,
        merchant_id: &common_utils::id_type::MerchantId,
        connector_webhook_details: Option<common_utils::pii::SecretSerdeValue>,
        connector_name: &str,
    ) -> CustomResult<Vec<u8>, errors::ConnectorError> {
        let algorithm = self.get_webhook_body_decoding_algorithm(request)?;

        let message = self
            .get_webhook_body_decoding_message(request)
            .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)?;
        let secret = self
            .get_webhook_source_verification_merchant_secret(
                merchant_id,
                connector_name,
                connector_webhook_details,
            )
            .await
            .change_context(errors::ConnectorError::WebhookSourceVerificationFailed)?;

        algorithm
            .decode_message(&secret.secret, message.into())
            .change_context(errors::ConnectorError::WebhookBodyDecodingFailed)
    }

    /// fn get_webhook_source_verification_algorithm
    fn get_webhook_source_verification_algorithm(
        &self,
        _request: &IncomingWebhookRequestDetails<'_>,
    ) -> CustomResult<Box<dyn crypto::VerifySignature + Send>, errors::ConnectorError> {
        Ok(Box::new(crypto::NoAlgorithm))
    }

    /// fn get_webhook_source_verification_merchant_secret
    async fn get_webhook_source_verification_merchant_secret(
        &self,
        merchant_id: &common_utils::id_type::MerchantId,
        connector_name: &str,
        connector_webhook_details: Option<common_utils::pii::SecretSerdeValue>,
    ) -> CustomResult<api_models::webhooks::ConnectorWebhookSecrets, errors::ConnectorError> {
        let debug_suffix =
            format!("For merchant_id: {merchant_id:?}, and connector_name: {connector_name}");
        let default_secret = "default_secret".to_string();
        let merchant_secret = match connector_webhook_details {
            Some(merchant_connector_webhook_details) => {
                let connector_webhook_details = merchant_connector_webhook_details
                    .parse_value::<api_models::admin::MerchantConnectorWebhookDetails>(
                        "MerchantConnectorWebhookDetails",
                    )
                    .change_context_lazy(|| errors::ConnectorError::WebhookSourceVerificationFailed)
                    .attach_printable_lazy(|| {
                        format!(
                            "Deserializing MerchantConnectorWebhookDetails failed {debug_suffix}",
                        )
                    })?;
                api_models::webhooks::ConnectorWebhookSecrets {
                    secret: connector_webhook_details
                        .merchant_secret
                        .expose()
                        .into_bytes(),
                    additional_secret: connector_webhook_details.additional_secret,
                }
            }

            None => api_models::webhooks::ConnectorWebhookSecrets {
                secret: default_secret.into_bytes(),
                additional_secret: None,
            },
        };

        //need to fetch merchant secret from config table with caching in future for enhanced performance

        //If merchant has not set the secret for webhook source verification, "default_secret" is returned.
        //So it will fail during verification step and goes to psync flow.
        Ok(merchant_secret)
    }

    /// fn get_webhook_source_verification_signature
    fn get_webhook_source_verification_signature(
        &self,
        _request: &IncomingWebhookRequestDetails<'_>,
        _connector_webhook_secrets: &api_models::webhooks::ConnectorWebhookSecrets,
    ) -> CustomResult<Vec<u8>, errors::ConnectorError> {
        Ok(Vec::new())
    }

    /// fn get_webhook_source_verification_message
    fn get_webhook_source_verification_message(
        &self,
        _request: &IncomingWebhookRequestDetails<'_>,
        _merchant_id: &common_utils::id_type::MerchantId,
        _connector_webhook_secrets: &api_models::webhooks::ConnectorWebhookSecrets,
    ) -> CustomResult<Vec<u8>, errors::ConnectorError> {
        Ok(Vec::new())
    }

    /// fn verify_webhook_source
    async fn verify_webhook_source(
        &self,
        request: &IncomingWebhookRequestDetails<'_>,
        merchant_id: &common_utils::id_type::MerchantId,
        connector_webhook_details: Option<common_utils::pii::SecretSerdeValue>,
        _connector_account_details: crypto::Encryptable<Secret<serde_json::Value>>,
        connector_name: &str,
    ) -> CustomResult<bool, errors::ConnectorError> {
        let algorithm = self
            .get_webhook_source_verification_algorithm(request)
            .change_context(errors::ConnectorError::WebhookSourceVerificationFailed)?;

        let connector_webhook_secrets = self
            .get_webhook_source_verification_merchant_secret(
                merchant_id,
                connector_name,
                connector_webhook_details,
            )
            .await
            .change_context(errors::ConnectorError::WebhookSourceVerificationFailed)?;

        let signature = self
            .get_webhook_source_verification_signature(request, &connector_webhook_secrets)
            .change_context(errors::ConnectorError::WebhookSourceVerificationFailed)?;

        let message = self
            .get_webhook_source_verification_message(
                request,
                merchant_id,
                &connector_webhook_secrets,
            )
            .change_context(errors::ConnectorError::WebhookSourceVerificationFailed)?;

        algorithm
            .verify_signature(&connector_webhook_secrets.secret, &signature, &message)
            .change_context(errors::ConnectorError::WebhookSourceVerificationFailed)
    }

    /// fn get_webhook_object_reference_id
    fn get_webhook_object_reference_id(
        &self,
        _request: &IncomingWebhookRequestDetails<'_>,
    ) -> CustomResult<api_models::webhooks::ObjectReferenceId, errors::ConnectorError>;

    /// fn get_webhook_event_type
    fn get_webhook_event_type(
        &self,
        _request: &IncomingWebhookRequestDetails<'_>,
    ) -> CustomResult<api_models::webhooks::IncomingWebhookEvent, errors::ConnectorError>;

    /// fn get_webhook_resource_object
    fn get_webhook_resource_object(
        &self,
        _request: &IncomingWebhookRequestDetails<'_>,
    ) -> CustomResult<Box<dyn masking::ErasedMaskSerialize>, errors::ConnectorError>;

    /// fn get_webhook_api_response
    fn get_webhook_api_response(
        &self,
        _request: &IncomingWebhookRequestDetails<'_>,
        _error_kind: Option<IncomingWebhookFlowError>,
    ) -> CustomResult<ApplicationResponse<serde_json::Value>, errors::ConnectorError> {
        Ok(ApplicationResponse::StatusOk)
    }

    /// fn get_dispute_details
    fn get_dispute_details(
        &self,
        _request: &IncomingWebhookRequestDetails<'_>,
    ) -> CustomResult<crate::disputes::DisputePayload, errors::ConnectorError> {
        Err(errors::ConnectorError::NotImplemented("get_dispute_details method".to_string()).into())
    }

    /// fn get_external_authentication_details
    fn get_external_authentication_details(
        &self,
        _request: &IncomingWebhookRequestDetails<'_>,
    ) -> CustomResult<crate::authentication::ExternalAuthenticationPayload, errors::ConnectorError>
    {
        Err(errors::ConnectorError::NotImplemented(
            "get_external_authentication_details method".to_string(),
        )
        .into())
    }

    /// fn get_mandate_details
    fn get_mandate_details(
        &self,
        _request: &IncomingWebhookRequestDetails<'_>,
    ) -> CustomResult<
        Option<hyperswitch_domain_models::router_flow_types::ConnectorMandateDetails>,
        errors::ConnectorError,
    > {
        Ok(None)
    }

    /// fn get_network_txn_id
    fn get_network_txn_id(
        &self,
        _request: &IncomingWebhookRequestDetails<'_>,
    ) -> CustomResult<
        Option<hyperswitch_domain_models::router_flow_types::ConnectorNetworkTxnId>,
        errors::ConnectorError,
    > {
        Ok(None)
    }

    #[cfg(all(feature = "revenue_recovery", feature = "v2"))]
    /// get revenue recovery invoice details
    fn get_revenue_recovery_attempt_details(
        &self,
        _request: &IncomingWebhookRequestDetails<'_>,
    ) -> CustomResult<
        hyperswitch_domain_models::revenue_recovery::RevenueRecoveryAttemptData,
        errors::ConnectorError,
    > {
        Err(errors::ConnectorError::NotImplemented(
            "get_revenue_recovery_attempt_details method".to_string(),
        )
        .into())
    }
    #[cfg(all(feature = "revenue_recovery", feature = "v2"))]
    /// get revenue recovery transaction details
    fn get_revenue_recovery_invoice_details(
        &self,
        _request: &IncomingWebhookRequestDetails<'_>,
    ) -> CustomResult<
        hyperswitch_domain_models::revenue_recovery::RevenueRecoveryInvoiceData,
        errors::ConnectorError,
    > {
        Err(errors::ConnectorError::NotImplemented(
            "get_revenue_recovery_invoice_details method".to_string(),
        )
        .into())
    }
}


// Function: get_expiry_date_as_mmyy
// File: crates/common_types/src/payments.rs
// Module: common_types

// Documentation: Get the expiry date in MMYY format from the Google Pay pre-decrypt data

pub fn get_expiry_date_as_mmyy(&self) -> Result<Secret<String>, errors::ValidationError>


// Implementation: impl webhooks::IncomingWebhook for for Inespay
// File: crates/hyperswitch_connectors/src/connectors/inespay.rs
// Module: hyperswitch_connectors
// Methods: 7 total (0 public)

impl webhooks::IncomingWebhook for for Inespay


// Struct: ZenWebhookBody
// File: crates/hyperswitch_connectors/src/connectors/zen/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct ZenWebhookBody


// Implementation: impl api::PaymentCapture for for Stax
// File: crates/hyperswitch_connectors/src/connectors/stax.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl api::PaymentCapture for for Stax


// Struct: ServiceSessionIds
// File: crates/hyperswitch_connectors/src/connectors/unified_authentication_service/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct ServiceSessionIds


// Struct: DwollaAccessTokenResponse
// File: crates/hyperswitch_connectors/src/connectors/dwolla/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct DwollaAccessTokenResponse


// Implementation: impl api::Payment for for Breadpay
// File: crates/hyperswitch_connectors/src/connectors/breadpay.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl api::Payment for for Breadpay


// Implementation: impl api::Refund for for Barclaycard
// File: crates/hyperswitch_connectors/src/connectors/barclaycard.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl api::Refund for for Barclaycard


// Struct: ResetPassword
// File: crates/router/src/services/email/types.rs
// Module: router
// Implementations: 1
// Traits: EmailData

pub struct ResetPassword


// Implementation: impl api::MandateSetup for for Opennode
// File: crates/hyperswitch_connectors/src/connectors/opennode.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl api::MandateSetup for for Opennode


// Struct: BillwerkCaptureRequest
// File: crates/hyperswitch_connectors/src/connectors/billwerk/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct BillwerkCaptureRequest


// Function: merchant_account_retrieve
// File: crates/openapi/src/routes/merchant_account.rs
// Module: openapi

pub fn merchant_account_retrieve()


// Implementation: impl api::payments::PaymentsCompleteAuthorize for for Prophetpay
// File: crates/hyperswitch_connectors/src/connectors/prophetpay.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl api::payments::PaymentsCompleteAuthorize for for Prophetpay


// Function: new
// File: crates/storage_impl/src/mock_db.rs
// Module: storage_impl

pub fn new(redis: &RedisSettings) -> error_stack::Result<Self, StorageError>


// Function: list_invitations_for_user
// File: crates/router/src/routes/user_role.rs
// Module: router

pub fn list_invitations_for_user(
    state: web::Data<AppState>,
    req: HttpRequest,
) -> HttpResponse


// File: crates/hyperswitch_connectors/src/connectors/worldpay/response.rs
// Module: hyperswitch_connectors
// Public functions: 5
// Public structs: 30

use error_stack::ResultExt;
use hyperswitch_interfaces::errors;
use masking::Secret;
use serde::{Deserialize, Serialize};
use url::Url;

use super::requests::*;

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct WorldpayPaymentsResponse {
    pub outcome: PaymentOutcome,
    pub transaction_reference: Option<String>,
    #[serde(flatten)]
    pub other_fields: Option<WorldpayPaymentResponseFields>,
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(untagged)]
pub enum WorldpayPaymentResponseFields {
    RefusedResponse(RefusedResponse),
    DDCResponse(DDCResponse),
    ThreeDsChallenged(ThreeDsChallengedResponse),
    FraudHighRisk(FraudHighRiskResponse),
    AuthorizedResponse(Box<AuthorizedResponse>),
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AuthorizedResponse {
    pub payment_instrument: PaymentsResPaymentInstrument,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub issuer: Option<Issuer>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub scheme: Option<PaymentsResponseScheme>,
    #[serde(rename = "_links", skip_serializing_if = "Option::is_none")]
    pub links: Option<SelfLink>,
    #[serde(rename = "_actions")]
    pub actions: Option<ActionLinks>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub description: Option<String>,
    pub risk_factors: Option<Vec<RiskFactorsInner>>,
    pub fraud: Option<Fraud>,
    /// Mandate's token
    pub token: Option<MandateToken>,
    /// Network transaction ID
    pub scheme_reference: Option<Secret<String>>,
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct MandateToken {
    pub href: Secret<String>,
    pub token_id: String,
    pub token_expiry_date_time: String,
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct FraudHighRiskResponse {
    pub score: f32,
    pub reason: Vec<String>,
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RefusedResponse {
    pub refusal_description: String,
    // Access Worldpay returns a raw response code in the refusalCode field (if enabled) containing the unmodified response code received either directly from the card scheme for Worldpay-acquired transactions, or from third party acquirers.
    pub refusal_code: String,
    pub risk_factors: Option<Vec<RiskFactorsInner>>,
    pub fraud: Option<Fraud>,
    #[serde(rename = "threeDS")]
    pub three_ds: Option<ThreeDsResponse>,
    pub advice: Option<Advice>,
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct Advice {
    pub code: Option<String>,
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ThreeDsResponse {
    pub outcome: String,
    pub issuer_response: IssuerResponse,
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ThreeDsChallengedResponse {
    pub authentication: AuthenticationResponse,
    pub challenge: ThreeDsChallenge,
    #[serde(rename = "_actions")]
    pub actions: CompleteThreeDsActionLink,
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct AuthenticationResponse {
    pub version: String,
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct ThreeDsChallenge {
    pub reference: String,
    pub url: Url,
    pub jwt: Secret<String>,
    pub payload: Secret<String>,
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct CompleteThreeDsActionLink {
    #[serde(rename = "complete3dsChallenge")]
    pub complete_three_ds_challenge: ActionLink,
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum IssuerResponse {
    Challenged,
    Frictionless,
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct DDCResponse {
    pub device_data_collection: DDCToken,
    #[serde(rename = "_actions")]
    pub actions: DDCActionLink,
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct DDCToken {
    pub jwt: Secret<String>,
    pub url: Url,
    pub bin: Secret<String>,
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct DDCActionLink {
    #[serde(rename = "supply3dsDeviceData")]
    supply_ddc_data: ActionLink,
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum PaymentOutcome {
    #[serde(alias = "authorized", alias = "Authorized")]
    Authorized,
    Refused,
    SentForSettlement,
    SentForRefund,
    FraudHighRisk,
    #[serde(alias = "3dsDeviceDataRequired")]
    ThreeDsDeviceDataRequired,
    SentForCancellation,
    #[serde(alias = "3dsAuthenticationFailed")]
    ThreeDsAuthenticationFailed,
    SentForPartialRefund,
    #[serde(alias = "3dsChallenged")]
    ThreeDsChallenged,
    #[serde(alias = "3dsUnavailable")]
    ThreeDsUnavailable,
}

impl std::fmt::Display for PaymentOutcome {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            Self::Authorized => write!(f, "authorized"),
            Self::Refused => write!(f, "refused"),
            Self::SentForSettlement => write!(f, "sentForSettlement"),
            Self::SentForRefund => write!(f, "sentForRefund"),
            Self::FraudHighRisk => write!(f, "fraudHighRisk"),
            Self::ThreeDsDeviceDataRequired => write!(f, "3dsDeviceDataRequired"),
            Self::SentForCancellation => write!(f, "sentForCancellation"),
            Self::ThreeDsAuthenticationFailed => write!(f, "3dsAuthenticationFailed"),
            Self::SentForPartialRefund => write!(f, "sentForPartialRefund"),
            Self::ThreeDsChallenged => write!(f, "3dsChallenged"),
            Self::ThreeDsUnavailable => write!(f, "3dsUnavailable"),
        }
    }
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct SelfLink {
    #[serde(rename = "self")]
    pub self_link: SelfLinkInner,
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct SelfLinkInner {
    pub href: String,
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ActionLinks {
    supply_3ds_device_data: Option<ActionLink>,
    settle_payment: Option<ActionLink>,
    partially_settle_payment: Option<ActionLink>,
    refund_payment: Option<ActionLink>,
    partially_refund_payment: Option<ActionLink>,
    cancel_payment: Option<ActionLink>,
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct ActionLink {
    pub href: String,
    pub method: String,
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct Fraud {
    pub outcome: FraudOutcome,
    pub score: f32,
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum FraudOutcome {
    LowRisk,
    HighRisk,
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct WorldpayEventResponse {
    pub last_event: EventType,
    #[serde(rename = "_links", skip_serializing_if = "Option::is_none")]
    pub links: Option<EventLinks>,
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum EventType {
    SentForAuthorization,
    #[serde(alias = "Authorized")]
    Authorized,
    #[serde(alias = "Sent for Settlement")]
    SentForSettlement,
    Settled,
    SettlementFailed,
    Cancelled,
    Error,
    Expired,
    Refused,
    #[serde(alias = "Sent for Refund")]
    SentForRefund,
    Refunded,
    RefundFailed,
    #[serde(other)]
    Unknown,
}

#[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize)]
pub struct EventLinks {
    #[serde(rename = "payments:events", skip_serializing_if = "Option::is_none")]
    pub events: Option<String>,
}

pub fn get_resource_id<T, F>(
    response: WorldpayPaymentsResponse,
    connector_transaction_id: Option<String>,
    transform_fn: F,
) -> Result<T, error_stack::Report<errors::ConnectorError>>
where
    F: Fn(String) -> T,
{
    let optional_reference_id = response
        .other_fields
        .as_ref()
        .and_then(|other_fields| match other_fields {
            WorldpayPaymentResponseFields::AuthorizedResponse(res) => res
                .links
                .as_ref()
                .and_then(|link| link.self_link.href.rsplit_once('/').map(|(_, h)| h)),
            WorldpayPaymentResponseFields::DDCResponse(res) => {
                res.actions.supply_ddc_data.href.split('/').nth_back(1)
            }
            WorldpayPaymentResponseFields::ThreeDsChallenged(res) => res
                .actions
                .complete_three_ds_challenge
                .href
                .split('/')
                .nth_back(1),
            WorldpayPaymentResponseFields::FraudHighRisk(_)
            | WorldpayPaymentResponseFields::RefusedResponse(_) => None,
        })
        .map(|href| {
            urlencoding::decode(href)
                .map(|s| transform_fn(s.into_owned()))
                .change_context(errors::ConnectorError::ResponseHandlingFailed)
        })
        .transpose()?;
    optional_reference_id
        .or_else(|| connector_transaction_id.map(transform_fn))
        .ok_or_else(|| {
            errors::ConnectorError::MissingRequiredField {
                field_name: "_links.self.href",
            }
            .into()
        })
}

pub struct ResponseIdStr {
    pub id: String,
}

#[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Issuer {
    pub authorization_code: Secret<String>,
}

impl Issuer {
    pub fn new(code: String) -> Self {
        Self {
            authorization_code: Secret::new(code),
        }
    }
}

#[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct PaymentsResPaymentInstrument {
    #[serde(rename = "type")]
    pub payment_instrument_type: String,
    pub card_bin: Option<String>,
    pub last_four: Option<String>,
    pub expiry_date: Option<ExpiryDate>,
    pub card_brand: Option<String>,
    pub funding_type: Option<String>,
    pub category: Option<String>,
    pub issuer_name: Option<String>,
    pub payment_account_reference: Option<String>,
}

#[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RiskFactorsInner {
    #[serde(rename = "type")]
    pub risk_type: RiskType,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub detail: Option<Detail>,
    pub risk: Risk,
}

impl RiskFactorsInner {
    pub fn new(risk_type: RiskType, risk: Risk) -> Self {
        Self {
            risk_type,
            detail: None,
            risk,
        }
    }
}

#[derive(
    Clone, Copy, Default, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize,
)]
#[serde(rename_all = "camelCase")]
pub enum RiskType {
    #[default]
    Avs,
    Cvc,
    RiskProfile,
}

#[derive(
    Clone, Copy, Default, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize,
)]
#[serde(rename_all = "lowercase")]
pub enum Detail {
    #[default]
    Address,
    Postcode,
}

#[derive(
    Clone, Copy, Default, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize,
)]
#[serde(rename_all = "camelCase")]
pub enum Risk {
    #[default]
    NotChecked,
    NotMatched,
    NotSupplied,
    VerificationFailed,
}

#[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize)]
pub struct PaymentsResponseScheme {
    pub reference: String,
}

impl PaymentsResponseScheme {
    pub fn new(reference: String) -> Self {
        Self { reference }
    }
}

#[derive(Debug, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct WorldpayErrorResponse {
    pub error_name: String,
    pub message: String,
    pub validation_errors: Option<serde_json::Value>,
}

impl WorldpayErrorResponse {
    pub fn default(status_code: u16) -> Self {
        match status_code {
            code @ 404 => Self {
                error_name: format!("{code} Not found"),
                message: "Resource not found".to_string(),
                validation_errors: None,
            },
            code => Self {
                error_name: code.to_string(),
                message: "Unknown error".to_string(),
                validation_errors: None,
            },
        }
    }
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct WorldpayWebhookTransactionId {
    pub event_details: EventDetails,
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct EventDetails {
    #[serde(rename = "type")]
    pub event_type: EventType,
    pub transaction_reference: String,
    /// Mandate's token
    pub token: Option<MandateToken>,
    /// Network transaction ID
    pub scheme_reference: Option<Secret<String>>,
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct WorldpayWebhookEventType {
    pub event_id: String,
    pub event_timestamp: String,
    pub event_details: EventDetails,
}

/// Worldpay's unique reference ID for a request
pub(super) const WP_CORRELATION_ID: &str = "WP-CorrelationId";


// Struct: DeleteUserRoleRequest
// File: crates/api_models/src/user_role.rs
// Module: api_models
// Implementations: 0

pub struct DeleteUserRoleRequest


// Struct: ErrorObject
// File: crates/hyperswitch_connectors/src/connectors/braintree/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct ErrorObject


// Struct: OpensearchHits
// File: crates/api_models/src/analytics/search.rs
// Module: api_models
// Implementations: 0

pub struct OpensearchHits