        flow: PhantomData,
        merchant_id: merchant_context.get_merchant_account().get_id().clone(),
        customer_id,
        tenant_id: state.tenant.tenant_id.clone(),
        connector: connector_id.to_owned(),
        payment_id: payment_data
            .payment_attempt
            .payment_id
            .get_string_repr()
            .to_owned(),
        attempt_id: payment_data.payment_attempt.attempt_id.clone(),
        status: payment_data.payment_attempt.status,
        payment_method,
        connector_auth_type: auth_type,
        description: payment_data.payment_intent.description.clone(),
        address: unified_address,
        auth_type: payment_data
            .payment_attempt
            .authentication_type
            .unwrap_or_default(),
        connector_meta_data: merchant_connector_account.get_metadata(),
        connector_wallets_details: merchant_connector_account.get_connector_wallets_details(),
        request: types::PaymentsUpdateMetadataData::try_from(additional_data)?,
        response,
        amount_captured: payment_data
            .payment_intent
            .amount_captured
            .map(|amt| amt.get_amount_as_i64()),
        minor_amount_captured: payment_data.payment_intent.amount_captured,
        access_token: None,
        session_token: None,
        reference_id: None,
        payment_method_status: payment_data.payment_method_info.map(|info| info.status),
        payment_method_token: payment_data
            .pm_token
            .map(|token| types::PaymentMethodToken::Token(Secret::new(token))),
        connector_customer: payment_data.connector_customer_id,
        recurring_mandate_payment_data: payment_data.recurring_mandate_payment_data,
        connector_request_reference_id: core_utils::get_connector_request_reference_id(
            &state.conf,
            merchant_context.get_merchant_account().get_id(),
            &payment_data.payment_intent,
            &payment_data.payment_attempt,
            connector_id,
        )?,
        preprocessing_id: payment_data.payment_attempt.preprocessing_step_id,
        #[cfg(feature = "payouts")]
        payout_method_data: None,
        #[cfg(feature = "payouts")]
        quote_id: None,
        test_mode,
        payment_method_balance: None,
        connector_api_version,
        connector_http_status_code: None,
        external_latency: None,
        apple_pay_flow,
        frm_metadata: None,
        refund_id: None,
        dispute_id: None,
        connector_response: None,
        integrity_check: Ok(()),
        additional_merchant_data: merchant_recipient_data.map(|data| {
            api_models::admin::AdditionalMerchantData::foreign_from(
                types::AdditionalMerchantData::OpenBankingRecipientData(data),
            )
        }),
        header_payload,
        connector_mandate_request_reference_id,
        authentication_id: None,
        psd2_sca_exemption_type: payment_data.payment_intent.psd2_sca_exemption_type,
        raw_connector_response: None,
        is_payment_id_from_merchant: payment_data.payment_intent.is_payment_id_from_merchant,
        l2_l3_data: None,
        minor_amount_capturable: None,
    };

    Ok(router_data)
}

pub trait ToResponse<F, D, Op>
where
    Self: Sized,
    Op: Debug,
    D: OperationSessionGetters<F>,
{
    #[cfg(feature = "v1")]
    #[allow(clippy::too_many_arguments)]
    fn generate_response(
        data: D,
        customer: Option<domain::Customer>,
        auth_flow: services::AuthFlow,
        base_url: &str,
        operation: Op,
        connector_request_reference_id_config: &ConnectorRequestReferenceIdConfig,
        connector_http_status_code: Option<u16>,
        external_latency: Option<u128>,
        is_latency_header_enabled: Option<bool>,
    ) -> RouterResponse<Self>;

    #[cfg(feature = "v2")]
    #[allow(clippy::too_many_arguments)]
    fn generate_response(
        data: D,
        customer: Option<domain::Customer>,
        base_url: &str,
        operation: Op,
        connector_request_reference_id_config: &ConnectorRequestReferenceIdConfig,
        connector_http_status_code: Option<u16>,
        external_latency: Option<u128>,
        is_latency_header_enabled: Option<bool>,
        merchant_context: &domain::MerchantContext,
    ) -> RouterResponse<Self>;
}

/// Generate a response from the given Data. This should be implemented on a payment data object
pub trait GenerateResponse<Response>
where
    Self: Sized,
{
    #[cfg(feature = "v2")]
    #[allow(clippy::too_many_arguments)]
    fn generate_response(
        self,
        state: &SessionState,
        connector_http_status_code: Option<u16>,
        external_latency: Option<u128>,
        is_latency_header_enabled: Option<bool>,
        merchant_context: &domain::MerchantContext,
        profile: &domain::Profile,
        connector_response_data: Option<common_types::domain::ConnectorResponseData>,
    ) -> RouterResponse<Response>;
}

#[cfg(feature = "v2")]
impl<F> GenerateResponse<api_models::payments::PaymentsCaptureResponse>
    for hyperswitch_domain_models::payments::PaymentCaptureData<F>
where
    F: Clone,
{
    fn generate_response(
        self,
        state: &SessionState,
        connector_http_status_code: Option<u16>,
        external_latency: Option<u128>,
        is_latency_header_enabled: Option<bool>,
        merchant_context: &domain::MerchantContext,
        profile: &domain::Profile,
        _connector_response_data: Option<common_types::domain::ConnectorResponseData>,
    ) -> RouterResponse<api_models::payments::PaymentsCaptureResponse> {
        let payment_intent = &self.payment_intent;
        let payment_attempt = &self.payment_attempt;

        let amount = api_models::payments::PaymentAmountDetailsResponse::foreign_from((
            &payment_intent.amount_details,
            &payment_attempt.amount_details,
        ));

        let response = api_models::payments::PaymentsCaptureResponse {
            id: payment_intent.id.clone(),
            amount,
            status: payment_intent.status,
        };

        let headers = connector_http_status_code
            .map(|status_code| {
                vec![(
                    X_CONNECTOR_HTTP_STATUS_CODE.to_string(),
                    Maskable::new_normal(status_code.to_string()),
                )]
            })
            .unwrap_or_default();

        Ok(services::ApplicationResponse::JsonWithHeaders((
            response, headers,
        )))
    }
}

#[cfg(feature = "v2")]
impl<F> GenerateResponse<api_models::payments::PaymentsCancelResponse>
    for hyperswitch_domain_models::payments::PaymentCancelData<F>
where
    F: Clone,
{
    fn generate_response(
        self,
        state: &SessionState,
        connector_http_status_code: Option<u16>,
        external_latency: Option<u128>,
        is_latency_header_enabled: Option<bool>,
        merchant_context: &domain::MerchantContext,
        profile: &domain::Profile,
        _connector_response_data: Option<common_types::domain::ConnectorResponseData>,
    ) -> RouterResponse<api_models::payments::PaymentsCancelResponse> {
        let payment_intent = &self.payment_intent;
        let payment_attempt = &self.payment_attempt;

        let amount = api_models::payments::PaymentAmountDetailsResponse::foreign_from((
            &payment_intent.amount_details,
            &payment_attempt.amount_details,
        ));

        let connector = payment_attempt
            .connector
            .as_ref()
            .and_then(|conn| api_enums::Connector::from_str(conn).ok());
        let response = api_models::payments::PaymentsCancelResponse {
            id: payment_intent.id.clone(),
            status: payment_intent.status,
            cancellation_reason: payment_attempt.cancellation_reason.clone(),
            amount,
            customer_id: payment_intent.customer_id.clone(),
            connector,
            created: payment_intent.created_at,
            payment_method_type: Some(payment_attempt.payment_method_type),
            payment_method_subtype: Some(payment_attempt.payment_method_subtype),
            attempts: None,
            return_url: payment_intent.return_url.clone(),
        };

        let headers = connector_http_status_code
            .map(|status_code| {
                vec![(
                    X_CONNECTOR_HTTP_STATUS_CODE.to_string(),
                    Maskable::new_normal(status_code.to_string()),
                )]
            })
            .unwrap_or_default();

        Ok(services::ApplicationResponse::JsonWithHeaders((
            response, headers,
        )))
    }
}

#[cfg(feature = "v1")]
impl<F, Op, D> ToResponse<F, D, Op> for api::PaymentsResponse
where
    F: Clone,
    Op: Debug,
    D: OperationSessionGetters<F>,
{
    #[allow(clippy::too_many_arguments)]
    fn generate_response(
        payment_data: D,
        customer: Option<domain::Customer>,
        auth_flow: services::AuthFlow,
        base_url: &str,
        operation: Op,
        connector_request_reference_id_config: &ConnectorRequestReferenceIdConfig,
        connector_http_status_code: Option<u16>,
        external_latency: Option<u128>,
        is_latency_header_enabled: Option<bool>,
    ) -> RouterResponse<Self> {
        let captures = payment_data
            .get_multiple_capture_data()
            .and_then(|multiple_capture_data| {
                multiple_capture_data
                    .expand_captures
                    .and_then(|should_expand| {
                        should_expand.then_some(
                            multiple_capture_data
                                .get_all_captures()
                                .into_iter()
                                .cloned()
                                .collect(),
                        )
                    })
            });

        payments_to_payments_response(
            payment_data,
            captures,
            customer,
            auth_flow,
            base_url,
            &operation,
            connector_request_reference_id_config,
            connector_http_status_code,
            external_latency,
            is_latency_header_enabled,
        )
    }
}

#[cfg(feature = "v1")]
impl<F, Op, D> ToResponse<F, D, Op> for api::PaymentsSessionResponse
where
    F: Clone,
    Op: Debug,
    D: OperationSessionGetters<F>,
{
    #[allow(clippy::too_many_arguments)]
    fn generate_response(
        payment_data: D,
        _customer: Option<domain::Customer>,
        _auth_flow: services::AuthFlow,
        _base_url: &str,
        _operation: Op,
        _connector_request_reference_id_config: &ConnectorRequestReferenceIdConfig,
        _connector_http_status_code: Option<u16>,
        _external_latency: Option<u128>,
        _is_latency_header_enabled: Option<bool>,
    ) -> RouterResponse<Self> {
        Ok(services::ApplicationResponse::JsonWithHeaders((
            Self {
                session_token: payment_data.get_sessions_token(),
                payment_id: payment_data.get_payment_attempt().payment_id.clone(),
                client_secret: payment_data
                    .get_payment_intent()
                    .client_secret
                    .clone()
                    .get_required_value("client_secret")?
                    .into(),
            },
            vec![],
        )))
    }
}

