diff --git a/api-reference-v2/openapi_spec.json b/api-reference-v2/openapi_spec.json index 3f1a0ae01d..b1c33c253a 100644 --- a/api-reference-v2/openapi_spec.json +++ b/api-reference-v2/openapi_spec.json @@ -5613,6 +5613,21 @@ "type": "string", "description": "User-agent of the browser", "nullable": true + }, + "os_type": { + "type": "string", + "description": "The os type of the client device", + "nullable": true + }, + "os_version": { + "type": "string", + "description": "The os version of the client device", + "nullable": true + }, + "device_model": { + "type": "string", + "description": "The device model of the client", + "nullable": true } } }, diff --git a/api-reference/openapi_spec.json b/api-reference/openapi_spec.json index 2f34aa9ec6..c7527405a5 100644 --- a/api-reference/openapi_spec.json +++ b/api-reference/openapi_spec.json @@ -8325,6 +8325,21 @@ "type": "string", "description": "User-agent of the browser", "nullable": true + }, + "os_type": { + "type": "string", + "description": "The os type of the client device", + "nullable": true + }, + "os_version": { + "type": "string", + "description": "The os version of the client device", + "nullable": true + }, + "device_model": { + "type": "string", + "description": "The device model of the client", + "nullable": true } } }, diff --git a/crates/api_models/src/payments.rs b/crates/api_models/src/payments.rs index a7211e6f82..ed537c3efe 100644 --- a/crates/api_models/src/payments.rs +++ b/crates/api_models/src/payments.rs @@ -1282,6 +1282,15 @@ pub struct BrowserInformation { /// User-agent of the browser pub user_agent: Option, + + /// The os type of the client device + pub os_type: Option, + + /// The os version of the client device + pub os_version: Option, + + /// The device model of the client + pub device_model: Option, } impl RequestSurchargeDetails { diff --git a/crates/common_utils/src/types.rs b/crates/common_utils/src/types.rs index 0d39841fe0..9e71ca7673 100644 --- a/crates/common_utils/src/types.rs +++ b/crates/common_utils/src/types.rs @@ -1399,6 +1399,15 @@ pub struct BrowserInformation { /// User-agent of the browser pub user_agent: Option, + + /// The os type of the client device + pub os_type: Option, + + /// The os version of the client device + pub os_version: Option, + + /// The device model of the client + pub device_model: Option, } #[cfg(feature = "v2")] diff --git a/crates/hyperswitch_connectors/src/connectors/airwallex/transformers.rs b/crates/hyperswitch_connectors/src/connectors/airwallex/transformers.rs index e8ab479c97..075a7b070d 100644 --- a/crates/hyperswitch_connectors/src/connectors/airwallex/transformers.rs +++ b/crates/hyperswitch_connectors/src/connectors/airwallex/transformers.rs @@ -1,5 +1,5 @@ use common_enums::enums; -use common_utils::{errors::ParsingError, request::Method}; +use common_utils::{errors::ParsingError, pii::IpAddress, request::Method}; use error_stack::ResultExt; use hyperswitch_domain_models::{ payment_method_data::{PaymentMethodData, WalletData}, @@ -21,7 +21,7 @@ use uuid::Uuid; use crate::{ types::{RefundsResponseRouterData, ResponseRouterData}, - utils::{self, CardData as _}, + utils::{self, BrowserInformationData, CardData as _, PaymentsAuthorizeRequestData}, }; pub struct AirwallexAuthType { @@ -124,6 +124,40 @@ pub struct AirwallexPaymentsRequest { payment_method: AirwallexPaymentMethod, payment_method_options: Option, return_url: Option, + device_data: DeviceData, +} + +#[derive(Debug, Serialize)] +pub struct DeviceData { + accept_header: String, + browser: Browser, + ip_address: Secret, + language: String, + mobile: Option, + screen_color_depth: u8, + screen_height: u32, + screen_width: u32, + timezone: String, +} + +#[derive(Debug, Serialize)] +pub struct Browser { + java_enabled: bool, + javascript_enabled: bool, + user_agent: String, +} + +#[derive(Debug, Serialize)] +pub struct Location { + lat: String, + lon: String, +} + +#[derive(Debug, Serialize)] +pub struct Mobile { + device_model: Option, + os_type: Option, + os_version: Option, } #[derive(Debug, Serialize)] @@ -242,16 +276,55 @@ impl TryFrom<&AirwallexRouterData<&types::PaymentsAuthorizeRouterData>> )) } }?; + let device_data = get_device_data(item.router_data)?; Ok(Self { request_id: Uuid::new_v4().to_string(), payment_method, payment_method_options, return_url: request.complete_authorize_url.clone(), + device_data, }) } } +fn get_device_data( + item: &types::PaymentsAuthorizeRouterData, +) -> Result> { + let info = item.request.get_browser_info()?; + let browser = Browser { + java_enabled: info.get_java_enabled()?, + javascript_enabled: info.get_java_script_enabled()?, + user_agent: info.get_user_agent()?, + }; + let mobile = { + let device_model = info.get_device_model().ok(); + let os_type = info.get_os_type().ok(); + let os_version = info.get_os_version().ok(); + + if device_model.is_some() || os_type.is_some() || os_version.is_some() { + Some(Mobile { + device_model, + os_type, + os_version, + }) + } else { + None + } + }; + Ok(DeviceData { + accept_header: info.get_accept_header()?, + browser, + ip_address: info.get_ip_address()?, + mobile, + screen_color_depth: info.get_color_depth()?, + screen_height: info.get_screen_height()?, + screen_width: info.get_screen_width()?, + timezone: info.get_time_zone()?.to_string(), + language: info.get_language()?, + }) +} + fn get_wallet_details( wallet_data: &WalletData, ) -> Result { diff --git a/crates/hyperswitch_connectors/src/utils.rs b/crates/hyperswitch_connectors/src/utils.rs index cf32d966e0..d1205dd8bb 100644 --- a/crates/hyperswitch_connectors/src/utils.rs +++ b/crates/hyperswitch_connectors/src/utils.rs @@ -1759,6 +1759,9 @@ pub trait BrowserInformationData { fn get_java_enabled(&self) -> Result; fn get_java_script_enabled(&self) -> Result; fn get_ip_address(&self) -> Result, Error>; + fn get_os_type(&self) -> Result; + fn get_os_version(&self) -> Result; + fn get_device_model(&self) -> Result; } impl BrowserInformationData for BrowserInformation { @@ -1807,6 +1810,21 @@ impl BrowserInformationData for BrowserInformation { self.java_script_enabled .ok_or_else(missing_field_err("browser_info.java_script_enabled")) } + fn get_os_type(&self) -> Result { + self.os_type + .clone() + .ok_or_else(missing_field_err("browser_info.os_type")) + } + fn get_os_version(&self) -> Result { + self.os_version + .clone() + .ok_or_else(missing_field_err("browser_info.os_version")) + } + fn get_device_model(&self) -> Result { + self.device_model + .clone() + .ok_or_else(missing_field_err("browser_info.device_model")) + } } pub fn get_header_key_value<'a>( diff --git a/crates/hyperswitch_domain_models/src/router_request_types.rs b/crates/hyperswitch_domain_models/src/router_request_types.rs index 55624af9f7..aa9fb2b5f1 100644 --- a/crates/hyperswitch_domain_models/src/router_request_types.rs +++ b/crates/hyperswitch_domain_models/src/router_request_types.rs @@ -486,6 +486,9 @@ pub struct BrowserInformation { pub ip_address: Option, pub accept_header: Option, pub user_agent: Option, + pub os_type: Option, + pub os_version: Option, + pub device_model: Option, } #[derive(Debug, Clone, Default, Serialize)] diff --git a/crates/router/src/connector/trustpay/transformers.rs b/crates/router/src/connector/trustpay/transformers.rs index c20cc1aeb3..3006a73a3e 100644 --- a/crates/router/src/connector/trustpay/transformers.rs +++ b/crates/router/src/connector/trustpay/transformers.rs @@ -398,6 +398,9 @@ impl TryFrom<&TrustpayRouterData<&types::PaymentsAuthorizeRouterData>> for Trust accept_header: Some(browser_info.accept_header.unwrap_or("*".to_string())), user_agent: browser_info.user_agent, ip_address: browser_info.ip_address, + os_type: None, + os_version: None, + device_model: None, }; let params = get_mandatory_fields(item.router_data)?; let amount = item.amount.to_owned(); diff --git a/crates/router/src/routes/payments/helpers.rs b/crates/router/src/routes/payments/helpers.rs index 5b0ef815b2..529475a358 100644 --- a/crates/router/src/routes/payments/helpers.rs +++ b/crates/router/src/routes/payments/helpers.rs @@ -31,6 +31,9 @@ pub fn populate_ip_into_browser_info( accept_header: None, user_agent: None, ip_address: None, + os_type: None, + os_version: None, + device_model: None, }); let ip_address = req diff --git a/crates/router/tests/connectors/trustpay.rs b/crates/router/tests/connectors/trustpay.rs index 308bf51358..2e5ea6d50f 100644 --- a/crates/router/tests/connectors/trustpay.rs +++ b/crates/router/tests/connectors/trustpay.rs @@ -49,6 +49,9 @@ fn get_default_browser_info() -> BrowserInformation { accept_header: Some("*".to_string()), user_agent: Some("none".to_string()), ip_address: None, + os_type: None, + os_version: None, + device_model: None, } } diff --git a/crates/router/tests/connectors/utils.rs b/crates/router/tests/connectors/utils.rs index 489b55a227..361cda63a9 100644 --- a/crates/router/tests/connectors/utils.rs +++ b/crates/router/tests/connectors/utils.rs @@ -1013,6 +1013,9 @@ impl Default for BrowserInfoType { java_enabled: Some(true), java_script_enabled: Some(true), ip_address: Some("127.0.0.1".parse().unwrap()), + device_model: Some("Apple IPHONE 7".to_string()), + os_type: Some("IOS or ANDROID".to_string()), + os_version: Some("IOS 14.5".to_string()), }; Self(data) }