Bug: Collect billing details from wallet connector based on the `collect_billing_details_from_wallet_connector` field



We were always passing in some parameters in the wallet session token in order to collect the billing details form the wallet connectors (like google pay and apple pay) always. Instead of collecting it always this we should add a field (`collect_billing_details_from_wallet_connector`) in the business profile which if set to `true` we should add some fields in the session token to collect the shipping details from the wallet connectors.
Reference: https://github.com/juspay/hyperswitch/pull/4601
diff --git a/crates/api_models/src/admin.rs b/crates/api_models/src/admin.rs
index 81761fac70d..58e11c4d0d4 100644
--- a/crates/api_models/src/admin.rs
+++ b/crates/api_models/src/admin.rs
@@ -950,9 +950,14 @@ pub struct BusinessProfileCreate {
     /// Whether to use the billing details passed when creating the intent as payment method billing
     pub use_billing_as_payment_method_billing: Option<bool>,
 
-    /// A boolean value to indicate if customer shipping details needs to be sent for wallets payments
+    /// A boolean value to indicate if customer shipping details needs to be collected from wallet connector (Eg. Apple pay, Google pay etc)
+    #[schema(default = false, example = false)]
     pub collect_shipping_details_from_wallet_connector: Option<bool>,
 
+    /// A boolean value to indicate if customer billing details needs to be collected from wallet connector (Eg. Apple pay, Google pay etc)
+    #[schema(default = false, example = false)]
+    pub collect_billing_details_from_wallet_connector: Option<bool>,
+
     /// Indicates if the MIT (merchant initiated transaction) payments can be made connector
     /// agnostic, i.e., MITs may be processed through different connector than CIT (customer
     /// initiated transaction) based on the routing rules.
@@ -1038,9 +1043,14 @@ pub struct BusinessProfileResponse {
     /// Merchant's config to support extended card info feature
     pub extended_card_info_config: Option<ExtendedCardInfoConfig>,
 
-    /// A boolean value to indicate if customer shipping details needs to be sent for wallets payments
+    /// A boolean value to indicate if customer shipping details needs to be collected from wallet connector (Eg. Apple pay, Google pay etc)
+    #[schema(default = false, example = false)]
     pub collect_shipping_details_from_wallet_connector: Option<bool>,
 
+    /// A boolean value to indicate if customer billing details needs to be collected from wallet connector (Eg. Apple pay, Google pay etc)
+    #[schema(default = false, example = false)]
+    pub collect_billing_details_from_wallet_connector: Option<bool>,
+
     /// Indicates if the MIT (merchant initiated transaction) payments can be made connector
     /// agnostic, i.e., MITs may be processed through different connector than CIT (customer
     /// initiated transaction) based on the routing rules.
@@ -1118,9 +1128,14 @@ pub struct BusinessProfileUpdate {
     // Whether to use the billing details passed when creating the intent as payment method billing
     pub use_billing_as_payment_method_billing: Option<bool>,
 
-    /// A boolean value to indicate if customer shipping details needs to be sent for wallets payments
+    /// A boolean value to indicate if customer shipping details needs to be collected from wallet connector (Eg. Apple pay, Google pay etc)
+    #[schema(default = false, example = false)]
     pub collect_shipping_details_from_wallet_connector: Option<bool>,
 
+    /// A boolean value to indicate if customer billing details needs to be collected from wallet connector (Eg. Apple pay, Google pay etc)
+    #[schema(default = false, example = false)]
+    pub collect_billing_details_from_wallet_connector: Option<bool>,
+
     /// Indicates if the MIT (merchant initiated transaction) payments can be made connector
     /// agnostic, i.e., MITs may be processed through different connector than CIT (customer
     /// initiated transaction) based on the routing rules.
diff --git a/crates/api_models/src/payments.rs b/crates/api_models/src/payments.rs
index cd36c53a12b..d8321524a1e 100644
--- a/crates/api_models/src/payments.rs
+++ b/crates/api_models/src/payments.rs
@@ -4135,6 +4135,7 @@ pub struct GpayAllowedMethodsParameters {
     /// The list of allowed card networks (ex: AMEX,JCB etc)
     pub allowed_card_networks: Vec<String>,
     /// Is billing address required
+    #[serde(skip_serializing_if = "Option::is_none")]
     pub billing_address_required: Option<bool>,
     /// Billing address parameters
     #[serde(skip_serializing_if = "Option::is_none")]
diff --git a/crates/diesel_models/src/business_profile.rs b/crates/diesel_models/src/business_profile.rs
index b956140a65e..48eedc6110c 100644
--- a/crates/diesel_models/src/business_profile.rs
+++ b/crates/diesel_models/src/business_profile.rs
@@ -41,6 +41,7 @@ pub struct BusinessProfile {
     pub is_connector_agnostic_mit_enabled: Option<bool>,
     pub use_billing_as_payment_method_billing: Option<bool>,
     pub collect_shipping_details_from_wallet_connector: Option<bool>,
+    pub collect_billing_details_from_wallet_connector: Option<bool>,
 }
 
 #[derive(Clone, Debug, Insertable, router_derive::DebugAsDisplay)]
@@ -73,6 +74,7 @@ pub struct BusinessProfileNew {
     pub is_connector_agnostic_mit_enabled: Option<bool>,
     pub use_billing_as_payment_method_billing: Option<bool>,
     pub collect_shipping_details_from_wallet_connector: Option<bool>,
+    pub collect_billing_details_from_wallet_connector: Option<bool>,
 }
 
 #[derive(Clone, Debug, Default, AsChangeset, router_derive::DebugAsDisplay)]
@@ -102,6 +104,7 @@ pub struct BusinessProfileUpdateInternal {
     pub is_connector_agnostic_mit_enabled: Option<bool>,
     pub use_billing_as_payment_method_billing: Option<bool>,
     pub collect_shipping_details_from_wallet_connector: Option<bool>,
+    pub collect_billing_details_from_wallet_connector: Option<bool>,
 }
 
 #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
@@ -128,6 +131,7 @@ pub enum BusinessProfileUpdate {
         extended_card_info_config: Option<pii::SecretSerdeValue>,
         use_billing_as_payment_method_billing: Option<bool>,
         collect_shipping_details_from_wallet_connector: Option<bool>,
+        collect_billing_details_from_wallet_connector: Option<bool>,
         is_connector_agnostic_mit_enabled: Option<bool>,
     },
     ExtendedCardInfoUpdate {
@@ -163,6 +167,7 @@ impl From<BusinessProfileUpdate> for BusinessProfileUpdateInternal {
                 extended_card_info_config,
                 use_billing_as_payment_method_billing,
                 collect_shipping_details_from_wallet_connector,
+                collect_billing_details_from_wallet_connector,
                 is_connector_agnostic_mit_enabled,
             } => Self {
                 profile_name,
@@ -186,6 +191,7 @@ impl From<BusinessProfileUpdate> for BusinessProfileUpdateInternal {
                 extended_card_info_config,
                 use_billing_as_payment_method_billing,
                 collect_shipping_details_from_wallet_connector,
+                collect_billing_details_from_wallet_connector,
                 is_connector_agnostic_mit_enabled,
                 ..Default::default()
             },
@@ -235,6 +241,8 @@ impl From<BusinessProfileNew> for BusinessProfile {
             use_billing_as_payment_method_billing: new.use_billing_as_payment_method_billing,
             collect_shipping_details_from_wallet_connector: new
                 .collect_shipping_details_from_wallet_connector,
+            collect_billing_details_from_wallet_connector: new
+                .collect_billing_details_from_wallet_connector,
         }
     }
 }
@@ -265,6 +273,7 @@ impl BusinessProfileUpdate {
             is_connector_agnostic_mit_enabled,
             use_billing_as_payment_method_billing,
             collect_shipping_details_from_wallet_connector,
+            collect_billing_details_from_wallet_connector,
         } = self.into();
         BusinessProfile {
             profile_name: profile_name.unwrap_or(source.profile_name),
@@ -292,6 +301,7 @@ impl BusinessProfileUpdate {
             extended_card_info_config,
             use_billing_as_payment_method_billing,
             collect_shipping_details_from_wallet_connector,
+            collect_billing_details_from_wallet_connector,
             ..source
         }
     }
diff --git a/crates/diesel_models/src/schema.rs b/crates/diesel_models/src/schema.rs
index 6149af1f505..98f1b2fbbec 100644
--- a/crates/diesel_models/src/schema.rs
+++ b/crates/diesel_models/src/schema.rs
@@ -203,6 +203,7 @@ diesel::table! {
         is_connector_agnostic_mit_enabled -> Nullable<Bool>,
         use_billing_as_payment_method_billing -> Nullable<Bool>,
         collect_shipping_details_from_wallet_connector -> Nullable<Bool>,
+        collect_billing_details_from_wallet_connector -> Nullable<Bool>,
     }
 }
 
diff --git a/crates/router/src/core/admin.rs b/crates/router/src/core/admin.rs
index 7d69b7f9971..b86fed02f32 100644
--- a/crates/router/src/core/admin.rs
+++ b/crates/router/src/core/admin.rs
@@ -456,6 +456,7 @@ pub async fn update_business_profile_cascade(
             extended_card_info_config: None,
             use_billing_as_payment_method_billing: None,
             collect_shipping_details_from_wallet_connector: None,
+            collect_billing_details_from_wallet_connector: None,
             is_connector_agnostic_mit_enabled: None,
         };
 
@@ -1723,6 +1724,8 @@ pub async fn update_business_profile(
         use_billing_as_payment_method_billing: request.use_billing_as_payment_method_billing,
         collect_shipping_details_from_wallet_connector: request
             .collect_shipping_details_from_wallet_connector,
+        collect_billing_details_from_wallet_connector: request
+            .collect_billing_details_from_wallet_connector,
         is_connector_agnostic_mit_enabled: request.is_connector_agnostic_mit_enabled,
     };
 
diff --git a/crates/router/src/core/payments/flows/session_flow.rs b/crates/router/src/core/payments/flows/session_flow.rs
index 1223d861ebd..43900ac2b64 100644
--- a/crates/router/src/core/payments/flows/session_flow.rs
+++ b/crates/router/src/core/payments/flows/session_flow.rs
@@ -295,23 +295,29 @@ async fn create_applepay_session_token(
             router_data.request.to_owned(),
         )?;
 
-        let billing_variants = enums::FieldType::get_billing_variants();
-
-        let required_billing_contact_fields = is_dynamic_fields_required(
-            &state.conf.required_fields,
-            enums::PaymentMethod::Wallet,
-            enums::PaymentMethodType::ApplePay,
-            &connector.connector_name,
-            billing_variants,
-        )
-        .then_some(payment_types::ApplePayBillingContactFields(vec![
-            payment_types::ApplePayAddressParameters::PostalAddress,
-        ]));
+        let required_billing_contact_fields = business_profile
+            .collect_billing_details_from_wallet_connector
+            .unwrap_or(false)
+            .then_some({
+                let billing_variants = enums::FieldType::get_billing_variants();
+                is_dynamic_fields_required(
+                    &state.conf.required_fields,
+                    enums::PaymentMethod::Wallet,
+                    enums::PaymentMethodType::ApplePay,
+                    &connector.connector_name,
+                    billing_variants,
+                )
+                .then_some(payment_types::ApplePayBillingContactFields(vec![
+                    payment_types::ApplePayAddressParameters::PostalAddress,
+                ]))
+            })
+            .flatten();
 
-        let required_shipping_contact_fields =
-            if business_profile.collect_shipping_details_from_wallet_connector == Some(true) {
+        let required_shipping_contact_fields = business_profile
+            .collect_shipping_details_from_wallet_connector
+            .unwrap_or(false)
+            .then_some({
                 let shipping_variants = enums::FieldType::get_shipping_variants();
-
                 is_dynamic_fields_required(
                     &state.conf.required_fields,
                     enums::PaymentMethod::Wallet,
@@ -324,9 +330,8 @@ async fn create_applepay_session_token(
                     payment_types::ApplePayAddressParameters::Phone,
                     payment_types::ApplePayAddressParameters::Email,
                 ]))
-            } else {
-                None
-            };
+            })
+            .flatten();
 
         // Get apple pay payment request
         let applepay_payment_request = get_apple_pay_payment_request(
@@ -562,15 +567,20 @@ fn create_gpay_session_token(
                 expected_format: "gpay_metadata_format".to_string(),
             })?;
 
-        let billing_variants = enums::FieldType::get_billing_variants();
+        let is_billing_details_required =
+            if business_profile.collect_billing_details_from_wallet_connector == Some(true) {
+                let billing_variants = enums::FieldType::get_billing_variants();
 
-        let is_billing_details_required = is_dynamic_fields_required(
-            &state.conf.required_fields,
-            enums::PaymentMethod::Wallet,
-            enums::PaymentMethodType::GooglePay,
-            &connector.connector_name,
-            billing_variants,
-        );
+                is_dynamic_fields_required(
+                    &state.conf.required_fields,
+                    enums::PaymentMethod::Wallet,
+                    enums::PaymentMethodType::GooglePay,
+                    &connector.connector_name,
+                    billing_variants,
+                )
+            } else {
+                false
+            };
 
         let billing_address_parameters =
             is_billing_details_required.then_some(payment_types::GpayBillingAddressParameters {
diff --git a/crates/router/src/core/routing/helpers.rs b/crates/router/src/core/routing/helpers.rs
index caa976580b8..b9f5da13cf4 100644
--- a/crates/router/src/core/routing/helpers.rs
+++ b/crates/router/src/core/routing/helpers.rs
@@ -285,6 +285,7 @@ pub async fn update_business_profile_active_algorithm_ref(
         extended_card_info_config: None,
         use_billing_as_payment_method_billing: None,
         collect_shipping_details_from_wallet_connector: None,
+        collect_billing_details_from_wallet_connector: None,
         is_connector_agnostic_mit_enabled: None,
     };
 
diff --git a/crates/router/src/types/api/admin.rs b/crates/router/src/types/api/admin.rs
index 77693157f62..36c3ba96210 100644
--- a/crates/router/src/types/api/admin.rs
+++ b/crates/router/src/types/api/admin.rs
@@ -99,6 +99,8 @@ impl ForeignTryFrom<storage::business_profile::BusinessProfile> for BusinessProf
                 .transpose()?,
             collect_shipping_details_from_wallet_connector: item
                 .collect_shipping_details_from_wallet_connector,
+            collect_billing_details_from_wallet_connector: item
+                .collect_billing_details_from_wallet_connector,
             is_connector_agnostic_mit_enabled: item.is_connector_agnostic_mit_enabled,
         })
     }
@@ -211,7 +213,11 @@ impl ForeignTryFrom<(domain::MerchantAccount, BusinessProfileCreate)>
                 .use_billing_as_payment_method_billing
                 .or(Some(true)),
             collect_shipping_details_from_wallet_connector: request
-                .collect_shipping_details_from_wallet_connector,
+                .collect_shipping_details_from_wallet_connector
+                .or(Some(false)),
+            collect_billing_details_from_wallet_connector: request
+                .collect_billing_details_from_wallet_connector
+                .or(Some(false)),
         })
     }
 }
