Bug: [FEATURE] Open banking SDK fixes



### Feature Description

SDK would send headers in order to identify the client platform, we need to consume in the backend and process accordingly.

### Possible Implementation

Need to consume headers in specific flows. 

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

- [X] I checked and didn't find a 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/api_models/src/payments.rs b/crates/api_models/src/payments.rs
index 20f1205e14b..c50b1fb1d05 100644
--- a/crates/api_models/src/payments.rs
+++ b/crates/api_models/src/payments.rs
@@ -793,6 +793,8 @@ pub struct HeaderPayload {
     pub x_client_platform: Option<api_enums::ClientPlatform>,
     pub x_merchant_domain: Option<String>,
     pub locale: Option<String>,
+    pub x_app_id: Option<String>,
+    pub x_redirect_uri: Option<String>,
 }
 
 impl HeaderPayload {
diff --git a/crates/api_models/src/pm_auth.rs b/crates/api_models/src/pm_auth.rs
index 8ed52907da8..443a4c30394 100644
--- a/crates/api_models/src/pm_auth.rs
+++ b/crates/api_models/src/pm_auth.rs
@@ -4,6 +4,8 @@ use common_utils::{
     id_type, impl_api_event_type,
 };
 
+use crate::enums as api_enums;
+
 #[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
 #[serde(rename_all = "snake_case")]
 pub struct LinkTokenCreateRequest {
@@ -12,6 +14,9 @@ pub struct LinkTokenCreateRequest {
     pub payment_id: id_type::PaymentId, // payment_id to be passed in req body for redis pm_auth connector name fetch
     pub payment_method: PaymentMethod,  // payment_method to be used for filtering pm_auth connector
     pub payment_method_type: PaymentMethodType, // payment_method_type to be used for filtering pm_auth connector
+    pub client_platform: api_enums::ClientPlatform, // Client Platform to perform platform based processing
+    pub android_package_name: Option<String>, // Android Package name to be sent for Android platform
+    pub redirect_uri: Option<String>, // Merchant redirect_uri to be sent in case of IOS platform
 }
 
 #[derive(Debug, Clone, serde::Serialize)]
diff --git a/crates/common_enums/src/enums.rs b/crates/common_enums/src/enums.rs
index 653275bd560..9136ee35c7d 100644
--- a/crates/common_enums/src/enums.rs
+++ b/crates/common_enums/src/enums.rs
@@ -2479,6 +2479,7 @@ pub enum ClientPlatform {
     #[default]
     Web,
     Ios,
+    Android,
     #[serde(other)]
     Unknown,
 }
diff --git a/crates/hyperswitch_domain_models/src/router_data.rs b/crates/hyperswitch_domain_models/src/router_data.rs
index df0b63833d9..dde38561b44 100644
--- a/crates/hyperswitch_domain_models/src/router_data.rs
+++ b/crates/hyperswitch_domain_models/src/router_data.rs
@@ -80,6 +80,10 @@ pub struct RouterData<Flow, Request, Response> {
     pub minor_amount_captured: Option<MinorUnit>,
 
     pub integrity_check: Result<(), IntegrityCheckError>,
+
+    pub additional_merchant_data: Option<api_models::admin::AdditionalMerchantData>,
+
+    pub header_payload: Option<api_models::payments::HeaderPayload>,
 }
 
 // Different patterns of authentication.
diff --git a/crates/hyperswitch_domain_models/src/router_request_types.rs b/crates/hyperswitch_domain_models/src/router_request_types.rs
index ec182056f6c..93ace230f19 100644
--- a/crates/hyperswitch_domain_models/src/router_request_types.rs
+++ b/crates/hyperswitch_domain_models/src/router_request_types.rs
@@ -346,6 +346,8 @@ pub struct PaymentsPostProcessingData {
     pub customer_id: Option<id_type::CustomerId>,
     pub connector_transaction_id: Option<String>,
     pub country: Option<common_enums::CountryAlpha2>,
+    pub connector_meta_data: Option<pii::SecretSerdeValue>,
+    pub header_payload: Option<api_models::payments::HeaderPayload>,
 }
 
 impl<F> TryFrom<RouterData<F, PaymentsAuthorizeData, response_types::PaymentsResponseData>>
@@ -371,6 +373,8 @@ impl<F> TryFrom<RouterData<F, PaymentsAuthorizeData, response_types::PaymentsRes
                 .get_payment_billing()
                 .and_then(|bl| bl.address.as_ref())
                 .and_then(|address| address.country),
+            connector_meta_data: data.connector_meta_data.clone(),
+            header_payload: data.header_payload,
         })
     }
 }
diff --git a/crates/pm_auth/src/connector/plaid/transformers.rs b/crates/pm_auth/src/connector/plaid/transformers.rs
index 109cc5a5c15..af0c26a5b85 100644
--- a/crates/pm_auth/src/connector/plaid/transformers.rs
+++ b/crates/pm_auth/src/connector/plaid/transformers.rs
@@ -15,6 +15,8 @@ pub struct PlaidLinkTokenRequest {
     language: String,
     products: Vec<String>,
     user: User,
+    android_package_name: Option<String>,
+    redirect_uri: Option<String>,
 }
 
 #[derive(Debug, Serialize, Eq, PartialEq)]
@@ -42,6 +44,30 @@ impl TryFrom<&types::LinkTokenRouterData> for PlaidLinkTokenRequest {
                     },
                 )?,
             },
+            android_package_name: match item.request.client_platform {
+                api_models::enums::ClientPlatform::Android => {
+                    Some(item.request.android_package_name.clone().ok_or(
+                        errors::ConnectorError::MissingRequiredField {
+                            field_name: "android_package_name",
+                        },
+                    )?)
+                }
+                api_models::enums::ClientPlatform::Ios
+                | api_models::enums::ClientPlatform::Web
+                | api_models::enums::ClientPlatform::Unknown => None,
+            },
+            redirect_uri: match item.request.client_platform {
+                api_models::enums::ClientPlatform::Ios => {
+                    Some(item.request.redirect_uri.clone().ok_or(
+                        errors::ConnectorError::MissingRequiredField {
+                            field_name: "redirect_uri",
+                        },
+                    )?)
+                }
+                api_models::enums::ClientPlatform::Android
+                | api_models::enums::ClientPlatform::Web
+                | api_models::enums::ClientPlatform::Unknown => None,
+            },
         })
     }
 }
diff --git a/crates/pm_auth/src/types.rs b/crates/pm_auth/src/types.rs
index 4c20e879d8b..878043afe50 100644
--- a/crates/pm_auth/src/types.rs
+++ b/crates/pm_auth/src/types.rs
@@ -3,6 +3,7 @@ pub mod api;
 use std::marker::PhantomData;
 
 use api::auth_service::{BankAccountCredentials, ExchangeToken, LinkToken, RecipientCreate};
+use api_models::enums as api_enums;
 use common_enums::{CountryAlpha2, PaymentMethod, PaymentMethodType};
 use common_utils::{id_type, types};
 use masking::Secret;
@@ -24,6 +25,9 @@ pub struct LinkTokenRequest {
     pub country_codes: Option<Vec<String>>,
     pub language: Option<String>,
     pub user_info: Option<id_type::CustomerId>,
+    pub client_platform: api_enums::ClientPlatform,
+    pub android_package_name: Option<String>,
+    pub redirect_uri: Option<String>,
 }
 
 #[derive(Debug, Clone)]
diff --git a/crates/router/src/connector/plaid/transformers.rs b/crates/router/src/connector/plaid/transformers.rs
index cf9c91afd0c..c4eb5a7a035 100644
--- a/crates/router/src/connector/plaid/transformers.rs
+++ b/crates/router/src/connector/plaid/transformers.rs
@@ -1,6 +1,5 @@
 use common_enums::Currency;
 use common_utils::types::FloatMajorUnit;
-use error_stack::ResultExt;
 use masking::{PeekInterface, Secret};
 use serde::{Deserialize, Serialize};
 
