Skip to content

Commit

Permalink
feat(core): payment links - consume layout, background image and bran…
Browse files Browse the repository at this point in the history
…d visibility in payment links template
  • Loading branch information
kashif-m committed Dec 5, 2024
1 parent 7a160ed commit e5119b6
Show file tree
Hide file tree
Showing 12 changed files with 273 additions and 100 deletions.
12 changes: 8 additions & 4 deletions crates/api_models/src/admin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2619,6 +2619,8 @@ pub struct BusinessPaymentLinkConfig {
/// A list of allowed domains (glob patterns) where this link can be embedded / opened from
#[schema(value_type = Option<HashSet<String>>)]
pub allowed_domains: Option<HashSet<String>>,
/// Toggle for HyperSwitch branding visibility
pub branding_visibility: Option<bool>,
}

impl BusinessPaymentLinkConfig {
Expand Down Expand Up @@ -2677,10 +2679,10 @@ pub struct PaymentLinkConfigRequest {
pub show_card_form_by_default: Option<bool>,
/// Dynamic details related to merchant to be rendered in payment link
pub transaction_details: Option<Vec<PaymentLinkTransactionDetails>>,
/// Configurations for image
/// Configurations for the background image for details section
pub background_image: Option<PaymentLinkBackgroundImageConfig>,
/// Custom layout for details section
pub details_layout: Option<api_enums::PaymentLinkDetailsLayout>
pub details_layout: Option<api_enums::PaymentLinkDetailsLayout>,
}

#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, PartialEq, ToSchema)]
Expand Down Expand Up @@ -2743,10 +2745,12 @@ pub struct PaymentLinkConfig {
pub allowed_domains: Option<HashSet<String>>,
/// Dynamic details related to merchant to be rendered in payment link
pub transaction_details: Option<Vec<PaymentLinkTransactionDetails>>,
/// Configurations for image
/// Configurations for the background image for details section
pub background_image: Option<PaymentLinkBackgroundImageConfig>,
/// Custom layout for details section
pub details_layout: Option<api_enums::PaymentLinkDetailsLayout>
pub details_layout: Option<api_enums::PaymentLinkDetailsLayout>,
/// Toggle for HyperSwitch branding visibility
pub branding_visibility: Option<bool>,
}

#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, Eq)]
Expand Down
3 changes: 3 additions & 0 deletions crates/api_models/src/payments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6669,6 +6669,9 @@ pub struct PaymentLinkDetails {
pub show_card_form_by_default: bool,
pub locale: Option<String>,
pub transaction_details: Option<Vec<admin::PaymentLinkTransactionDetails>>,
pub background_image: Option<admin::PaymentLinkBackgroundImageConfig>,
pub details_layout: Option<api_enums::PaymentLinkDetailsLayout>,
pub branding_visibility: Option<bool>,
}

#[derive(Debug, serde::Serialize, Clone)]
Expand Down
34 changes: 16 additions & 18 deletions crates/common_enums/src/enums/ui.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use serde::{de::Visitor, Deserialize, Deserializer, Serialize};
use std::fmt;
use serde::{Serialize, Deserialize, Deserializer, de::Visitor};
use utoipa::ToSchema;

#[derive(
Expand All @@ -17,32 +17,25 @@ use utoipa::ToSchema;
ToSchema,
)]
#[router_derive::diesel_enum(storage_type = "db_enum")]
#[serde(rename_all = "kebab-case")]
#[strum(serialize_all = "kebab-case")]
#[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,
)]
#[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),
Expand Down Expand Up @@ -115,7 +108,8 @@ impl<'de> Deserialize<'de> for ElementSize {
E: serde::de::Error,
{
if let Some(percent) = value.strip_suffix('%') {
percent.parse::<u32>()
percent
.parse::<u32>()
.map(ElementSize::Percentage)
.map_err(E::custom)
} else if let Some(px) = value.strip_suffix("px") {
Expand All @@ -142,9 +136,13 @@ impl Serialize for ElementSize {
S: serde::ser::Serializer,
{
match self {
ElementSize::Variants(variant) => serializer.serialize_str(variant.to_string().as_str()),
ElementSize::Pixels(pixel_count) => serializer.serialize_str(format!("{}px", pixel_count).as_str()),
ElementSize::Percentage(pixel_count) => serializer.serialize_str(format!("{}%", pixel_count).as_str()),
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())
}
}
}
}
5 changes: 3 additions & 2 deletions crates/diesel_models/src/business_profile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,7 @@ pub struct BusinessPaymentLinkConfig {
pub default_config: Option<PaymentLinkConfigRequest>,
pub business_specific_configs: Option<HashMap<String, PaymentLinkConfigRequest>>,
pub allowed_domains: Option<HashSet<String>>,
pub branding_visibility: Option<bool>,
}

#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
Expand All @@ -545,10 +546,10 @@ pub struct PaymentLinkConfigRequest {
pub hide_card_nickname_field: Option<bool>,
pub show_card_form_by_default: Option<bool>,
pub background_image: Option<PaymentLinkBackgroundImageConfig>,
pub details_layout: Option<common_enums::PaymentLinkDetailsLayout>
pub details_layout: Option<common_enums::PaymentLinkDetailsLayout>,
}

#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, PartialEq)]
pub struct PaymentLinkBackgroundImageConfig {
pub url: common_utils::types::Url,
pub position: Option<common_enums::ElementPosition>,
Expand Down
5 changes: 5 additions & 0 deletions crates/diesel_models/src/payment_intent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use diesel::{AsChangeset, Identifiable, Insertable, Queryable, Selectable};
use serde::{Deserialize, Serialize};
use time::PrimitiveDateTime;

use crate::business_profile::PaymentLinkBackgroundImageConfig;
use crate::enums as storage_enums;
#[cfg(feature = "v1")]
use crate::schema::payment_intent;
Expand Down Expand Up @@ -160,6 +161,10 @@ pub struct PaymentLinkConfigRequestForPayments {
pub show_card_form_by_default: Option<bool>,
/// Dynamic details related to merchant to be rendered in payment link
pub transaction_details: Option<Vec<PaymentLinkTransactionDetails>>,
/// Configurations for the background image for details section
pub background_image: Option<PaymentLinkBackgroundImageConfig>,
/// Custom layout for details section
pub details_layout: Option<common_enums::PaymentLinkDetailsLayout>,
}

common_utils::impl_to_sql_from_sql_json!(PaymentLinkConfigRequestForPayments);
Expand Down
36 changes: 36 additions & 0 deletions crates/hyperswitch_domain_models/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ impl ApiModelToDieselModelConvertor<api_models::admin::PaymentLinkConfigRequest>
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()
Expand All @@ -203,6 +204,11 @@ impl ApiModelToDieselModelConvertor<api_models::admin::PaymentLinkConfigRequest>
})
.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 {
Expand All @@ -216,6 +222,8 @@ impl ApiModelToDieselModelConvertor<api_models::admin::PaymentLinkConfigRequest>
hide_card_nickname_field,
show_card_form_by_default,
transaction_details,
background_image,
details_layout,
} = self;
api_models::admin::PaymentLinkConfigRequest {
theme,
Expand All @@ -226,12 +234,15 @@ impl ApiModelToDieselModelConvertor<api_models::admin::PaymentLinkConfigRequest>
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()),
}
}
}
Expand Down Expand Up @@ -264,6 +275,31 @@ impl ApiModelToDieselModelConvertor<api_models::admin::PaymentLinkTransactionDet
}
}