diff --git a/migrations/2024-06-20-142013_collect_billing_details_from_wallet_connector/down.sql b/migrations/2024-06-20-142013_collect_billing_details_from_wallet_connector/down.sql
new file mode 100644
index 00000000000..417bdac8b5a
--- /dev/null
+++ b/migrations/2024-06-20-142013_collect_billing_details_from_wallet_connector/down.sql
@@ -0,0 +1,3 @@
+-- This file should undo anything in `up.sql`
+
+ALTER TABLE business_profile DROP COLUMN IF EXISTS collect_billing_details_from_wallet_connector;
\ No newline at end of file
diff --git a/migrations/2024-06-20-142013_collect_billing_details_from_wallet_connector/up.sql b/migrations/2024-06-20-142013_collect_billing_details_from_wallet_connector/up.sql
new file mode 100644
index 00000000000..edfda3f468b
--- /dev/null
+++ b/migrations/2024-06-20-142013_collect_billing_details_from_wallet_connector/up.sql
@@ -0,0 +1,3 @@
+-- Your SQL goes here
+
+ALTER TABLE business_profile ADD COLUMN IF NOT EXISTS collect_billing_details_from_wallet_connector BOOLEAN DEFAULT FALSE;
\ No newline at end of file

## 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 -->
We were always passing in some parameters in the wallet session token in order to collect the billing details form the wallet connectors (like google pay and apple pay) always. Instead of collecting it always this feature adds a field (`collect_billing_details_from_wallet_connector`) in the business profile which if set to `true` we will add some fields in the session token to collect the shipping details from the wallet connectors.
Reference: https://github.com/juspay/hyperswitch/pull/4601