@@ -73,6 +72,8 @@ pub struct PlaidLinkTokenRequest {
     products: Vec<String>,
     user: User,
     payment_initiation: PlaidPaymentInitiation,
+    redirect_uri: Option<String>,
+    android_package_name: Option<String>,
 }
 
 #[derive(Default, Debug, Serialize, Deserialize)]
@@ -105,21 +106,21 @@ impl TryFrom<&PlaidRouterData<&types::PaymentsAuthorizeRouterData>> for PlaidPay
                     .ok_or(errors::ConnectorError::MissingRequiredField {
                         field_name: "payment_id",
                     })?;
-                    let recipient_val = item
+                    let recipient_type = item
                         .router_data
-                        .connector_meta_data
+                        .additional_merchant_data
                         .as_ref()
+                        .map(|merchant_data| match merchant_data {
+                            api_models::admin::AdditionalMerchantData::OpenBankingRecipientData(
+                                data,
+                            ) => data.clone(),
+                        })
                         .ok_or(errors::ConnectorError::MissingRequiredField {
-                            field_name: "connector_customer",
-                        })?
-                        .peek()
-                        .clone();
-
-                    let recipient_type =
-                        serde_json::from_value::<types::MerchantRecipientData>(recipient_val)
-                            .change_context(errors::ConnectorError::ParsingFailed)?;
+                            field_name: "additional_merchant_data",
+                        })?;
+
                     let recipient_id = match recipient_type {
-                        types::MerchantRecipientData::ConnectorRecipientId(id) => {
+                        api_models::admin::MerchantRecipientData::ConnectorRecipientId(id) => {
                             Ok(id.peek().to_string())
                         }
                         _ => Err(errors::ConnectorError::MissingRequiredField {
@@ -159,35 +160,73 @@ impl TryFrom<&types::PaymentsSyncRouterData> for PlaidSyncRequest {
 impl TryFrom<&types::PaymentsPostProcessingRouterData> for PlaidLinkTokenRequest {
     type Error = error_stack::Report<errors::ConnectorError>;
     fn try_from(item: &types::PaymentsPostProcessingRouterData) -> Result<Self, Self::Error> {
-        match item.request.payment_method_data.clone() {
+        match item.request.payment_method_data {
             domain::PaymentMethodData::OpenBanking(ref data) => match data {
-                domain::OpenBankingData::OpenBankingPIS { .. } => Ok(Self {
-                    client_name: "Hyperswitch".to_string(),
-                    country_codes: item
-                        .request
-                        .country
-                        .map(|code| vec![code.to_string()])
-                        .ok_or(errors::ConnectorError::MissingRequiredField {
-                            field_name: "billing.address.country",
-                        })?,
-                    language: "en".to_string(),
-                    products: vec!["payment_initiation".to_string()],
-                    user: User {
-                        client_user_id: item
-                            .request
-                            .customer_id
-                            .clone()
-                            .map(|id| id.get_string_repr().to_string())
-                            .unwrap_or("default cust".to_string()),
-                    },
-                    payment_initiation: PlaidPaymentInitiation {
-                        payment_id: item
+                domain::OpenBankingData::OpenBankingPIS { .. } => {
+                    let headers = item.header_payload.clone().ok_or(
+                        errors::ConnectorError::MissingRequiredField {
+                            field_name: "header_payload",
+                        },
+                    )?;
+
+                    let platform = headers.x_client_platform.ok_or(
+                        errors::ConnectorError::MissingRequiredField {
+                            field_name: "x_client_platform",
+                        },
+                    )?;
+
+                    let (is_android, is_ios) = match platform {
+                        common_enums::ClientPlatform::Android => (true, false),
+                        common_enums::ClientPlatform::Ios => (false, true),
+                        _ => (false, false),
+                    };
+
+                    Ok(Self {
+                        client_name: "Hyperswitch".to_string(),
+                        country_codes: item
                             .request
-                            .connector_transaction_id
-                            .clone()
-                            .ok_or(errors::ConnectorError::MissingConnectorTransactionID)?,
-                    },
-                }),
+                            .country
+                            .map(|code| vec![code.to_string()])
+                            .ok_or(errors::ConnectorError::MissingRequiredField {
+                                field_name: "billing.address.country",
+                            })?,
+                        language: "en".to_string(),
+                        products: vec!["payment_initiation".to_string()],
+                        user: User {
+                            client_user_id: item
+                                .request
+                                .customer_id
+                                .clone()
+                                .map(|id| id.get_string_repr().to_string())
+                                .unwrap_or("default cust".to_string()),
+                        },
+                        payment_initiation: PlaidPaymentInitiation {
+                            payment_id: item
+                                .request
+                                .connector_transaction_id
+                                .clone()
+                                .ok_or(errors::ConnectorError::MissingConnectorTransactionID)?,
+                        },
+                        android_package_name: if is_android {
+                            Some(headers.x_app_id.ok_or(
+                                errors::ConnectorError::MissingRequiredField {
+                                    field_name: "x-app-id",
+                                },
+                            )?)
+                        } else {
+                            None
+                        },
+                        redirect_uri: if is_ios {
+                            Some(headers.x_redirect_uri.ok_or(
+                                errors::ConnectorError::MissingRequiredField {
+                                    field_name: "x_redirect_uri",
+                                },
+                            )?)
+                        } else {
+                            None
+                        },
+                    })
+                }
             },
             _ => Err(errors::ConnectorError::NotImplemented("Payment methods".to_string()).into()),
         }
diff --git a/crates/router/src/core/authentication.rs b/crates/router/src/core/authentication.rs
index f77296d7bc1..5b512bdd2b6 100644
--- a/crates/router/src/core/authentication.rs
+++ b/crates/router/src/core/authentication.rs
@@ -61,8 +61,12 @@ pub async fn perform_authentication(
         webhook_url,
         three_ds_requestor_url,
     )?;
-    let response =
-        utils::do_auth_connector_call(state, authentication_connector.clone(), router_data).await?;
+    let response = Box::pin(utils::do_auth_connector_call(
+        state,
+        authentication_connector.clone(),
+        router_data,
+    ))
+    .await?;
     let authentication =
         utils::update_trackers(state, response.clone(), authentication_data, None).await?;
     response
diff --git a/crates/router/src/core/authentication/transformers.rs b/crates/router/src/core/authentication/transformers.rs
index 4a1298bb7bf..bbbbf9a2514 100644
--- a/crates/router/src/core/authentication/transformers.rs
+++ b/crates/router/src/core/authentication/transformers.rs
@@ -182,6 +182,8 @@ pub fn construct_router_data<F: Clone, Req, Res>(
         payment_method_status: None,
         connector_response: None,
         integrity_check: Ok(()),
+        additional_merchant_data: None,
+        header_payload: None,
     })
 }
 
diff --git a/crates/router/src/core/fraud_check.rs b/crates/router/src/core/fraud_check.rs
index 90c36ba9aa8..72a75661984 100644
--- a/crates/router/src/core/fraud_check.rs
+++ b/crates/router/src/core/fraud_check.rs
@@ -93,6 +93,7 @@ where
             customer,
             &merchant_connector_account,
             None,
+            None,
         )
         .await?;
 
diff --git a/crates/router/src/core/fraud_check/flows/checkout_flow.rs b/crates/router/src/core/fraud_check/flows/checkout_flow.rs
index 74606eb5917..92dc2a99e8a 100644
--- a/crates/router/src/core/fraud_check/flows/checkout_flow.rs
+++ b/crates/router/src/core/fraud_check/flows/checkout_flow.rs
@@ -39,6 +39,7 @@ impl ConstructFlowSpecificData<frm_api::Checkout, FraudCheckCheckoutData, FraudC
         _customer: &Option<domain::Customer>,
         _merchant_connector_account: &helpers::MerchantConnectorAccountType,
         _merchant_recipient_data: Option<MerchantRecipientData>,
+        _header_payload: Option<api_models::payments::HeaderPayload>,
     ) -> RouterResult<RouterData<frm_api::Checkout, FraudCheckCheckoutData, FraudCheckResponseData>>
     {
         todo!()
@@ -54,6 +55,7 @@ impl ConstructFlowSpecificData<frm_api::Checkout, FraudCheckCheckoutData, FraudC
         customer: &Option<domain::Customer>,
         merchant_connector_account: &helpers::MerchantConnectorAccountType,
         _merchant_recipient_data: Option<MerchantRecipientData>,
+        header_payload: Option<api_models::payments::HeaderPayload>,
     ) -> RouterResult<RouterData<frm_api::Checkout, FraudCheckCheckoutData, FraudCheckResponseData>>
     {
         let status = storage_enums::AttemptStatus::Pending;
@@ -151,6 +153,8 @@ impl ConstructFlowSpecificData<frm_api::Checkout, FraudCheckCheckoutData, FraudC
             dispute_id: None,
             connector_response: None,
             integrity_check: Ok(()),
+            additional_merchant_data: None,
+            header_payload,
         };
 
         Ok(router_data)
diff --git a/crates/router/src/core/fraud_check/flows/fulfillment_flow.rs b/crates/router/src/core/fraud_check/flows/fulfillment_flow.rs
index f3eab2dd8d1..5ca790d4813 100644
--- a/crates/router/src/core/fraud_check/flows/fulfillment_flow.rs
+++ b/crates/router/src/core/fraud_check/flows/fulfillment_flow.rs
@@ -108,6 +108,8 @@ pub async fn construct_fulfillment_router_data<'a>(
         dispute_id: None,
         connector_response: None,
         integrity_check: Ok(()),
+        additional_merchant_data: None,
+        header_payload: None,
     };
     Ok(router_data)
 }
diff --git a/crates/router/src/core/fraud_check/flows/record_return.rs b/crates/router/src/core/fraud_check/flows/record_return.rs
index 6603f09cad3..e4d002931ec 100644
--- a/crates/router/src/core/fraud_check/flows/record_return.rs
+++ b/crates/router/src/core/fraud_check/flows/record_return.rs
@@ -36,6 +36,7 @@ impl ConstructFlowSpecificData<RecordReturn, FraudCheckRecordReturnData, FraudCh
         _customer: &Option<domain::Customer>,
         _merchant_connector_account: &helpers::MerchantConnectorAccountType,
         _merchant_recipient_data: Option<MerchantRecipientData>,
+        _header_payload: Option<api_models::payments::HeaderPayload>,
     ) -> RouterResult<RouterData<RecordReturn, FraudCheckRecordReturnData, FraudCheckResponseData>>
     {
         todo!()
@@ -51,6 +52,7 @@ impl ConstructFlowSpecificData<RecordReturn, FraudCheckRecordReturnData, FraudCh
         customer: &Option<domain::Customer>,
         merchant_connector_account: &helpers::MerchantConnectorAccountType,
         _merchant_recipient_data: Option<MerchantRecipientData>,
+        header_payload: Option<api_models::payments::HeaderPayload>,
     ) -> RouterResult<RouterData<RecordReturn, FraudCheckRecordReturnData, FraudCheckResponseData>>
     {
         let status = storage_enums::AttemptStatus::Pending;
@@ -120,6 +122,8 @@ impl ConstructFlowSpecificData<RecordReturn, FraudCheckRecordReturnData, FraudCh
             dispute_id: None,
             connector_response: None,
             integrity_check: Ok(()),
+            additional_merchant_data: None,
+            header_payload,
         };
 
         Ok(router_data)
diff --git a/crates/router/src/core/fraud_check/flows/sale_flow.rs b/crates/router/src/core/fraud_check/flows/sale_flow.rs
index 70006f555fe..56f6545cfd7 100644
--- a/crates/router/src/core/fraud_check/flows/sale_flow.rs
+++ b/crates/router/src/core/fraud_check/flows/sale_flow.rs
@@ -34,6 +34,7 @@ impl ConstructFlowSpecificData<frm_api::Sale, FraudCheckSaleData, FraudCheckResp
         _customer: &Option<domain::Customer>,
         _merchant_connector_account: &helpers::MerchantConnectorAccountType,
         _merchant_recipient_data: Option<MerchantRecipientData>,
+        _header_payload: Option<api_models::payments::HeaderPayload>,
     ) -> RouterResult<RouterData<frm_api::Sale, FraudCheckSaleData, FraudCheckResponseData>> {
         todo!()
     }
