Bug: Gift Card Balance check API for split payments



We need to add an API to check balance for gift card.

This API will be called by the SDK and based on the gift card balance and transaction amount, we will collect either only gift card details or gift card details + another payment method
diff --git a/crates/api_models/src/events/payment.rs b/crates/api_models/src/events/payment.rs
index 2571ca53816..8a0af806334 100644
--- a/crates/api_models/src/events/payment.rs
+++ b/crates/api_models/src/events/payment.rs
@@ -181,6 +181,13 @@ impl ApiEventMetric for PaymentsCreateIntentRequest {
     }
 }
 
+#[cfg(feature = "v2")]
+impl ApiEventMetric for payments::GiftCardBalanceCheckResponse {
+    fn get_api_event_type(&self) -> Option<ApiEventsType> {
+        None
+    }
+}
+
 #[cfg(feature = "v2")]
 impl ApiEventMetric for PaymentsRequest {
     fn get_api_event_type(&self) -> Option<ApiEventsType> {
diff --git a/crates/api_models/src/payments.rs b/crates/api_models/src/payments.rs
index 52f75bbe8be..62390067d3b 100644
--- a/crates/api_models/src/payments.rs
+++ b/crates/api_models/src/payments.rs
@@ -664,6 +664,23 @@ pub struct PaymentsIntentResponse {
     pub payment_type: api_enums::PaymentType,
 }
 
+#[cfg(feature = "v2")]
+#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize, ToSchema)]
+pub struct GiftCardBalanceCheckResponse {
+    /// Global Payment Id for the payment
+    #[schema(value_type = String)]
+    pub payment_id: id_type::GlobalPaymentId,
+    /// The balance of the gift card
+    pub balance: MinorUnit,
+    /// The currency of the Gift Card
+    #[schema(value_type = Currency)]
+    pub currency: common_enums::Currency,
+    /// Whether the gift card balance is enough for the transaction (Used for split payments case)
+    pub needs_additional_pm_data: bool,
+    /// Transaction amount left after subtracting gift card balance (Used for split payments)
+    pub remaining_amount: MinorUnit,
+}
+
 #[cfg(feature = "v2")]
 #[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize, ToSchema)]
 pub struct AmountDetails {
@@ -5768,6 +5785,17 @@ pub struct PaymentsConfirmIntentRequest {
     pub return_raw_connector_response: Option<bool>,
 }
 
+// Serialize is implemented because, this will be serialized in the api events.
+// Usually request types should not have serialize implemented.
+//
+/// Request for Gift Card balance check
+#[cfg(feature = "v2")]
+#[derive(Debug, serde::Deserialize, serde::Serialize, ToSchema)]
+#[serde(deny_unknown_fields)]
+pub struct PaymentsGiftCardBalanceCheckRequest {
+    pub gift_card_data: GiftCardData,
+}
+
 #[cfg(feature = "v2")]
 #[derive(Debug, serde::Deserialize, serde::Serialize, ToSchema)]
 #[serde(deny_unknown_fields)]
diff --git a/crates/common_utils/src/id_type/global_id/payment.rs b/crates/common_utils/src/id_type/global_id/payment.rs
index 94ffbed57af..b6d62689ec5 100644
--- a/crates/common_utils/src/id_type/global_id/payment.rs
+++ b/crates/common_utils/src/id_type/global_id/payment.rs
@@ -36,6 +36,11 @@ impl GlobalPaymentId {
     ) -> String {
         format!("{runner}_{task}_{}", self.get_string_repr())
     }
+
+    /// Generate a key for gift card connector
+    pub fn get_gift_card_connector_key(&self) -> String {
+        format!("gift_mca_{}", self.get_string_repr())
+    }
 }
 
 // TODO: refactor the macro to include this id use case as well
diff --git a/crates/hyperswitch_connectors/src/connectors/adyen.rs b/crates/hyperswitch_connectors/src/connectors/adyen.rs
index 47f2eefeafc..a07986ba18e 100644
--- a/crates/hyperswitch_connectors/src/connectors/adyen.rs
+++ b/crates/hyperswitch_connectors/src/connectors/adyen.rs
@@ -25,24 +25,25 @@ use hyperswitch_domain_models::{
             Void,
         },
         refunds::{Execute, RSync},
-        Accept, Defend, Evidence, Retrieve, Upload,
+        Accept, Defend, Evidence, GiftCardBalanceCheck, Retrieve, Upload,
     },
     router_request_types::{
         AcceptDisputeRequestData, AccessTokenRequestData, DefendDisputeRequestData,
-        PaymentMethodTokenizationData, PaymentsAuthorizeData, PaymentsCancelData,
-        PaymentsCaptureData, PaymentsPreProcessingData, PaymentsSessionData, PaymentsSyncData,
-        RefundsData, RetrieveFileRequestData, SetupMandateRequestData, SubmitEvidenceRequestData,
-        SyncRequestType, UploadFileRequestData,
+        GiftCardBalanceCheckRequestData, PaymentMethodTokenizationData, PaymentsAuthorizeData,
+        PaymentsCancelData, PaymentsCaptureData, PaymentsPreProcessingData, PaymentsSessionData,
+        PaymentsSyncData, RefundsData, RetrieveFileRequestData, SetupMandateRequestData,
+        SubmitEvidenceRequestData, SyncRequestType, UploadFileRequestData,
     },
     router_response_types::{
-        AcceptDisputeResponse, ConnectorInfo, DefendDisputeResponse, PaymentMethodDetails,
-        PaymentsResponseData, RefundsResponseData, RetrieveFileResponse, SubmitEvidenceResponse,
-        SupportedPaymentMethods, SupportedPaymentMethodsExt, UploadFileResponse,
+        AcceptDisputeResponse, ConnectorInfo, DefendDisputeResponse,
+        GiftCardBalanceCheckResponseData, PaymentMethodDetails, PaymentsResponseData,
+        RefundsResponseData, RetrieveFileResponse, SubmitEvidenceResponse, SupportedPaymentMethods,
+        SupportedPaymentMethodsExt, UploadFileResponse,
     },
     types::{
         PaymentsAuthorizeRouterData, PaymentsCancelRouterData, PaymentsCaptureRouterData,
-        PaymentsPreProcessingRouterData, PaymentsSyncRouterData, RefundsRouterData,
-        SetupMandateRouterData,
+        PaymentsGiftCardBalanceCheckRouterData, PaymentsPreProcessingRouterData,
+        PaymentsSyncRouterData, RefundsRouterData, SetupMandateRouterData,
     },
 };
 #[cfg(feature = "payouts")]
@@ -69,8 +70,8 @@ use hyperswitch_interfaces::{
     events::connector_api_logs::ConnectorEvent,
     types::{
         AcceptDisputeType, DefendDisputeType, PaymentsAuthorizeType, PaymentsCaptureType,
-        PaymentsPreProcessingType, PaymentsSyncType, PaymentsVoidType, RefundExecuteType, Response,
-        SetupMandateType, SubmitEvidenceType,
+        PaymentsGiftCardBalanceCheckType, PaymentsPreProcessingType, PaymentsSyncType,
+        PaymentsVoidType, RefundExecuteType, Response, SetupMandateType, SubmitEvidenceType,
     },
     webhooks::{IncomingWebhook, IncomingWebhookFlowError, IncomingWebhookRequestDetails},
 };
@@ -416,6 +417,7 @@ impl api::PaymentCapture for Adyen {}
 impl api::MandateSetup for Adyen {}
 impl api::ConnectorAccessToken for Adyen {}
 impl api::PaymentToken for Adyen {}
+impl api::PaymentsGiftCardBalanceCheck for Adyen {}
 
 impl ConnectorIntegration<PaymentMethodToken, PaymentMethodTokenizationData, PaymentsResponseData>
     for Adyen
@@ -1164,6 +1166,114 @@ impl ConnectorIntegration<Void, PaymentsCancelData, PaymentsResponseData> for Ad
     }
 }
 
