Repository: juspay/hyperswitch
File: crates/router/src/core/payments/flows/session_flow.rs (Rust)

Code before:
            );

        if google_pay_wallets_details.is_some() {
            let gpay_data = router_data
                .connector_wallets_details
                .clone()
                .parse_value::<payment_types::GooglePayWalletDetails>("GooglePayWalletDetails")
                .change_context(errors::ConnectorError::NoConnectorWalletDetails)
                .attach_printable(format!(
                    "cannot parse gpay connector_wallets_details from the given value {:?}",
                    router_data.connector_wallets_details
                ))
                .change_context(errors::ApiErrorResponse::InvalidDataFormat {
                    field_name: "connector_wallets_details".to_string(),
                    expected_format: "gpay_connector_wallets_details_format".to_string(),
                })?;

            let (provider_details, cards) = if let Some(google_pay_info) = gpay_data.google_pay.data
            {
                (google_pay_info.provider_details, google_pay_info.cards)
            } else {
                return Err(errors::ApiErrorResponse::InvalidDataFormat {
                    field_name: "connector_wallets_details".to_string(),
                    expected_format: "gpay_connector_wallets_details_format".to_string(),
                }
                .into());
            };
            let payment_types::GooglePayProviderDetails::GooglePayMerchantDetails(gpay_info) =
                provider_details.clone();

            let gpay_allowed_payment_methods = get_allowed_payment_methods_from_cards(
                cards,
                &gpay_info.merchant_info.tokenization_specification,
                is_billing_details_required,
            )?;

            Ok(types::PaymentsSessionRouterData {
                response: Ok(types::PaymentsResponseData::SessionResponse {
                    session_token: payment_types::SessionToken::GooglePay(Box::new(
                        payment_types::GpaySessionTokenResponse::GooglePaySession(
                            payment_types::GooglePaySessionResponse {
                                merchant_info: payment_types::GpayMerchantInfo {
                                    merchant_name: gpay_info.merchant_info.merchant_name,
                                    merchant_id: gpay_info.merchant_info.merchant_id,
                                },
                                allowed_payment_methods: vec![gpay_allowed_payment_methods],
                                transaction_info,
                                connector: connector.connector_name.to_string(),
                                sdk_next_action: payment_types::SdkNextAction {
                                    next_action: payment_types::NextActionCall::Confirm,
                                },

Review comment (suggestion):
Whenever a `/session` call is made with a connector configured only for pre-decrypted Apple Pay, it results in an error.

When a pre-decrypted flow is configured, the expectation is that the `/session` call should not—and cannot—be made, since the session is already initiated and a decrypted token is being passed.

If a `/session` call is made in this scenario, we can return `SessionToken::NoSessionTokenReceived` for now.

Ideally, however, this should be handled at the routing level by selecting only the connectors that are eligible for the `/session` call.

Code after:
        let is_billing_details_required = is_billing_address_required_to_be_collected_from_wallet(
            state,
            connector,
            business_profile,
            enums::PaymentMethodType::GooglePay,
        );

        let required_amount_type = StringMajorUnitForConnector;
        let google_pay_amount = required_amount_type
            .convert(
                router_data.request.minor_amount,
                router_data.request.currency,
            )
            .change_context(errors::ApiErrorResponse::PreconditionFailed {
                message: "Failed to convert amount to string major unit for googlePay".to_string(),
            })?;
        let session_data = router_data.request.clone();
        let transaction_info = payment_types::GpayTransactionInfo {
            country_code: session_data.country.unwrap_or_default(),
            currency_code: router_data.request.currency,
            total_price_status: "Final".to_string(),
            total_price: google_pay_amount,
        };

        let required_shipping_contact_fields =
            is_shipping_address_required_to_be_collected_form_wallet(
                state,
                connector,
                business_profile,
                enums::PaymentMethodType::GooglePay,
            );

        if google_pay_wallets_details.is_some() {
            let gpay_data = router_data
                .connector_wallets_details
                .clone()
                .parse_value::<payment_types::GooglePayWalletDetails>("GooglePayWalletDetails")
                .change_context(errors::ConnectorError::NoConnectorWalletDetails)
                .attach_printable(format!(
                    "cannot parse gpay connector_wallets_details from the given value {:?}",
                    router_data.connector_wallets_details
                ))
                .change_context(errors::ApiErrorResponse::InvalidDataFormat {
                    field_name: "connector_wallets_details".to_string(),
                    expected_format: "gpay_connector_wallets_details_format".to_string(),
                })?;

            let (provider_details, cards) = (
                gpay_data.google_pay.provider_details,
                gpay_data.google_pay.cards,
            );