@@ -48,6 +49,7 @@ impl ConstructFlowSpecificData<frm_api::Sale, FraudCheckSaleData, FraudCheckResp
         customer: &Option<domain::Customer>,
         merchant_connector_account: &helpers::MerchantConnectorAccountType,
         _merchant_recipient_data: Option<MerchantRecipientData>,
+        header_payload: Option<api_models::payments::HeaderPayload>,
     ) -> RouterResult<RouterData<frm_api::Sale, FraudCheckSaleData, FraudCheckResponseData>> {
         let status = storage_enums::AttemptStatus::Pending;
 
@@ -128,6 +130,8 @@ impl ConstructFlowSpecificData<frm_api::Sale, FraudCheckSaleData, FraudCheckResp
             dispute_id: None,
             connector_response: None,
             integrity_check: Ok(()),
+            additional_merchant_data: None,
+            header_payload,
         };
 
         Ok(router_data)
diff --git a/crates/router/src/core/fraud_check/flows/transaction_flow.rs b/crates/router/src/core/fraud_check/flows/transaction_flow.rs
index ad62541155f..ebd967e7515 100644
--- a/crates/router/src/core/fraud_check/flows/transaction_flow.rs
+++ b/crates/router/src/core/fraud_check/flows/transaction_flow.rs
@@ -39,6 +39,7 @@ impl
         _customer: &Option<domain::Customer>,
         _merchant_connector_account: &helpers::MerchantConnectorAccountType,
         _merchant_recipient_data: Option<MerchantRecipientData>,
+        _header_payload: Option<api_models::payments::HeaderPayload>,
     ) -> RouterResult<
         RouterData<frm_api::Transaction, FraudCheckTransactionData, FraudCheckResponseData>,
     > {
@@ -55,6 +56,7 @@ impl
         customer: &Option<domain::Customer>,
         merchant_connector_account: &helpers::MerchantConnectorAccountType,
         _merchant_recipient_data: Option<MerchantRecipientData>,
+        header_payload: Option<api_models::payments::HeaderPayload>,
     ) -> RouterResult<
         RouterData<frm_api::Transaction, FraudCheckTransactionData, FraudCheckResponseData>,
     > {
@@ -134,6 +136,8 @@ impl
             dispute_id: None,
             connector_response: None,
             integrity_check: Ok(()),
+            additional_merchant_data: None,
+            header_payload,
         };
 
         Ok(router_data)
diff --git a/crates/router/src/core/mandate/utils.rs b/crates/router/src/core/mandate/utils.rs
index de4b0b77feb..544f9ea756e 100644
--- a/crates/router/src/core/mandate/utils.rs
+++ b/crates/router/src/core/mandate/utils.rs
@@ -78,6 +78,8 @@ pub async fn construct_mandate_revoke_router_data(
         dispute_id: None,
         connector_response: None,
         integrity_check: Ok(()),
+        additional_merchant_data: None,
+        header_payload: None,
     };
 
     Ok(router_data)
diff --git a/crates/router/src/core/payments.rs b/crates/router/src/core/payments.rs
index 0ec14bd69ed..420757048f7 100644
--- a/crates/router/src/core/payments.rs
+++ b/crates/router/src/core/payments.rs
@@ -374,6 +374,7 @@ where
                             &connector,
                             &mut payment_data,
                             op_ref,
+                            Some(header_payload.clone()),
                         )
                         .await?;
                     }
@@ -498,6 +499,7 @@ where
                             &connector_data,
                             &mut payment_data,
                             op_ref,