+impl
+    ConnectorIntegration<
+        GiftCardBalanceCheck,
+        GiftCardBalanceCheckRequestData,
+        GiftCardBalanceCheckResponseData,
+    > for Adyen
+{
+    fn get_headers(
+        &self,
+        req: &PaymentsGiftCardBalanceCheckRouterData,
+        _connectors: &Connectors,
+    ) -> CustomResult<Vec<(String, Maskable<String>)>, errors::ConnectorError> {
+        let mut header = vec![(
+            headers::CONTENT_TYPE.to_string(),
+            PaymentsGiftCardBalanceCheckType::get_content_type(self)
+                .to_string()
+                .into(),
+        )];
+        let mut api_key = self.get_auth_header(&req.connector_auth_type)?;
+        header.append(&mut api_key);
+        Ok(header)
+    }
+
+    fn get_url(
+        &self,
+        req: &PaymentsGiftCardBalanceCheckRouterData,
+        connectors: &Connectors,
+    ) -> CustomResult<String, errors::ConnectorError> {
+        let endpoint = build_env_specific_endpoint(
+            self.base_url(connectors),
+            req.test_mode,
+            &req.connector_meta_data,
+        )?;
+        Ok(format!(
+            "{endpoint}{ADYEN_API_VERSION}/paymentMethods/balance",
+        ))
+    }
+
+    fn get_request_body(
+        &self,
+        req: &PaymentsGiftCardBalanceCheckRouterData,
+        _connectors: &Connectors,
+    ) -> CustomResult<RequestContent, errors::ConnectorError> {
+        let connector_req = adyen::AdyenBalanceRequest::try_from(req)?;
+
+        Ok(RequestContent::Json(Box::new(connector_req)))
+    }
+
+    fn build_request(
+        &self,
+        req: &PaymentsGiftCardBalanceCheckRouterData,
+        connectors: &Connectors,
+    ) -> CustomResult<Option<Request>, errors::ConnectorError> {
+        Ok(Some(
+            RequestBuilder::new()
+                .method(Method::Post)
+                .url(&PaymentsGiftCardBalanceCheckType::get_url(
+                    self, req, connectors,
+                )?)
+                .attach_default_headers()
+                .headers(PaymentsGiftCardBalanceCheckType::get_headers(
+                    self, req, connectors,
+                )?)
+                .set_body(PaymentsGiftCardBalanceCheckType::get_request_body(
+                    self, req, connectors,
+                )?)
+                .build(),
+        ))
+    }
+
+    fn handle_response(
+        &self,
+        data: &PaymentsGiftCardBalanceCheckRouterData,
+        event_builder: Option<&mut ConnectorEvent>,
+        res: Response,
+    ) -> CustomResult<PaymentsGiftCardBalanceCheckRouterData, errors::ConnectorError> {
+        let response: adyen::AdyenBalanceResponse = res
+            .response
+            .parse_struct("AdyenBalanceResponse")
+            .change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
+        event_builder.map(|i| i.set_response_body(&response));
+        router_env::logger::info!(connector_response=?response);
+
+        RouterData::try_from(ResponseRouterData {
+            response,
+            data: data.clone(),
+            http_code: res.status_code,
+        })
+        .change_context(errors::ConnectorError::ResponseHandlingFailed)
+    }
+
+    fn get_error_response(
+        &self,
+        res: Response,
+        event_builder: Option<&mut ConnectorEvent>,
+    ) -> CustomResult<ErrorResponse, errors::ConnectorError> {
+        self.build_error_response(res, event_builder)
+    }
+
+    fn get_5xx_error_response(
+        &self,
+        res: Response,
+        event_builder: Option<&mut ConnectorEvent>,
+    ) -> CustomResult<ErrorResponse, errors::ConnectorError> {
+        self.build_error_response(res, event_builder)
+    }
+}
+
 impl api::Payouts for Adyen {}
 #[cfg(feature = "payouts")]
 impl api::PayoutCancel for Adyen {}
diff --git a/crates/hyperswitch_connectors/src/connectors/adyen/transformers.rs b/crates/hyperswitch_connectors/src/connectors/adyen/transformers.rs
index 4858e70b6fc..6b679f40b1f 100644
--- a/crates/hyperswitch_connectors/src/connectors/adyen/transformers.rs
+++ b/crates/hyperswitch_connectors/src/connectors/adyen/transformers.rs
@@ -27,14 +27,19 @@ use hyperswitch_domain_models::{
     router_data::{
         ConnectorAuthType, ErrorResponse, PaymentMethodBalance, PaymentMethodToken, RouterData,
     },
-    router_request_types::{PaymentsPreProcessingData, ResponseId, SubmitEvidenceRequestData},
+    router_flow_types::GiftCardBalanceCheck,
+    router_request_types::{
+        GiftCardBalanceCheckRequestData, PaymentsPreProcessingData, ResponseId,
+        SubmitEvidenceRequestData,
+    },
     router_response_types::{
-        AcceptDisputeResponse, DefendDisputeResponse, MandateReference, PaymentsResponseData,
-        RedirectForm, RefundsResponseData, SubmitEvidenceResponse,
+        AcceptDisputeResponse, DefendDisputeResponse, GiftCardBalanceCheckResponseData,
+        MandateReference, PaymentsResponseData, RedirectForm, RefundsResponseData,
+        SubmitEvidenceResponse,
     },
     types::{
         PaymentsAuthorizeRouterData, PaymentsCancelRouterData, PaymentsCaptureRouterData,
-        PaymentsPreProcessingRouterData, RefundsRouterData,
+        PaymentsGiftCardBalanceCheckRouterData, PaymentsPreProcessingRouterData, RefundsRouterData,
     },
 };
 #[cfg(feature = "payouts")]
@@ -1805,6 +1810,41 @@ impl TryFrom<&PaymentsPreProcessingRouterData> for AdyenBalanceRequest<'_> {
     }
 }
 
