Bug: [BUG] Missing payment_method_data mappings in the helpers.rs



### Bug Description

Need to add the mappings for the latest payment methods. This would be a follow-up task for this PR : https://github.com/juspay/hyperswitch/pull/1236.

### Have you spent some time to check if this bug 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?

Yes I am willing to submit a PR!
diff --git a/crates/common_enums/src/enums.rs b/crates/common_enums/src/enums.rs
index ba69cedad9c..6e604c52204 100644
--- a/crates/common_enums/src/enums.rs
+++ b/crates/common_enums/src/enums.rs
@@ -954,6 +954,7 @@ pub enum PaymentMethod {
     Reward,
     Upi,
     Voucher,
+    GiftCard,
 }
 
 #[derive(
diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs
index 2953a5a390c..326ac771960 100644
--- a/crates/router/src/core/payments/helpers.rs
+++ b/crates/router/src/core/payments/helpers.rs
@@ -37,7 +37,7 @@ use crate::{
             types::{self, AsyncLift},
         },
         storage::{self, enums as storage_enums, ephemeral_key, CustomerUpdate::Update},
-        transformers::ForeignInto,
+        transformers::ForeignTryFrom,
         ErrorResponse, RouterData,
     },
     utils::{
@@ -1400,65 +1400,156 @@ pub(crate) fn validate_payment_method_fields_present(
         },
     )?;
 
-    let payment_method: Option<api_enums::PaymentMethod> =
-        (req.payment_method_type).map(ForeignInto::foreign_into);
-
     utils::when(
-        req.payment_method.is_some()
-            && req.payment_method_type.is_some()
-            && (req.payment_method != payment_method),
+        req.payment_method.is_some() && req.payment_method_type.is_some(),
         || {
-            Err(errors::ApiErrorResponse::InvalidRequestData {
-                message: ("payment_method_type doesn't correspond to the specified payment_method"
-                    .to_string()),
-            })
+            req.payment_method
+                .map_or(Ok(()), |req_payment_method| {
+                    req.payment_method_type.map_or(Ok(()), |req_payment_method_type| {
+                        if !validate_payment_method_type_against_payment_method(req_payment_method, req_payment_method_type) {
+                            Err(errors::ApiErrorResponse::InvalidRequestData {
+                                message: ("payment_method_type doesn't correspond to the specified payment_method"
+                                    .to_string()),
+                            })
+                        } else {
+                            Ok(())
+                        }
+                    })
+                })
         },
     )?;
 
+    let validate_payment_method_and_payment_method_data =
+        |req_payment_method_data, req_payment_method: api_enums::PaymentMethod| {
+            api_enums::PaymentMethod::foreign_try_from(req_payment_method_data).and_then(|payment_method|
+                if req_payment_method != payment_method {
+                    Err(errors::ApiErrorResponse::InvalidRequestData {
+                        message: ("payment_method_data doesn't correspond to the specified payment_method"
+                            .to_string()),
+                    })
+                } else {
+                    Ok(())
+                })
+        };
+
     utils::when(
-        !matches!(
-            req.payment_method
-                .as_ref()
-                .zip(req.payment_method_data.as_ref()),
-            Some(
-                (
-                    api_enums::PaymentMethod::Card,
-                    api::PaymentMethodData::Card(..)
-                ) | (
-                    api_enums::PaymentMethod::Wallet,
-                    api::PaymentMethodData::Wallet(..)
-                ) | (
-                    api_enums::PaymentMethod::PayLater,
-                    api::PaymentMethodData::PayLater(..)
-                ) | (
-                    api_enums::PaymentMethod::BankRedirect,
-                    api::PaymentMethodData::BankRedirect(..)
-                ) | (
-                    api_enums::PaymentMethod::BankDebit,
-                    api::PaymentMethodData::BankDebit(..)
-                ) | (
-                    api_enums::PaymentMethod::Crypto,
-                    api::PaymentMethodData::Crypto(..)
-                ) | (
-                    api_enums::PaymentMethod::Upi,
-                    api::PaymentMethodData::Upi(..)
-                ) | (
-                    api_enums::PaymentMethod::Voucher,
-                    api::PaymentMethodData::Voucher(..)
-                )
-            ) | None
-        ),
+        req.payment_method.is_some() && req.payment_method_data.is_some(),
         || {
-            Err(errors::ApiErrorResponse::InvalidRequestData {
-                message: "payment_method_data doesn't correspond to the specified payment_method"
-                    .to_string(),
-            })
+            req.payment_method_data
+                .clone()
+                .map_or(Ok(()), |req_payment_method_data| {
+                    req.payment_method.map_or(Ok(()), |req_payment_method| {
+                        validate_payment_method_and_payment_method_data(
+                            req_payment_method_data,
+                            req_payment_method,
+                        )
+                    })
+                })
         },
     )?;
 
     Ok(())
 }
 