#[cfg(feature = "v2")]
impl<F, Op, D> ToResponse<F, D, Op> for api::PaymentsSessionResponse
where
    F: Clone,
    Op: Debug,
    D: OperationSessionGetters<F>,
{
    #[allow(clippy::too_many_arguments)]
    fn generate_response(
        payment_data: D,
        _customer: Option<domain::Customer>,
        _base_url: &str,
        _operation: Op,
        _connector_request_reference_id_config: &ConnectorRequestReferenceIdConfig,
        _connector_http_status_code: Option<u16>,
        _external_latency: Option<u128>,
        _is_latency_header_enabled: Option<bool>,
        _merchant_context: &domain::MerchantContext,
    ) -> RouterResponse<Self> {
        Ok(services::ApplicationResponse::JsonWithHeaders((
            Self {
                session_token: payment_data.get_sessions_token(),
                payment_id: payment_data.get_payment_intent().id.clone(),
                vault_details: payment_data.get_optional_external_vault_session_details(),
            },
            vec![],
        )))
    }
}

#[cfg(feature = "v1")]
impl<F, Op, D> ToResponse<F, D, Op> for api::PaymentsDynamicTaxCalculationResponse
where
    F: Clone,
    Op: Debug,
    D: OperationSessionGetters<F>,
{
    #[allow(clippy::too_many_arguments)]
    fn generate_response(
        payment_data: D,
        _customer: Option<domain::Customer>,
        _auth_flow: services::AuthFlow,
        _base_url: &str,
        _operation: Op,
        _connector_request_reference_id_config: &ConnectorRequestReferenceIdConfig,
        _connector_http_status_code: Option<u16>,
        _external_latency: Option<u128>,
        _is_latency_header_enabled: Option<bool>,
    ) -> RouterResponse<Self> {
        let mut amount = payment_data.get_payment_intent().amount;
        let shipping_cost = payment_data.get_payment_intent().shipping_cost;
        if let Some(shipping_cost) = shipping_cost {
            amount = amount + shipping_cost;
        }
        let order_tax_amount = payment_data
            .get_payment_intent()
            .tax_details
            .clone()
            .and_then(|tax| {
                tax.payment_method_type
                    .map(|a| a.order_tax_amount)
                    .or_else(|| tax.default.map(|a| a.order_tax_amount))
            });
        if let Some(tax_amount) = order_tax_amount {
            amount = amount + tax_amount;
        }

        let currency = payment_data
            .get_payment_attempt()
            .currency
            .get_required_value("currency")?;

        Ok(services::ApplicationResponse::JsonWithHeaders((
            Self {
                net_amount: amount,
                payment_id: payment_data.get_payment_attempt().payment_id.clone(),
                order_tax_amount,
                shipping_cost,
                display_amount: api_models::payments::DisplayAmountOnSdk::foreign_try_from((
                    amount,
                    shipping_cost,
                    order_tax_amount,
                    currency,
                ))?,
            },
            vec![],
        )))
    }
}

#[cfg(feature = "v2")]
impl<F, Op, D> ToResponse<F, D, Op> for api::PaymentsIntentResponse
where
    F: Clone,
    Op: Debug,
    D: OperationSessionGetters<F>,
{
    #[allow(clippy::too_many_arguments)]
    fn generate_response(
        payment_data: D,
        _customer: Option<domain::Customer>,
        _base_url: &str,
        operation: Op,
        _connector_request_reference_id_config: &ConnectorRequestReferenceIdConfig,
        _connector_http_status_code: Option<u16>,
        _external_latency: Option<u128>,
        _is_latency_header_enabled: Option<bool>,
        _merchant_context: &domain::MerchantContext,
    ) -> RouterResponse<Self> {
        let payment_intent = payment_data.get_payment_intent();
        let client_secret = payment_data.get_client_secret();

        let is_cit_transaction = payment_intent.setup_future_usage.is_off_session();

        let mandate_type = if payment_intent.customer_present
            == common_enums::PresenceOfCustomerDuringPayment::Absent
        {
            Some(api::MandateTransactionType::RecurringMandateTransaction)
        } else if is_cit_transaction {
            Some(api::MandateTransactionType::NewMandateTransaction)
        } else {
            None
        };

        let payment_type = helpers::infer_payment_type(
            payment_intent.amount_details.order_amount.into(),
            mandate_type.as_ref(),
        );

        Ok(services::ApplicationResponse::JsonWithHeaders((
            Self {
                id: payment_intent.id.clone(),
                profile_id: payment_intent.profile_id.clone(),
                status: payment_intent.status,
                amount_details: api_models::payments::AmountDetailsResponse::foreign_from(
                    payment_intent.amount_details.clone(),
                ),
                client_secret: client_secret.clone(),
                merchant_reference_id: payment_intent.merchant_reference_id.clone(),
                routing_algorithm_id: payment_intent.routing_algorithm_id.clone(),
                capture_method: payment_intent.capture_method,
                authentication_type: payment_intent.authentication_type,
                billing: payment_intent
                    .billing_address
                    .clone()
                    .map(|billing| billing.into_inner())
                    .map(From::from),
                shipping: payment_intent
                    .shipping_address
                    .clone()
                    .map(|shipping| shipping.into_inner())
                    .map(From::from),
                customer_id: payment_intent.customer_id.clone(),
                customer_present: payment_intent.customer_present,
                description: payment_intent.description.clone(),
                return_url: payment_intent.return_url.clone(),
                setup_future_usage: payment_intent.setup_future_usage,
                apply_mit_exemption: payment_intent.apply_mit_exemption,
                statement_descriptor: payment_intent.statement_descriptor.clone(),
                order_details: payment_intent.order_details.clone().map(|order_details| {
                    order_details
                        .into_iter()
                        .map(|order_detail| order_detail.expose().convert_back())
                        .collect()
                }),
                allowed_payment_method_types: payment_intent.allowed_payment_method_types.clone(),
                metadata: payment_intent.metadata.clone(),
                connector_metadata: payment_intent.connector_metadata.clone(),
                feature_metadata: payment_intent
                    .feature_metadata
                    .clone()
                    .map(|feature_metadata| feature_metadata.convert_back()),
                payment_link_enabled: payment_intent.enable_payment_link,
                payment_link_config: payment_intent
                    .payment_link_config
                    .clone()
                    .map(ForeignFrom::foreign_from),
                request_incremental_authorization: payment_intent.request_incremental_authorization,
                split_txns_enabled: payment_intent.split_txns_enabled,
                expires_on: payment_intent.session_expiry,
                frm_metadata: payment_intent.frm_metadata.clone(),
                request_external_three_ds_authentication: payment_intent
                    .request_external_three_ds_authentication,
                payment_type,
                enable_partial_authorization: payment_intent.enable_partial_authorization,
            },
            vec![],
        )))
    }
}

#[cfg(feature = "v2")]
impl<F, Op, D> ToResponse<F, D, Op> for api::PaymentAttemptListResponse
where
    F: Clone,
    Op: Debug,
    D: OperationSessionGetters<F>,
{
    #[allow(clippy::too_many_arguments)]
    fn generate_response(
        payment_data: D,
        _customer: Option<domain::Customer>,
        _base_url: &str,
        _operation: Op,
        _connector_request_reference_id_config: &ConnectorRequestReferenceIdConfig,
        _connector_http_status_code: Option<u16>,
        _external_latency: Option<u128>,
        _is_latency_header_enabled: Option<bool>,
        _merchant_context: &domain::MerchantContext,
    ) -> RouterResponse<Self> {
        Ok(services::ApplicationResponse::JsonWithHeaders((
            Self {
                payment_attempt_list: payment_data
                    .list_payments_attempts()
                    .iter()
                    .map(api_models::payments::PaymentAttemptResponse::foreign_from)
                    .collect(),
            },
            vec![],
        )))
    }
}

#[cfg(feature = "v2")]
impl<F> GenerateResponse<api_models::payments::PaymentsResponse>
    for hyperswitch_domain_models::payments::PaymentConfirmData<F>
