Skip to content

Commit

Permalink
feat(router): add accept-language from request headers into browser-i…
Browse files Browse the repository at this point in the history
…nfo (#7074)

Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
  • Loading branch information
sai-harsha-vardhan and hyperswitch-bot[bot] authored Jan 29, 2025
1 parent 275958a commit 5381eb9
Show file tree
Hide file tree
Showing 9 changed files with 45 additions and 10 deletions.
5 changes: 5 additions & 0 deletions api-reference-v2/openapi_spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -5696,6 +5696,11 @@
"type": "string",
"description": "The device model of the client",
"nullable": true
},
"accept_language": {
"type": "string",
"description": "Accept-language of the browser",
"nullable": true
}
}
},
Expand Down
3 changes: 3 additions & 0 deletions crates/common_utils/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1408,6 +1408,9 @@ pub struct BrowserInformation {

/// The device model of the client
pub device_model: Option<String>,

/// Accept-language of the browser
pub accept_language: Option<String>,
}

#[cfg(feature = "v2")]
Expand Down
2 changes: 2 additions & 0 deletions crates/hyperswitch_domain_models/src/router_request_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,7 @@ pub struct BrowserInformation {
pub os_type: Option<String>,
pub os_version: Option<String>,
pub device_model: Option<String>,
pub accept_language: Option<String>,
}

#[cfg(feature = "v2")]
Expand All @@ -508,6 +509,7 @@ impl From<common_utils::types::BrowserInformation> for BrowserInformation {
os_type: value.os_type,
os_version: value.os_version,
device_model: value.device_model,
accept_language: value.accept_language,
}
}
}
Expand Down
16 changes: 14 additions & 2 deletions crates/router/src/connector/netcetera/netcetera_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1372,6 +1372,15 @@ pub struct Browser {
accept_language: Option<Vec<String>>,
}

// Split by comma and return the list of accept languages
// If Accept-Language is : fr-CH, fr;q=0.9, en;q=0.8, de;q=0.7, List should be [fr-CH, fr, en, de]
pub fn get_list_of_accept_languages(accept_language: String) -> Vec<String> {
accept_language
.split(',')
.map(|lang| lang.split(';').next().unwrap_or(lang).trim().to_string())
.collect()
}

impl From<crate::types::BrowserInformation> for Browser {
fn from(value: crate::types::BrowserInformation) -> Self {
Self {
Expand All @@ -1388,8 +1397,11 @@ impl From<crate::types::BrowserInformation> for Browser {
browser_user_agent: value.user_agent,
challenge_window_size: Some(ChallengeWindowSizeEnum::FullScreen),
browser_javascript_enabled: value.java_script_enabled,
// Hardcoding to "en" for now, as there's no accept_language in BrowserInformation
accept_language: Some(vec!["en".to_string()]),
// Default to ["en"] locale if accept_language is not provided
accept_language: value
.accept_language
.map(get_list_of_accept_languages)
.or(Some(vec!["en".to_string()])),
}
}
}
Expand Down
1 change: 1 addition & 0 deletions crates/router/src/connector/trustpay/transformers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,7 @@ impl TryFrom<&TrustpayRouterData<&types::PaymentsAuthorizeRouterData>> for Trust
os_type: None,
os_version: None,
device_model: None,
accept_language: Some(browser_info.accept_language.unwrap_or("en".to_string())),
};
let params = get_mandatory_fields(item.router_data)?;
let amount = item.amount.to_owned();
Expand Down
15 changes: 8 additions & 7 deletions crates/router/src/routes/payments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -602,20 +602,21 @@ pub async fn payments_confirm(
return http_not_implemented();
};

if let Err(err) = helpers::populate_ip_into_browser_info(&req, &mut payload) {
let header_payload = match HeaderPayload::foreign_try_from(req.headers()) {
Ok(headers) => headers,
Err(err) => {
return api::log_and_return_error_response(err);
}
};

if let Err(err) = helpers::populate_browser_info(&req, &mut payload, &header_payload) {
return api::log_and_return_error_response(err);
}

let payment_id = path.into_inner();
tracing::Span::current().record("payment_id", payment_id.get_string_repr());
payload.payment_id = Some(payment_types::PaymentIdType::PaymentIntentId(payment_id));
payload.confirm = Some(true);
let header_payload = match HeaderPayload::foreign_try_from(req.headers()) {
Ok(headers) => headers,
Err(err) => {
return api::log_and_return_error_response(err);
}
};

let (auth_type, auth_flow) =
match auth::check_client_secret_and_get_auth(req.headers(), &payload) {
Expand Down
11 changes: 10 additions & 1 deletion crates/router/src/routes/payments/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ use crate::{
};

#[cfg(feature = "v1")]
pub fn populate_ip_into_browser_info(
pub fn populate_browser_info(
req: &actix_web::HttpRequest,
payload: &mut api::PaymentsRequest,
header_payload: &hyperswitch_domain_models::payments::HeaderPayload,
) -> RouterResult<()> {
let mut browser_info: types::BrowserInformation = payload
.browser_info
Expand All @@ -34,6 +35,7 @@ pub fn populate_ip_into_browser_info(
os_type: None,
os_version: None,
device_model: None,
accept_language: None,
});

let ip_address = req
Expand All @@ -59,6 +61,13 @@ pub fn populate_ip_into_browser_info(
})
});

// If the locale is present in the header payload, we will use it as the accept language
if header_payload.locale.is_some() {
browser_info.accept_language = browser_info
.accept_language
.or(header_payload.locale.clone());
}

if let Some(api::MandateData {
customer_acceptance:
Some(api::CustomerAcceptance {
Expand Down
1 change: 1 addition & 0 deletions crates/router/tests/connectors/trustpay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ fn get_default_browser_info() -> BrowserInformation {
os_type: None,
os_version: None,
device_model: None,
accept_language: Some("en".to_string()),
}
}

Expand Down
1 change: 1 addition & 0 deletions crates/router/tests/connectors/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1022,6 +1022,7 @@ impl Default for BrowserInfoType {
device_model: Some("Apple IPHONE 7".to_string()),
os_type: Some("IOS or ANDROID".to_string()),
os_version: Some("IOS 14.5".to_string()),
accept_language: Some("en".to_string()),
};
Self(data)
}
Expand Down

0 comments on commit 5381eb9

Please sign in to comment.