diff --git a/api-reference-v2/openapi_spec.json b/api-reference-v2/openapi_spec.json index 6c3e9f5072ae..0f62f1112770 100644 --- a/api-reference-v2/openapi_spec.json +++ b/api-reference-v2/openapi_spec.json @@ -5537,6 +5537,11 @@ "description": "A list of allowed domains (glob patterns) where this link can be embedded / opened from", "uniqueItems": true, "nullable": true + }, + "branding_visibility": { + "type": "boolean", + "description": "Toggle for HyperSwitch branding visibility", + "nullable": true } } } @@ -7882,6 +7887,61 @@ } } }, + "ElementPosition": { + "type": "string", + "enum": [ + "left", + "top left", + "top", + "top right", + "right", + "bottom right", + "bottom", + "bottom left", + "center" + ] + }, + "ElementSize": { + "oneOf": [ + { + "type": "object", + "required": [ + "Variants" + ], + "properties": { + "Variants": { + "$ref": "#/components/schemas/SizeVariants" + } + } + }, + { + "type": "object", + "required": [ + "Percentage" + ], + "properties": { + "Percentage": { + "type": "integer", + "format": "int32", + "minimum": 0 + } + } + }, + { + "type": "object", + "required": [ + "Pixels" + ], + "properties": { + "Pixels": { + "type": "integer", + "format": "int32", + "minimum": 0 + } + } + } + ] + }, "EnablePaymentLinkRequest": { "type": "string", "description": "Whether payment link is requested to be enabled or not for this transaction", @@ -12540,6 +12600,35 @@ } } }, + "PaymentLinkBackgroundImageConfig": { + "type": "object", + "required": [ + "url" + ], + "properties": { + "url": { + "type": "string", + "description": "URL of the image", + "example": "https://hyperswitch.io/favicon.ico" + }, + "position": { + "allOf": [ + { + "$ref": "#/components/schemas/ElementPosition" + } + ], + "nullable": true + }, + "size": { + "allOf": [ + { + "$ref": "#/components/schemas/ElementSize" + } + ], + "nullable": true + } + } + }, "PaymentLinkConfig": { "type": "object", "required": [ @@ -12601,6 +12690,27 @@ }, "description": "Dynamic details related to merchant to be rendered in payment link", "nullable": true + }, + "background_image": { + "allOf": [ + { + "$ref": "#/components/schemas/PaymentLinkBackgroundImageConfig" + } + ], + "nullable": true + }, + "details_layout": { + "allOf": [ + { + "$ref": "#/components/schemas/PaymentLinkDetailsLayout" + } + ], + "nullable": true + }, + "branding_visibility": { + "type": "boolean", + "description": "Toggle for HyperSwitch branding visibility", + "nullable": true } } }, @@ -12670,9 +12780,32 @@ }, "description": "Dynamic details related to merchant to be rendered in payment link", "nullable": true + }, + "background_image": { + "allOf": [ + { + "$ref": "#/components/schemas/PaymentLinkBackgroundImageConfig" + } + ], + "nullable": true + }, + "details_layout": { + "allOf": [ + { + "$ref": "#/components/schemas/PaymentLinkDetailsLayout" + } + ], + "nullable": true } } }, + "PaymentLinkDetailsLayout": { + "type": "string", + "enum": [ + "layout1", + "layout2" + ] + }, "PaymentLinkInitiateRequest": { "type": "object", "required": [ @@ -20016,6 +20149,13 @@ } ] }, + "SizeVariants": { + "type": "string", + "enum": [ + "cover", + "contain" + ] + }, "StraightThroughAlgorithm": { "oneOf": [ { diff --git a/api-reference/openapi_spec.json b/api-reference/openapi_spec.json index ce383f240647..8b06e167e21a 100644 --- a/api-reference/openapi_spec.json +++ b/api-reference/openapi_spec.json @@ -7974,6 +7974,11 @@ "description": "A list of allowed domains (glob patterns) where this link can be embedded / opened from", "uniqueItems": true, "nullable": true + }, + "branding_visibility": { + "type": "boolean", + "description": "Toggle for HyperSwitch branding visibility", + "nullable": true } } } @@ -10268,6 +10273,61 @@ "none" ] }, + "ElementPosition": { + "type": "string", + "enum": [ + "left", + "top left", + "top", + "top right", + "right", + "bottom right", + "bottom", + "bottom left", + "center" + ] + }, + "ElementSize": { + "oneOf": [ + { + "type": "object", + "required": [ + "Variants" + ], + "properties": { + "Variants": { + "$ref": "#/components/schemas/SizeVariants" + } + } + }, + { + "type": "object", + "required": [ + "Percentage" + ], + "properties": { + "Percentage": { + "type": "integer", + "format": "int32", + "minimum": 0 + } + } + }, + { + "type": "object", + "required": [ + "Pixels" + ], + "properties": { + "Pixels": { + "type": "integer", + "format": "int32", + "minimum": 0 + } + } + } + ] + }, "EnabledPaymentMethod": { "type": "object", "description": "Object for EnabledPaymentMethod", @@ -15255,6 +15315,35 @@ } } }, + "PaymentLinkBackgroundImageConfig": { + "type": "object", + "required": [ + "url" + ], + "properties": { + "url": { + "type": "string", + "description": "URL of the image", + "example": "https://hyperswitch.io/favicon.ico" + }, + "position": { + "allOf": [ + { + "$ref": "#/components/schemas/ElementPosition" + } + ], + "nullable": true + }, + "size": { + "allOf": [ + { + "$ref": "#/components/schemas/ElementSize" + } + ], + "nullable": true + } + } + }, "PaymentLinkConfig": { "type": "object", "required": [ @@ -15316,6 +15405,27 @@ }, "description": "Dynamic details related to merchant to be rendered in payment link", "nullable": true + }, + "background_image": { + "allOf": [ + { + "$ref": "#/components/schemas/PaymentLinkBackgroundImageConfig" + } + ], + "nullable": true + }, + "details_layout": { + "allOf": [ + { + "$ref": "#/components/schemas/PaymentLinkDetailsLayout" + } + ], + "nullable": true + }, + "branding_visibility": { + "type": "boolean", + "description": "Toggle for HyperSwitch branding visibility", + "nullable": true } } }, @@ -15385,9 +15495,32 @@ }, "description": "Dynamic details related to merchant to be rendered in payment link", "nullable": true + }, + "background_image": { + "allOf": [ + { + "$ref": "#/components/schemas/PaymentLinkBackgroundImageConfig" + } + ], + "nullable": true + }, + "details_layout": { + "allOf": [ + { + "$ref": "#/components/schemas/PaymentLinkDetailsLayout" + } + ], + "nullable": true } } }, + "PaymentLinkDetailsLayout": { + "type": "string", + "enum": [ + "layout1", + "layout2" + ] + }, "PaymentLinkInitiateRequest": { "type": "object", "required": [ @@ -23934,6 +24067,13 @@ } ] }, + "SizeVariants": { + "type": "string", + "enum": [ + "cover", + "contain" + ] + }, "StraightThroughAlgorithm": { "oneOf": [ { diff --git a/config/deployments/production.toml b/config/deployments/production.toml index 82f9b65b27a7..d4432b7021b9 100644 --- a/config/deployments/production.toml +++ b/config/deployments/production.toml @@ -179,7 +179,7 @@ card.credit = { connector_list = "cybersource" } # Update Mandate sup card.debit = { connector_list = "cybersource" } # Update Mandate supported payment method type and connector for card [network_transaction_id_supported_connectors] -connector_list = "stripe,adyen,cybersource" +connector_list = "adyen" [payouts] payout_eligibility = true # Defaults the eligibility of a payout method to true in case connector does not provide checks for payout eligibility diff --git a/crates/api_models/src/admin.rs b/crates/api_models/src/admin.rs index 769ef5928030..226d39740533 100644 --- a/crates/api_models/src/admin.rs +++ b/crates/api_models/src/admin.rs @@ -2667,6 +2667,8 @@ pub struct BusinessPaymentLinkConfig { /// A list of allowed domains (glob patterns) where this link can be embedded / opened from #[schema(value_type = Option>)] pub allowed_domains: Option>, + /// Toggle for HyperSwitch branding visibility + pub branding_visibility: Option, } impl BusinessPaymentLinkConfig { @@ -2725,6 +2727,11 @@ pub struct PaymentLinkConfigRequest { pub show_card_form_by_default: Option, /// Dynamic details related to merchant to be rendered in payment link pub transaction_details: Option>, + /// Configurations for the background image for details section + pub background_image: Option, + /// Custom layout for details section + #[schema(value_type = Option, example = "layout1")] + pub details_layout: Option, } #[derive(Clone, Debug, serde::Deserialize, serde::Serialize, PartialEq, ToSchema)] @@ -2752,6 +2759,19 @@ pub struct TransactionDetailsUiConfiguration { pub is_value_bold: Option, } +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, PartialEq, ToSchema)] +pub struct PaymentLinkBackgroundImageConfig { + /// URL of the image + #[schema(value_type = String, example = "https://hyperswitch.io/favicon.ico")] + pub url: common_utils::types::Url, + /// Position of the image in the UI + #[schema(value_type = Option, example = "top-left")] + pub position: Option, + /// Size of the image in the UI + #[schema(value_type = Option, example = "contain")] + pub size: Option, +} + #[derive(Clone, Debug, serde::Serialize, serde::Deserialize, PartialEq, ToSchema)] pub struct PaymentLinkConfig { /// custom theme for the payment link @@ -2774,6 +2794,13 @@ pub struct PaymentLinkConfig { pub allowed_domains: Option>, /// Dynamic details related to merchant to be rendered in payment link pub transaction_details: Option>, + /// Configurations for the background image for details section + pub background_image: Option, + /// Custom layout for details section + #[schema(value_type = Option, example = "layout1")] + pub details_layout: Option, + /// Toggle for HyperSwitch branding visibility + pub branding_visibility: Option, } #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, Eq)] diff --git a/crates/api_models/src/payments.rs b/crates/api_models/src/payments.rs index 2114bc9f6ca5..83246d944a31 100644 --- a/crates/api_models/src/payments.rs +++ b/crates/api_models/src/payments.rs @@ -6856,6 +6856,9 @@ pub struct PaymentLinkDetails { pub show_card_form_by_default: bool, pub locale: Option, pub transaction_details: Option>, + pub background_image: Option, + pub details_layout: Option, + pub branding_visibility: Option, } #[derive(Debug, serde::Serialize, Clone)] diff --git a/crates/common_enums/src/enums.rs b/crates/common_enums/src/enums.rs index 88c3b6846781..2a74983f2512 100644 --- a/crates/common_enums/src/enums.rs +++ b/crates/common_enums/src/enums.rs @@ -1,8 +1,10 @@ mod payments; +mod ui; use std::num::{ParseFloatError, TryFromIntError}; pub use payments::ProductType; use serde::{Deserialize, Serialize}; +pub use ui::*; use utoipa::ToSchema; pub use super::connector_enums::RoutableConnectors; diff --git a/crates/common_enums/src/enums/ui.rs b/crates/common_enums/src/enums/ui.rs new file mode 100644 index 000000000000..aec6c7ed64a2 --- /dev/null +++ b/crates/common_enums/src/enums/ui.rs @@ -0,0 +1,149 @@ +use std::fmt; + +use serde::{de::Visitor, Deserialize, Deserializer, Serialize}; +use utoipa::ToSchema; + +#[derive( + Clone, + Copy, + Debug, + Default, + Eq, + Hash, + PartialEq, + Serialize, + Deserialize, + strum::Display, + strum::EnumString, + ToSchema, +)] +#[router_derive::diesel_enum(storage_type = "db_enum")] +#[serde(rename_all = "lowercase")] +pub enum ElementPosition { + Left, + #[default] + #[serde(rename = "top left")] + TopLeft, + Top, + #[serde(rename = "top right")] + TopRight, + Right, + #[serde(rename = "bottom right")] + BottomRight, + Bottom, + #[serde(rename = "bottom left")] + BottomLeft, + Center, +} + +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, strum::Display, strum::EnumString, ToSchema)] +#[router_derive::diesel_enum(storage_type = "db_enum")] +pub enum ElementSize { + Variants(SizeVariants), + Percentage(u32), + Pixels(u32), +} + +#[derive( + Clone, + Copy, + Debug, + Default, + Eq, + Hash, + PartialEq, + Serialize, + Deserialize, + strum::Display, + strum::EnumString, + ToSchema, +)] +#[router_derive::diesel_enum(storage_type = "db_enum")] +#[serde(rename_all = "lowercase")] +#[strum(serialize_all = "lowercase")] +pub enum SizeVariants { + #[default] + Cover, + Contain, +} + +#[derive( + Clone, + Copy, + Debug, + Default, + Eq, + Hash, + PartialEq, + Serialize, + Deserialize, + strum::Display, + strum::EnumString, + ToSchema, +)] +#[router_derive::diesel_enum(storage_type = "db_enum")] +#[serde(rename_all = "lowercase")] +#[strum(serialize_all = "lowercase")] +pub enum PaymentLinkDetailsLayout { + #[default] + Layout1, + Layout2, +} + +impl<'de> Deserialize<'de> for ElementSize { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct ElementSizeVisitor; + + impl Visitor<'_> for ElementSizeVisitor { + type Value = ElementSize; + + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + formatter.write_str("a string with possible values - contain, cover or values in percentage or pixels. For eg: 48px or 50%") + } + + fn visit_str(self, value: &str) -> Result + where + E: serde::de::Error, + { + if let Some(percent) = value.strip_suffix('%') { + percent + .parse::() + .map(ElementSize::Percentage) + .map_err(E::custom) + } else if let Some(px) = value.strip_suffix("px") { + px.parse::() + .map(ElementSize::Pixels) + .map_err(E::custom) + } else { + match value { + "cover" => Ok(ElementSize::Variants(SizeVariants::Cover)), + "contain" => Ok(ElementSize::Variants(SizeVariants::Contain)), + _ => Err(E::custom("invalid size variant")), + } + } + } + } + + deserializer.deserialize_str(ElementSizeVisitor) + } +} + +impl Serialize for ElementSize { + fn serialize(&self, serializer: S) -> Result + where + S: serde::ser::Serializer, + { + match self { + Self::Variants(variant) => serializer.serialize_str(variant.to_string().as_str()), + Self::Pixels(pixel_count) => { + serializer.serialize_str(format!("{}px", pixel_count).as_str()) + } + Self::Percentage(pixel_count) => { + serializer.serialize_str(format!("{}%", pixel_count).as_str()) + } + } + } +} diff --git a/crates/diesel_models/src/business_profile.rs b/crates/diesel_models/src/business_profile.rs index 0cae67873d65..bafd1897200c 100644 --- a/crates/diesel_models/src/business_profile.rs +++ b/crates/diesel_models/src/business_profile.rs @@ -556,6 +556,7 @@ pub struct BusinessPaymentLinkConfig { pub default_config: Option, pub business_specific_configs: Option>, pub allowed_domains: Option>, + pub branding_visibility: Option, } #[derive(Clone, Debug, serde::Deserialize, serde::Serialize)] @@ -568,6 +569,15 @@ pub struct PaymentLinkConfigRequest { pub enabled_saved_payment_method: Option, pub hide_card_nickname_field: Option, pub show_card_form_by_default: Option, + pub background_image: Option, + pub details_layout: Option, +} + +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, PartialEq)] +pub struct PaymentLinkBackgroundImageConfig { + pub url: common_utils::types::Url, + pub position: Option, + pub size: Option, } common_utils::impl_to_sql_from_sql_json!(BusinessPaymentLinkConfig); diff --git a/crates/diesel_models/src/payment_intent.rs b/crates/diesel_models/src/payment_intent.rs index b29da50d0a7d..8d037c5356f4 100644 --- a/crates/diesel_models/src/payment_intent.rs +++ b/crates/diesel_models/src/payment_intent.rs @@ -4,13 +4,13 @@ use diesel::{AsChangeset, Identifiable, Insertable, Queryable, Selectable}; use serde::{Deserialize, Serialize}; use time::PrimitiveDateTime; -use crate::enums as storage_enums; #[cfg(feature = "v1")] use crate::schema::payment_intent; #[cfg(feature = "v2")] use crate::schema_v2::payment_intent; #[cfg(feature = "v2")] use crate::types::{FeatureMetadata, OrderDetailsWithAmount}; +use crate::{business_profile::PaymentLinkBackgroundImageConfig, enums as storage_enums}; #[cfg(feature = "v2")] #[derive(Clone, Debug, PartialEq, Identifiable, Queryable, Serialize, Deserialize, Selectable)] @@ -161,6 +161,10 @@ pub struct PaymentLinkConfigRequestForPayments { pub show_card_form_by_default: Option, /// Dynamic details related to merchant to be rendered in payment link pub transaction_details: Option>, + /// Configurations for the background image for details section + pub background_image: Option, + /// Custom layout for details section + pub details_layout: Option, } common_utils::impl_to_sql_from_sql_json!(PaymentLinkConfigRequestForPayments); diff --git a/crates/hyperswitch_domain_models/src/lib.rs b/crates/hyperswitch_domain_models/src/lib.rs index 31732e132868..0e8722644bd4 100644 --- a/crates/hyperswitch_domain_models/src/lib.rs +++ b/crates/hyperswitch_domain_models/src/lib.rs @@ -193,6 +193,7 @@ impl ApiModelToDieselModelConvertor enabled_saved_payment_method: item.enabled_saved_payment_method, hide_card_nickname_field: item.hide_card_nickname_field, show_card_form_by_default: item.show_card_form_by_default, + details_layout: item.details_layout, transaction_details: item.transaction_details.map(|transaction_details| { transaction_details .into_iter() @@ -203,6 +204,11 @@ impl ApiModelToDieselModelConvertor }) .collect() }), + background_image: item.background_image.map(|background_image| { + diesel_models::business_profile::PaymentLinkBackgroundImageConfig::convert_from( + background_image, + ) + }), } } fn convert_back(self) -> api_models::admin::PaymentLinkConfigRequest { @@ -216,6 +222,8 @@ impl ApiModelToDieselModelConvertor hide_card_nickname_field, show_card_form_by_default, transaction_details, + background_image, + details_layout, } = self; api_models::admin::PaymentLinkConfigRequest { theme, @@ -226,12 +234,15 @@ impl ApiModelToDieselModelConvertor enabled_saved_payment_method, hide_card_nickname_field, show_card_form_by_default, + details_layout, transaction_details: transaction_details.map(|transaction_details| { transaction_details .into_iter() .map(|transaction_detail| transaction_detail.convert_back()) .collect() }), + background_image: background_image + .map(|background_image| background_image.convert_back()), } } } @@ -264,6 +275,31 @@ impl ApiModelToDieselModelConvertor + for diesel_models::business_profile::PaymentLinkBackgroundImageConfig +{ + fn convert_from(from: api_models::admin::PaymentLinkBackgroundImageConfig) -> Self { + Self { + url: from.url, + position: from.position, + size: from.size, + } + } + fn convert_back(self) -> api_models::admin::PaymentLinkBackgroundImageConfig { + let Self { + url, + position, + size, + } = self; + api_models::admin::PaymentLinkBackgroundImageConfig { + url, + position, + size, + } + } +} + #[cfg(feature = "v2")] impl ApiModelToDieselModelConvertor for diesel_models::TransactionDetailsUiConfiguration diff --git a/crates/openapi/src/openapi.rs b/crates/openapi/src/openapi.rs index d50bf863b5b8..68b0893bcc00 100644 --- a/crates/openapi/src/openapi.rs +++ b/crates/openapi/src/openapi.rs @@ -286,6 +286,10 @@ Never share your secret api keys. Keep them guarded and secure. api_models::enums::ReconStatus, api_models::enums::ConnectorStatus, api_models::enums::AuthorizationStatus, + api_models::enums::ElementPosition, + api_models::enums::ElementSize, + api_models::enums::SizeVariants, + api_models::enums::PaymentLinkDetailsLayout, api_models::enums::PaymentMethodStatus, api_models::enums::UIWidgetFormLayout, api_models::admin::MerchantConnectorCreate, @@ -305,6 +309,7 @@ Never share your secret api keys. Keep them guarded and secure. api_models::admin::ProfileCreate, api_models::admin::ProfileResponse, api_models::admin::BusinessPaymentLinkConfig, + api_models::admin::PaymentLinkBackgroundImageConfig, api_models::admin::PaymentLinkConfigRequest, api_models::admin::PaymentLinkConfig, api_models::admin::PaymentLinkTransactionDetails, diff --git a/crates/openapi/src/openapi_v2.rs b/crates/openapi/src/openapi_v2.rs index 688d749d5d99..e3c9ef0b0155 100644 --- a/crates/openapi/src/openapi_v2.rs +++ b/crates/openapi/src/openapi_v2.rs @@ -247,6 +247,10 @@ Never share your secret api keys. Keep them guarded and secure. api_models::enums::ReconStatus, api_models::enums::ConnectorStatus, api_models::enums::AuthorizationStatus, + api_models::enums::ElementPosition, + api_models::enums::ElementSize, + api_models::enums::SizeVariants, + api_models::enums::PaymentLinkDetailsLayout, api_models::enums::PaymentMethodStatus, api_models::enums::OrderFulfillmentTimeOrigin, api_models::enums::UIWidgetFormLayout, @@ -267,6 +271,7 @@ Never share your secret api keys. Keep them guarded and secure. api_models::admin::ProfileCreate, api_models::admin::ProfileResponse, api_models::admin::BusinessPaymentLinkConfig, + api_models::admin::PaymentLinkBackgroundImageConfig, api_models::admin::PaymentLinkConfigRequest, api_models::admin::PaymentLinkConfig, api_models::admin::PaymentLinkTransactionDetails, diff --git a/crates/router/src/core/payment_link.rs b/crates/router/src/core/payment_link.rs index bc66461e8192..f9522b04d95c 100644 --- a/crates/router/src/core/payment_link.rs +++ b/crates/router/src/core/payment_link.rs @@ -35,7 +35,7 @@ use crate::{ api::payment_link::PaymentLinkResponseExt, domain, storage::{enums as storage_enums, payment_link::PaymentLink}, - transformers::ForeignFrom, + transformers::{ForeignFrom, ForeignInto}, }, }; @@ -129,6 +129,9 @@ pub async fn form_payment_link_data( show_card_form_by_default: DEFAULT_SHOW_CARD_FORM, allowed_domains: DEFAULT_ALLOWED_DOMAINS, transaction_details: None, + background_image: None, + details_layout: None, + branding_visibility: None, } }; @@ -271,6 +274,9 @@ pub async fn form_payment_link_data( show_card_form_by_default: payment_link_config.show_card_form_by_default, locale, transaction_details: payment_link_config.transaction_details.clone(), + background_image: payment_link_config.background_image.clone(), + details_layout: payment_link_config.details_layout, + branding_visibility: payment_link_config.branding_visibility, }; Ok(( @@ -586,18 +592,16 @@ pub fn get_payment_link_config_based_on_priority( default_domain_name: String, payment_link_config_id: Option, ) -> Result<(PaymentLinkConfig, String), error_stack::Report> { - let (domain_name, business_theme_configs, allowed_domains) = + let (domain_name, business_theme_configs, allowed_domains, branding_visibility) = if let Some(business_config) = business_link_config { - logger::info!( - "domain name set to custom domain https://{:?}", - business_config.domain_name - ); - ( business_config .domain_name .clone() - .map(|d_name| format!("https://{}", d_name)) + .map(|d_name| { + logger::info!("domain name set to custom domain https://{:?}", d_name); + format!("https://{}", d_name) + }) .unwrap_or_else(|| default_domain_name.clone()), payment_link_config_id .and_then(|id| { @@ -608,9 +612,10 @@ pub fn get_payment_link_config_based_on_priority( }) .or(business_config.default_config), business_config.allowed_domains, + business_config.branding_visibility, ) } else { - (default_domain_name, None, None) + (default_domain_name, None, None, None) }; let ( @@ -637,19 +642,45 @@ pub fn get_payment_link_config_based_on_priority( (hide_card_nickname_field, DEFAULT_HIDE_CARD_NICKNAME_FIELD), (show_card_form_by_default, DEFAULT_SHOW_CARD_FORM) ); - let payment_link_config = PaymentLinkConfig { - theme, - logo, - seller_name, - sdk_layout, - display_sdk_only, - enabled_saved_payment_method, - hide_card_nickname_field, - show_card_form_by_default, - allowed_domains, - transaction_details: payment_create_link_config - .and_then(|payment_link_config| payment_link_config.theme_config.transaction_details), - }; + let payment_link_config = + PaymentLinkConfig { + theme, + logo, + seller_name, + sdk_layout, + display_sdk_only, + enabled_saved_payment_method, + hide_card_nickname_field, + show_card_form_by_default, + allowed_domains, + branding_visibility, + transaction_details: payment_create_link_config.as_ref().and_then( + |payment_link_config| payment_link_config.theme_config.transaction_details.clone(), + ), + details_layout: payment_create_link_config + .as_ref() + .and_then(|payment_link_config| payment_link_config.theme_config.details_layout) + .or_else(|| { + business_theme_configs + .as_ref() + .and_then(|business_theme_config| business_theme_config.details_layout) + }), + background_image: payment_create_link_config + .as_ref() + .and_then(|payment_link_config| { + payment_link_config.theme_config.background_image.clone() + }) + .or_else(|| { + business_theme_configs + .as_ref() + .and_then(|business_theme_config| { + business_theme_config + .background_image + .as_ref() + .map(|background_image| background_image.clone().foreign_into()) + }) + }), + }; Ok((payment_link_config, domain_name)) } @@ -752,6 +783,9 @@ pub async fn get_payment_link_status( show_card_form_by_default: DEFAULT_SHOW_CARD_FORM, allowed_domains: DEFAULT_ALLOWED_DOMAINS, transaction_details: None, + background_image: None, + details_layout: None, + branding_visibility: None, } }; diff --git a/crates/router/src/core/payment_link/payment_link_initiate/payment_link.css b/crates/router/src/core/payment_link/payment_link_initiate/payment_link.css index 65a50e967f3b..b8ccdeba33aa 100644 --- a/crates/router/src/core/payment_link/payment_link_initiate/payment_link.css +++ b/crates/router/src/core/payment_link/payment_link_initiate/payment_link.css @@ -71,6 +71,7 @@ body { #hyper-checkout-details { font-family: "Montserrat"; + background-repeat: no-repeat; } .hyper-checkout-payment { @@ -144,7 +145,7 @@ body { #hyper-checkout-merchant-image, #hyper-checkout-cart-image { height: 64px; - width: 64px; + padding: 0 10px; border-radius: 4px; display: flex; align-self: flex-start; @@ -153,8 +154,7 @@ body { } #hyper-checkout-merchant-image > img { - height: 48px; - width: 48px; + height: 40px; } #hyper-checkout-cart-image { @@ -279,7 +279,7 @@ body { #hyper-checkout-merchant-description { font-size: 13px; - color: #808080; + margin: 10px 0 20px 0; } .powered-by-hyper { @@ -292,7 +292,6 @@ body { min-width: 584px; z-index: 2; background-color: var(--primary-color); - box-shadow: 0px 1px 10px #f2f2f2; display: flex; flex-flow: column; align-items: center; @@ -665,6 +664,12 @@ body { animation: loading 1s linear infinite; } +@media only screen and (min-width: 1199px) { + #hyper-checkout-merchant-description { + color: #808080; + } +} + @media only screen and (max-width: 1199px) { body { overflow-y: scroll; diff --git a/crates/router/src/core/payment_link/payment_link_initiate/payment_link.html b/crates/router/src/core/payment_link/payment_link_initiate/payment_link.html index 963b4d6083a6..9abcc440068a 100644 --- a/crates/router/src/core/payment_link/payment_link_initiate/payment_link.html +++ b/crates/router/src/core/payment_link/payment_link_initiate/payment_link.html @@ -185,7 +185,7 @@
-
+
@@ -313,17 +301,6 @@
-