where
    F: Clone,
{
    fn generate_response(
        self,
        state: &SessionState,
        connector_http_status_code: Option<u16>,
        external_latency: Option<u128>,
        is_latency_header_enabled: Option<bool>,
        merchant_context: &domain::MerchantContext,
        profile: &domain::Profile,
        connector_response_data: Option<common_types::domain::ConnectorResponseData>,
    ) -> RouterResponse<api_models::payments::PaymentsResponse> {
        let payment_intent = self.payment_intent;
        let payment_attempt = self.payment_attempt;

        let amount = api_models::payments::PaymentAmountDetailsResponse::foreign_from((
            &payment_intent.amount_details,
            &payment_attempt.amount_details,
        ));

        let connector = payment_attempt
            .connector
            .clone()
            .get_required_value("connector")
            .change_context(errors::ApiErrorResponse::InternalServerError)
            .attach_printable("Connector is none when constructing response")?;

        let merchant_connector_id = payment_attempt.merchant_connector_id.clone();

        let error = payment_attempt
            .error
            .as_ref()
            .map(api_models::payments::ErrorDetails::foreign_from);

        let payment_address = self.payment_address;

        let raw_connector_response =
            connector_response_data.and_then(|data| data.raw_connector_response);

        let payment_method_data =
            Some(api_models::payments::PaymentMethodDataResponseWithBilling {
                payment_method_data: None,
                billing: payment_address
                    .get_request_payment_method_billing()
                    .cloned()
                    .map(From::from),
            });

        // TODO: Add support for other next actions, currently only supporting redirect to url
        let redirect_to_url = payment_intent.create_start_redirection_url(
            &state.base_url,
            merchant_context
                .get_merchant_account()
                .publishable_key
                .clone(),
        )?;

        let next_action_containing_wait_screen =
            wait_screen_next_steps_check(payment_attempt.clone())?;

        let next_action = if payment_intent.status.is_in_terminal_state() {
            None
        } else {
            payment_attempt
                .redirection_data
                .as_ref()
                .map(|_| api_models::payments::NextActionData::RedirectToUrl { redirect_to_url })
                .or(next_action_containing_wait_screen.map(|wait_screen_data| {
                    api_models::payments::NextActionData::WaitScreenInformation {
                        display_from_timestamp: wait_screen_data.display_from_timestamp,
                        display_to_timestamp: wait_screen_data.display_to_timestamp,
                        poll_config: wait_screen_data.poll_config,
                    }
                }))
        };

        let connector_token_details = payment_attempt
            .connector_token_details
            .and_then(Option::<api_models::payments::ConnectorTokenDetails>::foreign_from);

        let return_url = payment_intent
            .return_url
            .clone()
            .or(profile.return_url.clone());

        let headers = connector_http_status_code
            .map(|status_code| {
                vec![(
                    X_CONNECTOR_HTTP_STATUS_CODE.to_string(),
                    Maskable::new_normal(status_code.to_string()),
                )]
            })
            .unwrap_or_default();

        let response = api_models::payments::PaymentsResponse {
            id: payment_intent.id.clone(),
            status: payment_intent.status,
            amount,
            customer_id: payment_intent.customer_id.clone(),
            connector: Some(connector),
            created: payment_intent.created_at,
            modified_at: payment_intent.modified_at,
            payment_method_data,
            payment_method_type: Some(payment_attempt.payment_method_type),
            payment_method_subtype: Some(payment_attempt.payment_method_subtype),
            next_action,
            connector_transaction_id: payment_attempt.connector_payment_id.clone(),
            connector_reference_id: payment_attempt.connector_response_reference_id.clone(),
            connector_token_details,
            merchant_connector_id,
            browser_info: None,
            error,
            return_url,
            authentication_type: payment_intent.authentication_type,
            authentication_type_applied: Some(payment_attempt.authentication_type),
            payment_method_id: payment_attempt.payment_method_id,
            attempts: None,
            billing: None,  //TODO: add this
            shipping: None, //TODO: add this
            is_iframe_redirection_enabled: None,
            merchant_reference_id: payment_intent.merchant_reference_id.clone(),
            raw_connector_response,
            feature_metadata: payment_intent
                .feature_metadata
                .map(|feature_metadata| feature_metadata.convert_back()),
            metadata: payment_intent.metadata,
        };

        Ok(services::ApplicationResponse::JsonWithHeaders((
            response, headers,
        )))
    }
}

#[cfg(feature = "v2")]
impl<F> GenerateResponse<api_models::payments::PaymentsResponse>
    for hyperswitch_domain_models::payments::PaymentStatusData<F>
where
    F: Clone,
{
    fn generate_response(
        self,
        state: &SessionState,
        connector_http_status_code: Option<u16>,
        external_latency: Option<u128>,
        is_latency_header_enabled: Option<bool>,
        merchant_context: &domain::MerchantContext,
        profile: &domain::Profile,
        connector_response_data: Option<common_types::domain::ConnectorResponseData>,
    ) -> RouterResponse<api_models::payments::PaymentsResponse> {
        let payment_intent = self.payment_intent;
        let payment_attempt = &self.payment_attempt;

        let amount = api_models::payments::PaymentAmountDetailsResponse::foreign_from((
            &payment_intent.amount_details,
            &payment_attempt.amount_details,
        ));

        let connector = payment_attempt.connector.clone();

        let merchant_connector_id = payment_attempt.merchant_connector_id.clone();

        let error = payment_attempt
            .error
            .as_ref()
            .map(api_models::payments::ErrorDetails::foreign_from);
        let attempts = self.attempts.as_ref().map(|attempts| {
            attempts
                .iter()
                .map(api_models::payments::PaymentAttemptResponse::foreign_from)
                .collect()
        });

        let payment_method_data =
            Some(api_models::payments::PaymentMethodDataResponseWithBilling {
                payment_method_data: None,
                billing: self
                    .payment_address
                    .get_request_payment_method_billing()
                    .cloned()
                    .map(From::from),
            });

        let raw_connector_response =
            connector_response_data.and_then(|data| data.raw_connector_response);

        let connector_token_details = self
            .payment_attempt
            .connector_token_details
            .clone()
            .and_then(Option::<api_models::payments::ConnectorTokenDetails>::foreign_from);

        let return_url = payment_intent.return_url.or(profile.return_url.clone());

        let headers = connector_http_status_code
            .map(|status_code| {
                vec![(
                    X_CONNECTOR_HTTP_STATUS_CODE.to_string(),
                    Maskable::new_normal(status_code.to_string()),
                )]
            })
            .unwrap_or_default();

        let response = api_models::payments::PaymentsResponse {
            id: payment_intent.id.clone(),
            status: payment_intent.status,
            amount,
            customer_id: payment_intent.customer_id.clone(),
            connector,
            billing: self
                .payment_address
                .get_payment_billing()
                .cloned()
                .map(From::from),
            shipping: self.payment_address.get_shipping().cloned().map(From::from),
            created: payment_intent.created_at,
            modified_at: payment_intent.modified_at,
            payment_method_data,
            payment_method_type: Some(payment_attempt.payment_method_type),
            payment_method_subtype: Some(payment_attempt.payment_method_subtype),
            connector_transaction_id: payment_attempt.connector_payment_id.clone(),
            connector_reference_id: payment_attempt.connector_response_reference_id.clone(),
            merchant_connector_id,
            browser_info: None,
            connector_token_details,
            payment_method_id: payment_attempt.payment_method_id.clone(),
            error,
            authentication_type_applied: payment_attempt.authentication_applied,
            authentication_type: payment_intent.authentication_type,
            next_action: None,
            attempts,
            return_url,
            is_iframe_redirection_enabled: payment_intent.is_iframe_redirection_enabled,
            merchant_reference_id: payment_intent.merchant_reference_id.clone(),
            raw_connector_response,
            feature_metadata: payment_intent
                .feature_metadata
                .map(|feature_metadata| feature_metadata.convert_back()),
            metadata: payment_intent.metadata,
        };

        Ok(services::ApplicationResponse::JsonWithHeaders((
            response, headers,
        )))
    }
}

#[cfg(feature = "v2")]
impl<F> GenerateResponse<api_models::payments::PaymentAttemptResponse>
    for hyperswitch_domain_models::payments::PaymentAttemptRecordData<F>
where
    F: Clone,
{
    fn generate_response(
        self,
        _state: &SessionState,
        _connector_http_status_code: Option<u16>,
        _external_latency: Option<u128>,
        _is_latency_header_enabled: Option<bool>,
        _merchant_context: &domain::MerchantContext,
        _profile: &domain::Profile,
        _connector_response_data: Option<common_types::domain::ConnectorResponseData>,
    ) -> RouterResponse<api_models::payments::PaymentAttemptResponse> {
        let payment_attempt = self.payment_attempt;
        let response = api_models::payments::PaymentAttemptResponse::foreign_from(&payment_attempt);
        Ok(services::ApplicationResponse::JsonWithHeaders((
            response,
            vec![],
        )))
    }
}

#[cfg(feature = "v2")]
impl<F> GenerateResponse<api_models::payments::PaymentAttemptRecordResponse>
    for hyperswitch_domain_models::payments::PaymentAttemptRecordData<F>
where
    F: Clone,
{
    fn generate_response(
        self,
        _state: &SessionState,
        _connector_http_status_code: Option<u16>,
        _external_latency: Option<u128>,
        _is_latency_header_enabled: Option<bool>,
        _merchant_context: &domain::MerchantContext,
        _profile: &domain::Profile,
        _connector_response_data: Option<common_types::domain::ConnectorResponseData>,
    ) -> RouterResponse<api_models::payments::PaymentAttemptRecordResponse> {
        let payment_attempt = self.payment_attempt;
        let payment_intent = self.payment_intent;
        let response = api_models::payments::PaymentAttemptRecordResponse {
            id: payment_attempt.id.clone(),
            status: payment_attempt.status,
            amount: payment_attempt.amount_details.get_net_amount(),
            payment_intent_feature_metadata: payment_intent
                .feature_metadata
                .as_ref()
                .map(api_models::payments::FeatureMetadata::foreign_from),
            payment_attempt_feature_metadata: payment_attempt
                .feature_metadata
                .as_ref()
                .map(api_models::payments::PaymentAttemptFeatureMetadata::foreign_from),
            error_details: payment_attempt
                .error
                .map(api_models::payments::RecordAttemptErrorDetails::from),
            created_at: payment_attempt.created_at,
        };
        Ok(services::ApplicationResponse::JsonWithHeaders((
            response,
            vec![],
        )))
    }
}

#[cfg(feature = "v1")]
impl<F, Op, D> ToResponse<F, D, Op> for api::PaymentsPostSessionTokensResponse
where
    F: Clone,
    Op: Debug,
    D: OperationSessionGetters<F>,
{
    fn generate_response(
        payment_data: D,
        _customer: Option<domain::Customer>,
        _auth_flow: services::AuthFlow,
        _base_url: &str,
        _operation: Op,
        _connector_request_reference_id_config: &ConnectorRequestReferenceIdConfig,
        _connector_http_status_code: Option<u16>,
        _external_latency: Option<u128>,
        _is_latency_header_enabled: Option<bool>,
    ) -> RouterResponse<Self> {
        let papal_sdk_next_action =
            paypal_sdk_next_steps_check(payment_data.get_payment_attempt().clone())?;
        let next_action = papal_sdk_next_action.map(|paypal_next_action_data| {
            api_models::payments::NextActionData::InvokeSdkClient {
                next_action_data: paypal_next_action_data,
            }
        });
        Ok(services::ApplicationResponse::JsonWithHeaders((
            Self {
                payment_id: payment_data.get_payment_intent().payment_id.clone(),
                next_action,
                status: payment_data.get_payment_intent().status,
            },
            vec![],
        )))
    }
}

