Bug: [FEATURE] statement_descriptor_suffix and statement_descriptor_name not being sent to Adyen. Please implement.



### Feature Description

It is important to be able to have custom statements (and also it is available feature on Stripe), so it should be on Adyen as well.

### Possible Implementation

It should propagate to `shopperStatement` in the Adyen't API

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

None
diff --git a/config/deployments/production.toml b/config/deployments/production.toml
index 382ad018f1d..7c543feed7e 100644
--- a/config/deployments/production.toml
+++ b/config/deployments/production.toml
@@ -17,7 +17,7 @@ payout_connector_list = "wise"
 
 [connectors]
 aci.base_url = "https://eu-test.oppwa.com/"
-adyen.base_url = "https://{{merchant_endpoint_prefix}}-checkout-live.adyenpayments.com/"
+adyen.base_url = "https://{{merchant_endpoint_prefix}}-checkout-live.adyenpayments.com/checkout"
 adyen.secondary_base_url = "https://{{merchant_endpoint_prefix}}-pal-live.adyenpayments.com/"
 airwallex.base_url = "https://api-demo.airwallex.com/"
 applepay.base_url = "https://apple-pay-gateway.apple.com/"
diff --git a/config/development.toml b/config/development.toml
index 6d4914af8b4..41497021c3a 100644
--- a/config/development.toml
+++ b/config/development.toml
@@ -88,7 +88,7 @@ vault_private_key = ""
 tunnel_private_key = ""
 
 [connectors.supported]
-wallets = ["klarna", "braintree", "applepay"]
+wallets = ["klarna", "braintree", "applepay", "adyen"]
 rewards = ["cashtocode", "zen"]
 cards = [
     "aci",
@@ -323,8 +323,8 @@ pay_bright = { country = "CA", currency = "CAD" }
 walley = { country = "SE,NO,DK,FI", currency = "DKK,EUR,NOK,SEK" }
 giropay = { country = "DE", currency = "EUR" }
 eps = { country = "AT", currency = "EUR" }
-sofort = { country =  "AT,BE,DE,ES,CH,NL", currency =  "CHF,EUR"}
-ideal = { country = "NL", currency = "EUR" }
+sofort = {not_available_flows = { capture_method = "manual" }, country =  "AT,BE,DE,ES,CH,NL", currency =  "CHF,EUR"}
+ideal = { not_available_flows = { capture_method = "manual" }, country = "NL", currency = "EUR" }
 blik = {country = "PL", currency = "PLN"}
 trustly = {country = "ES,GB,SE,NO,AT,NL,DE,DK,FI,EE,LT,LV", currency = "CZK,DKK,EUR,GBP,NOK,SEK"}
 online_banking_czech_republic = {country = "CZ", currency = "EUR,CZK"}
diff --git a/crates/router/src/connector/adyen/transformers.rs b/crates/router/src/connector/adyen/transformers.rs
index c44d590e2f1..8af99420fa4 100644
--- a/crates/router/src/connector/adyen/transformers.rs
+++ b/crates/router/src/connector/adyen/transformers.rs
@@ -9,12 +9,10 @@ use reqwest::Url;
 use serde::{Deserialize, Serialize};
 use time::{Duration, OffsetDateTime, PrimitiveDateTime};
 
-#[cfg(feature = "payouts")]
-use crate::{connector::utils::AddressDetailsData, types::api::payouts, utils::OptionExt};
 use crate::{
     connector::utils::{
-        self, BrowserInformationData, CardData, MandateReferenceData, PaymentsAuthorizeRequestData,
-        RouterData,
+        self, AddressDetailsData, BrowserInformationData, CardData, MandateReferenceData,
+        PaymentsAuthorizeRequestData, RouterData,
     },
     consts,
     core::errors,
@@ -29,6 +27,8 @@ use crate::{
     },
     utils as crate_utils,
 };
+#[cfg(feature = "payouts")]
+use crate::{types::api::payouts, utils::OptionExt};
 
 type Error = error_stack::Report<errors::ConnectorError>;
 
@@ -130,12 +130,12 @@ pub struct ShopperName {
 #[derive(Default, Debug, Serialize, Deserialize)]
 #[serde(rename_all = "camelCase")]
 pub struct Address {
-    city: Option<String>,
-    country: Option<api_enums::CountryAlpha2>,
-    house_number_or_name: Option<Secret<String>>,
-    postal_code: Option<Secret<String>>,
+    city: String,
+    country: api_enums::CountryAlpha2,
+    house_number_or_name: Secret<String>,
+    postal_code: Secret<String>,
     state_or_province: Option<Secret<String>>,
-    street: Option<Secret<String>>,
+    street: Secret<String>,
 }
 
 #[derive(Debug, Serialize)]
@@ -165,8 +165,11 @@ pub struct AdyenPaymentRequest<'a> {
     shopper_reference: Option<String>,
     store_payment_method: Option<bool>,
     shopper_name: Option<ShopperName>,
+    #[serde(rename = "shopperIP")]
+    shopper_ip: Option<Secret<String, pii::IpAddress>>,
     shopper_locale: Option<String>,
     shopper_email: Option<Email>,
+    shopper_statement: Option<String>,
     social_security_number: Option<Secret<String>>,
     telephone_number: Option<Secret<String>>,
     billing_address: Option<Address>,
@@ -174,6 +177,7 @@ pub struct AdyenPaymentRequest<'a> {
     country_code: Option<api_enums::CountryAlpha2>,
     line_items: Option<Vec<LineItem>>,
     channel: Option<Channel>,
+    metadata: Option<pii::SecretSerdeValue>,
 }
 
 #[derive(Debug, Serialize)]
@@ -1729,16 +1733,22 @@ fn get_amount_data(item: &AdyenRouterData<&types::PaymentsAuthorizeRouterData>)
     }
 }
 
