Bug: [BUG] Custom address struct not present in the /customers endpoints



### Bug Description

Currently the `/customers` endpoints use address as a `SecretSerdeValue` which may cause inconsistencies going on further. We need to change it to a custom struct type and populate the fields as per our API reference.

### Have you spent some time to check if this bug has been raised before?

- [X] I checked and didn't find similar issue

### Have you read the Contributing Guidelines?

- [X] I have read the [Contributing Guidelines](https://github.com/juspay/hyperswitch/blob/main/docs/CONTRIBUTING.md)

### Are you willing to submit a PR?

Yes I am willing to submit a PR!
diff --git a/crates/api_models/src/customers.rs b/crates/api_models/src/customers.rs
index 1c28617d745..d8c864746a8 100644
--- a/crates/api_models/src/customers.rs
+++ b/crates/api_models/src/customers.rs
@@ -3,6 +3,8 @@ use masking::Secret;
 use serde::{Deserialize, Serialize};
 use utoipa::ToSchema;
 
+use crate::payments;
+
 /// The customer details
 #[derive(Debug, Default, Clone, Deserialize, Serialize, ToSchema)]
 pub struct CustomerRequest {
@@ -30,18 +32,8 @@ pub struct CustomerRequest {
     #[schema(max_length = 255, example = "+65")]
     pub phone_country_code: Option<String>,
     /// The address for the customer
-    #[schema(value_type = Option<Object>,example = json!({
-    "city": "Bangalore",
-    "country": "IN",
-    "line1": "Hyperswitch router",
-    "line2": "Koramangala",
-    "line3": "Stallion",
-    "state": "Karnataka",
-    "zip": "560095",
-    "first_name": "John",
-    "last_name": "Doe"
-  }))]
-    pub address: Option<pii::SecretSerdeValue>,
+    #[schema(value_type = Option<AddressDetails>)]
+    pub address: Option<payments::AddressDetails>,
     /// You can specify up to 50 keys, with key names up to 40 characters long and values up to 500
     /// characters long. Metadata is useful for storing additional, structured information on an
     /// object.
@@ -70,18 +62,8 @@ pub struct CustomerResponse {
     #[schema(max_length = 255, example = "First Customer")]
     pub description: Option<String>,
     /// The address for the customer
-    #[schema(value_type = Option<Object>,example = json!({
-    "city": "Bangalore",
-    "country": "IN",
-    "line1": "Hyperswitch router",
-    "line2": "Koramangala",
-    "line3": "Stallion",
-    "state": "Karnataka",
-    "zip": "560095",
-    "first_name": "John",
-    "last_name": "Doe"
-  }))]
-    pub address: Option<Secret<serde_json::Value>>,
+    #[schema(value_type = Option<AddressDetails>)]
+    pub address: Option<payments::AddressDetails>,
     ///  A timestamp (ISO 8601 code) that determines when the customer was created
     #[schema(value_type = PrimitiveDateTime,example = "2023-01-18T11:04:09.922Z")]
     #[serde(with = "custom_serde::iso8601")]
diff --git a/crates/router/src/compatibility/stripe/customers/types.rs b/crates/router/src/compatibility/stripe/customers/types.rs
index c605a4efefe..8298595bbc5 100644
--- a/crates/router/src/compatibility/stripe/customers/types.rs
+++ b/crates/router/src/compatibility/stripe/customers/types.rs
@@ -1,6 +1,6 @@
 use std::{convert::From, default::Default};
 