#[cfg(feature = "v1")]
impl<F, Op, D> ToResponse<F, D, Op> for api::PaymentsUpdateMetadataResponse
where
    F: Clone,
    Op: Debug,
    D: OperationSessionGetters<F>,
{
    fn generate_response(
        payment_data: D,
        _customer: Option<domain::Customer>,
        _auth_flow: services::AuthFlow,
        _base_url: &str,
        _operation: Op,
        _connector_request_reference_id_config: &ConnectorRequestReferenceIdConfig,
        _connector_http_status_code: Option<u16>,
        _external_latency: Option<u128>,
        _is_latency_header_enabled: Option<bool>,
    ) -> RouterResponse<Self> {
        Ok(services::ApplicationResponse::JsonWithHeaders((
            Self {
                payment_id: payment_data.get_payment_intent().payment_id.clone(),
                metadata: payment_data
                    .get_payment_intent()
                    .metadata
                    .clone()
                    .map(Secret::new),
            },
            vec![],
        )))
    }
}

impl ForeignTryFrom<(MinorUnit, Option<MinorUnit>, Option<MinorUnit>, Currency)>
    for api_models::payments::DisplayAmountOnSdk
{
    type Error = error_stack::Report<errors::ApiErrorResponse>;

    fn foreign_try_from(
        (net_amount, shipping_cost, order_tax_amount, currency): (
            MinorUnit,
            Option<MinorUnit>,
            Option<MinorUnit>,
            Currency,
        ),
    ) -> Result<Self, Self::Error> {
        let major_unit_convertor = StringMajorUnitForConnector;

        let sdk_net_amount = major_unit_convertor
            .convert(net_amount, currency)
            .change_context(errors::ApiErrorResponse::PreconditionFailed {
                message: "Failed to convert net_amount to base unit".to_string(),
            })
            .attach_printable("Failed to convert net_amount to string major unit")?;

        let sdk_shipping_cost = shipping_cost
            .map(|cost| {
                major_unit_convertor
                    .convert(cost, currency)
                    .change_context(errors::ApiErrorResponse::PreconditionFailed {
                        message: "Failed to convert shipping_cost to base unit".to_string(),
                    })
                    .attach_printable("Failed to convert shipping_cost to string major unit")
            })
            .transpose()?;

        let sdk_order_tax_amount = order_tax_amount
            .map(|cost| {
                major_unit_convertor
                    .convert(cost, currency)
                    .change_context(errors::ApiErrorResponse::PreconditionFailed {
                        message: "Failed to convert order_tax_amount to base unit".to_string(),
                    })
                    .attach_printable("Failed to convert order_tax_amount to string major unit")
            })
            .transpose()?;
        Ok(Self {
            net_amount: sdk_net_amount,
            shipping_cost: sdk_shipping_cost,
            order_tax_amount: sdk_order_tax_amount,
        })
    }
}

#[cfg(feature = "v1")]
impl<F, Op, D> ToResponse<F, D, Op> for api::VerifyResponse
where
    F: Clone,
    Op: Debug,
    D: OperationSessionGetters<F>,
{
    #[cfg(feature = "v2")]
    #[allow(clippy::too_many_arguments)]
    fn generate_response(
        _data: D,
        _customer: Option<domain::Customer>,
        _auth_flow: services::AuthFlow,
        _base_url: &str,
        _operation: Op,
        _connector_request_reference_id_config: &ConnectorRequestReferenceIdConfig,
        _connector_http_status_code: Option<u16>,
        _external_latency: Option<u128>,
        _is_latency_header_enabled: Option<bool>,
    ) -> RouterResponse<Self> {
        todo!()
    }

    #[cfg(feature = "v1")]
    #[allow(clippy::too_many_arguments)]
    fn generate_response(
        payment_data: D,
        customer: Option<domain::Customer>,
        _auth_flow: services::AuthFlow,
        _base_url: &str,
        _operation: Op,
        _connector_request_reference_id_config: &ConnectorRequestReferenceIdConfig,
        _connector_http_status_code: Option<u16>,
        _external_latency: Option<u128>,
        _is_latency_header_enabled: Option<bool>,
    ) -> RouterResponse<Self> {
        let additional_payment_method_data: Option<api_models::payments::AdditionalPaymentData> =
            payment_data
                .get_payment_attempt()
                .payment_method_data
                .clone()
                .map(|data| data.parse_value("payment_method_data"))
                .transpose()
                .change_context(errors::ApiErrorResponse::InvalidDataValue {
                    field_name: "payment_method_data",
                })?;
        let payment_method_data_response =
            additional_payment_method_data.map(api::PaymentMethodDataResponse::from);
        Ok(services::ApplicationResponse::JsonWithHeaders((
            Self {
                verify_id: Some(payment_data.get_payment_intent().payment_id.clone()),
                merchant_id: Some(payment_data.get_payment_intent().merchant_id.clone()),
                client_secret: payment_data
                    .get_payment_intent()
                    .client_secret
                    .clone()
                    .map(Secret::new),
                customer_id: customer.as_ref().map(|x| x.customer_id.clone()),
                email: customer
                    .as_ref()
                    .and_then(|cus| cus.email.as_ref().map(|s| s.to_owned())),
                name: customer
                    .as_ref()
                    .and_then(|cus| cus.name.as_ref().map(|s| s.to_owned())),
                phone: customer
                    .as_ref()
                    .and_then(|cus| cus.phone.as_ref().map(|s| s.to_owned())),
                mandate_id: payment_data
                    .get_mandate_id()
                    .and_then(|mandate_ids| mandate_ids.mandate_id.clone()),
                payment_method: payment_data.get_payment_attempt().payment_method,
                payment_method_data: payment_method_data_response,
                payment_token: payment_data.get_token().map(ToString::to_string),
                error_code: payment_data.get_payment_attempt().clone().error_code,
                error_message: payment_data.get_payment_attempt().clone().error_message,
            },
            vec![],
        )))
    }
}

#[cfg(feature = "v2")]
#[instrument(skip_all)]
// try to use router data here so that already validated things , we don't want to repeat the validations.
// Add internal value not found and external value not found so that we can give 500 / Internal server error for internal value not found
#[allow(clippy::too_many_arguments)]
pub fn payments_to_payments_response<Op, F: Clone, D>(
    _payment_data: D,
    _captures: Option<Vec<storage::Capture>>,
    _customer: Option<domain::Customer>,
    _auth_flow: services::AuthFlow,
    _base_url: &str,
    _operation: &Op,
    _connector_request_reference_id_config: &ConnectorRequestReferenceIdConfig,
    _connector_http_status_code: Option<u16>,
    _external_latency: Option<u128>,
    _is_latency_header_enabled: Option<bool>,
) -> RouterResponse<api_models::payments::PaymentsResponse>
where
    Op: Debug,
    D: OperationSessionGetters<F>,
{
    todo!()
}

#[cfg(feature = "v1")]
#[instrument(skip_all)]
// try to use router data here so that already validated things , we don't want to repeat the validations.


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

impl api::PaymentToken for for Payu


// Struct: Sdk
// File: crates/hyperswitch_connectors/src/connectors/netcetera/netcetera_types.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct Sdk


// Function: get_connector_config
// File: crates/euclid_wasm/src/lib.rs
// Module: euclid_wasm

pub fn get_connector_config(key: &str) -> JsResult


// Function: decrypt
// File: crates/external_services/src/no_encryption/core.rs
// Module: external_services

// Documentation: Decryption functionality

pub fn decrypt(&self, data: impl AsRef<[u8]>) -> Vec<u8>


// Struct: MifinityData
// File: crates/hyperswitch_domain_models/src/payment_method_data.rs
// Module: hyperswitch_domain_models
// Implementations: 0

pub struct MifinityData


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

pub fn new(
        conf: &redis_interface::RedisSettings,
    ) -> error_stack::Result<Self, redis_interface::errors::RedisError>


            },
        }
    }
}

impl
    TryFrom<(
        &WellsfargoRouterData<&PaymentsAuthorizeRouterData>,
        BankDebitData,
    )> for WellsfargoPaymentsRequest
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        (item, bank_debit_data): (
            &WellsfargoRouterData<&PaymentsAuthorizeRouterData>,
            BankDebitData,
        ),
    ) -> Result<Self, Self::Error> {
        let email = item.router_data.request.get_email()?;
        let bill_to = build_bill_to(item.router_data.get_optional_billing(), email)?;
        let order_information = OrderInformationWithBill::from((item, Some(bill_to)));
        let payment_information = match bank_debit_data {
            BankDebitData::AchBankDebit {
                account_number,
                routing_number,
                bank_type,
                ..
            } => Ok(PaymentInformation::AchDebitPayment(Box::new(
                AchPaymentInformation {
                    bank: AchBankAccount {
                        account: Account {
                            account_type: AccountType::try_from(bank_type)?,
                            number: account_number,
                        },
                        routing_number,
                    },
                },
            ))),
            BankDebitData::SepaBankDebit { .. }
            | BankDebitData::BacsBankDebit { .. }
            | BankDebitData::BecsBankDebit { .. } => Err(errors::ConnectorError::NotImplemented(
                utils::get_unimplemented_payment_method_error_message("Wellsfargo"),
            )),
        }?;
        let processing_information =
            ProcessingInformation::try_from((item, Some(PaymentSolution::GooglePay), None))?;
        let client_reference_information = ClientReferenceInformation::from(item);
        Ok(Self {
            processing_information,
            payment_information,
            order_information,
            client_reference_information,
            consumer_authentication_information: None,
            merchant_defined_information: None,
        })
    }
}