-fn get_address_info(address: Option<&api_models::payments::Address>) -> Option<Address> {
+fn get_address_info(
+    address: Option<&api_models::payments::Address>,
+) -> Option<Result<Address, error_stack::Report<errors::ConnectorError>>> {
     address.and_then(|add| {
-        add.address.as_ref().map(|a| Address {
-            city: a.city.clone(),
-            country: a.country,
-            house_number_or_name: a.line1.clone(),
-            postal_code: a.zip.clone(),
-            state_or_province: a.state.clone(),
-            street: a.line2.clone(),
-        })
+        add.address.as_ref().map(
+            |a| -> Result<Address, error_stack::Report<errors::ConnectorError>> {
+                Ok(Address {
+                    city: a.get_city()?.to_owned(),
+                    country: a.get_country()?.to_owned(),
+                    house_number_or_name: a.get_line1()?.to_owned(),
+                    postal_code: a.get_zip()?.to_owned(),
+                    state_or_province: a.state.clone(),
+                    street: a.get_line2()?.to_owned(),
+                })
+            },
+        )
     })
 }
 
@@ -1823,6 +1833,12 @@ fn get_social_security_number(
     }
 }
 
+fn build_shopper_reference(customer_id: &Option<String>, merchant_id: String) -> Option<String> {
+    customer_id
+        .clone()
+        .map(|c_id| format!("{}_{}", merchant_id, c_id))
+}
+
 impl<'a> TryFrom<&api_models::payments::BankDebitData> for AdyenPaymentMethod<'a> {
     type Error = Error;
     fn try_from(
@@ -2125,27 +2141,81 @@ impl<'a> TryFrom<&api::WalletData> for AdyenPaymentMethod<'a> {
     }
 }
 
-impl<'a> TryFrom<(&api::PayLaterData, Option<api_enums::CountryAlpha2>)>
-    for AdyenPaymentMethod<'a>
+pub fn check_required_field<'a, T>(
+    field: &'a Option<T>,
+    message: &'static str,
+) -> Result<&'a T, errors::ConnectorError> {
+    field
+        .as_ref()
+        .ok_or(errors::ConnectorError::MissingRequiredField {
+            field_name: message,
+        })
+}
+
+impl<'a>
+    TryFrom<(
+        &api::PayLaterData,
+        &Option<api_enums::CountryAlpha2>,
+        &Option<Email>,
+        &Option<String>,
+        &Option<ShopperName>,
+        &Option<Secret<String>>,
+        &Option<Address>,
+        &Option<Address>,
+    )> for AdyenPaymentMethod<'a>
 {
     type Error = Error;
     fn try_from(
-        value: (&api::PayLaterData, Option<api_enums::CountryAlpha2>),
+        value: (
+            &api::PayLaterData,
+            &Option<api_enums::CountryAlpha2>,
+            &Option<Email>,
+            &Option<String>,
+            &Option<ShopperName>,
+            &Option<Secret<String>>,
+            &Option<Address>,
+            &Option<Address>,
+        ),
     ) -> Result<Self, Self::Error> {
-        let (pay_later_data, country_code) = value;
+        let (
+            pay_later_data,
+            country_code,
+            shopper_email,
+            shopper_reference,
+            shopper_name,
+            telephone_number,
+            billing_address,
+            delivery_address,
+        ) = value;
         match pay_later_data {
             api_models::payments::PayLaterData::KlarnaRedirect { .. } => {
                 let klarna = PmdForPaymentType {
                     payment_type: PaymentType::Klarna,
                 };
+                check_required_field(shopper_email, "email")?;
+                check_required_field(shopper_reference, "customer_id")?;
+                check_required_field(country_code, "billing.country")?;
+
                 Ok(AdyenPaymentMethod::AdyenKlarna(Box::new(klarna)))
             }
-            api_models::payments::PayLaterData::AffirmRedirect { .. } => Ok(
-                AdyenPaymentMethod::AdyenAffirm(Box::new(PmdForPaymentType {
-                    payment_type: PaymentType::Affirm,
-                })),
-            ),
+            api_models::payments::PayLaterData::AffirmRedirect { .. } => {
+                check_required_field(shopper_email, "email")?;
+                check_required_field(shopper_name, "billing.first_name, billing.last_name")?;
+                check_required_field(telephone_number, "billing.phone")?;
+                check_required_field(billing_address, "billing")?;
+
+                Ok(AdyenPaymentMethod::AdyenAffirm(Box::new(
+                    PmdForPaymentType {
+                        payment_type: PaymentType::Affirm,
+                    },
+                )))
+            }
             api_models::payments::PayLaterData::AfterpayClearpayRedirect { .. } => {
+                check_required_field(shopper_email, "email")?;
+                check_required_field(shopper_name, "billing.first_name, billing.last_name")?;
+                check_required_field(delivery_address, "shipping")?;
+                check_required_field(billing_address, "billing")?;
+
                 if let Some(country) = country_code {
                     match country {
                         api_enums::CountryAlpha2::IT
@@ -2163,17 +2233,36 @@ impl<'a> TryFrom<(&api::PayLaterData, Option<api_enums::CountryAlpha2>)>
                 }
             }
             api_models::payments::PayLaterData::PayBrightRedirect { .. } => {
+                check_required_field(shopper_name, "billing.first_name, billing.last_name")?;
+                check_required_field(telephone_number, "billing.phone")?;
+                check_required_field(shopper_email, "email")?;
+                check_required_field(billing_address, "billing")?;
+                check_required_field(delivery_address, "shipping")?;
+                check_required_field(country_code, "billing.country")?;
                 Ok(AdyenPaymentMethod::PayBright)
             }
             api_models::payments::PayLaterData::WalleyRedirect { .. } => {
+                //[TODO: Line items specific sub-fields are mandatory]
+                check_required_field(telephone_number, "billing.phone")?;
+                check_required_field(shopper_email, "email")?;
                 Ok(AdyenPaymentMethod::Walley)
             }
-            api_models::payments::PayLaterData::AlmaRedirect { .. } => Ok(
-                AdyenPaymentMethod::AlmaPayLater(Box::new(PmdForPaymentType {
-                    payment_type: PaymentType::Alma,
-                })),
-            ),
+            api_models::payments::PayLaterData::AlmaRedirect { .. } => {
+                check_required_field(telephone_number, "billing.phone")?;
+                check_required_field(shopper_email, "email")?;
+                check_required_field(billing_address, "billing")?;
+                check_required_field(delivery_address, "shipping")?;
+                Ok(AdyenPaymentMethod::AlmaPayLater(Box::new(
+                    PmdForPaymentType {
+                        payment_type: PaymentType::Alma,
+                    },
+                )))
+            }
             api_models::payments::PayLaterData::AtomeRedirect { .. } => {
+                check_required_field(shopper_email, "email")?;
+                check_required_field(shopper_name, "billing.first_name, billing.last_name")?;
+                check_required_field(telephone_number, "billing.phone")?;
+                check_required_field(billing_address, "billing")?;
                 Ok(AdyenPaymentMethod::Atome)
             }
             payments::PayLaterData::KlarnaSdk { .. } => Err(errors::ConnectorError::NotSupported {
@@ -2544,6 +2633,9 @@ impl<'a>
             shopper_reference,
             store_payment_method,
             channel: None,
+            shopper_statement: item.router_data.request.statement_descriptor.clone(),
+            shopper_ip: item.router_data.request.get_ip_address_as_optional(),
+            metadata: item.router_data.request.metadata.clone(),
         })
     }
 }
@@ -2564,12 +2656,22 @@ impl<'a>
         let amount = get_amount_data(item);
         let auth_type = AdyenAuthType::try_from(&item.router_data.connector_auth_type)?;
         let shopper_interaction = AdyenShopperInteraction::from(item.router_data);
-        let (recurring_processing_model, store_payment_method, shopper_reference) =
+        let shopper_reference = build_shopper_reference(
+            &item.router_data.customer_id,
+            item.router_data.merchant_id.clone(),
+        );
+        let (recurring_processing_model, store_payment_method, _) =
             get_recurring_processing_model(item.router_data)?;
         let browser_info = get_browser_info(item.router_data)?;
+        let billing_address =
+            get_address_info(item.router_data.address.billing.as_ref()).transpose()?;
+        let country_code = get_country_code(item.router_data.address.billing.as_ref());
         let additional_data = get_additional_data(item.router_data);
         let return_url = item.router_data.request.get_return_url()?;
         let payment_method = AdyenPaymentMethod::try_from(card_data)?;
+        let shopper_email = item.router_data.request.email.clone();
+        let shopper_name = get_shopper_name(item.router_data.address.billing.as_ref());
+
         Ok(AdyenPaymentRequest {
             amount,
             merchant_account: auth_type.merchant_account,
@@ -2581,17 +2683,20 @@ impl<'a>
             browser_info,
             additional_data,
             telephone_number: None,
-            shopper_name: None,
-            shopper_email: None,
+            shopper_name,
+            shopper_email,
             shopper_locale: None,
             social_security_number: None,
-            billing_address: None,
+            billing_address,
             delivery_address: None,
-            country_code: None,
+            country_code,
             line_items: None,
             shopper_reference,
             store_payment_method,
             channel: None,
+            shopper_statement: item.router_data.request.statement_descriptor.clone(),
+            shopper_ip: item.router_data.request.get_ip_address_as_optional(),
+            metadata: item.router_data.request.metadata.clone(),
         })
     }
 }