+                            Some(header_payload.clone()),
                         )
                         .await?;
                     }
@@ -1625,6 +1627,7 @@ where
             customer,
             &merchant_connector_account,
             merchant_recipient_data,
+            None,
         )
         .await?;
 
@@ -1958,6 +1961,7 @@ where
                 customer,
                 &merchant_connector_account,
                 None,
+                None,
             )
             .await?;
 
@@ -2103,6 +2107,7 @@ where
                         customer,
                         merchant_connector_account,
                         None,
+                        None,
                     )
                     .await?;
 
@@ -2287,6 +2292,7 @@ async fn complete_postprocessing_steps_if_required<F, Q, RouterDReq, D>(
     connector: &api::ConnectorData,
     payment_data: &mut D,
     _operation: &BoxedOperation<'_, F, Q, D>,
+    header_payload: Option<HeaderPayload>,
 ) -> RouterResult<RouterData<F, RouterDReq, router_types::PaymentsResponseData>>
 where
     F: Send + Clone + Sync,
@@ -2307,6 +2313,7 @@ where
             customer,
             merchant_conn_account,
             None,
+            header_payload,
         )
         .await?;
 
diff --git a/crates/router/src/core/payments/flows.rs b/crates/router/src/core/payments/flows.rs
index 1dec8911d31..e82af808b55 100644
--- a/crates/router/src/core/payments/flows.rs
+++ b/crates/router/src/core/payments/flows.rs
@@ -38,6 +38,7 @@ pub trait ConstructFlowSpecificData<F, Req, Res> {
         customer: &Option<domain::Customer>,
         merchant_connector_account: &helpers::MerchantConnectorAccountType,
         merchant_recipient_data: Option<types::MerchantRecipientData>,
+        header_payload: Option<api_models::payments::HeaderPayload>,
     ) -> RouterResult<types::RouterData<F, Req, Res>>;
 
     #[cfg(all(feature = "v2", feature = "customer_v2"))]
@@ -50,6 +51,7 @@ pub trait ConstructFlowSpecificData<F, Req, Res> {
         _customer: &Option<domain::Customer>,
         _merchant_connector_account: &helpers::MerchantConnectorAccountType,
         _merchant_recipient_data: Option<types::MerchantRecipientData>,
+        _header_payload: Option<api_models::payments::HeaderPayload>,
     ) -> RouterResult<types::RouterData<F, Req, Res>>;
 
     async fn get_merchant_recipient_data<'a>(
diff --git a/crates/router/src/core/payments/flows/approve_flow.rs b/crates/router/src/core/payments/flows/approve_flow.rs
index e425abce336..aba38a40cb2 100644
--- a/crates/router/src/core/payments/flows/approve_flow.rs
+++ b/crates/router/src/core/payments/flows/approve_flow.rs
@@ -25,6 +25,7 @@ impl
         customer: &Option<domain::Customer>,
         merchant_connector_account: &helpers::MerchantConnectorAccountType,
         merchant_recipient_data: Option<types::MerchantRecipientData>,
+        header_payload: Option<api_models::payments::HeaderPayload>,
     ) -> RouterResult<types::PaymentsApproveRouterData> {
         Box::pin(transformers::construct_payment_router_data::<
             api::Approve,
@@ -38,6 +39,7 @@ impl
             customer,
             merchant_connector_account,
             merchant_recipient_data,
+            header_payload,
         ))
         .await
     }
diff --git a/crates/router/src/core/payments/flows/authorize_flow.rs b/crates/router/src/core/payments/flows/authorize_flow.rs
index 0a55cefb427..ca01f377de7 100644
--- a/crates/router/src/core/payments/flows/authorize_flow.rs
+++ b/crates/router/src/core/payments/flows/authorize_flow.rs
@@ -37,6 +37,7 @@ impl
         customer: &Option<domain::Customer>,
         merchant_connector_account: &helpers::MerchantConnectorAccountType,
         merchant_recipient_data: Option<types::MerchantRecipientData>,
+        header_payload: Option<api_models::payments::HeaderPayload>,
     ) -> RouterResult<
         types::RouterData<
             api::Authorize,
@@ -56,6 +57,7 @@ impl
             customer,
             merchant_connector_account,
             merchant_recipient_data,
+            header_payload,
         ))
         .await
     }
diff --git a/crates/router/src/core/payments/flows/cancel_flow.rs b/crates/router/src/core/payments/flows/cancel_flow.rs
index a56c49611a6..144bea32592 100644
--- a/crates/router/src/core/payments/flows/cancel_flow.rs
+++ b/crates/router/src/core/payments/flows/cancel_flow.rs
@@ -25,6 +25,7 @@ impl ConstructFlowSpecificData<api::Void, types::PaymentsCancelData, types::Paym
         customer: &Option<domain::Customer>,
         merchant_connector_account: &helpers::MerchantConnectorAccountType,
         merchant_recipient_data: Option<types::MerchantRecipientData>,
+        header_payload: Option<api_models::payments::HeaderPayload>,
     ) -> RouterResult<types::PaymentsCancelRouterData> {
         Box::pin(transformers::construct_payment_router_data::<
             api::Void,
@@ -38,6 +39,7 @@ impl ConstructFlowSpecificData<api::Void, types::PaymentsCancelData, types::Paym
             customer,
             merchant_connector_account,
             merchant_recipient_data,
+            header_payload,
         ))
         .await
     }
diff --git a/crates/router/src/core/payments/flows/capture_flow.rs b/crates/router/src/core/payments/flows/capture_flow.rs
index cb37a75813b..196466d208d 100644
--- a/crates/router/src/core/payments/flows/capture_flow.rs
+++ b/crates/router/src/core/payments/flows/capture_flow.rs
@@ -25,6 +25,7 @@ impl
         customer: &Option<domain::Customer>,
         merchant_connector_account: &helpers::MerchantConnectorAccountType,
         merchant_recipient_data: Option<types::MerchantRecipientData>,
+        header_payload: Option<api_models::payments::HeaderPayload>,
     ) -> RouterResult<types::PaymentsCaptureRouterData> {
         Box::pin(transformers::construct_payment_router_data::<
             api::Capture,
@@ -38,6 +39,7 @@ impl
             customer,
             merchant_connector_account,
             merchant_recipient_data,
+            header_payload,
         ))
         .await
     }
diff --git a/crates/router/src/core/payments/flows/complete_authorize_flow.rs b/crates/router/src/core/payments/flows/complete_authorize_flow.rs
index 212fb4bc240..1335e44b660 100644
--- a/crates/router/src/core/payments/flows/complete_authorize_flow.rs
+++ b/crates/router/src/core/payments/flows/complete_authorize_flow.rs
@@ -29,6 +29,7 @@ impl
         customer: &Option<domain::Customer>,
         merchant_connector_account: &helpers::MerchantConnectorAccountType,
         merchant_recipient_data: Option<types::MerchantRecipientData>,
+        header_payload: Option<api_models::payments::HeaderPayload>,
     ) -> RouterResult<
         types::RouterData<
             api::CompleteAuthorize,
@@ -48,6 +49,7 @@ impl
             customer,
             merchant_connector_account,
             merchant_recipient_data,
+            header_payload,
         ))
         .await
     }
diff --git a/crates/router/src/core/payments/flows/incremental_authorization_flow.rs b/crates/router/src/core/payments/flows/incremental_authorization_flow.rs
index 226852e4a3c..76141537351 100644
--- a/crates/router/src/core/payments/flows/incremental_authorization_flow.rs
+++ b/crates/router/src/core/payments/flows/incremental_authorization_flow.rs
@@ -28,6 +28,7 @@ impl
         customer: &Option<domain::Customer>,
         merchant_connector_account: &helpers::MerchantConnectorAccountType,
         merchant_recipient_data: Option<types::MerchantRecipientData>,