impl TryFrom<&WellsfargoRouterData<&PaymentsAuthorizeRouterData>> for WellsfargoPaymentsRequest {
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: &WellsfargoRouterData<&PaymentsAuthorizeRouterData>,
    ) -> Result<Self, Self::Error> {
        match item.router_data.request.connector_mandate_id() {
            Some(connector_mandate_id) => Self::try_from((item, connector_mandate_id)),
            None => {
                match item.router_data.request.payment_method_data.clone() {
                    PaymentMethodData::Card(ccard) => Self::try_from((item, ccard)),
                    PaymentMethodData::Wallet(wallet_data) => match wallet_data {
                        WalletData::ApplePay(apple_pay_data) => {
                            match item.router_data.payment_method_token.clone() {
                                Some(payment_method_token) => match payment_method_token {
                                    PaymentMethodToken::ApplePayDecrypt(decrypt_data) => {
                                        Self::try_from((item, decrypt_data, apple_pay_data))
                                    }
                                    PaymentMethodToken::Token(_) => {
                                        Err(unimplemented_payment_method!(
                                            "Apple Pay",
                                            "Manual",
                                            "Wellsfargo"
                                        ))?
                                    }
                                    PaymentMethodToken::PazeDecrypt(_) => {
                                        Err(unimplemented_payment_method!("Paze", "Wellsfargo"))?
                                    }
                                    PaymentMethodToken::GooglePayDecrypt(_) => Err(
                                        unimplemented_payment_method!("Google Pay", "Wellsfargo"),
                                    )?,
                                },
                                None => {
                                    let email = item.router_data.request.get_email()?;
                                    let bill_to = build_bill_to(
                                        item.router_data.get_optional_billing(),
                                        email,
                                    )?;
                                    let order_information =
                                        OrderInformationWithBill::from((item, Some(bill_to)));
                                    let processing_information =
                                        ProcessingInformation::try_from((
                                            item,
                                            Some(PaymentSolution::ApplePay),
                                            Some(apple_pay_data.payment_method.network.clone()),
                                        ))?;
                                    let client_reference_information =
                                        ClientReferenceInformation::from(item);

                                    let apple_pay_encrypted_data = apple_pay_data
                                        .payment_data
                                        .get_encrypted_apple_pay_payment_data_mandatory()
                                        .change_context(
                                            errors::ConnectorError::MissingRequiredField {
                                                field_name: "Apple pay encrypted data",
                                            },
                                        )?;
                                    let payment_information = PaymentInformation::ApplePayToken(
                                        Box::new(ApplePayTokenPaymentInformation {
                                            fluid_data: FluidData {
                                                value: Secret::from(
                                                    apple_pay_encrypted_data.to_string(),
                                                ),
                                                descriptor: Some(FLUID_DATA_DESCRIPTOR.to_string()),
                                            },
                                            tokenized_card: ApplePayTokenizedCard {
                                                transaction_type: TransactionType::ApplePay,
                                            },
                                        }),
                                    );
                                    let merchant_defined_information =
                                        item.router_data.request.metadata.clone().map(|metadata| {
                                            convert_metadata_to_merchant_defined_info(metadata)
                                        });
                                    let ucaf_collection_indicator = match apple_pay_data
                                        .payment_method
                                        .network
                                        .to_lowercase()
                                        .as_str()
                                    {
                                        "mastercard" => Some("2".to_string()),
                                        _ => None,
                                    };
                                    Ok(Self {
                                        processing_information,
                                        payment_information,
                                        order_information,
                                        client_reference_information,
                                        merchant_defined_information,
                                        consumer_authentication_information: Some(
                                            WellsfargoConsumerAuthInformation {
                                                ucaf_collection_indicator,
                                                cavv: None,
                                                ucaf_authentication_data: None,
                                                xid: None,
                                                directory_server_transaction_id: None,
                                                specification_version: None,
                                                pa_specification_version: None,
                                                veres_enrolled: None,
                                            },
                                        ),
                                    })
                                }
                            }
                        }
                        WalletData::GooglePay(google_pay_data) => {
                            Self::try_from((item, google_pay_data))
                        }
                        WalletData::AliPayQr(_)
                        | WalletData::AliPayRedirect(_)
                        | WalletData::AliPayHkRedirect(_)
                        | WalletData::AmazonPayRedirect(_)
                        | WalletData::Paysera(_)
                        | WalletData::Skrill(_)
                        | WalletData::MomoRedirect(_)
                        | WalletData::KakaoPayRedirect(_)
                        | WalletData::GoPayRedirect(_)
                        | WalletData::GcashRedirect(_)
                        | WalletData::BluecodeRedirect {}
                        | WalletData::ApplePayRedirect(_)
                        | WalletData::ApplePayThirdPartySdk(_)
                        | WalletData::DanaRedirect {}
                        | WalletData::GooglePayRedirect(_)
                        | WalletData::GooglePayThirdPartySdk(_)
                        | WalletData::MbWayRedirect(_)
                        | WalletData::MobilePayRedirect(_)
                        | WalletData::PaypalRedirect(_)
                        | WalletData::PaypalSdk(_)
                        | WalletData::Paze(_)
                        | WalletData::SamsungPay(_)
                        | WalletData::AmazonPay(_)
                        | WalletData::TwintRedirect {}
                        | WalletData::VippsRedirect {}
                        | WalletData::TouchNGoRedirect(_)
                        | WalletData::WeChatPayRedirect(_)
                        | WalletData::WeChatPayQr(_)
                        | WalletData::CashappQr(_)
                        | WalletData::SwishQr(_)
                        | WalletData::Mifinity(_)
                        | WalletData::RevolutPay(_) => Err(errors::ConnectorError::NotImplemented(
                            utils::get_unimplemented_payment_method_error_message("Wellsfargo"),
                        )
                        .into()),
                    },
                    // If connector_mandate_id is present MandatePayment will be the PMD, the case will be handled in the first `if` clause.
                    // This is a fallback implementation in the event of catastrophe.
                    PaymentMethodData::MandatePayment => {
                        let connector_mandate_id =
                            item.router_data.request.connector_mandate_id().ok_or(
                                errors::ConnectorError::MissingRequiredField {
                                    field_name: "connector_mandate_id",
                                },
                            )?;
                        Self::try_from((item, connector_mandate_id))
                    }
                    PaymentMethodData::BankDebit(bank_debit) => Self::try_from((item, bank_debit)),
                    PaymentMethodData::CardRedirect(_)
                    | PaymentMethodData::PayLater(_)
                    | PaymentMethodData::BankRedirect(_)
                    | PaymentMethodData::BankTransfer(_)
                    | PaymentMethodData::Crypto(_)
                    | PaymentMethodData::Reward
                    | PaymentMethodData::RealTimePayment(_)
                    | PaymentMethodData::MobilePayment(_)
                    | PaymentMethodData::Upi(_)
                    | PaymentMethodData::Voucher(_)
                    | PaymentMethodData::GiftCard(_)
                    | PaymentMethodData::OpenBanking(_)
                    | PaymentMethodData::CardToken(_)
                    | PaymentMethodData::NetworkToken(_)
                    | PaymentMethodData::CardDetailsForNetworkTransactionId(_) => {
                        Err(errors::ConnectorError::NotImplemented(
                            utils::get_unimplemented_payment_method_error_message("Wellsfargo"),
                        )
                        .into())
                    }
                }
            }
        }
    }
}

impl TryFrom<(&WellsfargoRouterData<&PaymentsAuthorizeRouterData>, String)>
    for WellsfargoPaymentsRequest
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        (item, connector_mandate_id): (&WellsfargoRouterData<&PaymentsAuthorizeRouterData>, String),
    ) -> Result<Self, Self::Error> {
        let processing_information = ProcessingInformation::try_from((item, None, None))?;
        let payment_instrument = WellsfargoPaymentInstrument {
            id: connector_mandate_id.into(),
        };
        let bill_to =
            item.router_data.request.get_email().ok().and_then(|email| {
                build_bill_to(item.router_data.get_optional_billing(), email).ok()
            });
        let order_information = OrderInformationWithBill::from((item, bill_to));
        let payment_information =
            PaymentInformation::MandatePayment(Box::new(MandatePaymentInformation {
                payment_instrument,
            }));
        let client_reference_information = ClientReferenceInformation::from(item);
        let merchant_defined_information = item
            .router_data
            .request
            .metadata
            .clone()
            .map(convert_metadata_to_merchant_defined_info);
        Ok(Self {
            processing_information,
            payment_information,
            order_information,
            client_reference_information,
            merchant_defined_information,
            consumer_authentication_information: None,
        })
    }
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct WellsfargoPaymentsCaptureRequest {
    processing_information: ProcessingInformation,
    order_information: OrderInformationWithBill,
    client_reference_information: ClientReferenceInformation,
    #[serde(skip_serializing_if = "Option::is_none")]
    merchant_defined_information: Option<Vec<MerchantDefinedInformation>>,
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct WellsfargoPaymentsIncrementalAuthorizationRequest {
    processing_information: ProcessingInformation,
    order_information: OrderInformationIncrementalAuthorization,
}

impl TryFrom<&WellsfargoRouterData<&PaymentsCaptureRouterData>>
    for WellsfargoPaymentsCaptureRequest
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: &WellsfargoRouterData<&PaymentsCaptureRouterData>,
    ) -> Result<Self, Self::Error> {
        let merchant_defined_information = item
            .router_data
            .request
            .metadata
            .clone()
            .map(convert_metadata_to_merchant_defined_info);
        Ok(Self {
            processing_information: ProcessingInformation {
                capture_options: Some(CaptureOptions {
                    capture_sequence_number: 1,
                    total_capture_count: 1,
                }),
                action_list: None,
                action_token_types: None,
                authorization_options: None,
                capture: None,
                commerce_indicator: String::from("internet"),
                payment_solution: None,
            },
            order_information: OrderInformationWithBill {
                amount_details: Amount {
                    total_amount: item.amount.clone(),
                    currency: item.router_data.request.currency,
                },
                bill_to: None,
            },
            client_reference_information: ClientReferenceInformation {
                code: Some(item.router_data.connector_request_reference_id.clone()),
            },
            merchant_defined_information,
        })
    }
}

