Bug: store network transaction id only when pg_agnostic config is enabled in the authorize_flow



Currently there is no validation while storing the network transaction id in the authorize flow. As network transaction is only being used for the processor agnostic MITs it should be stored only if the `pg_agnostic` flag is enabled.
diff --git a/crates/router/src/connector/stripe/transformers.rs b/crates/router/src/connector/stripe/transformers.rs
index 7d1862b2068..e22942fecd6 100644
--- a/crates/router/src/connector/stripe/transformers.rs
+++ b/crates/router/src/connector/stripe/transformers.rs
@@ -2664,12 +2664,23 @@ impl<F, T>
                 item.response.id.clone(),
             ))
         } else {
+            let network_transaction_id = match item.response.latest_charge.clone() {
+                Some(StripeChargeEnum::ChargeObject(charge_object)) => charge_object
+                    .payment_method_details
+                    .and_then(|payment_method_details| match payment_method_details {
+                        StripePaymentMethodDetailsResponse::Card { card } => {
+                            card.network_transaction_id
+                        }
+                        _ => None,
+                    }),
+                _ => None,
+            };
             Ok(types::PaymentsResponseData::TransactionResponse {
                 resource_id: types::ResponseId::ConnectorTransactionId(item.response.id.clone()),
                 redirection_data,
                 mandate_reference,
                 connector_metadata,
-                network_txn_id: None,
+                network_txn_id: network_transaction_id,
                 connector_response_reference_id: Some(item.response.id.clone()),
                 incremental_authorization_allowed: None,
             })
diff --git a/crates/router/src/core/payments.rs b/crates/router/src/core/payments.rs
index 22f7cb311c6..91b1d7f3190 100644
--- a/crates/router/src/core/payments.rs
+++ b/crates/router/src/core/payments.rs
@@ -1347,6 +1347,7 @@ where
                 merchant_account,
                 connector_request,
                 key_store,
+                payment_data.payment_intent.profile_id.clone(),
             )
             .await
     } else {
@@ -1475,6 +1476,7 @@ where
             merchant_account,
             None,
             key_store,
+            payment_data.payment_intent.profile_id.clone(),
         );
 
         join_handlers.push(res);
@@ -3069,6 +3071,7 @@ pub async fn decide_multiplex_connector_for_normal_or_recurring_payment<F: Clone
                     connector_data.connector_name,
                     payment_method_info,
                 ) {
+                    logger::info!("using network_transaction_id for MIT flow");
                     let network_transaction_id = payment_method_info
                         .network_transaction_id
                         .as_ref()
diff --git a/crates/router/src/core/payments/flows.rs b/crates/router/src/core/payments/flows.rs
index 6c952dc2593..abe23016f7d 100644
--- a/crates/router/src/core/payments/flows.rs
+++ b/crates/router/src/core/payments/flows.rs
@@ -49,6 +49,7 @@ pub trait Feature<F, T> {
         merchant_account: &domain::MerchantAccount,
         connector_request: Option<services::Request>,
         key_store: &domain::MerchantKeyStore,
+        profile_id: Option<String>,
     ) -> RouterResult<Self>
     where
         Self: Sized,
diff --git a/crates/router/src/core/payments/flows/approve_flow.rs b/crates/router/src/core/payments/flows/approve_flow.rs
index 14b710de914..43e36847eb9 100644
--- a/crates/router/src/core/payments/flows/approve_flow.rs
+++ b/crates/router/src/core/payments/flows/approve_flow.rs
@@ -54,6 +54,7 @@ impl Feature<api::Approve, types::PaymentsApproveData>
         _merchant_account: &domain::MerchantAccount,
         _connector_request: Option<services::Request>,
         _key_store: &domain::MerchantKeyStore,
+        _profile_id: Option<String>,
     ) -> RouterResult<Self> {
         Err(ApiErrorResponse::NotImplemented {
             message: NotImplementedMessage::Reason("Flow not supported".to_string()),
diff --git a/crates/router/src/core/payments/flows/authorize_flow.rs b/crates/router/src/core/payments/flows/authorize_flow.rs
index f891f44f099..cccfab5a74b 100644
--- a/crates/router/src/core/payments/flows/authorize_flow.rs
+++ b/crates/router/src/core/payments/flows/authorize_flow.rs
@@ -66,6 +66,7 @@ impl Feature<api::Authorize, types::PaymentsAuthorizeData> for types::PaymentsAu
         merchant_account: &domain::MerchantAccount,
         connector_request: Option<services::Request>,
         key_store: &domain::MerchantKeyStore,
+        profile_id: Option<String>,
     ) -> RouterResult<Self> {
         let connector_integration: services::BoxedConnectorIntegration<
             '_,
@@ -103,6 +104,7 @@ impl Feature<api::Authorize, types::PaymentsAuthorizeData> for types::PaymentsAu
                         key_store,
                         Some(resp.request.amount),
                         Some(resp.request.currency),
+                        profile_id,
                     ))
                     .await?;
 
@@ -132,6 +134,7 @@ impl Feature<api::Authorize, types::PaymentsAuthorizeData> for types::PaymentsAu
                     key_store,
                     Some(resp.request.amount),
                     Some(resp.request.currency),
+                    profile_id,
                 ))
                 .await;
 
