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

Code before:
        )),
        (
            api_models::payments::AdditionalPaymentData::PayLater { .. },
            AdditionalPaymentMethodConnectorResponse::PayLater {
                klarna_sdk: Some(KlarnaSdkResponse { payment_type }),
            },
        ) => api_models::payments::AdditionalPaymentData::PayLater {
            klarna_sdk: Some(api_models::payments::KlarnaSdkPaymentMethod { payment_type }),
        },
        (
            api_models::payments::AdditionalPaymentData::BankRedirect { .. },
            AdditionalPaymentMethodConnectorResponse::BankRedirect {
                interac: Some(InteracCustomerInfo { customer_info }),
            },
        ) => api_models::payments::AdditionalPaymentData::BankRedirect {
            bank_name: None,
            details: None,
            interac: Some(api_models::payments::InteracPaymentMethod { customer_info }),
        },
        (
            api_models::payments::AdditionalPaymentData::Wallet {
                apple_pay,
                google_pay,
                samsung_pay,
            },
            AdditionalPaymentMethodConnectorResponse::Card { auth_code, .. },
        ) => api_models::payments::AdditionalPaymentData::Wallet {
            apple_pay: apple_pay.clone().map(|apple_pay| {
                Box::new(api_models::payments::ApplepayPaymentMethod {
                    auth_code: auth_code.clone(),
                    ..*apple_pay.clone()
                })
            }),
            google_pay: google_pay.clone().map(|google_pay| {
                Box::new(payment_additional_types::WalletAdditionalDataForCard {
                    auth_code: auth_code.clone(),
                    ..*google_pay.clone()
                })
            }),
            samsung_pay: samsung_pay.clone(),
        },

        _ => additional_payment_data,
    }
}

#[cfg(feature = "v1")]
pub async fn get_payment_method_data_and_encrypted_payment_method_data(
    payment_attempt: &PaymentAttempt,
    key_manager_state: &KeyManagerState,
    key_store: &domain::MerchantKeyStore,

Review comment (security):
Matching this up with cards because we get auth code when ever there is card involved only, it will be unnecessary matching in connector code if we decide to create two new enums for applepay and googlepay

Code after:
    amount: MinorUnit,
    should_validate: bool,
) -> Result<(), errors::ApiErrorResponse> {
    if should_validate {
        let total_order_details_amount: MinorUnit = order_details
            .iter()
            .map(|order| order.amount * order.quantity)
            .sum();

        if total_order_details_amount != amount {
            Err(errors::ApiErrorResponse::InvalidRequestData {
                message: "Total sum of order details doesn't match amount in payment request"
                    .to_string(),
            })
        } else {
            Ok(())
        }
    } else {
        Ok(())
    }
}

// This function validates the client secret expiry set by the merchant in the request
pub fn validate_session_expiry(session_expiry: u32) -> Result<(), errors::ApiErrorResponse> {
    if !(consts::MIN_SESSION_EXPIRY..=consts::MAX_SESSION_EXPIRY).contains(&session_expiry) {
        Err(errors::ApiErrorResponse::InvalidRequestData {
            message: "session_expiry should be between 60(1 min) to 7890000(3 months).".to_string(),
        })
    } else {
        Ok(())
    }
}

pub fn get_recipient_id_for_open_banking(
    merchant_data: &AdditionalMerchantData,
) -> Result<Option<String>, errors::ApiErrorResponse> {
    match merchant_data {
        AdditionalMerchantData::OpenBankingRecipientData(data) => match data {
            MerchantRecipientData::ConnectorRecipientId(id) => Ok(Some(id.peek().clone())),
            MerchantRecipientData::AccountData(acc_data) => {
                let connector_recipient_id = match acc_data {
                    MerchantAccountData::Bacs {
                        connector_recipient_id,
                        ..
                    }
                    | MerchantAccountData::Iban {
                        connector_recipient_id,
                        ..
                    }
                    | MerchantAccountData::FasterPayments {
                        connector_recipient_id,