impl TryFrom<&WellsfargoRouterData<&PaymentsIncrementalAuthorizationRouterData>>
    for WellsfargoPaymentsIncrementalAuthorizationRequest
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: &WellsfargoRouterData<&PaymentsIncrementalAuthorizationRouterData>,
    ) -> Result<Self, Self::Error> {
        Ok(Self {
            processing_information: ProcessingInformation {
                action_list: None,
                action_token_types: None,
                authorization_options: Some(WellsfargoAuthorizationOptions {
                    initiator: Some(WellsfargoPaymentInitiator {
                        initiator_type: None,
                        credential_stored_on_file: None,
                        stored_credential_used: Some(true),
                    }),
                    merchant_intitiated_transaction: Some(MerchantInitiatedTransaction {
                        reason: Some("5".to_owned()),
                        previous_transaction_id: None,
                        original_authorized_amount: None,
                    }),
                }),
                commerce_indicator: String::from("internet"),
                capture: None,
                capture_options: None,
                payment_solution: None,
            },
            order_information: OrderInformationIncrementalAuthorization {
                amount_details: AdditionalAmount {
                    additional_amount: item.amount.clone(),
                    currency: item.router_data.request.currency.to_string(),
                },
            },
        })
    }
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct WellsfargoVoidRequest {
    client_reference_information: ClientReferenceInformation,
    reversal_information: ReversalInformation,
    #[serde(skip_serializing_if = "Option::is_none")]
    merchant_defined_information: Option<Vec<MerchantDefinedInformation>>,
    // The connector documentation does not mention the merchantDefinedInformation field for Void requests. But this has been still added because it works!
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ReversalInformation {
    amount_details: Amount,
    reason: String,
}

impl TryFrom<&WellsfargoRouterData<&PaymentsCancelRouterData>> for WellsfargoVoidRequest {
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        value: &WellsfargoRouterData<&PaymentsCancelRouterData>,
    ) -> Result<Self, Self::Error> {
        let merchant_defined_information = value
            .router_data
            .request
            .metadata
            .clone()
            .map(convert_metadata_to_merchant_defined_info);
        Ok(Self {
            client_reference_information: ClientReferenceInformation {
                code: Some(value.router_data.connector_request_reference_id.clone()),
            },
            reversal_information: ReversalInformation {
                amount_details: Amount {
                    total_amount: value.amount.to_owned(),
                    currency: value.router_data.request.currency.ok_or(
                        errors::ConnectorError::MissingRequiredField {
                            field_name: "Currency",
                        },
                    )?,
                },
                reason: value
                    .router_data
                    .request
                    .cancellation_reason
                    .clone()
                    .ok_or(errors::ConnectorError::MissingRequiredField {
                        field_name: "Cancellation Reason",
                    })?,
            },
            merchant_defined_information,
        })
    }
}

pub struct WellsfargoAuthType {
    pub(super) api_key: Secret<String>,
    pub(super) merchant_account: Secret<String>,
    pub(super) api_secret: Secret<String>,
}

impl TryFrom<&ConnectorAuthType> for WellsfargoAuthType {
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(auth_type: &ConnectorAuthType) -> Result<Self, Self::Error> {
        if let ConnectorAuthType::SignatureKey {
            api_key,
            key1,
            api_secret,
        } = auth_type
        {
            Ok(Self {
                api_key: api_key.to_owned(),
                merchant_account: key1.to_owned(),
                api_secret: api_secret.to_owned(),
            })
        } else {
            Err(errors::ConnectorError::FailedToObtainAuthType)?
        }
    }
}

#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum WellsfargoPaymentStatus {
    Authorized,
    Succeeded,
    Failed,
    Voided,
    Reversed,
    Pending,
    Declined,
    Rejected,
    Challenge,
    AuthorizedPendingReview,
    AuthorizedRiskDeclined,
    Transmitted,
    InvalidRequest,
    ServerError,
    PendingAuthentication,
    PendingReview,
    Accepted,
    Cancelled,
    StatusNotReceived,
    //PartialAuthorized, not being consumed yet.
}

#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum WellsfargoIncrementalAuthorizationStatus {
    Authorized,
    Declined,
    AuthorizedPendingReview,
}

fn map_attempt_status(status: WellsfargoPaymentStatus, capture: bool) -> enums::AttemptStatus {
    match status {
        WellsfargoPaymentStatus::Authorized | WellsfargoPaymentStatus::AuthorizedPendingReview => {
            if capture {
                // Because Wellsfargo will return Payment Status as Authorized even in AutoCapture Payment
                enums::AttemptStatus::Charged
            } else {
                enums::AttemptStatus::Authorized
            }
        }
        WellsfargoPaymentStatus::Pending => {
            if capture {
                enums::AttemptStatus::Charged
            } else {
                enums::AttemptStatus::Pending
            }
        }
        WellsfargoPaymentStatus::Succeeded | WellsfargoPaymentStatus::Transmitted => {
            enums::AttemptStatus::Charged
        }
        WellsfargoPaymentStatus::Voided
        | WellsfargoPaymentStatus::Reversed
        | WellsfargoPaymentStatus::Cancelled => enums::AttemptStatus::Voided,
        WellsfargoPaymentStatus::Failed
        | WellsfargoPaymentStatus::Declined
        | WellsfargoPaymentStatus::AuthorizedRiskDeclined
        | WellsfargoPaymentStatus::Rejected
        | WellsfargoPaymentStatus::InvalidRequest
        | WellsfargoPaymentStatus::ServerError => enums::AttemptStatus::Failure,
        WellsfargoPaymentStatus::PendingAuthentication => {
            enums::AttemptStatus::AuthenticationPending
        }
        WellsfargoPaymentStatus::PendingReview
        | WellsfargoPaymentStatus::StatusNotReceived
        | WellsfargoPaymentStatus::Challenge
        | WellsfargoPaymentStatus::Accepted => enums::AttemptStatus::Pending,
    }
}

impl From<WellsfargoIncrementalAuthorizationStatus> for common_enums::AuthorizationStatus {
    fn from(item: WellsfargoIncrementalAuthorizationStatus) -> Self {
        match item {
            WellsfargoIncrementalAuthorizationStatus::Authorized
            | WellsfargoIncrementalAuthorizationStatus::AuthorizedPendingReview => Self::Success,
            WellsfargoIncrementalAuthorizationStatus::Declined => Self::Failure,
        }
    }
}

#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct WellsfargoPaymentsResponse {
    id: String,
    status: Option<WellsfargoPaymentStatus>,
    client_reference_information: Option<ClientReferenceInformation>,
    processor_information: Option<ClientProcessorInformation>,
    risk_information: Option<ClientRiskInformation>,
    token_information: Option<WellsfargoTokenInformation>,
    error_information: Option<WellsfargoErrorInformation>,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct WellsfargoErrorInformationResponse {
    id: String,
    error_information: WellsfargoErrorInformation,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct WellsfargoPaymentsIncrementalAuthorizationResponse {
    status: WellsfargoIncrementalAuthorizationStatus,
    error_information: Option<WellsfargoErrorInformation>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ClientReferenceInformation {
    code: Option<String>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ClientProcessorInformation {
    network_transaction_id: Option<String>,
    avs: Option<Avs>,
    card_verification: Option<CardVerification>,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CardVerification {
    result_code: Option<String>,
    result_code_raw: Option<String>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Avs {
    code: Option<String>,
    code_raw: Option<String>,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ClientRiskInformation {
    rules: Option<Vec<ClientRiskInformationRules>>,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct ClientRiskInformationRules {
    name: Option<Secret<String>>,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct WellsfargoTokenInformation {
    payment_instrument: Option<WellsfargoPaymentInstrument>,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct WellsfargoErrorInformation {
    reason: Option<String>,
    message: Option<String>,
    details: Option<Vec<Details>>,
}

fn get_error_response_if_failure(
    (info_response, status, http_code): (&WellsfargoPaymentsResponse, enums::AttemptStatus, u16),
) -> Option<ErrorResponse> {
    if utils::is_payment_failure(status) {
        Some(get_error_response(
            &info_response.error_information,
            &info_response.risk_information,
            Some(status),
            http_code,
            info_response.id.clone(),
        ))
    } else {
        None
    }
}

fn get_payment_response(
    (info_response, status, http_code): (&WellsfargoPaymentsResponse, enums::AttemptStatus, u16),
) -> Result<PaymentsResponseData, Box<ErrorResponse>> {
    let error_response = get_error_response_if_failure((info_response, status, http_code));
    match error_response {
        Some(error) => Err(Box::new(error)),
        None => {
            let incremental_authorization_allowed =
                Some(status == enums::AttemptStatus::Authorized);
            let mandate_reference =
                info_response
                    .token_information
                    .clone()
                    .map(|token_info| MandateReference {
                        connector_mandate_id: token_info
                            .payment_instrument
                            .map(|payment_instrument| payment_instrument.id.expose()),
                        payment_method_id: None,
                        mandate_metadata: None,
                        connector_mandate_request_reference_id: None,
                    });

            Ok(PaymentsResponseData::TransactionResponse {
                resource_id: ResponseId::ConnectorTransactionId(info_response.id.clone()),
                redirection_data: Box::new(None),
                mandate_reference: Box::new(mandate_reference),
                connector_metadata: None,
                network_txn_id: info_response.processor_information.as_ref().and_then(
                    |processor_information| processor_information.network_transaction_id.clone(),
                ),
                connector_response_reference_id: Some(
                    info_response
                        .client_reference_information
                        .clone()
                        .and_then(|client_reference_information| client_reference_information.code)
                        .unwrap_or(info_response.id.clone()),
                ),
                incremental_authorization_allowed,
                charges: None,
            })
        }
    }
}

impl
    TryFrom<
        ResponseRouterData<
            Authorize,
            WellsfargoPaymentsResponse,
            PaymentsAuthorizeData,
            PaymentsResponseData,
        >,
    > for RouterData<Authorize, PaymentsAuthorizeData, PaymentsResponseData>
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: ResponseRouterData<
            Authorize,
            WellsfargoPaymentsResponse,
            PaymentsAuthorizeData,
            PaymentsResponseData,
        >,
    ) -> Result<Self, Self::Error> {
        let status = map_attempt_status(
            item.response
                .status
                .clone()
                .unwrap_or(WellsfargoPaymentStatus::StatusNotReceived),
            item.data.request.is_auto_capture()?,
        );
        let response =
            get_payment_response((&item.response, status, item.http_code)).map_err(|err| *err);
        let connector_response = item
            .response
            .processor_information
            .as_ref()
            .map(AdditionalPaymentMethodConnectorResponse::from)
            .map(ConnectorResponseData::with_additional_payment_method_data);

        Ok(Self {
            status,
            response,
            connector_response,
            ..item.data
        })
    }
}

impl From<&ClientProcessorInformation> for AdditionalPaymentMethodConnectorResponse {
    fn from(processor_information: &ClientProcessorInformation) -> Self {
        let payment_checks = Some(
            serde_json::json!({"avs_response": processor_information.avs, "card_verification": processor_information.card_verification}),
        );

        Self::Card {
            authentication_data: None,
            payment_checks,
            card_network: None,
            domestic_network: None,
        }
    }
}

impl<F>
    TryFrom<
        ResponseRouterData<
            F,
            WellsfargoPaymentsResponse,
            PaymentsCaptureData,
            PaymentsResponseData,
        >,
    > for RouterData<F, PaymentsCaptureData, PaymentsResponseData>
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: ResponseRouterData<
            F,
            WellsfargoPaymentsResponse,
            PaymentsCaptureData,
            PaymentsResponseData,
        >,
    ) -> Result<Self, Self::Error> {
        let status = map_attempt_status(
            item.response
                .status
                .clone()
                .unwrap_or(WellsfargoPaymentStatus::StatusNotReceived),
            true,
        );
        let response =
            get_payment_response((&item.response, status, item.http_code)).map_err(|err| *err);
        Ok(Self {
            status,
            response,
            ..item.data
        })
    }
}

impl<F>
    TryFrom<
        ResponseRouterData<F, WellsfargoPaymentsResponse, PaymentsCancelData, PaymentsResponseData>,
    > for RouterData<F, PaymentsCancelData, PaymentsResponseData>
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: ResponseRouterData<
            F,
            WellsfargoPaymentsResponse,
            PaymentsCancelData,
            PaymentsResponseData,
        >,
    ) -> Result<Self, Self::Error> {
        let status = map_attempt_status(
            item.response
                .status
                .clone()
                .unwrap_or(WellsfargoPaymentStatus::StatusNotReceived),
            false,
        );
        let response =
            get_payment_response((&item.response, status, item.http_code)).map_err(|err| *err);
        Ok(Self {
            status,
            response,
            ..item.data
        })
    }
}

// zero dollar response
impl
    TryFrom<
        ResponseRouterData<
            SetupMandate,
            WellsfargoPaymentsResponse,
            SetupMandateRequestData,
            PaymentsResponseData,
        >,
    > for RouterData<SetupMandate, SetupMandateRequestData, PaymentsResponseData>
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: ResponseRouterData<
            SetupMandate,
            WellsfargoPaymentsResponse,
            SetupMandateRequestData,
            PaymentsResponseData,
        >,
    ) -> Result<Self, Self::Error> {
        let mandate_reference =
            item.response
                .token_information
                .clone()
                .map(|token_info| MandateReference {
                    connector_mandate_id: token_info
                        .payment_instrument
                        .map(|payment_instrument| payment_instrument.id.expose()),
                    payment_method_id: None,
                    mandate_metadata: None,
                    connector_mandate_request_reference_id: None,
                });
        let mut mandate_status = map_attempt_status(
            item.response
                .status
                .clone()
                .unwrap_or(WellsfargoPaymentStatus::StatusNotReceived),
            false,
        );
        if matches!(mandate_status, enums::AttemptStatus::Authorized) {
            //In case of zero auth mandates we want to make the payment reach the terminal status so we are converting the authorized status to charged as well.
            mandate_status = enums::AttemptStatus::Charged
        }
        let error_response =
            get_error_response_if_failure((&item.response, mandate_status, item.http_code));

        let connector_response = item
            .response
            .processor_information
            .as_ref()
            .map(AdditionalPaymentMethodConnectorResponse::from)
            .map(ConnectorResponseData::with_additional_payment_method_data);

        Ok(Self {
            status: mandate_status,
            response: match error_response {
                Some(error) => Err(error),
                None => Ok(PaymentsResponseData::TransactionResponse {
                    resource_id: ResponseId::ConnectorTransactionId(item.response.id.clone()),
                    redirection_data: Box::new(None),
                    mandate_reference: Box::new(mandate_reference),
                    connector_metadata: None,
                    network_txn_id: item.response.processor_information.as_ref().and_then(
                        |processor_information| {
                            processor_information.network_transaction_id.clone()
                        },
                    ),
                    connector_response_reference_id: Some(
                        item.response
                            .client_reference_information
                            .and_then(|client_reference_information| {
                                client_reference_information.code.clone()
                            })
                            .unwrap_or(item.response.id),
                    ),
                    incremental_authorization_allowed: Some(
                        mandate_status == enums::AttemptStatus::Authorized,
                    ),
                    charges: None,
                }),
            },
            connector_response,
            ..item.data
        })
    }
}

impl<F, T>
    TryFrom<
        ResponseRouterData<
            F,
            WellsfargoPaymentsIncrementalAuthorizationResponse,
            T,
            PaymentsResponseData,
        >,
    > for RouterData<F, T, PaymentsResponseData>
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: ResponseRouterData<
            F,
            WellsfargoPaymentsIncrementalAuthorizationResponse,
            T,
            PaymentsResponseData,
        >,
    ) -> Result<Self, Self::Error> {
        Ok(Self {
            response: match item.response.error_information {
                Some(error) => Ok(PaymentsResponseData::IncrementalAuthorizationResponse {
                    status: common_enums::AuthorizationStatus::Failure,
                    error_code: error.reason,
                    error_message: error.message,
                    connector_authorization_id: None,
                }),
                _ => Ok(PaymentsResponseData::IncrementalAuthorizationResponse {
                    status: item.response.status.into(),
                    error_code: None,
                    error_message: None,
                    connector_authorization_id: None,
                }),
            },
            ..item.data
        })
    }
}

