Bug: [FEATURE] Addition of Client Secret Validation in Payment Methods API.



### Feature Description

With the current workflow the clientSecret essentially gets verified at the very end during confirm payment. What we basically want to do however is to make sure to not show the SDK or throw the appropriate errors when that is the case as soon as possible. So during Payment Methods API call that happens at the very beginning.

### Possible Implementation

So instead of sending the payment_methods  list , in the case of incorrect client secret, we want an error body which will tell us one of the 3 things. 
1. Expired ClientSecret. 
2. Completed/Failed ClientSecret. 
3. Incorrect ClientSecret. 
After knowing any 1 of these, we can throw an error in the UI for the same.


### Have you spent some time to check if this feature request has been raised before?

- [X] I checked and didn't find similar issue

### Have you read the Contributing Guidelines?

- [X] I have read the [Contributing Guidelines](https://github.com/juspay/hyperswitch/blob/main/docs/CONTRIBUTING.md)

### Are you willing to submit a PR?

None
diff --git a/crates/router/src/compatibility/stripe/errors.rs b/crates/router/src/compatibility/stripe/errors.rs
index 6886be1f2e0..144c14e2736 100644
--- a/crates/router/src/compatibility/stripe/errors.rs
+++ b/crates/router/src/compatibility/stripe/errors.rs
@@ -406,7 +406,8 @@ impl From<errors::ApiErrorResponse> for StripeErrorCode {
             errors::ApiErrorResponse::CustomerNotFound => Self::CustomerNotFound,
             errors::ApiErrorResponse::PaymentNotFound => Self::PaymentNotFound,
             errors::ApiErrorResponse::PaymentMethodNotFound => Self::PaymentMethodNotFound,
-            errors::ApiErrorResponse::ClientSecretNotGiven => Self::ClientSecretNotFound,
+            errors::ApiErrorResponse::ClientSecretNotGiven
+            | errors::ApiErrorResponse::ClientSecretExpired => Self::ClientSecretNotFound,
             errors::ApiErrorResponse::MerchantAccountNotFound => Self::MerchantAccountNotFound,
             errors::ApiErrorResponse::ResourceIdNotFound => Self::ResourceIdNotFound,
             errors::ApiErrorResponse::MerchantConnectorAccountNotFound => {
diff --git a/crates/router/src/core/errors/api_error_response.rs b/crates/router/src/core/errors/api_error_response.rs
index f20f5cdd818..9dc761e3933 100644
--- a/crates/router/src/core/errors/api_error_response.rs
+++ b/crates/router/src/core/errors/api_error_response.rs
@@ -49,6 +49,8 @@ pub enum ApiErrorResponse {
     InvalidDataValue { field_name: &'static str },
     #[error(error_type = ErrorType::InvalidRequestError, code = "IR_08", message = "Client secret was not provided")]
     ClientSecretNotGiven,
+    #[error(error_type = ErrorType::InvalidRequestError, code = "IR_08", message = "Client secret has expired")]
+    ClientSecretExpired,
     #[error(error_type = ErrorType::InvalidRequestError, code = "IR_09", message = "The client_secret provided does not match the client_secret associated with the Payment")]
     ClientSecretInvalid,
     #[error(error_type = ErrorType::InvalidRequestError, code = "IR_10", message = "Customer has active mandate/subsciption")]
@@ -233,6 +235,7 @@ impl actix_web::ResponseError for ApiErrorResponse {
             | Self::MerchantConnectorAccountNotFound
             | Self::MandateNotFound
             | Self::ClientSecretNotGiven
+            | Self::ClientSecretExpired
             | Self::ClientSecretInvalid
             | Self::SuccessfulPaymentNotFound
             | Self::IncorrectConnectorNameGiven
@@ -316,7 +319,7 @@ impl common_utils::errors::ErrorSwitch<api_models::errors::types::ApiErrorRespon
             Self::ClientSecretNotGiven => AER::BadRequest(ApiError::new(
                 "IR",
                 8,
-                "Client secret was not provided", None
+                "client_secret was not provided", None
             )),
             Self::ClientSecretInvalid => {
                 AER::BadRequest(ApiError::new("IR", 9, "The client_secret provided does not match the client_secret associated with the Payment", None))
@@ -344,7 +347,12 @@ impl common_utils::errors::ErrorSwitch<api_models::errors::types::ApiErrorRespon
             Self::InvalidJwtToken => AER::Unauthorized(ApiError::new("IR", 17, "Access forbidden, invalid JWT token was used", None)),
             Self::GenericUnauthorized { message } => {
                 AER::Unauthorized(ApiError::new("IR", 18, message.to_string(), None))
-            }
+            },
+            Self::ClientSecretExpired => AER::BadRequest(ApiError::new(
+                "IR",
+                19,
+                "The provided client_secret has expired", None
+            )),
             Self::ExternalConnectorError {
                 code,
                 message,
diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs
index ef8032310b5..25f8c52dae5 100644
--- a/crates/router/src/core/payments/helpers.rs
+++ b/crates/router/src/core/payments/helpers.rs
@@ -1181,9 +1181,11 @@ pub(crate) fn authenticate_client_secret(
     payment_intent_client_secret: Option<&String>,
 ) -> Result<(), errors::ApiErrorResponse> {
     match (request_client_secret, payment_intent_client_secret) {
-        (Some(req_cs), Some(pi_cs)) => utils::when(req_cs.ne(pi_cs), || {
+        (Some(req_cs), Some(pi_cs)) if req_cs != pi_cs => {
             Err(errors::ApiErrorResponse::ClientSecretInvalid)
-        }),
+        }
+        // If there is no client in payment intent, then it has expired
+        (Some(_), None) => Err(errors::ApiErrorResponse::ClientSecretExpired),
         _ => Ok(()),
     }
 }

## Type of Change
<!-- Put an `x` in the boxes that apply -->

- [x] New feature

## Description
<!-- Describe your changes in detail -->
If there is no client secret in payment_intent then it has expired, so if we receive a client secret in request and there is no client secret in payment intent then the client secret provided has expired.


## Motivation and Context
<!--
Why is this change required? What problem does it solve?
If it fixes an open issue, please link to the issue here.

If you don't have an issue, we'd recommend starting with one first so the PR
can focus on the implementation (unless its an obvious bug or documentation fix
that will have little conversation).
-->
Closes #756 
For the client secret to be delete on failed payment #724 PR needs to be merged

## How did you test it?
<!--
Did you write an integration/unit/API test to verify the code changes?
Or did you test this change manually (provide relevant screenshots)?
-->
- Create a successful payment
- Call payment_method list which fails saying client secret is invalid

## Checklist
<!-- Put an `x` in the boxes that apply -->

- [x] I formatted the code `cargo +nightly fmt --all`
- [x] I addressed lints thrown by `cargo clippy`
- [x] I reviewed submitted code