@@ -2642,6 +2747,9 @@ impl<'a>
             shopper_reference: None,
             store_payment_method: None,
             channel: None,
+            shopper_statement: item.router_data.request.statement_descriptor.clone(),
+            shopper_ip: item.router_data.request.get_ip_address_as_optional(),
+            metadata: item.router_data.request.metadata.clone(),
         };
         Ok(request)
     }
@@ -2693,6 +2801,9 @@ impl<'a>
             shopper_reference: None,
             store_payment_method: None,
             channel: None,
+            shopper_statement: item.router_data.request.statement_descriptor.clone(),
+            shopper_ip: item.router_data.request.get_ip_address_as_optional(),
+            metadata: item.router_data.request.metadata.clone(),
         };
         Ok(request)
     }
@@ -2740,6 +2851,9 @@ impl<'a>
             shopper_reference: None,
             store_payment_method: None,
             channel: None,
+            shopper_statement: item.router_data.request.statement_descriptor.clone(),
+            shopper_ip: item.router_data.request.get_ip_address_as_optional(),
+            metadata: item.router_data.request.metadata.clone(),
         };
         Ok(request)
     }
@@ -2787,6 +2901,9 @@ impl<'a>
             store_payment_method: None,
             channel: None,
             social_security_number: None,
+            shopper_statement: item.router_data.request.statement_descriptor.clone(),
+            shopper_ip: item.router_data.request.get_ip_address_as_optional(),
+            metadata: item.router_data.request.metadata.clone(),
         };
         Ok(request)
     }
