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

Code before:
                        .as_ref()
                        .and_then(|d| d.paze.clone()),
                    google_pay: connector_wallets_details_optional
                        .as_ref()
                        .and_then(|d| d.google_pay.clone()),
                }
            }
        };

        return Ok(Some(updated_wallet_details));
    }

    // Return connector_wallets_details if no Apple Pay metadata was found
    Ok(connector_wallets_details_optional)
}

pub fn is_predecrypted_flow_supported_googlepay(
    connector_metadata: Option<pii::SecretSerdeValue>,
) -> bool {
    connector_metadata
        .parse_value::<api_models::payments::GpaySessionTokenData>("GpaySessionTokenData")
        .ok()
        .map(|metadata| metadata.google_pay.is_predecrypted_token_supported())
        .unwrap_or(false)
}
pub fn is_predecrypted_flow_supported_applepay(
    connector_metadata: Option<pii::SecretSerdeValue>,
) -> bool {
    connector_metadata
        .parse_value::<api_models::payments::ApplepayCombinedSessionTokenData>(
            "ApplepayCombinedSessionTokenData",
        )
        .ok()
        .map(|apple_pay_metadata| {
            apple_pay_metadata
                .apple_pay_combined
                .is_predecrypted_token_supported()
        })
        .unwrap_or(false)
}
pub fn get_applepay_metadata(
    connector_metadata: Option<pii::SecretSerdeValue>,
) -> RouterResult<api_models::payments::ApplepaySessionTokenMetadata> {
    connector_metadata
        .clone()
        .parse_value::<api_models::payments::ApplepayCombinedSessionTokenData>(
            "ApplepayCombinedSessionTokenData",
        )
        .change_context(errors::ConnectorError::ParsingFailed)
        .and_then(
            |combined_metadata| match combined_metadata.apple_pay_combined.data {

Review comment (suggestion):
```suggestion
pub fn is_applepay_predecrypted_flow_supported(
```

Code after:
) -> CustomResult<bool, errors::ApiErrorResponse> {
    let option_apple_pay_metadata = get_applepay_metadata(connector_metadata)
        .map_err(|error| {
            logger::info!(
                "Apple pay metadata parsing for {:?} in is_apple_pay_simplified_flow {:?}",
                connector_name,
                error
            )
        })
        .ok();

    // return true only if the apple flow type is simplified
    Ok(match option_apple_pay_metadata {
        Some(api_models::payments::ApplepaySessionTokenMetadata::ApplePayCombined(
            combined_data,
        )) => matches!(
            combined_data.data,
            Some(api_models::payments::ApplePayCombinedMetadata::Simplified { .. })
        ),
        _ => false,
    })
}

// This function will return the encrypted connector wallets details with Apple Pay certificates
// Currently apple pay certifiactes are stored in the metadata which is not encrypted.
// In future we want those certificates to be encrypted and stored in the connector_wallets_details.
// As part of migration fallback this function checks apple pay details are present in connector_wallets_details
// If yes, it will encrypt connector_wallets_details and store it in the database.
// If no, it will check if apple pay details are present in metadata and merge it with connector_wallets_details, encrypt and store it.
pub async fn get_connector_wallets_details_with_apple_pay_certificates(
    connector_metadata: &Option<masking::Secret<tera::Value>>,
    connector_wallets_details_optional: &Option<api_models::admin::ConnectorWalletDetails>,
) -> RouterResult<Option<masking::Secret<serde_json::Value>>> {
    let connector_wallet_details_with_apple_pay_metadata_optional =
        get_apple_pay_metadata_if_needed(connector_metadata, connector_wallets_details_optional)
            .await?;

    let connector_wallets_details = connector_wallet_details_with_apple_pay_metadata_optional
        .map(|details| {
            serde_json::to_value(details)
                .change_context(errors::ApiErrorResponse::InternalServerError)
                .attach_printable("Failed to serialize Apple Pay metadata as JSON")
        })
        .transpose()?
        .map(masking::Secret::new);

    Ok(connector_wallets_details)
}

async fn get_apple_pay_metadata_if_needed(
    connector_metadata: &Option<masking::Secret<tera::Value>>,