-use api_models::payment_methods as api_types;
+use api_models::{payment_methods as api_types, payments};
 use common_utils::{
     crypto::Encryptable,
     date_time,
@@ -8,7 +8,29 @@ use common_utils::{
 };
 use serde::{Deserialize, Serialize};
 
-use crate::{logger, types::api};
+use crate::{
+    logger,
+    types::{api, api::enums as api_enums},
+};
+
+#[derive(Default, Serialize, PartialEq, Eq, Deserialize, Clone)]
+pub struct Shipping {
+    pub address: StripeAddressDetails,
+    pub name: Option<masking::Secret<String>>,
+    pub carrier: Option<String>,
+    pub phone: Option<masking::Secret<String>>,
+    pub tracking_number: Option<masking::Secret<String>>,
+}
+
+#[derive(Default, Serialize, PartialEq, Eq, Deserialize, Clone)]
+pub struct StripeAddressDetails {
+    pub city: Option<String>,
+    pub country: Option<api_enums::CountryAlpha2>,
+    pub line1: Option<masking::Secret<String>>,
+    pub line2: Option<masking::Secret<String>>,
+    pub postal_code: Option<masking::Secret<String>>,
+    pub state: Option<masking::Secret<String>>,
+}
 
 #[derive(Clone, Default, Serialize, Deserialize, PartialEq, Eq)]
 pub struct CreateCustomerRequest {
@@ -16,9 +38,23 @@ pub struct CreateCustomerRequest {
     pub invoice_prefix: Option<String>,
     pub name: Option<masking::Secret<String>>,
     pub phone: Option<masking::Secret<String>>,
-    pub address: Option<masking::Secret<serde_json::Value>>,
+    pub address: Option<StripeAddressDetails>,
     pub metadata: Option<pii::SecretSerdeValue>,
     pub description: Option<String>,
+    pub shipping: Option<Shipping>,
+    pub payment_method: Option<String>,              // not used
+    pub balance: Option<i64>,                        // not used
+    pub cash_balance: Option<pii::SecretSerdeValue>, // not used
+    pub coupon: Option<String>,                      // not used
+    pub invoice_settings: Option<pii::SecretSerdeValue>, // not used
+    pub next_invoice_sequence: Option<String>,       // not used
+    pub preferred_locales: Option<String>,           // not used
+    pub promotion_code: Option<String>,              // not used
+    pub source: Option<String>,                      // not used
+    pub tax: Option<pii::SecretSerdeValue>,          // not used
+    pub tax_exempt: Option<String>,                  // not used
+    pub tax_id_data: Option<String>,                 // not used
+    pub test_clock: Option<String>,                  // not used
 }
 
 #[derive(Clone, Default, Serialize, Deserialize, PartialEq, Eq)]
@@ -27,8 +63,21 @@ pub struct CustomerUpdateRequest {
     pub email: Option<Email>,
     pub phone: Option<masking::Secret<String, masking::WithType>>,
     pub name: Option<masking::Secret<String>>,
-    pub address: Option<masking::Secret<serde_json::Value>>,
+    pub address: Option<StripeAddressDetails>,
     pub metadata: Option<pii::SecretSerdeValue>,
+    pub shipping: Option<Shipping>,
+    pub payment_method: Option<String>,              // not used
+    pub balance: Option<i64>,                        // not used
+    pub cash_balance: Option<pii::SecretSerdeValue>, // not used
+    pub coupon: Option<String>,                      // not used
+    pub default_source: Option<String>,              // not used
+    pub invoice_settings: Option<pii::SecretSerdeValue>, // not used
+    pub next_invoice_sequence: Option<String>,       // not used
+    pub preferred_locales: Option<String>,           // not used
+    pub promotion_code: Option<String>,              // not used
+    pub source: Option<String>,                      // not used
+    pub tax: Option<pii::SecretSerdeValue>,          // not used
+    pub tax_exempt: Option<String>,                  // not used
 }
 
 #[derive(Default, Serialize, PartialEq, Eq)]
@@ -52,6 +101,22 @@ pub struct CustomerDeleteResponse {
     pub deleted: bool,
 }
 
+impl From<StripeAddressDetails> for payments::AddressDetails {
+    fn from(address: StripeAddressDetails) -> Self {
+        Self {
+            city: address.city,
+            country: address.country,
+            line1: address.line1,
+            line2: address.line2,
+            zip: address.postal_code,
+            state: address.state,
+            first_name: None,
+            line3: None,
+            last_name: None,
+        }
+    }
+}
+
 impl From<CreateCustomerRequest> for api::CustomerRequest {
     fn from(req: CreateCustomerRequest) -> Self {
         Self {
@@ -61,7 +126,7 @@ impl From<CreateCustomerRequest> for api::CustomerRequest {
             email: req.email,
             description: req.description,
             metadata: req.metadata,
-            address: req.address,
+            address: req.address.map(|s| s.into()),
             ..Default::default()
         }
     }
@@ -75,6 +140,7 @@ impl From<CustomerUpdateRequest> for api::CustomerRequest {
             email: req.email,
             description: req.description,
             metadata: req.metadata,
+            address: req.address.map(|s| s.into()),
             ..Default::default()
         }
     }
diff --git a/crates/router/src/core/customers.rs b/crates/router/src/core/customers.rs
index eaee9c72399..6fe188058b5 100644
--- a/crates/router/src/core/customers.rs
+++ b/crates/router/src/core/customers.rs
@@ -1,7 +1,4 @@
-use common_utils::{
-    crypto::{Encryptable, GcmAes256},
-    ext_traits::ValueExt,
-};
+use common_utils::crypto::{Encryptable, GcmAes256};
 use error_stack::ResultExt;
 use masking::ExposeInterface;
 use router_env::{instrument, tracing};
@@ -42,11 +39,7 @@ pub async fn create_customer(
 
     let key = key_store.key.get_inner().peek();
     if let Some(addr) = &customer_data.address {
-        let customer_address: api_models::payments::AddressDetails = addr
-            .peek()
-            .clone()
-            .parse_value("AddressDetails")
-            .change_context(errors::ApiErrorResponse::AddressNotFound)?;
+        let customer_address: api_models::payments::AddressDetails = addr.clone();
 
         let address = async {
             Ok(domain::Address {
@@ -333,11 +326,7 @@ pub async fn update_customer(
     let key = key_store.key.get_inner().peek();
 
     if let Some(addr) = &update_customer.address {
-        let customer_address: api_models::payments::AddressDetails = addr
-            .peek()
-            .clone()
-            .parse_value("AddressDetails")
-            .change_context(errors::ApiErrorResponse::AddressNotFound)?;
+        let customer_address: api_models::payments::AddressDetails = addr.clone();
         let update_address = async {
             Ok(storage::AddressUpdate::Update {
                 city: customer_address.city,
diff --git a/openapi/openapi_spec.json b/openapi/openapi_spec.json
index 7ce3fe1dfd0..c5b02119182 100644
--- a/openapi/openapi_spec.json
+++ b/openapi/openapi_spec.json
@@ -3700,8 +3700,11 @@
             "maxLength": 255
           },
           "address": {
-            "type": "object",
-            "description": "The address for the customer",
+            "allOf": [
+              {
+                "$ref": "#/components/schemas/AddressDetails"
+              }
+            ],
             "nullable": true
           },
           "metadata": {
@@ -3760,8 +3763,11 @@
             "maxLength": 255
           },
           "address": {
-            "type": "object",
-            "description": "The address for the customer",
+            "allOf": [
+              {
+                "$ref": "#/components/schemas/AddressDetails"
+              }
+            ],
             "nullable": true
           },
           "created_at": {

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

- [x] Bugfix
- [x] Refactoring

## Description
<!-- Describe your changes in detail -->
Address of a new customer was being accepted as a `SecretSerdeValue` in the `CustomerCreate` and `CustomerUpdate` requests. This PR does the following : 

- Add a new struct `AddressDetails` in the `customers` flow for the `address` field.
- Add the `address` field in Stripe Compatibility Layer and the corresponding mappings for it.
- Add missing fields in `CustomerCreate` and `CustomerUpdate` requests as per Stripe API reference.

## Motivation and Context
<!--
Why is this change required? What problem does it solve?
If it fixes an open issue, please link to the issue here.

If you don't have an issue, we'd recommend starting with one first so the PR
can focus on the implementation (unless its an obvious bug or documentation fix
that will have little conversation).
-->
This PR closes the following issues : 

https://github.com/juspay/hyperswitch/issues/1646
https://github.com/juspay/hyperswitch/issues/1649

## How did you test it?
<!--
Did you write an integration/unit/API test to verify the code changes?
Or did you test this change manually (provide relevant screenshots)?
-->
Manually

## Checklist
<!-- Put an `x` in the boxes that apply -->

- [x] I formatted the code `cargo +nightly fmt --all`
- [x] I addressed lints thrown by `cargo clippy`
- [x] I reviewed submitted code