@@ -2841,6 +2958,9 @@ impl<'a>
             shopper_reference,
             store_payment_method,
             channel: None,
+            shopper_statement: item.router_data.request.statement_descriptor.clone(),
+            shopper_ip: item.router_data.request.get_ip_address_as_optional(),
+            metadata: item.router_data.request.metadata.clone(),
         })
     }
 }
@@ -2935,6 +3055,9 @@ impl<'a>
             shopper_reference,
             store_payment_method,
             channel,
+            shopper_statement: item.router_data.request.statement_descriptor.clone(),
+            shopper_ip: item.router_data.request.get_ip_address_as_optional(),
+            metadata: item.router_data.request.metadata.clone(),
         })
     }
 }
@@ -2958,18 +3081,33 @@ impl<'a>
         let browser_info = get_browser_info(item.router_data)?;
         let additional_data = get_additional_data(item.router_data);
         let country_code = get_country_code(item.router_data.address.billing.as_ref());
-        let payment_method = AdyenPaymentMethod::try_from((paylater_data, country_code))?;
         let shopper_interaction = AdyenShopperInteraction::from(item.router_data);
-        let (recurring_processing_model, store_payment_method, shopper_reference) =
+        let shopper_reference = build_shopper_reference(
+            &item.router_data.customer_id,
+            item.router_data.merchant_id.clone(),
+        );
+        let (recurring_processing_model, store_payment_method, _) =
             get_recurring_processing_model(item.router_data)?;
         let return_url = item.router_data.request.get_return_url()?;
         let shopper_name: Option<ShopperName> =
             get_shopper_name(item.router_data.address.billing.as_ref());
         let shopper_email = item.router_data.request.email.clone();