+        header_payload: Option<api_models::payments::HeaderPayload>,
     ) -> RouterResult<types::PaymentsIncrementalAuthorizationRouterData> {
         Box::pin(transformers::construct_payment_router_data::<
             api::IncrementalAuthorization,
@@ -41,6 +42,7 @@ impl
             customer,
             merchant_connector_account,
             merchant_recipient_data,
+            header_payload,
         ))
         .await
     }
diff --git a/crates/router/src/core/payments/flows/psync_flow.rs b/crates/router/src/core/payments/flows/psync_flow.rs
index 428d170633e..ac205bcb7c8 100644
--- a/crates/router/src/core/payments/flows/psync_flow.rs
+++ b/crates/router/src/core/payments/flows/psync_flow.rs
@@ -26,6 +26,7 @@ impl ConstructFlowSpecificData<api::PSync, types::PaymentsSyncData, types::Payme
         customer: &Option<domain::Customer>,
         merchant_connector_account: &helpers::MerchantConnectorAccountType,
         merchant_recipient_data: Option<types::MerchantRecipientData>,
+        header_payload: Option<api_models::payments::HeaderPayload>,
     ) -> RouterResult<
         types::RouterData<api::PSync, types::PaymentsSyncData, types::PaymentsResponseData>,
     > {
@@ -41,6 +42,7 @@ impl ConstructFlowSpecificData<api::PSync, types::PaymentsSyncData, types::Payme
             customer,
             merchant_connector_account,
             merchant_recipient_data,
+            header_payload,
         ))
         .await
     }
diff --git a/crates/router/src/core/payments/flows/reject_flow.rs b/crates/router/src/core/payments/flows/reject_flow.rs
index d2e65c8a638..f66bdfe3dfd 100644
--- a/crates/router/src/core/payments/flows/reject_flow.rs
+++ b/crates/router/src/core/payments/flows/reject_flow.rs
@@ -24,6 +24,7 @@ impl ConstructFlowSpecificData<api::Reject, types::PaymentsRejectData, types::Pa
         customer: &Option<domain::Customer>,
         merchant_connector_account: &helpers::MerchantConnectorAccountType,
         merchant_recipient_data: Option<types::MerchantRecipientData>,
+        header_payload: Option<api_models::payments::HeaderPayload>,
     ) -> RouterResult<types::PaymentsRejectRouterData> {
         Box::pin(transformers::construct_payment_router_data::<
             api::Reject,
@@ -37,6 +38,7 @@ impl ConstructFlowSpecificData<api::Reject, types::PaymentsRejectData, types::Pa
             customer,
             merchant_connector_account,
             merchant_recipient_data,
+            header_payload,
         ))
         .await
     }
diff --git a/crates/router/src/core/payments/flows/session_flow.rs b/crates/router/src/core/payments/flows/session_flow.rs
index 54d8dc230c7..c4037a1a5b6 100644
--- a/crates/router/src/core/payments/flows/session_flow.rs
+++ b/crates/router/src/core/payments/flows/session_flow.rs
@@ -40,6 +40,7 @@ impl
         customer: &Option<domain::Customer>,
         merchant_connector_account: &helpers::MerchantConnectorAccountType,
         merchant_recipient_data: Option<types::MerchantRecipientData>,
+        header_payload: Option<api_models::payments::HeaderPayload>,
     ) -> RouterResult<types::PaymentsSessionRouterData> {
         Box::pin(transformers::construct_payment_router_data::<
             api::Session,
@@ -53,6 +54,7 @@ impl
             customer,
             merchant_connector_account,
             merchant_recipient_data,
+            header_payload,
         ))
         .await
     }
diff --git a/crates/router/src/core/payments/flows/session_update_flow.rs b/crates/router/src/core/payments/flows/session_update_flow.rs
index c12667e19a2..682c20b725d 100644
--- a/crates/router/src/core/payments/flows/session_update_flow.rs
+++ b/crates/router/src/core/payments/flows/session_update_flow.rs
@@ -28,6 +28,7 @@ impl
         customer: &Option<domain::Customer>,
         merchant_connector_account: &helpers::MerchantConnectorAccountType,
         _merchant_recipient_data: Option<types::MerchantRecipientData>,
+        _header_payload: Option<api_models::payments::HeaderPayload>,
     ) -> RouterResult<types::SdkSessionUpdateRouterData> {
         Box::pin(
             transformers::construct_router_data_to_update_calculated_tax::<
diff --git a/crates/router/src/core/payments/flows/setup_mandate_flow.rs b/crates/router/src/core/payments/flows/setup_mandate_flow.rs
index c412fd2b37f..293371024c9 100644
--- a/crates/router/src/core/payments/flows/setup_mandate_flow.rs
+++ b/crates/router/src/core/payments/flows/setup_mandate_flow.rs
@@ -32,6 +32,7 @@ impl
         customer: &Option<domain::Customer>,
         merchant_connector_account: &helpers::MerchantConnectorAccountType,
         merchant_recipient_data: Option<types::MerchantRecipientData>,
+        header_payload: Option<api_models::payments::HeaderPayload>,
     ) -> RouterResult<types::SetupMandateRouterData> {
         Box::pin(transformers::construct_payment_router_data::<
             api::SetupMandate,
@@ -45,6 +46,7 @@ impl
             customer,
             merchant_connector_account,
             merchant_recipient_data,
+            header_payload,
         ))
         .await
     }
diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs
index 2af3c52d758..9be4b02cbbd 100644
--- a/crates/router/src/core/payments/helpers.rs
+++ b/crates/router/src/core/payments/helpers.rs
@@ -3634,6 +3634,8 @@ pub fn router_data_type_conversion<F1, F2, Req1, Req2, Res1, Res2>(
         connector_response: router_data.connector_response,
         integrity_check: Ok(()),
         connector_wallets_details: router_data.connector_wallets_details,
+        additional_merchant_data: router_data.additional_merchant_data,
+        header_payload: router_data.header_payload,
     }
 }
 
diff --git a/crates/router/src/core/payments/transformers.rs b/crates/router/src/core/payments/transformers.rs
index 93fa3ed44b8..de48f7e700a 100644
--- a/crates/router/src/core/payments/transformers.rs
+++ b/crates/router/src/core/payments/transformers.rs
@@ -151,6 +151,8 @@ where
         dispute_id: None,
         connector_response: None,
         integrity_check: Ok(()),
+        additional_merchant_data: None,
+        header_payload: None,
     };
     Ok(router_data)
 }
@@ -167,6 +169,7 @@ pub async fn construct_payment_router_data<'a, F, T>(
     _customer: &'a Option<domain::Customer>,
     _merchant_connector_account: &helpers::MerchantConnectorAccountType,
     _merchant_recipient_data: Option<types::MerchantRecipientData>,
+    _header_payload: Option<api_models::payments::HeaderPayload>,
 ) -> RouterResult<types::RouterData<F, T, types::PaymentsResponseData>>
 where
     T: TryFrom<PaymentAdditionalData<'a, F>>,
@@ -190,6 +193,7 @@ pub async fn construct_payment_router_data<'a, F, T>(
     customer: &'a Option<domain::Customer>,
     merchant_connector_account: &helpers::MerchantConnectorAccountType,
     merchant_recipient_data: Option<types::MerchantRecipientData>,
+    header_payload: Option<api_models::payments::HeaderPayload>,
 ) -> RouterResult<types::RouterData<F, T, types::PaymentsResponseData>>
 where
     T: TryFrom<PaymentAdditionalData<'a, F>>,
@@ -318,14 +322,7 @@ where
             .payment_attempt
             .authentication_type
             .unwrap_or_default(),
-        connector_meta_data: if let Some(data) = merchant_recipient_data {
-            let val = serde_json::to_value(data)
-                .change_context(errors::ApiErrorResponse::InternalServerError)
-                .attach_printable("Failed while encoding MerchantRecipientData")?;
-            Some(Secret::new(val))
-        } else {
-            merchant_connector_account.get_metadata()
-        },
+        connector_meta_data: merchant_connector_account.get_metadata(),
         connector_wallets_details: merchant_connector_account.get_connector_wallets_details(),
         request: T::try_from(additional_data)?,
         response,