#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct WellsfargoTransactionResponse {
    id: String,
    application_information: ApplicationInformation,
    client_reference_information: Option<ClientReferenceInformation>,
    error_information: Option<WellsfargoErrorInformation>,
}

#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ApplicationInformation {
    status: Option<WellsfargoPaymentStatus>,
}

impl<F>
    TryFrom<
        ResponseRouterData<
            F,
            WellsfargoTransactionResponse,
            PaymentsSyncData,
            PaymentsResponseData,
        >,
    > for RouterData<F, PaymentsSyncData, PaymentsResponseData>
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: ResponseRouterData<
            F,
            WellsfargoTransactionResponse,
            PaymentsSyncData,
            PaymentsResponseData,
        >,
    ) -> Result<Self, Self::Error> {
        match item.response.application_information.status {
            Some(status) => {
                let status = map_attempt_status(status, item.data.request.is_auto_capture()?);
                let incremental_authorization_allowed =
                    Some(status == enums::AttemptStatus::Authorized);
                let risk_info: Option<ClientRiskInformation> = None;
                if utils::is_payment_failure(status) {
                    Ok(Self {
                        response: Err(get_error_response(
                            &item.response.error_information,
                            &risk_info,
                            Some(status),
                            item.http_code,
                            item.response.id.clone(),
                        )),
                        status: enums::AttemptStatus::Failure,
                        ..item.data
                    })
                } else {
                    Ok(Self {
                        status,
                        response: Ok(PaymentsResponseData::TransactionResponse {
                            resource_id: ResponseId::ConnectorTransactionId(
                                item.response.id.clone(),
                            ),
                            redirection_data: Box::new(None),
                            mandate_reference: Box::new(None),
                            connector_metadata: None,
                            network_txn_id: None,
                            connector_response_reference_id: item
                                .response
                                .client_reference_information
                                .map(|cref| cref.code)
                                .unwrap_or(Some(item.response.id)),
                            incremental_authorization_allowed,
                            charges: None,
                        }),
                        ..item.data
                    })
                }
            }
            None => Ok(Self {
                status: item.data.status,
                response: Ok(PaymentsResponseData::TransactionResponse {
                    resource_id: ResponseId::ConnectorTransactionId(item.response.id.clone()),
                    redirection_data: Box::new(None),
                    mandate_reference: Box::new(None),
                    connector_metadata: None,
                    network_txn_id: None,
                    connector_response_reference_id: Some(item.response.id),
                    incremental_authorization_allowed: None,
                    charges: None,
                }),
                ..item.data
            }),
        }
    }
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct WellsfargoRefundRequest {
    order_information: OrderInformation,
    client_reference_information: ClientReferenceInformation,
}

impl<F> TryFrom<&WellsfargoRouterData<&RefundsRouterData<F>>> for WellsfargoRefundRequest {
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(item: &WellsfargoRouterData<&RefundsRouterData<F>>) -> Result<Self, Self::Error> {
        Ok(Self {
            order_information: OrderInformation {
                amount_details: Amount {
                    total_amount: item.amount.clone(),
                    currency: item.router_data.request.currency,
                },
            },
            client_reference_information: ClientReferenceInformation {
                code: Some(item.router_data.request.refund_id.clone()),
            },
        })
    }
}

impl From<WellsfargoRefundStatus> for enums::RefundStatus {
    fn from(item: WellsfargoRefundStatus) -> Self {
        match item {
            WellsfargoRefundStatus::Succeeded | WellsfargoRefundStatus::Transmitted => {
                Self::Success
            }
            WellsfargoRefundStatus::Cancelled
            | WellsfargoRefundStatus::Failed
            | WellsfargoRefundStatus::Voided => Self::Failure,
            WellsfargoRefundStatus::Pending => Self::Pending,
        }
    }
}

#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum WellsfargoRefundStatus {
    Succeeded,
    Transmitted,
    Failed,
    Pending,
    Voided,
    Cancelled,
}

#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct WellsfargoRefundResponse {
    id: String,
    status: WellsfargoRefundStatus,
    error_information: Option<WellsfargoErrorInformation>,
}

impl TryFrom<RefundsResponseRouterData<Execute, WellsfargoRefundResponse>>
    for RefundsRouterData<Execute>
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: RefundsResponseRouterData<Execute, WellsfargoRefundResponse>,
    ) -> Result<Self, Self::Error> {
        let refund_status = enums::RefundStatus::from(item.response.status.clone());
        let response = if utils::is_refund_failure(refund_status) {
            Err(get_error_response(
                &item.response.error_information,
                &None,
                None,
                item.http_code,
                item.response.id.clone(),
            ))
        } else {
            Ok(RefundsResponseData {
                connector_refund_id: item.response.id,
                refund_status: enums::RefundStatus::from(item.response.status),
            })
        };

        Ok(Self {
            response,
            ..item.data
        })
    }
}

#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct RsyncApplicationInformation {
    status: Option<WellsfargoRefundStatus>,
}

#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct WellsfargoRsyncResponse {
    id: String,
    application_information: Option<RsyncApplicationInformation>,
    error_information: Option<WellsfargoErrorInformation>,
}