+pub fn validate_payment_method_type_against_payment_method(
+    payment_method: api_enums::PaymentMethod,
+    payment_method_type: api_enums::PaymentMethodType,
+) -> bool {
+    match payment_method {
+        api_enums::PaymentMethod::Card => matches!(
+            payment_method_type,
+            api_enums::PaymentMethodType::Credit | api_enums::PaymentMethodType::Debit
+        ),
+        api_enums::PaymentMethod::PayLater => matches!(
+            payment_method_type,
+            api_enums::PaymentMethodType::Affirm
+                | api_enums::PaymentMethodType::Alma
+                | api_enums::PaymentMethodType::AfterpayClearpay
+                | api_enums::PaymentMethodType::Klarna
+                | api_enums::PaymentMethodType::PayBright
+                | api_enums::PaymentMethodType::Atome
+                | api_enums::PaymentMethodType::Walley
+        ),
+        api_enums::PaymentMethod::Wallet => matches!(
+            payment_method_type,
+            api_enums::PaymentMethodType::ApplePay
+                | api_enums::PaymentMethodType::GooglePay
+                | api_enums::PaymentMethodType::Paypal
+                | api_enums::PaymentMethodType::AliPay
+                | api_enums::PaymentMethodType::AliPayHk
+                | api_enums::PaymentMethodType::Dana
+                | api_enums::PaymentMethodType::MbWay
+                | api_enums::PaymentMethodType::MobilePay
+                | api_enums::PaymentMethodType::SamsungPay
+                | api_enums::PaymentMethodType::Twint
+                | api_enums::PaymentMethodType::Vipps
+                | api_enums::PaymentMethodType::TouchNGo
+                | api_enums::PaymentMethodType::Swish
+                | api_enums::PaymentMethodType::WeChatPay
+                | api_enums::PaymentMethodType::GoPay
+                | api_enums::PaymentMethodType::Gcash
+                | api_enums::PaymentMethodType::Momo
+                | api_enums::PaymentMethodType::KakaoPay
+        ),
+        api_enums::PaymentMethod::BankRedirect => matches!(
+            payment_method_type,
+            api_enums::PaymentMethodType::Giropay
+                | api_enums::PaymentMethodType::Ideal
+                | api_enums::PaymentMethodType::Sofort
+                | api_enums::PaymentMethodType::Eps
+                | api_enums::PaymentMethodType::BancontactCard
+                | api_enums::PaymentMethodType::Blik
+                | api_enums::PaymentMethodType::OnlineBankingThailand
+                | api_enums::PaymentMethodType::OnlineBankingCzechRepublic
+                | api_enums::PaymentMethodType::OnlineBankingFinland
+                | api_enums::PaymentMethodType::OnlineBankingFpx
+                | api_enums::PaymentMethodType::OnlineBankingPoland
+                | api_enums::PaymentMethodType::OnlineBankingSlovakia
+                | api_enums::PaymentMethodType::Przelewy24
+                | api_enums::PaymentMethodType::Trustly
+                | api_enums::PaymentMethodType::Bizum
+                | api_enums::PaymentMethodType::Interac
+        ),
+        api_enums::PaymentMethod::BankTransfer => matches!(
+            payment_method_type,
+            api_enums::PaymentMethodType::Ach
+                | api_enums::PaymentMethodType::Sepa
+                | api_enums::PaymentMethodType::Bacs
+                | api_enums::PaymentMethodType::Multibanco
+                | api_enums::PaymentMethodType::Pix
+                | api_enums::PaymentMethodType::Pse
+        ),
+        api_enums::PaymentMethod::BankDebit => matches!(
+            payment_method_type,
+            api_enums::PaymentMethodType::Ach
+                | api_enums::PaymentMethodType::Sepa
+                | api_enums::PaymentMethodType::Bacs
+                | api_enums::PaymentMethodType::Becs
+        ),
+        api_enums::PaymentMethod::Crypto => matches!(
+            payment_method_type,
+            api_enums::PaymentMethodType::CryptoCurrency
+        ),
+        api_enums::PaymentMethod::Reward => matches!(
+            payment_method_type,
+            api_enums::PaymentMethodType::Evoucher | api_enums::PaymentMethodType::ClassicReward
+        ),
+        api_enums::PaymentMethod::Upi => matches!(
+            payment_method_type,
+            api_enums::PaymentMethodType::UpiCollect
+        ),
+        api_enums::PaymentMethod::Voucher => matches!(
+            payment_method_type,
+            api_enums::PaymentMethodType::Boleto
+                | api_enums::PaymentMethodType::Efecty
+                | api_enums::PaymentMethodType::PagoEfectivo
+                | api_enums::PaymentMethodType::RedCompra
+                | api_enums::PaymentMethodType::RedPagos
+        ),
+        api_enums::PaymentMethod::GiftCard => false,
+    }
+}
+
 pub fn check_force_psync_precondition(
     status: &storage_enums::AttemptStatus,
     connector_transaction_id: &Option<String>,
diff --git a/crates/router/src/types/transformers.rs b/crates/router/src/types/transformers.rs
index b4d0b1298b9..5d9d9a73d91 100644
--- a/crates/router/src/types/transformers.rs
+++ b/crates/router/src/types/transformers.rs
@@ -230,6 +230,32 @@ impl ForeignFrom<api_enums::PaymentMethodType> for api_enums::PaymentMethod {
     }
 }
 