@@ -364,6 +361,12 @@ where
         dispute_id: None,
         connector_response: None,
         integrity_check: Ok(()),
+        additional_merchant_data: merchant_recipient_data.map(|data| {
+            api_models::admin::AdditionalMerchantData::foreign_from(
+                types::AdditionalMerchantData::OpenBankingRecipientData(data),
+            )
+        }),
+        header_payload,
     };
 
     Ok(router_data)
diff --git a/crates/router/src/core/payouts.rs b/crates/router/src/core/payouts.rs
index 85d5b78521f..6c8ad32234c 100644
--- a/crates/router/src/core/payouts.rs
+++ b/crates/router/src/core/payouts.rs
@@ -717,13 +717,13 @@ pub async fn payouts_fulfill_core(
         .await?
         .get_required_value("payout_method_data")?,
     );
-    fulfill_payout(
+    Box::pin(fulfill_payout(
         &state,
         &merchant_account,
         &key_store,
         &connector_data,
         &mut payout_data,
-    )
+    ))
     .await
     .attach_printable("Payout fulfillment failed for given Payout request")?;
 
@@ -1121,13 +1121,13 @@ pub async fn call_connector_payout(
     // Auto fulfillment flow
     let status = payout_data.payout_attempt.status;
     if payouts.auto_fulfill && status == storage_enums::PayoutStatus::RequiresFulfillment {
-        fulfill_payout(
+        Box::pin(fulfill_payout(
             state,
             merchant_account,
             key_store,
             connector_data,
             payout_data,
-        )
+        ))
         .await
         .attach_printable("Payout fulfillment failed for given Payout request")?;
     }
diff --git a/crates/router/src/core/pm_auth.rs b/crates/router/src/core/pm_auth.rs
index f948d7faaf9..78b06a421af 100644
--- a/crates/router/src/core/pm_auth.rs
+++ b/crates/router/src/core/pm_auth.rs
@@ -165,6 +165,9 @@ pub async fn create_link_token(
             )?]),
             language: payload.language,
             user_info: payment_intent.and_then(|pi| pi.customer_id),
+            client_platform: payload.client_platform,
+            android_package_name: payload.android_package_name,
+            redirect_uri: payload.redirect_uri,
         },
         response: Ok(pm_auth_types::LinkTokenResponse {
             link_token: "".to_string(),
diff --git a/crates/router/src/core/refunds.rs b/crates/router/src/core/refunds.rs
index 0f7abf44b14..a45b3be8a3c 100644
--- a/crates/router/src/core/refunds.rs
+++ b/crates/router/src/core/refunds.rs
@@ -1185,7 +1185,7 @@ pub async fn schedule_refund_execution(
                             Ok(refund)
                         }
                         api_models::refunds::RefundType::Instant => {
-                            let update_refund = trigger_refund_to_gateway(
+                            let update_refund = Box::pin(trigger_refund_to_gateway(
                                 state,
                                 &refund,
                                 merchant_account,
@@ -1194,7 +1194,7 @@ pub async fn schedule_refund_execution(
                                 payment_intent,
                                 creds_identifier,
                                 charges,
-                            )
+                            ))
                             .await;
 
                             match update_refund {
@@ -1438,7 +1438,7 @@ pub async fn trigger_refund_execute_workflow(
             };
 
             //trigger refund request to gateway
-            let updated_refund = trigger_refund_to_gateway(
+            let updated_refund = Box::pin(trigger_refund_to_gateway(
                 state,
                 &refund,
                 &merchant_account,
@@ -1447,7 +1447,7 @@ pub async fn trigger_refund_execute_workflow(
                 &payment_intent,
                 None,
                 charges,
-            )
+            ))
             .await?;
             add_refund_sync_task(
                 db,
diff --git a/crates/router/src/core/utils.rs b/crates/router/src/core/utils.rs
index 0e8b21f3a8a..8e86fb86967 100644
--- a/crates/router/src/core/utils.rs
+++ b/crates/router/src/core/utils.rs
@@ -215,6 +215,8 @@ pub async fn construct_payout_router_data<'a, F>(
         dispute_id: None,
         connector_response: None,
         integrity_check: Ok(()),
+        additional_merchant_data: None,
+        header_payload: None,
     };
 
     Ok(router_data)
@@ -370,6 +372,8 @@ pub async fn construct_refund_router_data<'a, F>(
         dispute_id: None,
         connector_response: None,
         integrity_check: Ok(()),
+        additional_merchant_data: None,
+        header_payload: None,
     };
 
     Ok(router_data)
@@ -677,6 +681,8 @@ pub async fn construct_accept_dispute_router_data<'a>(
         refund_id: None,
         connector_response: None,
         integrity_check: Ok(()),
+        additional_merchant_data: None,
+        header_payload: None,
     };
     Ok(router_data)
 }
@@ -769,6 +775,8 @@ pub async fn construct_submit_evidence_router_data<'a>(
         dispute_id: Some(dispute.dispute_id.clone()),
         connector_response: None,
         integrity_check: Ok(()),
+        additional_merchant_data: None,
+        header_payload: None,
     };
     Ok(router_data)
 }
@@ -867,6 +875,8 @@ pub async fn construct_upload_file_router_data<'a>(
         dispute_id: None,
         connector_response: None,
         integrity_check: Ok(()),
+        additional_merchant_data: None,
+        header_payload: None,
     };
     Ok(router_data)
 }
@@ -974,6 +984,8 @@ pub async fn construct_payments_dynamic_tax_calculation_router_data<'a, F: Clone
         payment_method_status: None,
         minor_amount_captured: None,
         integrity_check: Ok(()),
+        additional_merchant_data: None,
+        header_payload: None,
     };
     Ok(router_data)
 }
@@ -1069,6 +1081,8 @@ pub async fn construct_defend_dispute_router_data<'a>(
         dispute_id: Some(dispute.dispute_id.clone()),
         connector_response: None,
         integrity_check: Ok(()),
+        additional_merchant_data: None,
+        header_payload: None,
     };
     Ok(router_data)
 }
@@ -1159,6 +1173,8 @@ pub async fn construct_retrieve_file_router_data<'a>(
         dispute_id: None,
         connector_response: None,
         integrity_check: Ok(()),
+        additional_merchant_data: None,
+        header_payload: None,
     };
     Ok(router_data)
 }
diff --git a/crates/router/src/core/webhooks/utils.rs b/crates/router/src/core/webhooks/utils.rs
index 8987a9384df..8680e43eff3 100644
--- a/crates/router/src/core/webhooks/utils.rs
+++ b/crates/router/src/core/webhooks/utils.rs
@@ -120,6 +120,8 @@ pub async fn construct_webhook_router_data<'a>(
         dispute_id: None,
         connector_response: None,
         integrity_check: Ok(()),
+        additional_merchant_data: None,
+        header_payload: None,
     };
     Ok(router_data)
 }
diff --git a/crates/router/src/lib.rs b/crates/router/src/lib.rs
index caa96826937..b18c9ff4e80 100644
--- a/crates/router/src/lib.rs
+++ b/crates/router/src/lib.rs
@@ -83,6 +83,8 @@ pub mod headers {
     pub const BROWSER_NAME: &str = "x-browser-name";
     pub const X_CLIENT_PLATFORM: &str = "x-client-platform";
     pub const X_MERCHANT_DOMAIN: &str = "x-merchant-domain";
+    pub const X_APP_ID: &str = "x-app-id";
+    pub const X_REDIRECT_URI: &str = "x-redirect-uri";
     pub const X_TENANT_ID: &str = "x-tenant-id";
 }
 
diff --git a/crates/router/src/services/conversion_impls.rs b/crates/router/src/services/conversion_impls.rs
index f1aec19bd30..22930916093 100644
--- a/crates/router/src/services/conversion_impls.rs
+++ b/crates/router/src/services/conversion_impls.rs
@@ -74,6 +74,8 @@ fn get_default_router_data<F, Req, Resp>(
         payment_method_status: None,
         minor_amount_captured: None,
         integrity_check: Ok(()),
+        additional_merchant_data: None,
+        header_payload: None,
     }
 }
 