-        let billing_address = get_address_info(item.router_data.address.billing.as_ref());
-        let delivery_address = get_address_info(item.router_data.address.shipping.as_ref());
+        let billing_address =
+            get_address_info(item.router_data.address.billing.as_ref()).transpose()?;
+        let delivery_address =
+            get_address_info(item.router_data.address.shipping.as_ref()).transpose()?;
         let line_items = Some(get_line_items(item));
         let telephone_number = get_telephone_number(item.router_data);
+        let payment_method = AdyenPaymentMethod::try_from((
+            paylater_data,
+            &country_code,
+            &shopper_email,
+            &shopper_reference,
+            &shopper_name,
+            &telephone_number,
+            &billing_address,
+            &delivery_address,
+        ))?;
         Ok(AdyenPaymentRequest {
             amount,
             merchant_account: auth_type.merchant_account,
@@ -2992,6 +3130,9 @@ impl<'a>
             shopper_reference,
             store_payment_method,
             channel: None,
+            shopper_statement: item.router_data.request.statement_descriptor.clone(),
+            shopper_ip: item.router_data.request.get_ip_address_as_optional(),
+            metadata: item.router_data.request.metadata.clone(),
         })
     }
 }
@@ -3047,6 +3188,9 @@ impl<'a>
             store_payment_method: None,
             channel: None,
             social_security_number: None,
+            shopper_statement: item.router_data.request.statement_descriptor.clone(),
+            shopper_ip: item.router_data.request.get_ip_address_as_optional(),
+            metadata: item.router_data.request.metadata.clone(),
         })
     }
 }
@@ -4522,7 +4666,8 @@ impl<F> TryFrom<&AdyenRouterData<&types::PayoutsRouterData<F>>> for AdyenPayoutC
                     date_of_birth: None,
                     entity_type: Some(item.router_data.request.entity_type),
                     nationality: get_country_code(item.router_data.address.billing.as_ref()),
-                    billing_address: get_address_info(item.router_data.address.billing.as_ref()),
+                    billing_address: get_address_info(item.router_data.address.billing.as_ref())
+                        .transpose()?,
                 })
             }
             PayoutMethodData::Wallet(wallet_data) => {
@@ -4561,7 +4706,8 @@ impl<F> TryFrom<&AdyenRouterData<&types::PayoutsRouterData<F>>> for AdyenPayoutC
                     date_of_birth: None,
                     entity_type: Some(item.router_data.request.entity_type),
                     nationality: get_country_code(item.router_data.address.billing.as_ref()),
-                    billing_address: get_address_info(item.router_data.address.billing.as_ref()),
+                    billing_address: get_address_info(item.router_data.address.billing.as_ref())
+                        .transpose()?,
                 })
             }
         }