+impl ForeignTryFrom<api_models::payments::PaymentMethodData> for api_enums::PaymentMethod {
+    type Error = errors::ApiErrorResponse;
+    fn foreign_try_from(
+        payment_method_data: api_models::payments::PaymentMethodData,
+    ) -> Result<Self, Self::Error> {
+        match payment_method_data {
+            api_models::payments::PaymentMethodData::Card(..) => Ok(Self::Card),
+            api_models::payments::PaymentMethodData::Wallet(..) => Ok(Self::Wallet),
+            api_models::payments::PaymentMethodData::PayLater(..) => Ok(Self::PayLater),
+            api_models::payments::PaymentMethodData::BankRedirect(..) => Ok(Self::BankRedirect),
+            api_models::payments::PaymentMethodData::BankDebit(..) => Ok(Self::BankDebit),
+            api_models::payments::PaymentMethodData::BankTransfer(..) => Ok(Self::BankTransfer),
+            api_models::payments::PaymentMethodData::Crypto(..) => Ok(Self::Crypto),
+            api_models::payments::PaymentMethodData::Reward(..) => Ok(Self::Reward),
+            api_models::payments::PaymentMethodData::Upi(..) => Ok(Self::Upi),
+            api_models::payments::PaymentMethodData::Voucher(..) => Ok(Self::Voucher),
+            api_models::payments::PaymentMethodData::GiftCard(..) => Ok(Self::GiftCard),
+            api_models::payments::PaymentMethodData::MandatePayment => {
+                Err(errors::ApiErrorResponse::InvalidRequestData {
+                    message: ("Mandate payments cannot have payment_method_data field".to_string()),
+                })
+            }
+        }
+    }
+}
+
 impl ForeignTryFrom<storage_enums::RefundStatus> for storage_enums::EventType {
     type Error = errors::ValidationError;
 
diff --git a/openapi/openapi_spec.json b/openapi/openapi_spec.json
index 235cf476afa..8b703fa7334 100644
--- a/openapi/openapi_spec.json
+++ b/openapi/openapi_spec.json
@@ -6978,7 +6978,8 @@
           "bank_debit",
           "reward",
           "upi",
-          "voucher"
+          "voucher",
+          "gift_card"
         ]
       },
       "PaymentMethodCreate": {

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

- [x] Bugfix

## Description
<!-- Describe your changes in detail -->
This is a follow-up change for https://github.com/juspay/hyperswitch/pull/1236. This adds a `foreign_from` implementation for `payment_method_data` for the payment methods correspondence check.

## 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).
-->
This PR closes https://github.com/juspay/hyperswitch/issues/1800.

## 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)?
-->
Manually using Postman.

## 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