### Additional Changes

- [x] This PR modifies the API contract
- [x] 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)?
-->
-> Create a merchant connector account
-> Use the below curl to set the `collect_billing_details_from_wallet_connector`
```
curl --location 'http://localhost:8080/account/merchant_1718903636/business_profile/pro_D1HEnlPrKdJ33sefpb8W' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: test_admin' \
--data '{
    "collect_billing_details_from_wallet_connector": false
}'
```
<img width="940" alt="image" src="https://github.com/juspay/hyperswitch/assets/83439957/69f7a1fe-89b6-446e-8461-a98fc82f1d7f">

-> Create a payment with confirm false
```
{
    "amount": 6500,
    "currency": "USD",
    "confirm": false,
    "amount_to_capture": 6500,
    "customer_id": "test_priority_routing",
    "capture_method": "automatic",
    "capture_on": "2022-09-10T10:11:12Z",
    "authentication_type": "three_ds",
    "return_url": "https://google.com",
    "email": "something@gmail.com",
    "name": "Joseph Doe",
    "phone": "999999999",
    "phone_country_code": "+65",
    "description": "Its my first payment request",
    "statement_descriptor_name": "Juspay",
    "statement_descriptor_suffix": "Router",
    "billing": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "US",
            "first_name": "joseph",
            "last_name": "Doe"
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+91"
        }
       
    }
}
```
<img width="1046" alt="image" src="https://github.com/juspay/hyperswitch/assets/83439957/e9726e0b-31e5-4f91-b83b-9db2fdc750ec">