+impl TryFrom<&PaymentsGiftCardBalanceCheckRouterData> for AdyenBalanceRequest<'_> {
+    type Error = Error;
+    fn try_from(item: &PaymentsGiftCardBalanceCheckRouterData) -> Result<Self, Self::Error> {
+        let payment_method = match &item.request.payment_method_data {
+            PaymentMethodData::GiftCard(gift_card_data) => match gift_card_data.as_ref() {
+                GiftCardData::Givex(gift_card_data) => {
+                    let balance_pm = BalancePmData {
+                        number: gift_card_data.number.clone(),
+                        cvc: gift_card_data.cvc.clone(),
+                    };
+                    Ok(AdyenPaymentMethod::PaymentMethodBalance(Box::new(
+                        balance_pm,
+                    )))
+                }
+                GiftCardData::PaySafeCard {} | GiftCardData::BhnCardNetwork(_) => {
+                    Err(errors::ConnectorError::FlowNotSupported {
+                        flow: "Balance".to_string(),
+                        connector: "adyen".to_string(),
+                    })
+                }
+            },
+            _ => Err(errors::ConnectorError::FlowNotSupported {
+                flow: "Balance".to_string(),
+                connector: "adyen".to_string(),
+            }),
+        }?;
+
+        let auth_type = AdyenAuthType::try_from(&item.connector_auth_type)?;
+        Ok(Self {
+            payment_method,
+            merchant_account: auth_type.merchant_account,
+        })
+    }
+}
+
 impl From<&PaymentsAuthorizeRouterData> for AdyenShopperInteraction {
     fn from(item: &PaymentsAuthorizeRouterData) -> Self {
         match item.request.off_session {
@@ -3929,6 +3969,40 @@ impl<F>
     }
 }
 
+impl
+    TryFrom<
+        ResponseRouterData<
+            GiftCardBalanceCheck,
+            AdyenBalanceResponse,
+            GiftCardBalanceCheckRequestData,
+            GiftCardBalanceCheckResponseData,
+        >,
+    >
+    for RouterData<
+        GiftCardBalanceCheck,
+        GiftCardBalanceCheckRequestData,
+        GiftCardBalanceCheckResponseData,
+    >
+{
+    type Error = Error;
+    fn try_from(
+        item: ResponseRouterData<
+            GiftCardBalanceCheck,
+            AdyenBalanceResponse,
+            GiftCardBalanceCheckRequestData,
+            GiftCardBalanceCheckResponseData,
+        >,
+    ) -> Result<Self, Self::Error> {
+        Ok(Self {
+            response: Ok(GiftCardBalanceCheckResponseData {
+                balance: item.response.balance.value,
+                currency: item.response.balance.currency,
+            }),
+            ..item.data
+        })
+    }
+}
+
 pub fn get_adyen_response(
     response: AdyenResponse,
     is_capture_manual: bool,
diff --git a/crates/hyperswitch_connectors/src/default_implementations.rs b/crates/hyperswitch_connectors/src/default_implementations.rs
index 1e404df7f97..8b742d71026 100644
--- a/crates/hyperswitch_connectors/src/default_implementations.rs
+++ b/crates/hyperswitch_connectors/src/default_implementations.rs
@@ -35,9 +35,9 @@ use hyperswitch_domain_models::{
         mandate_revoke::MandateRevoke,
         payments::{
             Approve, AuthorizeSessionToken, CalculateTax, CompleteAuthorize,
-            CreateConnectorCustomer, CreateOrder, IncrementalAuthorization, PostCaptureVoid,
-            PostProcessing, PostSessionTokens, PreProcessing, Reject, SdkSessionUpdate,
-            UpdateMetadata,
+            CreateConnectorCustomer, CreateOrder, GiftCardBalanceCheck, IncrementalAuthorization,
+            PostCaptureVoid, PostProcessing, PostSessionTokens, PreProcessing, Reject,
+            SdkSessionUpdate, UpdateMetadata,
         },
         subscriptions::GetSubscriptionPlans,
         webhooks::VerifyWebhookSource,
@@ -56,8 +56,8 @@ use hyperswitch_domain_models::{
         AcceptDisputeRequestData, AccessTokenAuthenticationRequestData, AuthorizeSessionTokenData,
         CompleteAuthorizeData, ConnectorCustomerData, CreateOrderRequestData,
         DefendDisputeRequestData, DisputeSyncData, ExternalVaultProxyPaymentsData,
-        FetchDisputesRequestData, MandateRevokeRequestData, PaymentsApproveData,
-        PaymentsAuthenticateData, PaymentsCancelPostCaptureData,
+        FetchDisputesRequestData, GiftCardBalanceCheckRequestData, MandateRevokeRequestData,
+        PaymentsApproveData, PaymentsAuthenticateData, PaymentsCancelPostCaptureData,
         PaymentsIncrementalAuthorizationData, PaymentsPostAuthenticateData,
         PaymentsPostProcessingData, PaymentsPostSessionTokensData, PaymentsPreAuthenticateData,
         PaymentsPreProcessingData, PaymentsRejectData, PaymentsTaxCalculationData,
@@ -68,9 +68,10 @@ use hyperswitch_domain_models::{
     router_response_types::{
         subscriptions::GetSubscriptionPlansResponse, AcceptDisputeResponse,
         AuthenticationResponseData, DefendDisputeResponse, DisputeSyncResponse,
-        FetchDisputesResponse, MandateRevokeResponseData, PaymentsResponseData,
-        RetrieveFileResponse, SubmitEvidenceResponse, TaxCalculationResponseData,
-        UploadFileResponse, VaultResponseData, VerifyWebhookSourceResponseData,
+        FetchDisputesResponse, GiftCardBalanceCheckResponseData, MandateRevokeResponseData,
+        PaymentsResponseData, RetrieveFileResponse, SubmitEvidenceResponse,
+        TaxCalculationResponseData, UploadFileResponse, VaultResponseData,
+        VerifyWebhookSourceResponseData,
     },
 };
 #[cfg(feature = "frm")]
@@ -125,8 +126,8 @@ use hyperswitch_interfaces::{
             PaymentAuthorizeSessionToken, PaymentIncrementalAuthorization, PaymentPostCaptureVoid,
             PaymentPostSessionTokens, PaymentReject, PaymentSessionUpdate, PaymentUpdateMetadata,
             PaymentsAuthenticate, PaymentsCompleteAuthorize, PaymentsCreateOrder,
-            PaymentsPostAuthenticate, PaymentsPostProcessing, PaymentsPreAuthenticate,
-            PaymentsPreProcessing, TaxCalculation,
+            PaymentsGiftCardBalanceCheck, PaymentsPostAuthenticate, PaymentsPostProcessing,
+            PaymentsPreAuthenticate, PaymentsPreProcessing, TaxCalculation,
         },
         revenue_recovery::RevenueRecovery,
         subscriptions::{GetSubscriptionPlansFlow, Subscriptions},
@@ -7797,6 +7798,149 @@ default_imp_for_external_vault_insert!(
     connectors::Zsl
 );
 
+macro_rules! default_imp_for_gift_card_balance_check {
+    ($($path:ident::$connector:ident),*) => {
+        $(
+            impl PaymentsGiftCardBalanceCheck for $path::$connector {}
+            impl
+            ConnectorIntegration<
+            GiftCardBalanceCheck,
+            GiftCardBalanceCheckRequestData,
+            GiftCardBalanceCheckResponseData,
+        > for $path::$connector
+        {}
+    )*
+    };
+}
+default_imp_for_gift_card_balance_check!(
+    connectors::Aci,
+    connectors::Adyenplatform,
+    connectors::Affirm,
+    connectors::Airwallex,
+    connectors::Amazonpay,
+    connectors::Archipel,
+    connectors::Authipay,
+    connectors::Authorizedotnet,
+    connectors::Bambora,
+    connectors::Bamboraapac,
+    connectors::Bankofamerica,
+    connectors::Barclaycard,
+    connectors::Billwerk,
+    connectors::Bitpay,
+    connectors::Blackhawknetwork,
+    connectors::Bluecode,
+    connectors::Bluesnap,
+    connectors::Boku,
+    connectors::Braintree,
+    connectors::Breadpay,
+    connectors::Cashtocode,
+    connectors::Celero,
+    connectors::Chargebee,
+    connectors::Checkbook,
+    connectors::Checkout,
+    connectors::Coinbase,
+    connectors::Coingate,
+    connectors::Cryptopay,
+    connectors::CtpMastercard,
+    connectors::Custombilling,
+    connectors::Cybersource,
+    connectors::Datatrans,
+    connectors::Deutschebank,
+    connectors::Digitalvirgo,
+    connectors::Dlocal,
+    connectors::Dwolla,
+    connectors::Ebanx,
+    connectors::Elavon,
+    connectors::Facilitapay,
+    connectors::Fiserv,
+    connectors::Fiservemea,
+    connectors::Fiuu,
+    connectors::Flexiti,
+    connectors::Forte,
+    connectors::Getnet,
+    connectors::Globalpay,
+    connectors::Globepay,
+    connectors::Gocardless,
+    connectors::Gpayments,
+    connectors::Helcim,
+    connectors::Hipay,
+    connectors::HyperswitchVault,
+    connectors::Hyperwallet,
+    connectors::Iatapay,
+    connectors::Inespay,
+    connectors::Itaubank,
+    connectors::Jpmorgan,
+    connectors::Juspaythreedsserver,
+    connectors::Katapult,
+    connectors::Klarna,
+    connectors::Mifinity,
+    connectors::Mollie,
+    connectors::Moneris,
+    connectors::Mpgs,
+    connectors::Multisafepay,
+    connectors::Netcetera,
+    connectors::Nexinets,
+    connectors::Nexixpay,
+    connectors::Nmi,
+    connectors::Nomupay,
+    connectors::Noon,
+    connectors::Nordea,
+    connectors::Novalnet,
+    connectors::Nuvei,
+    connectors::Opayo,
+    connectors::Opennode,
+    connectors::Paybox,
+    connectors::Payeezy,
+    connectors::Payload,
+    connectors::Payme,
+    connectors::Payone,
+    connectors::Paypal,
+    connectors::Paystack,
+    connectors::Paysafe,
+    connectors::Paytm,
+    connectors::Payu,
+    connectors::Peachpayments,
+    connectors::Phonepe,
+    connectors::Placetopay,
+    connectors::Plaid,
+    connectors::Powertranz,
+    connectors::Prophetpay,
+    connectors::Rapyd,
+    connectors::Razorpay,
+    connectors::Recurly,
+    connectors::Redsys,
+    connectors::Riskified,
+    connectors::Santander,
+    connectors::Shift4,
+    connectors::Sift,
+    connectors::Signifyd,
+    connectors::Silverflow,
+    connectors::Square,
+    connectors::Stax,
+    connectors::Stripe,
+    connectors::Stripebilling,
+    connectors::Taxjar,
+    connectors::Threedsecureio,
+    connectors::Thunes,
+    connectors::Tokenio,
+    connectors::Trustpay,
+    connectors::Trustpayments,
+    connectors::Tsys,
+    connectors::UnifiedAuthenticationService,
+    connectors::Vgs,
+    connectors::Volt,
+    connectors::Wellsfargo,
+    connectors::Wellsfargopayout,
+    connectors::Wise,
+    connectors::Worldline,
+    connectors::Worldpay,
+    connectors::Worldpayvantiv,
+    connectors::Worldpayxml,
+    connectors::Xendit,
+    connectors::Zen,
+    connectors::Zsl
+);
+
 macro_rules! default_imp_for_external_vault_retrieve {
     ($($path:ident::$connector:ident),*) => {
         $(
@@ -8622,6 +8766,18 @@ impl<const T: u8> ConnectorIntegration<Dsync, DisputeSyncData, DisputeSyncRespon
 {
 }
 
+#[cfg(feature = "dummy_connector")]
+impl<const T: u8> PaymentsGiftCardBalanceCheck for connectors::DummyConnector<T> {}
+#[cfg(feature = "dummy_connector")]
+impl<const T: u8>
+    ConnectorIntegration<
+        GiftCardBalanceCheck,
+        GiftCardBalanceCheckRequestData,
+        GiftCardBalanceCheckResponseData,
+    > for connectors::DummyConnector<T>
+{
+}
+
 #[cfg(feature = "dummy_connector")]
 impl<const T: u8> PaymentsPreProcessing for connectors::DummyConnector<T> {}
 #[cfg(feature = "dummy_connector")]
diff --git a/crates/hyperswitch_connectors/src/default_implementations_v2.rs b/crates/hyperswitch_connectors/src/default_implementations_v2.rs
index 836ad796a05..01c42dfe63f 100644
--- a/crates/hyperswitch_connectors/src/default_implementations_v2.rs
+++ b/crates/hyperswitch_connectors/src/default_implementations_v2.rs
@@ -3,8 +3,8 @@ use hyperswitch_domain_models::{
     router_data_v2::{
         flow_common_types::{
             BillingConnectorInvoiceSyncFlowData, BillingConnectorPaymentsSyncFlowData,
-            DisputesFlowData, InvoiceRecordBackData, MandateRevokeFlowData, PaymentFlowData,
-            RefundFlowData, WebhookSourceVerifyData,
+            DisputesFlowData, GiftCardBalanceCheckFlowData, InvoiceRecordBackData,
+            MandateRevokeFlowData, PaymentFlowData, RefundFlowData, WebhookSourceVerifyData,
         },
         AccessTokenFlowData, AuthenticationTokenFlowData, ExternalAuthenticationFlowData,
         FilesFlowData, VaultConnectorFlowData,
@@ -18,9 +18,10 @@ use hyperswitch_domain_models::{
         mandate_revoke::MandateRevoke,
         payments::{
             Approve, Authorize, AuthorizeSessionToken, CalculateTax, Capture, CompleteAuthorize,
-            CreateConnectorCustomer, CreateOrder, ExternalVaultProxy, IncrementalAuthorization,
-            PSync, PaymentMethodToken, PostCaptureVoid, PostProcessing, PostSessionTokens,
-            PreProcessing, Reject, SdkSessionUpdate, Session, SetupMandate, UpdateMetadata, Void,
+            CreateConnectorCustomer, CreateOrder, ExternalVaultProxy, GiftCardBalanceCheck,
+            IncrementalAuthorization, PSync, PaymentMethodToken, PostCaptureVoid, PostProcessing,
+            PostSessionTokens, PreProcessing, Reject, SdkSessionUpdate, Session, SetupMandate,
+            UpdateMetadata, Void,
         },
         refunds::{Execute, RSync},
         revenue_recovery::{
@@ -39,10 +40,10 @@ use hyperswitch_domain_models::{
         AcceptDisputeRequestData, AccessTokenAuthenticationRequestData, AccessTokenRequestData,
         AuthorizeSessionTokenData, CompleteAuthorizeData, ConnectorCustomerData,
         CreateOrderRequestData, DefendDisputeRequestData, DisputeSyncData,
-        ExternalVaultProxyPaymentsData, FetchDisputesRequestData, MandateRevokeRequestData,
-        PaymentMethodTokenizationData, PaymentsApproveData, PaymentsAuthorizeData,
-        PaymentsCancelData, PaymentsCancelPostCaptureData, PaymentsCaptureData,
-        PaymentsIncrementalAuthorizationData, PaymentsPostProcessingData,
+        ExternalVaultProxyPaymentsData, FetchDisputesRequestData, GiftCardBalanceCheckRequestData,
+        MandateRevokeRequestData, PaymentMethodTokenizationData, PaymentsApproveData,
+        PaymentsAuthorizeData, PaymentsCancelData, PaymentsCancelPostCaptureData,
+        PaymentsCaptureData, PaymentsIncrementalAuthorizationData, PaymentsPostProcessingData,
         PaymentsPostSessionTokensData, PaymentsPreProcessingData, PaymentsRejectData,
         PaymentsSessionData, PaymentsSyncData, PaymentsTaxCalculationData,
         PaymentsUpdateMetadataData, RefundsData, RetrieveFileRequestData,
@@ -55,9 +56,9 @@ use hyperswitch_domain_models::{
             InvoiceRecordBackResponse,
         },
         AcceptDisputeResponse, AuthenticationResponseData, DefendDisputeResponse,
-        DisputeSyncResponse, FetchDisputesResponse, MandateRevokeResponseData,
-        PaymentsResponseData, RefundsResponseData, RetrieveFileResponse, SubmitEvidenceResponse,
-        TaxCalculationResponseData, UploadFileResponse, VaultResponseData,
+        DisputeSyncResponse, FetchDisputesResponse, GiftCardBalanceCheckResponseData,
+        MandateRevokeResponseData, PaymentsResponseData, RefundsResponseData, RetrieveFileResponse,
+        SubmitEvidenceResponse, TaxCalculationResponseData, UploadFileResponse, VaultResponseData,
         VerifyWebhookSourceResponseData,
     },
 };
@@ -108,8 +109,8 @@ use hyperswitch_interfaces::{
             PaymentCreateOrderV2, PaymentIncrementalAuthorizationV2, PaymentPostCaptureVoidV2,
             PaymentPostSessionTokensV2, PaymentRejectV2, PaymentSessionUpdateV2, PaymentSessionV2,
             PaymentSyncV2, PaymentTokenV2, PaymentUpdateMetadataV2, PaymentV2, PaymentVoidV2,
-            PaymentsCompleteAuthorizeV2, PaymentsPostProcessingV2, PaymentsPreProcessingV2,
-            TaxCalculationV2,
+            PaymentsCompleteAuthorizeV2, PaymentsGiftCardBalanceCheckV2, PaymentsPostProcessingV2,
+            PaymentsPreProcessingV2, TaxCalculationV2,
         },
         refunds_v2::{RefundExecuteV2, RefundSyncV2, RefundV2},
         revenue_recovery_v2::{
@@ -147,6 +148,7 @@ macro_rules! default_imp_for_new_connector_integration_payment {
             impl PaymentTokenV2 for $path::$connector{}
             impl ConnectorCustomerV2 for $path::$connector{}
             impl PaymentsPreProcessingV2 for $path::$connector{}
+            impl PaymentsGiftCardBalanceCheckV2 for $path::$connector{}
             impl PaymentsPostProcessingV2 for $path::$connector{}
             impl TaxCalculationV2 for $path::$connector{}
             impl PaymentSessionUpdateV2 for $path::$connector{}
@@ -216,6 +218,12 @@ macro_rules! default_imp_for_new_connector_integration_payment {
                 PaymentsPreProcessingData,
                 PaymentsResponseData,
             > for $path::$connector{}
+            impl ConnectorIntegrationV2<
+            GiftCardBalanceCheck,
+            GiftCardBalanceCheckFlowData,
+            GiftCardBalanceCheckRequestData,
+            GiftCardBalanceCheckResponseData,
+        > for $path::$connector{}
             impl ConnectorIntegrationV2<
             PostProcessing,
             PaymentFlowData,
diff --git a/crates/hyperswitch_domain_models/src/router_data_v2/flow_common_types.rs b/crates/hyperswitch_domain_models/src/router_data_v2/flow_common_types.rs
index 7e72bfa023f..471d2227640 100644
--- a/crates/hyperswitch_domain_models/src/router_data_v2/flow_common_types.rs
+++ b/crates/hyperswitch_domain_models/src/router_data_v2/flow_common_types.rs
@@ -170,6 +170,9 @@ pub struct VaultConnectorFlowData {
     pub merchant_id: common_utils::id_type::MerchantId,
 }
 
+#[derive(Debug, Clone)]
+pub struct GiftCardBalanceCheckFlowData;
+
 #[derive(Debug, Clone)]
 pub struct ExternalVaultProxyFlowData {
     pub merchant_id: common_utils::id_type::MerchantId,
diff --git a/crates/hyperswitch_domain_models/src/router_flow_types/payments.rs b/crates/hyperswitch_domain_models/src/router_flow_types/payments.rs
index eece6330e33..2b0e8b42046 100644
--- a/crates/hyperswitch_domain_models/src/router_flow_types/payments.rs
+++ b/crates/hyperswitch_domain_models/src/router_flow_types/payments.rs
@@ -85,3 +85,6 @@ pub struct PaymentGetListAttempts;
 
 #[derive(Debug, Clone)]
 pub struct ExternalVaultProxy;
+
+#[derive(Debug, Clone)]
+pub struct GiftCardBalanceCheck;
diff --git a/crates/hyperswitch_domain_models/src/router_request_types.rs b/crates/hyperswitch_domain_models/src/router_request_types.rs
index b97675006ed..0a91a9207e0 100644
--- a/crates/hyperswitch_domain_models/src/router_request_types.rs
+++ b/crates/hyperswitch_domain_models/src/router_request_types.rs
@@ -555,6 +555,13 @@ pub struct PaymentsPreProcessingData {
     pub minor_amount: Option<MinorUnit>,
 }
 
+#[derive(Debug, Clone)]
+pub struct GiftCardBalanceCheckRequestData {
+    pub payment_method_data: PaymentMethodData,
+    pub currency: Option<storage_enums::Currency>,
+    pub minor_amount: Option<MinorUnit>,
+}
+
 impl TryFrom<PaymentsAuthorizeData> for PaymentsPreProcessingData {
     type Error = error_stack::Report<ApiErrorResponse>;
 
diff --git a/crates/hyperswitch_domain_models/src/router_response_types.rs b/crates/hyperswitch_domain_models/src/router_response_types.rs
index cc766a00ba8..7ee0574178c 100644
--- a/crates/hyperswitch_domain_models/src/router_response_types.rs
+++ b/crates/hyperswitch_domain_models/src/router_response_types.rs
@@ -86,6 +86,12 @@ pub enum PaymentsResponseData {
     },
 }
 
+#[derive(Debug, Clone)]
+pub struct GiftCardBalanceCheckResponseData {
+    pub balance: MinorUnit,
+    pub currency: common_enums::Currency,
+}
+
 #[derive(Debug, Clone)]
 pub struct TaxCalculationResponseData {
     pub order_tax_amount: MinorUnit,
diff --git a/crates/hyperswitch_domain_models/src/types.rs b/crates/hyperswitch_domain_models/src/types.rs
index 683e2842837..15b1a3086a6 100644
--- a/crates/hyperswitch_domain_models/src/types.rs
+++ b/crates/hyperswitch_domain_models/src/types.rs
@@ -9,9 +9,9 @@ use crate::{
         Authenticate, AuthenticationConfirmation, Authorize, AuthorizeSessionToken,
         BillingConnectorInvoiceSync, BillingConnectorPaymentsSync, CalculateTax, Capture,
         CompleteAuthorize, CreateConnectorCustomer, CreateOrder, Execute, ExternalVaultProxy,
-        IncrementalAuthorization, PSync, PaymentMethodToken, PostAuthenticate, PostCaptureVoid,
-        PostSessionTokens, PreAuthenticate, PreProcessing, RSync, SdkSessionUpdate, Session,
-        SetupMandate, UpdateMetadata, VerifyWebhookSource, Void,
+        GiftCardBalanceCheck, IncrementalAuthorization, PSync, PaymentMethodToken,
+        PostAuthenticate, PostCaptureVoid, PostSessionTokens, PreAuthenticate, PreProcessing,
+        RSync, SdkSessionUpdate, Session, SetupMandate, UpdateMetadata, VerifyWebhookSource, Void,
     },
     router_request_types::{
         revenue_recovery::{
@@ -26,14 +26,14 @@ use crate::{
         },
         AccessTokenAuthenticationRequestData, AccessTokenRequestData, AuthorizeSessionTokenData,
         CompleteAuthorizeData, ConnectorCustomerData, CreateOrderRequestData,
-        ExternalVaultProxyPaymentsData, MandateRevokeRequestData, PaymentMethodTokenizationData,
-        PaymentsAuthenticateData, PaymentsAuthorizeData, PaymentsCancelData,
-        PaymentsCancelPostCaptureData, PaymentsCaptureData, PaymentsIncrementalAuthorizationData,
-        PaymentsPostAuthenticateData, PaymentsPostSessionTokensData, PaymentsPreAuthenticateData,
-        PaymentsPreProcessingData, PaymentsSessionData, PaymentsSyncData,
-        PaymentsTaxCalculationData, PaymentsUpdateMetadataData, RefundsData,
-        SdkPaymentsSessionUpdateData, SetupMandateRequestData, VaultRequestData,
-        VerifyWebhookSourceRequestData,
+        ExternalVaultProxyPaymentsData, GiftCardBalanceCheckRequestData, MandateRevokeRequestData,
+        PaymentMethodTokenizationData, PaymentsAuthenticateData, PaymentsAuthorizeData,
+        PaymentsCancelData, PaymentsCancelPostCaptureData, PaymentsCaptureData,
+        PaymentsIncrementalAuthorizationData, PaymentsPostAuthenticateData,
+        PaymentsPostSessionTokensData, PaymentsPreAuthenticateData, PaymentsPreProcessingData,
+        PaymentsSessionData, PaymentsSyncData, PaymentsTaxCalculationData,
+        PaymentsUpdateMetadataData, RefundsData, SdkPaymentsSessionUpdateData,
+        SetupMandateRequestData, VaultRequestData, VerifyWebhookSourceRequestData,
     },
     router_response_types::{
         revenue_recovery::{
@@ -41,8 +41,9 @@ use crate::{
             InvoiceRecordBackResponse,
         },
         subscriptions::GetSubscriptionPlansResponse,
-        MandateRevokeResponseData, PaymentsResponseData, RefundsResponseData,
-        TaxCalculationResponseData, VaultResponseData, VerifyWebhookSourceResponseData,
+        GiftCardBalanceCheckResponseData, MandateRevokeResponseData, PaymentsResponseData,
+        RefundsResponseData, TaxCalculationResponseData, VaultResponseData,
+        VerifyWebhookSourceResponseData,
     },
 };
 #[cfg(feature = "payouts")]
@@ -85,6 +86,11 @@ pub type AccessTokenAuthenticationRouterData = RouterData<
     AccessTokenAuthenticationRequestData,
     AccessTokenAuthenticationResponse,
 >;
+pub type PaymentsGiftCardBalanceCheckRouterData = RouterData<
+    GiftCardBalanceCheck,
+    GiftCardBalanceCheckRequestData,
+    GiftCardBalanceCheckResponseData,
+>;
 pub type RefreshTokenRouterData = RouterData<AccessTokenAuth, AccessTokenRequestData, AccessToken>;
 pub type PaymentsPostSessionTokensRouterData =
     RouterData<PostSessionTokens, PaymentsPostSessionTokensData, PaymentsResponseData>;
diff --git a/crates/hyperswitch_interfaces/src/api/payments.rs b/crates/hyperswitch_interfaces/src/api/payments.rs
index f4aa421240b..2120d3cf063 100644
--- a/crates/hyperswitch_interfaces/src/api/payments.rs
+++ b/crates/hyperswitch_interfaces/src/api/payments.rs
@@ -8,19 +8,23 @@ use hyperswitch_domain_models::{
             PostCaptureVoid, PostProcessing, PostSessionTokens, PreProcessing, Reject,
             SdkSessionUpdate, Session, SetupMandate, UpdateMetadata, Void,
         },
-        Authenticate, CreateOrder, ExternalVaultProxy, PostAuthenticate, PreAuthenticate,
+        Authenticate, CreateOrder, ExternalVaultProxy, GiftCardBalanceCheck, PostAuthenticate,
+        PreAuthenticate,
     },
     router_request_types::{
         AuthorizeSessionTokenData, CompleteAuthorizeData, ConnectorCustomerData,
-        CreateOrderRequestData, ExternalVaultProxyPaymentsData, PaymentMethodTokenizationData,
-        PaymentsApproveData, PaymentsAuthenticateData, PaymentsAuthorizeData, PaymentsCancelData,
-        PaymentsCancelPostCaptureData, PaymentsCaptureData, PaymentsIncrementalAuthorizationData,
-        PaymentsPostAuthenticateData, PaymentsPostProcessingData, PaymentsPostSessionTokensData,
-        PaymentsPreAuthenticateData, PaymentsPreProcessingData, PaymentsRejectData,
-        PaymentsSessionData, PaymentsSyncData, PaymentsTaxCalculationData,
-        PaymentsUpdateMetadataData, SdkPaymentsSessionUpdateData, SetupMandateRequestData,
+        CreateOrderRequestData, ExternalVaultProxyPaymentsData, GiftCardBalanceCheckRequestData,
+        PaymentMethodTokenizationData, PaymentsApproveData, PaymentsAuthenticateData,
+        PaymentsAuthorizeData, PaymentsCancelData, PaymentsCancelPostCaptureData,
+        PaymentsCaptureData, PaymentsIncrementalAuthorizationData, PaymentsPostAuthenticateData,
+        PaymentsPostProcessingData, PaymentsPostSessionTokensData, PaymentsPreAuthenticateData,
+        PaymentsPreProcessingData, PaymentsRejectData, PaymentsSessionData, PaymentsSyncData,
+        PaymentsTaxCalculationData, PaymentsUpdateMetadataData, SdkPaymentsSessionUpdateData,
+        SetupMandateRequestData,
+    },
+    router_response_types::{
+        GiftCardBalanceCheckResponseData, PaymentsResponseData, TaxCalculationResponseData,
     },
-    router_response_types::{PaymentsResponseData, TaxCalculationResponseData},
 };
 
 use crate::api;
@@ -51,6 +55,7 @@ pub trait Payment:
     + PaymentUpdateMetadata
     + PaymentsCreateOrder
     + ExternalVaultProxyPaymentsCreateV1
+    + PaymentsGiftCardBalanceCheck
 {
 }
 
@@ -207,3 +212,13 @@ pub trait ExternalVaultProxyPaymentsCreateV1:
     api::ConnectorIntegration<ExternalVaultProxy, ExternalVaultProxyPaymentsData, PaymentsResponseData>
 {
 }
+
+/// trait PaymentsGiftCardBalanceCheck
+pub trait PaymentsGiftCardBalanceCheck:
+    api::ConnectorIntegration<
+    GiftCardBalanceCheck,
+    GiftCardBalanceCheckRequestData,
+    GiftCardBalanceCheckResponseData,
+>
+{
+}
diff --git a/crates/hyperswitch_interfaces/src/api/payments_v2.rs b/crates/hyperswitch_interfaces/src/api/payments_v2.rs
index 88c3e39ca40..c0681670ebc 100644
--- a/crates/hyperswitch_interfaces/src/api/payments_v2.rs
+++ b/crates/hyperswitch_interfaces/src/api/payments_v2.rs
@@ -1,7 +1,7 @@
 //! Payments V2 interface
 
 use hyperswitch_domain_models::{
-    router_data_v2::PaymentFlowData,
+    router_data_v2::{flow_common_types::GiftCardBalanceCheckFlowData, PaymentFlowData},
     router_flow_types::{
         payments::{
             Approve, Authorize, AuthorizeSessionToken, CalculateTax, Capture, CompleteAuthorize,
@@ -9,19 +9,22 @@ use hyperswitch_domain_models::{
             PSync, PaymentMethodToken, PostCaptureVoid, PostProcessing, PostSessionTokens,
             PreProcessing, Reject, SdkSessionUpdate, Session, SetupMandate, UpdateMetadata, Void,
         },
-        Authenticate, PostAuthenticate, PreAuthenticate,
+        Authenticate, GiftCardBalanceCheck, PostAuthenticate, PreAuthenticate,
     },
     router_request_types::{
         AuthorizeSessionTokenData, CompleteAuthorizeData, ConnectorCustomerData,
-        CreateOrderRequestData, ExternalVaultProxyPaymentsData, PaymentMethodTokenizationData,
-        PaymentsApproveData, PaymentsAuthenticateData, PaymentsAuthorizeData, PaymentsCancelData,
-        PaymentsCancelPostCaptureData, PaymentsCaptureData, PaymentsIncrementalAuthorizationData,
-        PaymentsPostAuthenticateData, PaymentsPostProcessingData, PaymentsPostSessionTokensData,
-        PaymentsPreAuthenticateData, PaymentsPreProcessingData, PaymentsRejectData,
-        PaymentsSessionData, PaymentsSyncData, PaymentsTaxCalculationData,
-        PaymentsUpdateMetadataData, SdkPaymentsSessionUpdateData, SetupMandateRequestData,
+        CreateOrderRequestData, ExternalVaultProxyPaymentsData, GiftCardBalanceCheckRequestData,
+        PaymentMethodTokenizationData, PaymentsApproveData, PaymentsAuthenticateData,
+        PaymentsAuthorizeData, PaymentsCancelData, PaymentsCancelPostCaptureData,
+        PaymentsCaptureData, PaymentsIncrementalAuthorizationData, PaymentsPostAuthenticateData,
+        PaymentsPostProcessingData, PaymentsPostSessionTokensData, PaymentsPreAuthenticateData,
+        PaymentsPreProcessingData, PaymentsRejectData, PaymentsSessionData, PaymentsSyncData,
+        PaymentsTaxCalculationData, PaymentsUpdateMetadataData, SdkPaymentsSessionUpdateData,
+        SetupMandateRequestData,
+    },
+    router_response_types::{
+        GiftCardBalanceCheckResponseData, PaymentsResponseData, TaxCalculationResponseData,
     },
-    router_response_types::{PaymentsResponseData, TaxCalculationResponseData},
 };
 
 use crate::api::{
@@ -203,6 +206,17 @@ pub trait PaymentsPreProcessingV2:
 {
 }
 
+/// trait PaymentsGiftCardBalanceCheckV2
+pub trait PaymentsGiftCardBalanceCheckV2:
+    ConnectorIntegrationV2<
+    GiftCardBalanceCheck,
+    GiftCardBalanceCheckFlowData,
+    GiftCardBalanceCheckRequestData,
+    GiftCardBalanceCheckResponseData,
+>
+{
+}
+
 /// trait PaymentsPreAuthenticateV2
 pub trait PaymentsPreAuthenticateV2:
     ConnectorIntegrationV2<
@@ -235,7 +249,6 @@ pub trait PaymentsPostAuthenticateV2:
 >
 {
 }
-
 /// trait PaymentsPostProcessingV2
 pub trait PaymentsPostProcessingV2:
     ConnectorIntegrationV2<
@@ -285,5 +298,6 @@ pub trait PaymentV2:
     + PaymentUpdateMetadataV2
     + PaymentCreateOrderV2
     + ExternalVaultProxyPaymentsCreate
+    + PaymentsGiftCardBalanceCheckV2
 {
 }
diff --git a/crates/hyperswitch_interfaces/src/conversion_impls.rs b/crates/hyperswitch_interfaces/src/conversion_impls.rs
index 288ec0db952..32818ca5d4b 100644
--- a/crates/hyperswitch_interfaces/src/conversion_impls.rs
+++ b/crates/hyperswitch_interfaces/src/conversion_impls.rs
@@ -12,8 +12,9 @@ use hyperswitch_domain_models::{
             AccessTokenFlowData, AuthenticationTokenFlowData, BillingConnectorInvoiceSyncFlowData,
             BillingConnectorPaymentsSyncFlowData, DisputesFlowData, ExternalAuthenticationFlowData,
             ExternalVaultProxyFlowData, FilesFlowData, GetSubscriptionPlansData,
-            InvoiceRecordBackData, MandateRevokeFlowData, PaymentFlowData, RefundFlowData,
-            UasFlowData, VaultConnectorFlowData, WebhookSourceVerifyData,
+            GiftCardBalanceCheckFlowData, InvoiceRecordBackData, MandateRevokeFlowData,
+            PaymentFlowData, RefundFlowData, UasFlowData, VaultConnectorFlowData,
+            WebhookSourceVerifyData,
         },
         RouterDataV2,
     },
@@ -167,6 +168,45 @@ impl<T, Req: Clone, Resp: Clone> RouterDataConversion<T, Req, Resp> for AccessTo
     }
 }
 
+impl<T, Req: Clone, Resp: Clone> RouterDataConversion<T, Req, Resp>
+    for GiftCardBalanceCheckFlowData
+{
+    fn from_old_router_data(
+        old_router_data: &RouterData<T, Req, Resp>,
+    ) -> CustomResult<RouterDataV2<T, Self, Req, Resp>, ConnectorError>
+    where
+        Self: Sized,
+    {
+        let resource_common_data = Self;
+        Ok(RouterDataV2 {
+            flow: std::marker::PhantomData,
+            tenant_id: old_router_data.tenant_id.clone(),
+            resource_common_data,
+            connector_auth_type: old_router_data.connector_auth_type.clone(),
+            request: old_router_data.request.clone(),
+            response: old_router_data.response.clone(),
+        })
+    }
+
+    fn to_old_router_data(
+        new_router_data: RouterDataV2<T, Self, Req, Resp>,
+    ) -> CustomResult<RouterData<T, Req, Resp>, ConnectorError>
+    where
+        Self: Sized,
+    {
+        let request = new_router_data.request.clone();
+        let response = new_router_data.response.clone();
+        let mut router_data = get_default_router_data(
+            new_router_data.tenant_id.clone(),
+            "gift card balance check",
+            request,
+            response,
+        );
+        router_data.connector_auth_type = new_router_data.connector_auth_type;
+        Ok(router_data)
+    }
+}
+
 impl<T, Req: Clone, Resp: Clone> RouterDataConversion<T, Req, Resp> for PaymentFlowData {
     fn from_old_router_data(
         old_router_data: &RouterData<T, Req, Resp>,
diff --git a/crates/hyperswitch_interfaces/src/types.rs b/crates/hyperswitch_interfaces/src/types.rs
index e263735b8af..3afe6405315 100644
--- a/crates/hyperswitch_interfaces/src/types.rs
+++ b/crates/hyperswitch_interfaces/src/types.rs
@@ -25,7 +25,7 @@ use hyperswitch_domain_models::{
             ExternalVaultRetrieveFlow,
         },
         webhooks::VerifyWebhookSource,
-        AccessTokenAuthentication, BillingConnectorInvoiceSync,
+        AccessTokenAuthentication, BillingConnectorInvoiceSync, GiftCardBalanceCheck,
     },
     router_request_types::{
         revenue_recovery::{
@@ -41,12 +41,13 @@ use hyperswitch_domain_models::{
         AcceptDisputeRequestData, AccessTokenAuthenticationRequestData, AccessTokenRequestData,
         AuthorizeSessionTokenData, CompleteAuthorizeData, ConnectorCustomerData,
         CreateOrderRequestData, DefendDisputeRequestData, DisputeSyncData,
-        FetchDisputesRequestData, MandateRevokeRequestData, PaymentMethodTokenizationData,
-        PaymentsAuthenticateData, PaymentsAuthorizeData, PaymentsCancelData,
-        PaymentsCancelPostCaptureData, PaymentsCaptureData, PaymentsIncrementalAuthorizationData,
-        PaymentsPostAuthenticateData, PaymentsPostProcessingData, PaymentsPostSessionTokensData,
-        PaymentsPreAuthenticateData, PaymentsPreProcessingData, PaymentsSessionData,
-        PaymentsSyncData, PaymentsTaxCalculationData, PaymentsUpdateMetadataData, RefundsData,
+        FetchDisputesRequestData, GiftCardBalanceCheckRequestData, MandateRevokeRequestData,
+        PaymentMethodTokenizationData, PaymentsAuthenticateData, PaymentsAuthorizeData,
+        PaymentsCancelData, PaymentsCancelPostCaptureData, PaymentsCaptureData,
+        PaymentsIncrementalAuthorizationData, PaymentsPostAuthenticateData,
+        PaymentsPostProcessingData, PaymentsPostSessionTokensData, PaymentsPreAuthenticateData,
+        PaymentsPreProcessingData, PaymentsSessionData, PaymentsSyncData,
+        PaymentsTaxCalculationData, PaymentsUpdateMetadataData, RefundsData,
         RetrieveFileRequestData, SdkPaymentsSessionUpdateData, SetupMandateRequestData,
         SubmitEvidenceRequestData, UploadFileRequestData, VaultRequestData,
         VerifyWebhookSourceRequestData,
@@ -58,8 +59,9 @@ use hyperswitch_domain_models::{
         },
         subscriptions::GetSubscriptionPlansResponse,
         AcceptDisputeResponse, DefendDisputeResponse, DisputeSyncResponse, FetchDisputesResponse,
-        MandateRevokeResponseData, PaymentsResponseData, RefundsResponseData, RetrieveFileResponse,
-        SubmitEvidenceResponse, TaxCalculationResponseData, UploadFileResponse, VaultResponseData,
+        GiftCardBalanceCheckResponseData, MandateRevokeResponseData, PaymentsResponseData,
+        RefundsResponseData, RetrieveFileResponse, SubmitEvidenceResponse,
+        TaxCalculationResponseData, UploadFileResponse, VaultResponseData,
         VerifyWebhookSourceResponseData,
     },
 };
@@ -140,6 +142,12 @@ pub type PaymentsPreAuthorizeType = dyn ConnectorIntegration<
     AuthorizeSessionTokenData,
     PaymentsResponseData,
 >;
+/// Type alias for `ConnectorIntegration<GiftCardBalanceCheck, GiftCardBalanceCheckRequestData, GiftCardBalanceCheckResponseData>`
+pub type PaymentsGiftCardBalanceCheckType = dyn ConnectorIntegration<
+    GiftCardBalanceCheck,
+    GiftCardBalanceCheckRequestData,
+    GiftCardBalanceCheckResponseData,
+>;
 /// Type alias for `ConnectorIntegration<InitPayment, PaymentsAuthorizeData, PaymentsResponseData>`
 pub type PaymentsInitType =
     dyn ConnectorIntegration<InitPayment, PaymentsAuthorizeData, PaymentsResponseData>;
diff --git a/crates/openapi/src/openapi_v2.rs b/crates/openapi/src/openapi_v2.rs
index 71fe216322d..3942d01abf2 100644
--- a/crates/openapi/src/openapi_v2.rs
+++ b/crates/openapi/src/openapi_v2.rs
@@ -128,6 +128,7 @@ Never share your secret api keys. Keep them guarded and secure.
         routes::payments::payments_connector_session,
         routes::payments::list_payment_methods,
         routes::payments::payments_list,
+        routes::payments::payment_check_gift_card_balance,
 
         //Routes for payment methods
         routes::payment_method::create_payment_method_api,
@@ -543,6 +544,8 @@ Never share your secret api keys. Keep them guarded and secure.
         api_models::payments::RequestSurchargeDetails,
         api_models::payments::PaymentRevenueRecoveryMetadata,
         api_models::payments::BillingConnectorPaymentDetails,
+        api_models::payments::GiftCardBalanceCheckResponse,
+        api_models::payments::PaymentsGiftCardBalanceCheckRequest,
         api_models::enums::PaymentConnectorTransmission,
         api_models::enums::TriggeredBy,
         api_models::payments::PaymentAttemptResponse,
diff --git a/crates/openapi/src/routes/payments.rs b/crates/openapi/src/routes/payments.rs
index d3abd208e9a..026f4d6cc03 100644
--- a/crates/openapi/src/routes/payments.rs
+++ b/crates/openapi/src/routes/payments.rs
@@ -1268,3 +1268,30 @@ pub fn list_payment_methods() {}
     security(("api_key" = []), ("jwt_key" = []))
 )]
 pub fn payments_list() {}
+
+/// Payments - Gift Card Balance Check
+///
+/// Check the balance of the provided gift card. This endpoint also returns whether the gift card balance is enough to cover the entire amount or another payment method is needed
+#[cfg(feature = "v2")]
+#[utoipa::path(
+    get,
+    path = "/v2/payments/{id}/check-gift-card-balance",
+    params(
+        ("id" = String, Path, description = "The global payment id"),
+        (
+          "X-Profile-Id" = String, Header,
+          description = "Profile ID associated to the payment intent",
+          example = "pro_abcdefghijklmnop"
+        ),
+    ),
+    request_body(
+      content = PaymentsGiftCardBalanceCheckRequest,
+    ),
+    responses(
+        (status = 200, description = "Get the Gift Card Balance", body = GiftCardBalanceCheckResponse),
+    ),
+    tag = "Payments",
+    operation_id = "Retrieve Gift Card Balance",
+    security(("publishable_key" = []))
+)]
+pub fn payment_check_gift_card_balance() {}
diff --git a/crates/router/src/core.rs b/crates/router/src/core.rs
index 0fe3e57f872..f7cb256f587 100644
--- a/crates/router/src/core.rs
+++ b/crates/router/src/core.rs
@@ -24,6 +24,8 @@ pub mod external_service_auth;
 pub mod files;
 #[cfg(feature = "frm")]
 pub mod fraud_check;
+#[cfg(feature = "v2")]
+pub mod gift_card;
 pub mod gsm;
 pub mod health_check;
 #[cfg(feature = "v1")]
diff --git a/crates/router/src/core/gift_card.rs b/crates/router/src/core/gift_card.rs
new file mode 100644
index 00000000000..d1c89eafdbb
--- /dev/null
+++ b/crates/router/src/core/gift_card.rs
@@ -0,0 +1,179 @@
+use std::marker::PhantomData;
+
+#[cfg(feature = "v2")]
+use api_models::payments::{GiftCardBalanceCheckResponse, PaymentsGiftCardBalanceCheckRequest};
+use common_enums::CallConnectorAction;
+#[cfg(feature = "v2")]
+use common_utils::id_type;
+use common_utils::types::MinorUnit;
+use error_stack::ResultExt;
+#[cfg(feature = "v2")]
+use hyperswitch_domain_models::payments::HeaderPayload;
+use hyperswitch_domain_models::{
+    router_data_v2::{flow_common_types::GiftCardBalanceCheckFlowData, RouterDataV2},
+    router_flow_types::GiftCardBalanceCheck,
+    router_request_types::GiftCardBalanceCheckRequestData,
+    router_response_types::GiftCardBalanceCheckResponseData,
+};
+use hyperswitch_interfaces::connector_integration_interface::RouterDataConversion;
+
+use crate::db::errors::StorageErrorExt;
+#[cfg(feature = "v2")]
+use crate::{
+    core::{
+        errors::{self, RouterResponse},
+        payments::helpers,
+    },
+    routes::{app::ReqState, SessionState},
+    services,
+    types::{api, domain},
+};
+
+#[cfg(feature = "v2")]
+#[allow(clippy::too_many_arguments)]
+pub async fn payments_check_gift_card_balance_core(
+    state: SessionState,
+    merchant_context: domain::MerchantContext,
+    profile: domain::Profile,
+    _req_state: ReqState,
+    req: PaymentsGiftCardBalanceCheckRequest,
+    _header_payload: HeaderPayload,
+    payment_id: id_type::GlobalPaymentId,
+) -> RouterResponse<GiftCardBalanceCheckResponse> {
+    let db = state.store.as_ref();
+
+    let key_manager_state = &(&state).into();
+
+    let storage_scheme = merchant_context.get_merchant_account().storage_scheme;
+    let payment_intent = db
+        .find_payment_intent_by_id(
+            key_manager_state,
+            &payment_id,
+            merchant_context.get_merchant_key_store(),
+            storage_scheme,
+        )
+        .await
+        .to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?;
+
+    let redis_conn = db
+        .get_redis_conn()
+        .change_context(errors::ApiErrorResponse::InternalServerError)
+        .attach_printable("Could not get redis connection")?;
+
+    let gift_card_connector_id: String = redis_conn
+        .get_key(&payment_id.get_gift_card_connector_key().as_str().into())
+        .await
+        .attach_printable("Failed to fetch gift card connector from redis")
+        .change_context(errors::ApiErrorResponse::GenericNotFoundError {
+            message: "No connector found with Gift Card Support".to_string(),
+        })?;
+
+    let gift_card_connector_id = id_type::MerchantConnectorAccountId::wrap(gift_card_connector_id)
+        .attach_printable("Failed to deserialize MCA")
+        .change_context(errors::ApiErrorResponse::GenericNotFoundError {
+            message: "No connector found with Gift Card Support".to_string(),
+        })?;
+
+    let merchant_connector_account =
+        domain::MerchantConnectorAccountTypeDetails::MerchantConnectorAccount(Box::new(
+            helpers::get_merchant_connector_account_v2(
+                &state,
+                merchant_context.get_merchant_key_store(),
+                Some(&gift_card_connector_id),
+            )
+            .await
+            .attach_printable(
+                "failed to fetch merchant connector account for gift card balance check",
+            )?,
+        ));
+
+    let connector_name = merchant_connector_account
+        .get_connector_name()
+        .ok_or(errors::ApiErrorResponse::InternalServerError)
+        .attach_printable("Connector name not present for gift card balance check")?; // always get the connector name from this call
+
+    let connector_data = api::ConnectorData::get_connector_by_name(
+        &state.conf.connectors,
+        &connector_name.to_string(),
+        api::GetToken::Connector,
+        merchant_connector_account.get_mca_id(),
+    )
+    .change_context(errors::ApiErrorResponse::InternalServerError)
+    .attach_printable("Failed to get the connector data")?;
+
+    let connector_auth_type = merchant_connector_account
+        .get_connector_account_details()
+        .change_context(errors::ApiErrorResponse::InternalServerError)?;
+
+    let resource_common_data = GiftCardBalanceCheckFlowData;
+
+    let router_data: RouterDataV2<
+        GiftCardBalanceCheck,
+        GiftCardBalanceCheckFlowData,
+        GiftCardBalanceCheckRequestData,
+        GiftCardBalanceCheckResponseData,
+    > = RouterDataV2 {
+        flow: PhantomData,
+        resource_common_data,
+        tenant_id: state.tenant.tenant_id.clone(),
+        connector_auth_type,
+        request: GiftCardBalanceCheckRequestData {
+            payment_method_data: domain::PaymentMethodData::GiftCard(Box::new(
+                req.gift_card_data.into(),
+            )),
+            currency: Some(payment_intent.amount_details.currency),
+            minor_amount: Some(payment_intent.amount_details.order_amount),
+        },
+        response: Err(hyperswitch_domain_models::router_data::ErrorResponse::default()),
+    };
+
+    let old_router_data = GiftCardBalanceCheckFlowData::to_old_router_data(router_data)
+        .change_context(errors::ApiErrorResponse::InternalServerError)
+        .attach_printable(
+            "Cannot construct router data for making the gift card balance check api call",
+        )?;
+    let connector_integration: services::BoxedGiftCardBalanceCheckIntegrationInterface<
+        GiftCardBalanceCheck,
+        GiftCardBalanceCheckRequestData,
+        GiftCardBalanceCheckResponseData,
+    > = connector_data.connector.get_connector_integration();
+
+    let connector_response = services::execute_connector_processing_step(
+        &state,
+        connector_integration,
+        &old_router_data,
+        CallConnectorAction::Trigger,
+        None,
+        None,
+    )
+    .await
+    .change_context(errors::ApiErrorResponse::InternalServerError)
+    .attach_printable("Failed while calling gift card balance check connector api")?;
+
+    let gift_card_balance = connector_response
+        .response
+        .map_err(|_| errors::ApiErrorResponse::UnprocessableEntity {
+            message: "Error while fetching gift card balance".to_string(),
+        })
+        .attach_printable("Connector returned invalid response")?;
+
+    let balance = gift_card_balance.balance;
+    let currency = gift_card_balance.currency;
+    let remaining_amount =
+        if (payment_intent.amount_details.order_amount - balance).is_greater_than(0) {
+            payment_intent.amount_details.order_amount - balance
+        } else {
+            MinorUnit::zero()
+        };
+    let needs_additional_pm_data = remaining_amount.is_greater_than(0);
+
+    let resp = GiftCardBalanceCheckResponse {
+        payment_id: payment_intent.id.clone(),
+        balance,
+        currency,
+        needs_additional_pm_data,
+        remaining_amount,
+    };
+
+    Ok(services::ApplicationResponse::Json(resp))
+}
diff --git a/crates/router/src/core/payments/payment_methods.rs b/crates/router/src/core/payments/payment_methods.rs
index 36a8120fd18..9a2a809ba89 100644
--- a/crates/router/src/core/payments/payment_methods.rs
+++ b/crates/router/src/core/payments/payment_methods.rs
@@ -78,6 +78,7 @@ pub async fn list_payment_methods(
                 &req,
                 &payment_intent,
             ).await?
+            .store_gift_card_mca_in_redis(&payment_id, db, &profile).await
             .merge_and_transform()
             .get_required_fields(RequiredFieldsInput::new(state.conf.required_fields.clone(), payment_intent.setup_future_usage))
             .perform_surcharge_calculation()
@@ -189,6 +190,50 @@ impl FilteredPaymentMethodsEnabled {
             .collect();
         MergedEnabledPaymentMethodTypes(values)
     }
+    async fn store_gift_card_mca_in_redis(
+        self,
+        payment_id: &id_type::GlobalPaymentId,
+        db: &dyn crate::db::StorageInterface,
+        profile: &domain::Profile,
+    ) -> Self {
+        let gift_card_connector_id = self
+            .0
+            .iter()
+            .find(|item| item.payment_method == common_enums::PaymentMethod::GiftCard)
+            .map(|item| &item.merchant_connector_id);
+
+        if let Some(gift_card_mca) = gift_card_connector_id {
+            let gc_key = payment_id.get_gift_card_connector_key();
+            let redis_expiry = profile
+                .get_order_fulfillment_time()
+                .unwrap_or(common_utils::consts::DEFAULT_INTENT_FULFILLMENT_TIME);
+
+            let redis_conn = db
+                .get_redis_conn()
+                .map_err(|redis_error| logger::error!(?redis_error))
+                .ok();
+
+            if let Some(rc) = redis_conn {
+                rc.set_key_with_expiry(
+                    &gc_key.as_str().into(),
+                    gift_card_mca.get_string_repr().to_string(),
+                    redis_expiry,
+                )
+                .await
+                .attach_printable("Failed to store gift card mca_id in redis")
+                .unwrap_or_else(|error| {
+                    logger::error!(?error);
+                })
+            };
+        } else {
+            logger::error!(
+                "Could not find any configured MCA supporting gift card for payment_id -> {}",
+                payment_id.get_string_repr()
+            );
+        }
+
+        self
+    }
 }
 
 /// Element container to hold the filtered payment methods with payment_experience and connectors merged for a pm_subtype
diff --git a/crates/router/src/routes/app.rs b/crates/router/src/routes/app.rs
index f12730d7b63..d52dc1570ce 100644
--- a/crates/router/src/routes/app.rs
+++ b/crates/router/src/routes/app.rs
@@ -737,6 +737,10 @@ impl Payments {
                 )
                 .service(
                     web::resource("/capture").route(web::post().to(payments::payments_capture)),
+                )
+                .service(
+                    web::resource("/check-gift-card-balance")
+                        .route(web::post().to(payments::payment_check_gift_card_balance)),
                 ),
         );
 
diff --git a/crates/router/src/routes/lock_utils.rs b/crates/router/src/routes/lock_utils.rs
index c3efb561b42..28581198d83 100644
--- a/crates/router/src/routes/lock_utils.rs
+++ b/crates/router/src/routes/lock_utils.rs
@@ -163,6 +163,7 @@ impl From<Flow> for ApiIdentifier {
             | Flow::PaymentsConfirmIntent
             | Flow::PaymentsCreateIntent
             | Flow::PaymentsGetIntent
+            | Flow::GiftCardBalanceCheck
             | Flow::PaymentsPostSessionTokens
             | Flow::PaymentsUpdateMetadata
             | Flow::PaymentsUpdateIntent
diff --git a/crates/router/src/routes/payments.rs b/crates/router/src/routes/payments.rs
index 1136e9f84a6..6f29b4cb5d9 100644
--- a/crates/router/src/routes/payments.rs
+++ b/crates/router/src/routes/payments.rs
@@ -11,6 +11,8 @@ use router_env::{env, instrument, logger, tracing, types, Flow};
 
 use super::app::ReqState;
 #[cfg(feature = "v2")]
+use crate::core::gift_card;
+#[cfg(feature = "v2")]
 use crate::core::revenue_recovery::api as recovery;
 use crate::{
     self as app,
@@ -2984,6 +2986,69 @@ pub async fn payment_confirm_intent(
     .await
 }
 
+#[cfg(feature = "v2")]
+#[instrument(skip_all, fields(flow = ?Flow::GiftCardBalanceCheck, payment_id))]
+pub async fn payment_check_gift_card_balance(
+    state: web::Data<app::AppState>,
+    req: actix_web::HttpRequest,
+    json_payload: web::Json<api_models::payments::PaymentsGiftCardBalanceCheckRequest>,
+    path: web::Path<common_utils::id_type::GlobalPaymentId>,
+) -> impl Responder {
+    let flow = Flow::GiftCardBalanceCheck;
+
+    let global_payment_id = path.into_inner();
+    tracing::Span::current().record("payment_id", global_payment_id.get_string_repr());
+
+    let internal_payload = internal_payload_types::PaymentsGenericRequestWithResourceId {
+        global_payment_id: global_payment_id.clone(),
+        payload: json_payload.into_inner(),
+    };
+
+    let header_payload = match HeaderPayload::foreign_try_from(req.headers()) {
+        Ok(headers) => headers,
+        Err(err) => {
+            return api::log_and_return_error_response(err);
+        }
+    };
+
+    Box::pin(api::server_wrap(
+        flow,
+        state,
+        &req,
+        internal_payload,
+        |state, auth: auth::AuthenticationData, req, req_state| async {
+            let payment_id = req.global_payment_id;
+            let request = req.payload;
+
+            let merchant_context = domain::MerchantContext::NormalMerchant(Box::new(
+                domain::Context(auth.merchant_account, auth.key_store),
+            ));
+            Box::pin(gift_card::payments_check_gift_card_balance_core(
+                state,
+                merchant_context,
+                auth.profile,
+                req_state,
+                request,
+                header_payload.clone(),
+                payment_id,
+            ))
+            .await
+        },
+        auth::api_or_client_auth(
+            &auth::V2ApiKeyAuth {
+                is_connected_allowed: false,
+                is_platform_allowed: false,
+            },
+            &auth::V2ClientAuth(common_utils::types::authentication::ResourceId::Payment(
+                global_payment_id,
+            )),
+            req.headers(),
+        ),
+        api_locking::LockAction::NotApplicable,
+    ))
+    .await
+}
+
 #[cfg(feature = "v2")]
 #[instrument(skip_all, fields(flow = ?Flow::ProxyConfirmIntent, payment_id))]
 pub async fn proxy_confirm_intent(
diff --git a/crates/router/src/services/api.rs b/crates/router/src/services/api.rs
index 28928307646..e7e03a5f322 100644
--- a/crates/router/src/services/api.rs
+++ b/crates/router/src/services/api.rs
@@ -129,6 +129,9 @@ pub type BoxedBillingConnectorPaymentsSyncIntegrationInterface<T, Req, Res> =
 pub type BoxedVaultConnectorIntegrationInterface<T, Req, Res> =
     BoxedConnectorIntegrationInterface<T, common_types::VaultConnectorFlowData, Req, Res>;
 
+pub type BoxedGiftCardBalanceCheckIntegrationInterface<T, Req, Res> =
+    BoxedConnectorIntegrationInterface<T, common_types::GiftCardBalanceCheckFlowData, Req, Res>;
+
 /// Handle UCS webhook response processing
 fn handle_ucs_response<T, Req, Resp>(
     router_data: types::RouterData<T, Req, Resp>,
diff --git a/crates/router_env/src/logger/types.rs b/crates/router_env/src/logger/types.rs
index 2345469a4e1..f5359d84010 100644
--- a/crates/router_env/src/logger/types.rs
+++ b/crates/router_env/src/logger/types.rs
@@ -652,6 +652,8 @@ pub enum Flow {
     RecoveryPaymentsCreate,
     /// Tokenization delete flow
     TokenizationDelete,
+    /// Gift card balance check flow
+    GiftCardBalanceCheck,
 }
 
 /// Trait for providing generic behaviour to flow metric

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

- [ ] Bugfix
- [x] New feature
- [ ] Enhancement
- [ ] Refactoring
- [ ] Dependency updates
- [ ] Documentation
- [ ] CI/CD

## Description
<!-- Describe your changes in detail -->
- Added `check-gift-card-balance` API
- Added `GiftCardBalanceCheck` flow for connectors and implemented it for Adyen
- Updated PML flow to store gift card enabled MCA in redis

<img width="2314" height="1286" alt="image" src="https://github.com/user-attachments/assets/50087048-1ac5-459f-84ee-d6af7cdbfcae" />

### Additional Changes

- [x] This PR modifies the API contract
- [ ] This PR modifies the database schema
- [ ] This PR modifies application configuration/environment variables

<!--
Provide links to the files with corresponding changes.

Following are the paths where you can find config files:
1. `config`
2. `crates/router/src/configs`
3. `loadtest/config`
-->


## 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 it is an obvious bug or documentation fix
that will have little conversation).
-->
This change is required for supporting split payments. SDK will call this endpoint and based on the gift card balance and transaction amount it will either collect Gift card details only or Gift card + another payment method.
Closes #9101 

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

1. Create-Intent Call
2. PML for payments call

3. Request:
```
curl --location 'http://localhost:8080/v2/payments/12345_pay_019937e3515f7462b97fe6f5f6901191/check-gift-card-balance' \
--header 'api-key: dev_vzsdTpwwx2h18nUXDFGPaIJmPifOT7zsX9DkCIA3FZQyJgny7c7MrV6RTdgStgOB' \
--header 'Content-Type: application/json' \
--header 'x-profile-id: pro_qAkCNwFOT6asT6ENbmFn' \
--header 'Authorization: publishable-key=pk_dev_433fd28e6bd24a6bb79527cde2af25e1, client-secret=cs_019937e351c171f19b62d7c44802d53e' \
--data '{
    "gift_card_data": {
        "givex": {
            "number": "6036280000000000000",
            "cvc": "123"
        }
    }
}'
```

Response:
```
{
    "payment_id": "12345_pay_019937e3515f7462b97fe6f5f6901191",
    "balance": 5000,
    "currency": "EUR",
    "needs_additional_pm_data": false,
    "remaining_amount": 0
}
```

## 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 the submitted code
- [ ] I added unit tests for my changes where possible