impl TryFrom<RefundsResponseRouterData<RSync, WellsfargoRsyncResponse>>
    for RefundsRouterData<RSync>
{
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(
        item: RefundsResponseRouterData<RSync, WellsfargoRsyncResponse>,
    ) -> Result<Self, Self::Error> {
        let response = match item
            .response
            .application_information
            .and_then(|application_information| application_information.status)
        {
            Some(status) => {
                let refund_status = enums::RefundStatus::from(status.clone());
                if utils::is_refund_failure(refund_status) {
                    if status == WellsfargoRefundStatus::Voided {
                        Err(get_error_response(
                            &Some(WellsfargoErrorInformation {
                                message: Some(constants::REFUND_VOIDED.to_string()),
                                reason: Some(constants::REFUND_VOIDED.to_string()),
                                details: None,
                            }),
                            &None,
                            None,
                            item.http_code,
                            item.response.id.clone(),
                        ))
                    } else {
                        Err(get_error_response(
                            &item.response.error_information,
                            &None,
                            None,
                            item.http_code,
                            item.response.id.clone(),
                        ))
                    }
                } else {
                    Ok(RefundsResponseData {
                        connector_refund_id: item.response.id,
                        refund_status,
                    })
                }
            }

            None => Ok(RefundsResponseData {
                connector_refund_id: item.response.id.clone(),
                refund_status: match item.data.response {


// File: crates/diesel_models/src/query/organization.rs
// Module: diesel_models
// Public functions: 3

use common_utils::id_type;
use diesel::{associations::HasTable, ExpressionMethods};

#[cfg(feature = "v1")]
use crate::schema::organization::dsl::org_id as dsl_identifier;
#[cfg(feature = "v2")]
use crate::schema_v2::organization::dsl::id as dsl_identifier;
use crate::{organization::*, query::generics, PgPooledConn, StorageResult};

impl OrganizationNew {
    pub async fn insert(self, conn: &PgPooledConn) -> StorageResult<Organization> {
        generics::generic_insert(conn, self).await
    }
}

impl Organization {
    pub async fn find_by_org_id(
        conn: &PgPooledConn,
        org_id: id_type::OrganizationId,
    ) -> StorageResult<Self> {
        generics::generic_find_one::<<Self as HasTable>::Table, _, _>(
            conn,
            dsl_identifier.eq(org_id),
        )
        .await
    }

    pub async fn update_by_org_id(
        conn: &PgPooledConn,
        org_id: id_type::OrganizationId,
        update: OrganizationUpdate,
    ) -> StorageResult<Self> {
        generics::generic_update_with_unique_predicate_get_result::<
            <Self as HasTable>::Table,
            _,
            _,
            _,
        >(
            conn,
            dsl_identifier.eq(org_id),
            OrganizationUpdateInternal::from(update),
        )
        .await
    }
}


// Function: files_delete_core
// File: crates/router/src/core/files.rs
// Module: router

pub fn files_delete_core(
    state: SessionState,
    merchant_context: domain::MerchantContext,
    req: api::FileId,
) -> RouterResponse<serde_json::Value>


// File: crates/router/src/routes/payment_link.rs
// Module: router
// Public functions: 5

use actix_web::{web, Responder};
use router_env::{instrument, tracing, Flow};

use crate::{
    core::{api_locking, payment_link::*},
    services::{api, authentication as auth},
    types::domain,
    AppState,
};

/// Payments Link - Retrieve
///
/// To retrieve the properties of a Payment Link. This may be used to get the status of a previously initiated payment or next action for an ongoing payment
#[instrument(skip(state, req), fields(flow = ?Flow::PaymentLinkRetrieve))]
pub async fn payment_link_retrieve(
    state: web::Data<AppState>,
    req: actix_web::HttpRequest,
    path: web::Path<String>,
    json_payload: web::Query<api_models::payments::RetrievePaymentLinkRequest>,
) -> impl Responder {
    let flow = Flow::PaymentLinkRetrieve;
    let payload = json_payload.into_inner();
    let api_auth = auth::ApiKeyAuth::default();

    let (auth_type, _) =
        match auth::check_client_secret_and_get_auth(req.headers(), &payload, api_auth) {
            Ok(auth) => auth,
            Err(err) => return api::log_and_return_error_response(error_stack::report!(err)),
        };

    api::server_wrap(
        flow,
        state,
        &req,
        payload.clone(),
        |state, _auth, _, _| retrieve_payment_link(state, path.clone()),
        &*auth_type,
        api_locking::LockAction::NotApplicable,
    )
    .await
}

pub async fn initiate_payment_link(
    state: web::Data<AppState>,
    req: actix_web::HttpRequest,
    path: web::Path<(
        common_utils::id_type::MerchantId,
        common_utils::id_type::PaymentId,
    )>,
) -> impl Responder {
    let flow = Flow::PaymentLinkInitiate;
    let (merchant_id, payment_id) = path.into_inner();

    let payload = api_models::payments::PaymentLinkInitiateRequest {
        payment_id,
        merchant_id: merchant_id.clone(),
    };
    Box::pin(api::server_wrap(
        flow,
        state,
        &req,
        payload.clone(),
        |state, auth: auth::AuthenticationData, _, _| {
            let merchant_context = domain::MerchantContext::NormalMerchant(Box::new(
                domain::Context(auth.merchant_account, auth.key_store),
            ));
            initiate_payment_link_flow(
                state,
                merchant_context,
                payload.merchant_id.clone(),
                payload.payment_id.clone(),
            )
        },
        &crate::services::authentication::MerchantIdAuth(merchant_id),
        api_locking::LockAction::NotApplicable,
    ))
    .await
}

pub async fn initiate_secure_payment_link(
    state: web::Data<AppState>,
    req: actix_web::HttpRequest,
    path: web::Path<(
        common_utils::id_type::MerchantId,
        common_utils::id_type::PaymentId,
    )>,
) -> impl Responder {
    let flow = Flow::PaymentSecureLinkInitiate;
    let (merchant_id, payment_id) = path.into_inner();
    let payload = api_models::payments::PaymentLinkInitiateRequest {
        payment_id,
        merchant_id: merchant_id.clone(),
    };
    let headers = req.headers();
    Box::pin(api::server_wrap(
        flow,
        state,
        &req,
        payload.clone(),
        |state, auth: auth::AuthenticationData, _, _| {
            let merchant_context = domain::MerchantContext::NormalMerchant(Box::new(
                domain::Context(auth.merchant_account, auth.key_store),
            ));
            initiate_secure_payment_link_flow(
                state,
                merchant_context,
                payload.merchant_id.clone(),
                payload.payment_id.clone(),
                headers,
            )
        },
        &crate::services::authentication::MerchantIdAuth(merchant_id),
        api_locking::LockAction::NotApplicable,
    ))
    .await
}

/// Payment Link - List
///
/// To list the payment links
#[instrument(skip_all, fields(flow = ?Flow::PaymentLinkList))]
pub async fn payments_link_list(
    state: web::Data<AppState>,
    req: actix_web::HttpRequest,
    payload: web::Query<api_models::payments::PaymentLinkListConstraints>,
) -> impl Responder {
    let flow = Flow::PaymentLinkList;
    let payload = payload.into_inner();
    Box::pin(api::server_wrap(
        flow,
        state,
        &req,
        payload,
        |state, auth: auth::AuthenticationData, payload, _| {
            list_payment_link(state, auth.merchant_account, payload)
        },
        &auth::HeaderAuth(auth::ApiKeyAuth {
            is_connected_allowed: false,
            is_platform_allowed: false,
        }),
        api_locking::LockAction::NotApplicable,
    ))
    .await
}

pub async fn payment_link_status(
    state: web::Data<AppState>,
    req: actix_web::HttpRequest,
    path: web::Path<(
        common_utils::id_type::MerchantId,
        common_utils::id_type::PaymentId,
    )>,
) -> impl Responder {
    let flow = Flow::PaymentLinkStatus;
    let (merchant_id, payment_id) = path.into_inner();

    let payload = api_models::payments::PaymentLinkInitiateRequest {
        payment_id,
        merchant_id: merchant_id.clone(),
    };
    Box::pin(api::server_wrap(
        flow,
        state,
        &req,
        payload.clone(),
        |state, auth: auth::AuthenticationData, _, _| {
            let merchant_context = domain::MerchantContext::NormalMerchant(Box::new(
                domain::Context(auth.merchant_account, auth.key_store),
            ));
            get_payment_link_status(
                state,
                merchant_context,
                payload.merchant_id.clone(),
                payload.payment_id.clone(),
            )
        },
        &crate::services::authentication::MerchantIdAuth(merchant_id),
        api_locking::LockAction::NotApplicable,
    ))
    .await
}


// Function: profile_delete
// File: crates/router/src/routes/profiles.rs
// Module: router

pub fn profile_delete(
    state: web::Data<AppState>,
    req: HttpRequest,
    path: web::Path<(
        common_utils::id_type::MerchantId,
        common_utils::id_type::ProfileId,
    )


// Implementation: impl Responder
// File: crates/router/src/routes/routing.rs
// Module: router
// Methods: 0 total (0 public)

impl Responder


// Struct: ResponseIdStr
// File: crates/hyperswitch_connectors/src/connectors/worldpay/response.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct ResponseIdStr


// Struct: CallBackResponse
// File: crates/hyperswitch_connectors/src/connectors/breadpay/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct CallBackResponse


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

impl api::PaymentToken for for Iatapay


// Struct: NmiRefundRequest
// File: crates/hyperswitch_connectors/src/connectors/nmi/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct NmiRefundRequest


// Struct: AuthorizedotnetRefundRequest
// File: crates/hyperswitch_connectors/src/connectors/authorizedotnet/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct AuthorizedotnetRefundRequest


// File: crates/diesel_models/src/query/blocklist_fingerprint.rs
// Module: diesel_models
// Public functions: 2

use diesel::{associations::HasTable, BoolExpressionMethods, ExpressionMethods};

use super::generics;
use crate::{
    blocklist_fingerprint::{BlocklistFingerprint, BlocklistFingerprintNew},
    schema::blocklist_fingerprint::dsl,
    PgPooledConn, StorageResult,
};

impl BlocklistFingerprintNew {
    pub async fn insert(self, conn: &PgPooledConn) -> StorageResult<BlocklistFingerprint> {
        generics::generic_insert(conn, self).await
    }
}

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