#[cfg(feature = "v2")]
impl ApiModelToDieselModelConvertor<api_models::admin::PaymentLinkBackgroundImageConfig>
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<api_models::admin::TransactionDetailsUiConfiguration>
for diesel_models::TransactionDetailsUiConfiguration
Expand Down
52 changes: 38 additions & 14 deletions crates/router/src/core/payment_link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ use crate::{
api::payment_link::PaymentLinkResponseExt,
domain,
storage::{enums as storage_enums, payment_link::PaymentLink},
transformers::ForeignFrom,
transformers::{ForeignFrom, ForeignInto},
},
};

Expand Down Expand Up @@ -131,6 +131,7 @@ pub async fn form_payment_link_data(
transaction_details: None,
background_image: None,
details_layout: None,
branding_visibility: None,
}
};

Expand Down Expand Up @@ -273,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((
Expand Down Expand Up @@ -588,18 +592,16 @@ pub fn get_payment_link_config_based_on_priority(
default_domain_name: String,
payment_link_config_id: Option<String>,
) -> Result<(PaymentLinkConfig, String), error_stack::Report<errors::ApiErrorResponse>> {
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| {
Expand All @@ -610,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 (
Expand Down Expand Up @@ -649,15 +652,35 @@ pub fn get_payment_link_config_based_on_priority(
hide_card_nickname_field,
show_card_form_by_default,
allowed_domains,
details_layout: payment_create_link_config
.as_ref()
.and_then(|payment_link_config| payment_link_config.theme_config.details_layout.clone()),
branding_visibility,
transaction_details: payment_create_link_config
.as_ref()
.and_then(|payment_link_config| payment_link_config.theme_config.transaction_details.clone()),
.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.clone())
.or_else(|| {
business_theme_configs
.as_ref()
.and_then(|business_theme_config| business_theme_config.details_layout.clone())
}),
background_image: payment_create_link_config
.as_ref()
.and_then(|payment_link_config| payment_link_config.theme_config.background_image.clone()),
.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))
Expand Down Expand Up @@ -763,6 +786,7 @@ pub async fn get_payment_link_status(
transaction_details: None,
background_image: None,
details_layout: None,
branding_visibility: None,
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ body {

#hyper-checkout-details {
font-family: "Montserrat";
background-repeat: no-repeat;
}

.hyper-checkout-payment {
Expand Down Expand Up @@ -278,7 +279,7 @@ body {

#hyper-checkout-merchant-description {
font-size: 13px;
color: #808080;
margin: 10px 0 20px 0;
}

.powered-by-hyper {
Expand All @@ -291,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;
Expand Down Expand Up @@ -664,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;
Expand Down
Loading

0 comments on commit e5119b6

Please sign in to comment.