diff --git a/crates/router/src/types.rs b/crates/router/src/types.rs
index 16a8ed1ccc4..27fa1e1ced0 100644
--- a/crates/router/src/types.rs
+++ b/crates/router/src/types.rs
@@ -906,6 +906,8 @@ impl<F1, F2, T1, T2> ForeignFrom<(&RouterData<F1, T1, PaymentsResponseData>, T2)
             refund_id: data.refund_id.clone(),
             connector_response: data.connector_response.clone(),
             integrity_check: Ok(()),
+            additional_merchant_data: data.additional_merchant_data.clone(),
+            header_payload: data.header_payload.clone(),
         }
     }
 }
@@ -968,6 +970,8 @@ impl<F1, F2>
             dispute_id: None,
             connector_response: data.connector_response.clone(),
             integrity_check: Ok(()),
+            additional_merchant_data: data.additional_merchant_data.clone(),
+            header_payload: data.header_payload.clone(),
         }
     }
 }
diff --git a/crates/router/src/types/api/verify_connector.rs b/crates/router/src/types/api/verify_connector.rs
index 1b3162a3549..6c92b1b801a 100644
--- a/crates/router/src/types/api/verify_connector.rs
+++ b/crates/router/src/types/api/verify_connector.rs
@@ -113,6 +113,8 @@ impl VerifyConnectorData {
             dispute_id: None,
             connector_response: None,
             integrity_check: Ok(()),
+            additional_merchant_data: None,
+            header_payload: None,
         }
     }
 }
diff --git a/crates/router/src/types/transformers.rs b/crates/router/src/types/transformers.rs
index 46210d4dd09..3df2299a2ae 100644
--- a/crates/router/src/types/transformers.rs
+++ b/crates/router/src/types/transformers.rs
@@ -21,8 +21,8 @@ use super::domain;
 use crate::{
     core::errors,
     headers::{
-        ACCEPT_LANGUAGE, BROWSER_NAME, X_CLIENT_PLATFORM, X_CLIENT_SOURCE, X_CLIENT_VERSION,
-        X_MERCHANT_DOMAIN, X_PAYMENT_CONFIRM_SOURCE,
+        ACCEPT_LANGUAGE, BROWSER_NAME, X_APP_ID, X_CLIENT_PLATFORM, X_CLIENT_SOURCE,
+        X_CLIENT_VERSION, X_MERCHANT_DOMAIN, X_PAYMENT_CONFIRM_SOURCE, X_REDIRECT_URI,
     },
     services::authentication::get_header_value_by_key,
     types::{
@@ -1420,6 +1420,12 @@ impl ForeignTryFrom<&HeaderMap> for payments::HeaderPayload {
         let x_merchant_domain =
             get_header_value_by_key(X_MERCHANT_DOMAIN.into(), headers)?.map(|val| val.to_string());
 
+        let x_app_id =
+            get_header_value_by_key(X_APP_ID.into(), headers)?.map(|val| val.to_string());
+
+        let x_redirect_uri =
+            get_header_value_by_key(X_REDIRECT_URI.into(), headers)?.map(|val| val.to_string());
+
         Ok(Self {
             payment_confirm_source,
             client_source,
@@ -1429,6 +1435,8 @@ impl ForeignTryFrom<&HeaderMap> for payments::HeaderPayload {
             x_client_platform,
             x_merchant_domain,
             locale,
+            x_app_id,
+            x_redirect_uri,
         })
     }
 }
diff --git a/crates/router/tests/connectors/aci.rs b/crates/router/tests/connectors/aci.rs
index f3ff1a60361..5d48a0188ff 100644
--- a/crates/router/tests/connectors/aci.rs
+++ b/crates/router/tests/connectors/aci.rs
@@ -126,6 +126,8 @@ fn construct_payment_router_data() -> types::PaymentsAuthorizeRouterData {
         refund_id: None,
         dispute_id: None,
         integrity_check: Ok(()),
+        additional_merchant_data: None,
+        header_payload: None,
     }
 }
 
@@ -193,6 +195,8 @@ fn construct_refund_router_data<F>() -> types::RefundsRouterData<F> {
         refund_id: None,
         dispute_id: None,
         integrity_check: Ok(()),
+        additional_merchant_data: None,
+        header_payload: None,
     }
 }
 
diff --git a/crates/router/tests/connectors/utils.rs b/crates/router/tests/connectors/utils.rs
index ea12d463fbd..582c212c241 100644
--- a/crates/router/tests/connectors/utils.rs
+++ b/crates/router/tests/connectors/utils.rs
@@ -544,6 +544,8 @@ pub trait ConnectorActions: Connector {
             dispute_id: None,
             connector_response: None,
             integrity_check: Ok(()),
+            additional_merchant_data: None,
+            header_payload: None,
         }
     }
 

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

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

## Description
<!-- Describe your changes in detail -->
- Refactored RouterData to use HeaderPayload for Android/IOS Platform specific flows.
- Refactored Open banking flows to consume and process the header information to take decisions based on client platform.


### Additional Changes

- [ ] 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).
-->