-> Make a session call for the above payment id and client secret
```
curl --location 'http://localhost:8080/payments/session_tokens' \
--header 'Content-Type: application/json' \
--header 'api-key: pk_dev_f0a9fbe61ae744049578ca94244364b6' \
--data '{
    "payment_id": "pay_eX276M1t9ndwv0elPVHj",
    "wallets": [],
    "client_secret": "pay_eX276M1t9ndwv0elPVHj_secret_wjXQi2f5fRJkrhJWIbcs"
}'
```
<img width="1142" alt="image" src="https://github.com/juspay/hyperswitch/assets/83439957/50ca5b99-29cf-4027-85a9-7c94bb41b7ab">
<img width="1167" alt="image" src="https://github.com/juspay/hyperswitch/assets/83439957/4081beed-f425-48df-8950-22519b780abc">

In the above screenshots we can see that there is no billing details parameter for apple pay and for google pay its set to false as it is `collect_billing_details_from_wallet_connector` is set to false.

-> Set the `collect_billing_details_from_wallet_connector` to true
<img width="895" alt="image" src="https://github.com/juspay/hyperswitch/assets/83439957/07627b75-9162-4e8a-8350-09359a7281de">

-> Create a payment with confirm false and make a session call
<img width="1132" alt="image" src="https://github.com/juspay/hyperswitch/assets/83439957/adf90bce-bf83-44d7-9dde-81718c7b989e">
<img width="706" alt="image" src="https://github.com/juspay/hyperswitch/assets/83439957/62a0aa47-20ac-4e8e-a8d9-919f5ec15efe">


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