diff --git a/crates/router/src/core/payments/flows/cancel_flow.rs b/crates/router/src/core/payments/flows/cancel_flow.rs
index 5918380ee0b..5814b1cafb1 100644
--- a/crates/router/src/core/payments/flows/cancel_flow.rs
+++ b/crates/router/src/core/payments/flows/cancel_flow.rs
@@ -53,6 +53,7 @@ impl Feature<api::Void, types::PaymentsCancelData>
         _merchant_account: &domain::MerchantAccount,
         connector_request: Option<services::Request>,
         _key_store: &domain::MerchantKeyStore,
+        _profile_id: Option<String>,
     ) -> RouterResult<Self> {
         metrics::PAYMENT_CANCEL_COUNT.add(
             &metrics::CONTEXT,
diff --git a/crates/router/src/core/payments/flows/capture_flow.rs b/crates/router/src/core/payments/flows/capture_flow.rs
index d2b7c8e91bd..5f64014bce7 100644
--- a/crates/router/src/core/payments/flows/capture_flow.rs
+++ b/crates/router/src/core/payments/flows/capture_flow.rs
@@ -54,6 +54,7 @@ impl Feature<api::Capture, types::PaymentsCaptureData>
         _merchant_account: &domain::MerchantAccount,
         connector_request: Option<services::Request>,
         _key_store: &domain::MerchantKeyStore,
+        _profile_id: Option<String>,
     ) -> RouterResult<Self> {
         let connector_integration: services::BoxedConnectorIntegration<
             '_,
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 68d0ee8d475..e64240387d2 100644
--- a/crates/router/src/core/payments/flows/complete_authorize_flow.rs
+++ b/crates/router/src/core/payments/flows/complete_authorize_flow.rs
@@ -68,6 +68,7 @@ impl Feature<api::CompleteAuthorize, types::CompleteAuthorizeData>
         _merchant_account: &domain::MerchantAccount,
         connector_request: Option<services::Request>,
         _key_store: &domain::MerchantKeyStore,
+        _profile_id: Option<String>,
     ) -> RouterResult<Self> {
         let connector_integration: services::BoxedConnectorIntegration<
             '_,
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 387916bab7c..99f8e4831bb 100644
--- a/crates/router/src/core/payments/flows/incremental_authorization_flow.rs
+++ b/crates/router/src/core/payments/flows/incremental_authorization_flow.rs
@@ -61,6 +61,7 @@ impl Feature<api::IncrementalAuthorization, types::PaymentsIncrementalAuthorizat
         _merchant_account: &domain::MerchantAccount,
         connector_request: Option<services::Request>,
         _key_store: &domain::MerchantKeyStore,
+        _profile_id: Option<String>,
     ) -> RouterResult<Self> {
         let connector_integration: services::BoxedConnectorIntegration<
             '_,
diff --git a/crates/router/src/core/payments/flows/psync_flow.rs b/crates/router/src/core/payments/flows/psync_flow.rs
index cb7a764985d..6463e87279b 100644
--- a/crates/router/src/core/payments/flows/psync_flow.rs
+++ b/crates/router/src/core/payments/flows/psync_flow.rs
@@ -57,6 +57,7 @@ impl Feature<api::PSync, types::PaymentsSyncData>
         _merchant_account: &domain::MerchantAccount,
         connector_request: Option<services::Request>,
         _key_store: &domain::MerchantKeyStore,
+        _profile_id: Option<String>,
     ) -> RouterResult<Self> {
         let connector_integration: services::BoxedConnectorIntegration<
             '_,
diff --git a/crates/router/src/core/payments/flows/reject_flow.rs b/crates/router/src/core/payments/flows/reject_flow.rs
index 910cc955e63..4157edf8d0a 100644
--- a/crates/router/src/core/payments/flows/reject_flow.rs
+++ b/crates/router/src/core/payments/flows/reject_flow.rs
@@ -53,6 +53,7 @@ impl Feature<api::Reject, types::PaymentsRejectData>
         _merchant_account: &domain::MerchantAccount,
         _connector_request: Option<services::Request>,
         _key_store: &domain::MerchantKeyStore,
+        _profile_id: Option<String>,
     ) -> RouterResult<Self> {
         Err(ApiErrorResponse::NotImplemented {
             message: NotImplementedMessage::Reason("Flow not supported".to_string()),
diff --git a/crates/router/src/core/payments/flows/session_flow.rs b/crates/router/src/core/payments/flows/session_flow.rs
index 349c76cd23a..1ab72dff15b 100644
--- a/crates/router/src/core/payments/flows/session_flow.rs
+++ b/crates/router/src/core/payments/flows/session_flow.rs
@@ -58,6 +58,7 @@ impl Feature<api::Session, types::PaymentsSessionData> for types::PaymentsSessio
         _merchant_account: &domain::MerchantAccount,
         _connector_request: Option<services::Request>,
         _key_store: &domain::MerchantKeyStore,
+        _profile_id: Option<String>,
     ) -> RouterResult<Self> {
         metrics::SESSION_TOKEN_CREATED.add(
             &metrics::CONTEXT,
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 27204450a0a..d8acfe98f3b 100644
--- a/crates/router/src/core/payments/flows/setup_mandate_flow.rs
+++ b/crates/router/src/core/payments/flows/setup_mandate_flow.rs
@@ -62,6 +62,7 @@ impl Feature<api::SetupMandate, types::SetupMandateRequestData> for types::Setup
         merchant_account: &domain::MerchantAccount,
         connector_request: Option<services::Request>,
         key_store: &domain::MerchantKeyStore,
+        profile_id: Option<String>,
     ) -> RouterResult<Self> {
         if let Some(mandate_id) = self
             .request
@@ -79,6 +80,7 @@ impl Feature<api::SetupMandate, types::SetupMandateRequestData> for types::Setup
                 &state.conf.mandates.update_mandate_supported,
                 connector_request,
                 maybe_customer,
+                profile_id,
             ))
             .await
         } else {
@@ -109,6 +111,7 @@ impl Feature<api::SetupMandate, types::SetupMandateRequestData> for types::Setup
                 key_store,
                 resp.request.amount,
                 Some(resp.request.currency),
+                profile_id,
             ))
             .await?;
 
@@ -217,6 +220,7 @@ impl types::SetupMandateRouterData {
         call_connector_action: payments::CallConnectorAction,
         merchant_account: &domain::MerchantAccount,
         key_store: &domain::MerchantKeyStore,
+        profile_id: Option<String>,
     ) -> RouterResult<Self> {
         match confirm {
             Some(true) => {
@@ -248,6 +252,7 @@ impl types::SetupMandateRouterData {
                     key_store,
                     resp.request.amount,
                     Some(resp.request.currency),
+                    profile_id,
                 ))
                 .await?;
 
@@ -278,6 +283,7 @@ impl types::SetupMandateRouterData {
         supported_connectors_for_update_mandate: &settings::SupportedPaymentMethodsForMandate,
         connector_request: Option<services::Request>,
         maybe_customer: &Option<domain::Customer>,
+        profile_id: Option<String>,
     ) -> RouterResult<Self> {
         let payment_method_type = self.request.payment_method_type;
 
@@ -336,6 +342,7 @@ impl types::SetupMandateRouterData {
                 key_store,
                 resp.request.amount,
                 Some(resp.request.currency),
+                profile_id,
             ))
             .await?
             .0;
diff --git a/crates/router/src/core/payments/operations/payment_response.rs b/crates/router/src/core/payments/operations/payment_response.rs
index 70cf702311d..aeb4d6e5b1c 100644
--- a/crates/router/src/core/payments/operations/payment_response.rs
+++ b/crates/router/src/core/payments/operations/payment_response.rs
@@ -1001,12 +1001,13 @@ async fn update_payment_method_status_and_ntid<F: Clone>(
                     .change_context(errors::ApiErrorResponse::InternalServerError)
                     .attach_printable("The pg_agnostic config was not found in the DB")?;
 
-                if &pg_agnostic.config == "true" {
+                if &pg_agnostic.config == "true"
+                    && payment_data.payment_intent.setup_future_usage
+                        == Some(diesel_models::enums::FutureUsage::OffSession)
+                {
                     Some(network_transaction_id)
                 } else {
-                    logger::info!(
-                        "Skip storing network transaction id as pg_agnostic config is not enabled"
-                    );
+                    logger::info!("Skip storing network transaction id");
                     None
                 }
             } else {
diff --git a/crates/router/src/core/payments/tokenization.rs b/crates/router/src/core/payments/tokenization.rs
index 47cd1cd9eb7..3f24c55c998 100644
--- a/crates/router/src/core/payments/tokenization.rs
+++ b/crates/router/src/core/payments/tokenization.rs
@@ -41,6 +41,7 @@ pub async fn save_payment_method<F: Clone, FData>(
     key_store: &domain::MerchantKeyStore,
     amount: Option<i64>,
     currency: Option<storage_enums::Currency>,
+    profile_id: Option<String>,
 ) -> RouterResult<(Option<String>, Option<common_enums::PaymentMethodStatus>)>
 where
     FData: mandate::MandateBehaviour,
@@ -64,6 +65,35 @@ where
                 _ => None,
             };
 
+            let network_transaction_id =
+                if let Some(network_transaction_id) = network_transaction_id {
+                    let profile_id = profile_id
+                        .as_ref()
+                        .ok_or(errors::ApiErrorResponse::ResourceIdNotFound)?;
+
+                    let pg_agnostic = state
+                        .store
+                        .find_config_by_key_unwrap_or(
+                            &format!("pg_agnostic_mandate_{}", profile_id),
+                            Some("false".to_string()),
+                        )
+                        .await
+                        .change_context(errors::ApiErrorResponse::InternalServerError)
+                        .attach_printable("The pg_agnostic config was not found in the DB")?;
+
+                    if &pg_agnostic.config == "true"
+                        && resp.request.get_setup_future_usage()
+                            == Some(storage_enums::FutureUsage::OffSession)
+                    {
+                        Some(network_transaction_id)
+                    } else {
+                        logger::info!("Skip storing network transaction id");
+                        None
+                    }
+                } else {
+                    None
+                };
+
             let connector_token = if token_store {
                 let tokens = resp
                     .payment_method_token

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

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

## Description
<!-- Describe your changes in detail -->
Currently there is no validation while storing the network transaction id in the authorize flow. As network transaction is only being used for the processor agnostic MITs it should be stored (in `payment_methods` table) only if the pg_agnostic flag is enabled.

### 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)?
-->
`payment_method` table where `network_transaction_id` is null as `pg_agnotic` flag is not enabled.
<img width="1456" alt="image" src="https://github.com/juspay/hyperswitch/assets/83439957/c2b1971e-97fc-4da2-9d72-df656ae79bf2">

enabled `pg_agnotic` flag
```
curl --location 'https://sandbox.hyperswitch.io/routing/business_profile/:business_profile_id/configs/pg_agnostic_mit' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer JWT_Token' \
--data '{
    "enabled": true
}'
```

Preform a setup_mandate
```
{
    "amount": 1000,
    "currency": "USD",
    "confirm": true,
    "capture_method": "automatic",
    "capture_on": "2022-09-10T10:11:12Z",
    "customer_id": "ajjj",
    "email": "guest@example.com",
    "name": "John Doe",
    "phone": "999999999",
    "phone_country_code": "+65",
    "description": "Its my first payment request",
    "authentication_type": "no_three_ds",
    "return_url": "https://google.com",
    "payment_method": "card",
    "payment_method_type": "credit",
    "payment_method_data": {
        "card": {
            "card_number": "4111111111111111",
            "card_exp_month": "03",
            "card_exp_year": "2030",
            "card_holder_name": "joseph Doe",
            "card_cvc": "737"
        }
    },
    "setup_future_usage": "off_session",
    "payment_type": "setup_mandate",
    "customer_acceptance": {
        "acceptance_type": "offline",
        "accepted_at": "1963-05-03T04:07:52.723Z",
        "online": {
            "ip_address": "127.0.0.1",
            "user_agent": "amet irure esse"
        }
    },
    "billing": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "US",
            "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": "US",
            "first_name": "John",
            "last_name": "Doe"
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+91"
        }
    },
    "browser_info": {
        "user_agent": "Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/70.0.3538.110 Safari\/537.36",
        "accept_header": "text\/html,application\/xhtml+xml,application\/xml;q=0.9,image\/webp,image\/apng,*\/*;q=0.8",
        "language": "nl-NL",
        "color_depth": 24,
        "screen_height": 723,
        "screen_width": 1536,
        "time_zone": 0,
        "java_enabled": true,
        "java_script_enabled": true,
        "ip_address": "125.0.0.1"
    },
    "statement_descriptor_name": "joseph",
    "statement_descriptor_suffix": "JS",
    "metadata": {},
    "order_details": [
        {
            "product_name": "Apple iphone 15",
            "quantity": 1,
            "amount": 0,
            "account_name": "transaction_processing"
        }
    ]
}
```
<img width="1080" alt="image" src="https://github.com/juspay/hyperswitch/assets/83439957/f657c6f5-dda0-4f5c-958c-435774255af8">
Network transaction id being stored after the pg_agnotic flag is enabled.
<img width="1424" alt="image" src="https://github.com/juspay/hyperswitch/assets/83439957/eec4bdfc-caf2-4572-a8ba-bdba32974873">


## 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
- [ ] I added a [CHANGELOG](/CHANGELOG.md) entry if applicable