@@ -4598,7 +4744,8 @@ impl<F> TryFrom<&AdyenRouterData<&types::PayoutsRouterData<F>>> for AdyenPayoutF
                         currency: item.router_data.request.destination_currency,
                     },
                     card: PayoutCardDetails::try_from(&item.router_data.get_payout_method_data()?)?,
-                    billing_address: get_address_info(item.router_data.get_billing().ok()),
+                    billing_address: get_address_info(item.router_data.get_billing().ok())
+                        .transpose()?,
                     merchant_account,
                     reference: item.router_data.request.payout_id.clone(),
                     shopper_name: ShopperName {

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

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

## Description
<!-- Describe your changes in detail -->

- Add shopper statement and metadata in payments request
- Add additional fields and validations over fields like `IP address`, `billing_address`, `Email` and Shopper details

### Additional Changes

- [ ] This PR modifies the API contract
- [ ] This PR modifies the database schema
- [X] 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`
-->
Production URL got updated for Adyen

## 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).
-->
#3914 

## 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 Klarna Payment
```
curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_6LLuoNT8iBk4hTwVLSQ6zTJOiBmeuLSJ5NoakZTZItC4IifnHLy7cTWPZXW4uhbq' \
--data-raw '{
    "amount": 6540,
    "currency": "EUR",
    "confirm": true,
    "capture_method": "manual",
    "capture_on": "2022-09-10T10:11:12Z",
    "amount_to_capture": 6540,
    
    "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://duck.com",
    "profile_id": "pro_B0AWG00VLGTFt4rTrj6a",
    "business_country": "US",
    "payment_method": "pay_later",
    "payment_method_type": "klarna",
    "payment_experience": "redirect_to_url",
    "connector": [
        "adyen"
    ],
    "payment_method_data": {
        "pay_later": {
            "klarna_redirect": {
                "billing_email": "hyperswitch_sdk_demo_id@gmail.com",
                "billing_country": "DE"
            }
        }
    },
    "routing": {
        "type": "single",
        "data": "adyen"
    },
    "billing": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "DE",
            "first_name": "PiX"
        }
    },
    "shipping": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "US",
            "first_name": "PiX"
        }
    },
    "statement_descriptor_name": "joseph",
    "statement_descriptor_suffix": "JS",
    "metadata": {
        "udf1": "value1",
        "new_customer": "true",
        "login_date": "2019-09-10T10:11:12Z"
    }
}'
```
- Test in Adyen dashboard all the fields should be visible like shopper statement, address and shopper reference
- Klarna Validation when not sending Email
```
curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_6LLuoNT8iBk4hTwVLSQ6zTJOiBmeuLSJ5NoakZTZItC4IifnHLy7cTWPZXW4uhbq' \
--data-raw '{
    "amount": 6540,
    "currency": "EUR",
    "confirm": true,
    "capture_method": "manual",
    "capture_on": "2022-09-10T10:11:12Z",
    "amount_to_capture": 6540,
    "name": "John Doe",
    "phone": "999999999",
    "phone_country_code": "+1",
    "description": "Its my first payment request",
    "authentication_type": "no_three_ds",
    "return_url": "https://duck.com",
    "profile_id": "pro_B0AWG00VLGTFt4rTrj6a",
    "business_country": "US",
    "payment_method": "pay_later",
    "payment_method_type": "klarna",
    "payment_experience": "redirect_to_url",
    "connector": [
        "adyen"
    ],
    "payment_method_data": {
        "pay_later": {
            "klarna_redirect": {
                "billing_email": "hyperswitch_sdk_demo_id@gmail.com",
                "billing_country": "DE"
            }
        }
    },
    "routing": {
        "type": "single",
        "data": "adyen"
    },
    "billing": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "DE",
            "first_name": "PiX"
        }
    },
    "shipping": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "US",
            "first_name": "PiX"
        }
    },
    "statement_descriptor_name": "joseph",
    "statement_descriptor_suffix": "JS",
    "metadata": {
        "udf1": "value1",
        "new_customer": "true",
        "login_date": "2019-09-10T10:11:12Z"
    }
}'
```
Expected Response: 

```
{
    "error": {
        "type": "invalid_request",
        "message": "Missing required param: email",
        "code": "IR_04"
    }
}
```


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