## 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. Payments create - 
```
curl --location --request POST 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_uFcNSTN14N27NiyGdgkK8eN2fBmPWHHhbPZh6RMkBUxoByMfAdPlBItplwGctI6P' \
--data-raw '{
    "amount": 6500,
    "currency": "EUR",
    "confirm": false,
    "capture_method": "automatic",
    "capture_on": "2022-09-10T10:11:12Z",
    "email": "guest@example.com",
    "name": "John Doe", 
    "phone": "999999999",
    "phone_country_code": "+1",
    "description": "Its my first payment request",
    "authentication_type": "no_three_ds",
    "return_url": "https://google.com",
    "billing": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "GB",
            "first_name": "john",
            "last_name": "Doe"
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+91"
        }
    },
    "shipping": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "GB",
            "first_name": "joseph",
            "last_name": "Doe"
        },
        "phone": {
            "number": "8056594430",
            "country_code": "+91"
        }
    },
    "statement_descriptor_name": "joseph",
    "statement_descriptor_suffix": "JS",
    "metadata": {
        "udf1": "value1",
        "new_customer": "true",
        "login_date": "2019-09-10T10:11:12Z"
    }
}'
```
Response 
```
{
    "payment_id": "pay_qrNjDvodTni9SiSVeukh",
    "merchant_id": "merchant_1726386502",
    "status": "requires_payment_method",
    "amount": 6500,
    "net_amount": 6500,
    "amount_capturable": 0,
    "amount_received": null,
    "connector": null,
    "client_secret": "pay_qrNjDvodTni9SiSVeukh_secret_Y14Mk7PkltuhrpuVCqAI",
    "created": "2024-09-15T07:50:42.333Z",
    "currency": "EUR",
    "customer_id": null,
    "customer": {
        "id": null,
        "name": "John Doe",
        "email": "guest@example.com",
        "phone": "999999999",
        "phone_country_code": "+1"
    },
    "description": "Its my first payment request",
    "refunds": null,
    "disputes": null,
    "mandate_id": null,
    "mandate_data": null,
    "setup_future_usage": null,
    "off_session": null,
    "capture_on": null,
    "capture_method": "automatic",
    "payment_method": null,
    "payment_method_data": null,
    "payment_token": null,
    "shipping": {
        "address": {
            "city": "San Fransico",
            "country": "GB",
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "zip": "94122",
            "state": "California",
            "first_name": "joseph",
            "last_name": "Doe"
        },
        "phone": {
            "number": "8056594430",
            "country_code": "+91"
        },
        "email": null
    },
    "billing": {
        "address": {
            "city": "San Fransico",
            "country": "GB",
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "zip": "94122",
            "state": "California",
            "first_name": "john",
            "last_name": "Doe"
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+91"
        },
        "email": null
    },
    "order_details": null,
    "email": null,
    "name": null,
    "phone": null,
    "return_url": "https://google.com/",
    "authentication_type": "no_three_ds",
    "statement_descriptor_name": "joseph",
    "statement_descriptor_suffix": "JS",
    "next_action": null,
    "cancellation_reason": null,
    "error_code": null,
    "error_message": null,
    "unified_code": null,
    "unified_message": null,
    "payment_experience": null,
    "payment_method_type": null,
    "connector_label": null,
    "business_country": null,
    "business_label": "default",
    "business_sub_label": null,
    "allowed_payment_method_types": null,
    "ephemeral_key": null,
    "manual_retry_allowed": null,
    "connector_transaction_id": null,
    "frm_message": null,
    "metadata": {
        "udf1": "value1",
        "login_date": "2019-09-10T10:11:12Z",
        "new_customer": "true"
    },
    "connector_metadata": null,
    "feature_metadata": null,
    "reference_id": null,
    "payment_link": null,
    "profile_id": "pro_72r0N5WGBqazqsPQluK8",
    "surcharge_details": null,
    "attempt_count": 1,
    "merchant_decision": null,
    "merchant_connector_id": null,
    "incremental_authorization_allowed": null,
    "authorization_count": null,
    "incremental_authorizations": null,
    "external_authentication_details": null,
    "external_3ds_authentication_attempted": false,
    "expires_on": "2024-09-15T08:05:42.333Z",
    "fingerprint": null,
    "browser_info": null,
    "payment_method_id": null,
    "payment_method_status": null,
    "updated": "2024-09-15T07:50:42.348Z",
    "charges": null,
    "frm_metadata": null,
    "merchant_order_reference_id": null,
    "order_tax_amount": null
}
```
2. PML - 
```
curl --location --request GET 'http://localhost:8080/account/payment_methods?client_secret=pay_qrNjDvodTni9SiSVeukh_secret_Y14Mk7PkltuhrpuVCqAI' \
--header 'Accept: application/json' \
--header 'api-key: pk_dev_18865dbf242d48158d05eb8b49a55251'
```
Response - 
```
{
    "redirect_url": "https://google.com/success",
    "currency": "EUR",
    "payment_methods": [
        {
            "payment_method": "open_banking",
            "payment_method_types": [
                {
                    "payment_method_type": "open_banking_pis",
                    "payment_experience": [
                        {
                            "payment_experience_type": "redirect_to_url",
                            "eligible_connectors": [
                                "plaid"
                            ]
                        }
                    ],
                    "card_networks": null,
                    "bank_names": null,
                    "bank_debits": null,
                    "bank_transfers": null,
                    "required_fields": null,
                    "surcharge_details": null,
                    "pm_auth_connector": null
                }
            ]
        }
    ],
    "mandate_payment": null,
    "merchant_name": "Sarthak1",
    "show_surcharge_breakup_screen": false,
    "payment_type": "normal",
    "request_external_three_ds_authentication": false,
    "collect_shipping_details_from_wallets": false,
    "collect_billing_details_from_wallets": false,
    "is_tax_calculation_enabled": false
}
```
3. Payments confirm - 
```
curl --location --request POST 'http://localhost:8080/payments/pay_qrNjDvodTni9SiSVeukh/confirm' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'x-client-platform: android' \
--header 'x-app-id: io.hyperswitch' \
--header 'api-key: pk_dev_18865dbf242d48158d05eb8b49a55251' \
--data-raw '{
    "client_secret": "pay_qrNjDvodTni9SiSVeukh_secret_Y14Mk7PkltuhrpuVCqAI",
    "payment_method": "open_banking",
    "payment_method_type": "open_banking_pis",
    "payment_method_data": {
        "open_banking": {
            "open_banking_pis": {}
        }
    }
}'
```
Response - 
```
{
    "payment_id": "pay_qrNjDvodTni9SiSVeukh",
    "merchant_id": "merchant_1726386502",
    "status": "requires_customer_action",
    "amount": 6500,
    "net_amount": 6500,
    "amount_capturable": 6500,
    "amount_received": null,
    "connector": "plaid",
    "client_secret": "pay_qrNjDvodTni9SiSVeukh_secret_Y14Mk7PkltuhrpuVCqAI",
    "created": "2024-09-15T07:50:42.333Z",
    "currency": "EUR",
    "customer_id": null,
    "customer": {
        "id": null,
        "name": "John Doe",
        "email": "guest@example.com",
        "phone": "999999999",
        "phone_country_code": "+1"
    },
    "description": "Its my first payment request",
    "refunds": null,
    "disputes": null,
    "mandate_id": null,
    "mandate_data": null,
    "setup_future_usage": null,
    "off_session": null,
    "capture_on": null,
    "capture_method": "automatic",
    "payment_method": "open_banking",
    "payment_method_data": {
        "open_banking": {
            "open_banking_pis": {}
        },
        "billing": null
    },
    "payment_token": null,
    "shipping": {
        "address": {
            "city": "San Fransico",
            "country": "GB",
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "zip": "94122",
            "state": "California",
            "first_name": "joseph",
            "last_name": "Doe"
        },
        "phone": {
            "number": "8056594430",
            "country_code": "+91"
        },
        "email": null
    },
    "billing": {
        "address": {
            "city": "San Fransico",
            "country": "GB",
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "zip": "94122",
            "state": "California",
            "first_name": "john",
            "last_name": "Doe"
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+91"
        },
        "email": null
    },
    "order_details": null,
    "email": null,
    "name": null,
    "phone": null,
    "return_url": "https://google.com/",
    "authentication_type": "no_three_ds",
    "statement_descriptor_name": "joseph",
    "statement_descriptor_suffix": "JS",
    "next_action": {
        "type": "third_party_sdk_session_token",
        "session_token": {
            "wallet_name": "open_banking",
            "open_banking_session_token": "link-sandbox-9e376cad-8ab2-40f7-b0a0-4744d06a003b"
        }
    },
    "cancellation_reason": null,
    "error_code": null,
    "error_message": null,
    "unified_code": null,
    "unified_message": null,
    "payment_experience": null,
    "payment_method_type": "open_banking_pis",
    "connector_label": null,
    "business_country": null,
    "business_label": "default",
    "business_sub_label": null,
    "allowed_payment_method_types": null,
    "ephemeral_key": null,
    "manual_retry_allowed": null,
    "connector_transaction_id": "payment-id-sandbox-adcf53a4-c1ff-46d9-81c2-8e8bfa0d6db2",
    "frm_message": null,
    "metadata": {
        "udf1": "value1",
        "login_date": "2019-09-10T10:11:12Z",
        "new_customer": "true"
    },
    "connector_metadata": null,
    "feature_metadata": null,
    "reference_id": "payment-id-sandbox-adcf53a4-c1ff-46d9-81c2-8e8bfa0d6db2",
    "payment_link": null,
    "profile_id": "pro_72r0N5WGBqazqsPQluK8",
    "surcharge_details": null,
    "attempt_count": 1,
    "merchant_decision": null,
    "merchant_connector_id": "mca_jp7RozkyIQV4e9zTXjyf",
    "incremental_authorization_allowed": null,
    "authorization_count": null,
    "incremental_authorizations": null,
    "external_authentication_details": null,
    "external_3ds_authentication_attempted": false,
    "expires_on": "2024-09-15T08:05:42.333Z",
    "fingerprint": null,
    "browser_info": {
        "language": null,
        "time_zone": null,
        "ip_address": "::1",
        "user_agent": null,
        "color_depth": null,
        "java_enabled": null,
        "screen_width": null,
        "accept_header": null,
        "screen_height": null,
        "java_script_enabled": null
    },
    "payment_method_id": null,
    "payment_method_status": null,
    "updated": "2024-09-15T07:51:02.510Z",
    "charges": null,
    "frm_metadata": null,
    "merchant_order_reference_id": null,
    "order_tax_amount": null
}
```

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