From e4ec46604b28e34730acc947d773c7a98d40cb7e Mon Sep 17 00:00:00 2001 From: chikke srujan <121822803+srujanchikke@users.noreply.github.com> Date: Mon, 18 Nov 2024 13:06:02 +0530 Subject: [PATCH] feat(payments): [Payment links] add hide card nickname field config for secure payment links (#6554) Co-authored-by: Chikke Srujan Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com> --- api-reference-v2/openapi_spec.json | 14 ++++++++- api-reference/openapi_spec.json | 14 ++++++++- crates/api_models/src/admin.rs | 5 ++++ crates/api_models/src/payments.rs | 2 ++ crates/common_utils/src/consts.rs | 25 ---------------- crates/diesel_models/src/business_profile.rs | 1 + crates/diesel_models/src/payment_intent.rs | 2 ++ crates/hyperswitch_domain_models/src/lib.rs | 3 ++ crates/router/src/consts.rs | 28 +++++++++++++++++ crates/router/src/core/payment_link.rs | 30 ++++++++++++++----- .../payment_link_initiator.js | 1 + .../secure_payment_link_initiator.js | 2 ++ .../router/src/core/payments/transformers.rs | 2 ++ crates/router/src/types/transformers.rs | 2 ++ 14 files changed, 96 insertions(+), 35 deletions(-) diff --git a/api-reference-v2/openapi_spec.json b/api-reference-v2/openapi_spec.json index d2fa50d86293..f00998f154f4 100644 --- a/api-reference-v2/openapi_spec.json +++ b/api-reference-v2/openapi_spec.json @@ -11948,7 +11948,8 @@ "seller_name", "sdk_layout", "display_sdk_only", - "enabled_saved_payment_method" + "enabled_saved_payment_method", + "hide_card_nickname_field" ], "properties": { "theme": { @@ -11975,6 +11976,10 @@ "type": "boolean", "description": "Enable saved payment method option for payment link" }, + "hide_card_nickname_field": { + "type": "boolean", + "description": "Hide card nickname field option for payment link" + }, "allowed_domains": { "type": "array", "items": { @@ -12039,6 +12044,13 @@ "example": true, "nullable": true }, + "hide_card_nickname_field": { + "type": "boolean", + "description": "Hide card nickname field option for payment link", + "default": false, + "example": true, + "nullable": true + }, "transaction_details": { "type": "array", "items": { diff --git a/api-reference/openapi_spec.json b/api-reference/openapi_spec.json index 34d5be1b0ec0..d4c5717d2156 100644 --- a/api-reference/openapi_spec.json +++ b/api-reference/openapi_spec.json @@ -15074,7 +15074,8 @@ "seller_name", "sdk_layout", "display_sdk_only", - "enabled_saved_payment_method" + "enabled_saved_payment_method", + "hide_card_nickname_field" ], "properties": { "theme": { @@ -15101,6 +15102,10 @@ "type": "boolean", "description": "Enable saved payment method option for payment link" }, + "hide_card_nickname_field": { + "type": "boolean", + "description": "Hide card nickname field option for payment link" + }, "allowed_domains": { "type": "array", "items": { @@ -15165,6 +15170,13 @@ "example": true, "nullable": true }, + "hide_card_nickname_field": { + "type": "boolean", + "description": "Hide card nickname field option for payment link", + "default": false, + "example": true, + "nullable": true + }, "transaction_details": { "type": "array", "items": { diff --git a/crates/api_models/src/admin.rs b/crates/api_models/src/admin.rs index 7f5ae1556d27..d80a4ea11b4c 100644 --- a/crates/api_models/src/admin.rs +++ b/crates/api_models/src/admin.rs @@ -2692,6 +2692,9 @@ pub struct PaymentLinkConfigRequest { /// Enable saved payment method option for payment link #[schema(default = false, example = true)] pub enabled_saved_payment_method: Option, + /// Hide card nickname field option for payment link + #[schema(default = false, example = true)] + pub hide_card_nickname_field: Option, /// Dynamic details related to merchant to be rendered in payment link pub transaction_details: Option>, } @@ -2735,6 +2738,8 @@ pub struct PaymentLinkConfig { pub display_sdk_only: bool, /// Enable saved payment method option for payment link pub enabled_saved_payment_method: bool, + /// Hide card nickname field option for payment link + pub hide_card_nickname_field: bool, /// A list of allowed domains (glob patterns) where this link can be embedded / opened from pub allowed_domains: Option>, /// Dynamic details related to merchant to be rendered in payment link diff --git a/crates/api_models/src/payments.rs b/crates/api_models/src/payments.rs index 75dda21097ad..37389308aa39 100644 --- a/crates/api_models/src/payments.rs +++ b/crates/api_models/src/payments.rs @@ -6556,6 +6556,7 @@ pub struct PaymentLinkDetails { pub merchant_description: Option, pub sdk_layout: String, pub display_sdk_only: bool, + pub hide_card_nickname_field: bool, pub locale: Option, pub transaction_details: Option>, } @@ -6563,6 +6564,7 @@ pub struct PaymentLinkDetails { #[derive(Debug, serde::Serialize, Clone)] pub struct SecurePaymentLinkDetails { pub enabled_saved_payment_method: bool, + pub hide_card_nickname_field: bool, #[serde(flatten)] pub payment_link_details: PaymentLinkDetails, } diff --git a/crates/common_utils/src/consts.rs b/crates/common_utils/src/consts.rs index a50555ced920..b43efcb1feb1 100644 --- a/crates/common_utils/src/consts.rs +++ b/crates/common_utils/src/consts.rs @@ -1,7 +1,5 @@ //! Commonly used constants -use std::collections::HashSet; - /// Number of characters in a generated ID pub const ID_LENGTH: usize = 20; @@ -51,26 +49,12 @@ pub const SURCHARGE_PERCENTAGE_PRECISION_LENGTH: u8 = 2; /// Header Key for application overhead of a request pub const X_HS_LATENCY: &str = "x-hs-latency"; -/// Default Payment Link Background color -pub const DEFAULT_BACKGROUND_COLOR: &str = "#212E46"; - -/// Default product Img Link -pub const DEFAULT_PRODUCT_IMG: &str = - "https://live.hyperswitch.io/payment-link-assets/cart_placeholder.png"; - -/// Default Merchant Logo Link -pub const DEFAULT_MERCHANT_LOGO: &str = - "https://live.hyperswitch.io/payment-link-assets/Merchant_placeholder.png"; - /// Redirect url for Prophetpay pub const PROPHETPAY_REDIRECT_URL: &str = "https://ccm-thirdparty.cps.golf/hp/tokenize/"; /// Variable which store the card token for Prophetpay pub const PROPHETPAY_TOKEN: &str = "cctoken"; -/// Default SDK Layout -pub const DEFAULT_SDK_LAYOUT: &str = "tabs"; - /// Payment intent default client secret expiry (in seconds) pub const DEFAULT_SESSION_EXPIRY: i64 = 15 * 60; @@ -80,15 +64,6 @@ pub const DEFAULT_INTENT_FULFILLMENT_TIME: i64 = 15 * 60; /// Payment order fulfillment time (in seconds) pub const DEFAULT_ORDER_FULFILLMENT_TIME: i64 = 15 * 60; -/// Default bool for Display sdk only -pub const DEFAULT_DISPLAY_SDK_ONLY: bool = false; - -/// Default bool to enable saved payment method -pub const DEFAULT_ENABLE_SAVED_PAYMENT_METHOD: bool = false; - -/// Default allowed domains for payment links -pub const DEFAULT_ALLOWED_DOMAINS: Option> = None; - /// Default ttl for Extended card info in redis (in seconds) pub const DEFAULT_TTL_FOR_EXTENDED_CARD_INFO: u16 = 15 * 60; diff --git a/crates/diesel_models/src/business_profile.rs b/crates/diesel_models/src/business_profile.rs index 05c124c4c9cf..f4c7b86850eb 100644 --- a/crates/diesel_models/src/business_profile.rs +++ b/crates/diesel_models/src/business_profile.rs @@ -542,6 +542,7 @@ pub struct PaymentLinkConfigRequest { pub sdk_layout: Option, pub display_sdk_only: Option, pub enabled_saved_payment_method: Option, + pub hide_card_nickname_field: 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 18248048110a..26cb0b8c8a84 100644 --- a/crates/diesel_models/src/payment_intent.rs +++ b/crates/diesel_models/src/payment_intent.rs @@ -152,6 +152,8 @@ pub struct PaymentLinkConfigRequestForPayments { pub display_sdk_only: Option, /// Enable saved payment method option for payment link pub enabled_saved_payment_method: Option, + /// Hide card nickname field option for payment link + pub hide_card_nickname_field: Option, /// Dynamic details related to merchant to be rendered in payment link pub transaction_details: Option>, } diff --git a/crates/hyperswitch_domain_models/src/lib.rs b/crates/hyperswitch_domain_models/src/lib.rs index 02795481ad9c..386e0f01f383 100644 --- a/crates/hyperswitch_domain_models/src/lib.rs +++ b/crates/hyperswitch_domain_models/src/lib.rs @@ -190,6 +190,7 @@ impl ApiModelToDieselModelConvertor sdk_layout: item.sdk_layout, display_sdk_only: item.display_sdk_only, enabled_saved_payment_method: item.enabled_saved_payment_method, + hide_card_nickname_field: item.hide_card_nickname_field, transaction_details: item.transaction_details.map(|transaction_details| { transaction_details .into_iter() @@ -210,6 +211,7 @@ impl ApiModelToDieselModelConvertor sdk_layout, display_sdk_only, enabled_saved_payment_method, + hide_card_nickname_field, transaction_details, } = self; api_models::admin::PaymentLinkConfigRequest { @@ -219,6 +221,7 @@ impl ApiModelToDieselModelConvertor sdk_layout, display_sdk_only, enabled_saved_payment_method, + hide_card_nickname_field, transaction_details: transaction_details.map(|transaction_details| { transaction_details .into_iter() diff --git a/crates/router/src/consts.rs b/crates/router/src/consts.rs index 3f4faedff81b..51385593e9d1 100644 --- a/crates/router/src/consts.rs +++ b/crates/router/src/consts.rs @@ -3,6 +3,8 @@ pub mod opensearch; pub mod user; pub mod user_role; +use std::collections::HashSet; + use common_utils::consts; pub use hyperswitch_interfaces::consts::{NO_ERROR_CODE, NO_ERROR_MESSAGE}; // ID generation @@ -145,6 +147,32 @@ pub const RECON_FEATURE_TAG: &str = "RECONCILIATION AND SETTLEMENT"; // Length of the unique reference ID generated for connector mandate requests pub const CONNECTOR_MANDATE_REQUEST_REFERENCE_ID_LENGTH: usize = 18; +/// Default allowed domains for payment links +pub const DEFAULT_ALLOWED_DOMAINS: Option> = None; + +/// Default hide card nickname field +pub const DEFAULT_HIDE_CARD_NICKNAME_FIELD: bool = false; + +/// Default bool for Display sdk only +pub const DEFAULT_DISPLAY_SDK_ONLY: bool = false; + +/// Default bool to enable saved payment method +pub const DEFAULT_ENABLE_SAVED_PAYMENT_METHOD: bool = false; + +/// Default Merchant Logo Link +pub const DEFAULT_MERCHANT_LOGO: &str = + "https://live.hyperswitch.io/payment-link-assets/Merchant_placeholder.png"; + +/// Default Payment Link Background color +pub const DEFAULT_BACKGROUND_COLOR: &str = "#212E46"; + +/// Default product Img Link +pub const DEFAULT_PRODUCT_IMG: &str = + "https://live.hyperswitch.io/payment-link-assets/cart_placeholder.png"; + +/// Default SDK Layout +pub const DEFAULT_SDK_LAYOUT: &str = "tabs"; + /// Vault Add request url #[cfg(all(feature = "v2", feature = "payment_methods_v2"))] pub const ADD_VAULT_REQUEST_URL: &str = "/vault/add"; diff --git a/crates/router/src/core/payment_link.rs b/crates/router/src/core/payment_link.rs index 09a2457197cb..91829e56f2cc 100644 --- a/crates/router/src/core/payment_link.rs +++ b/crates/router/src/core/payment_link.rs @@ -5,11 +5,7 @@ use api_models::{ payments::{PaymentLinkData, PaymentLinkStatusWrap}, }; use common_utils::{ - consts::{ - DEFAULT_ALLOWED_DOMAINS, DEFAULT_BACKGROUND_COLOR, DEFAULT_DISPLAY_SDK_ONLY, - DEFAULT_ENABLE_SAVED_PAYMENT_METHOD, DEFAULT_LOCALE, DEFAULT_MERCHANT_LOGO, - DEFAULT_PRODUCT_IMG, DEFAULT_SDK_LAYOUT, DEFAULT_SESSION_EXPIRY, - }, + consts::{DEFAULT_LOCALE, DEFAULT_SESSION_EXPIRY}, ext_traits::{AsyncExt, OptionExt, ValueExt}, types::{AmountConvertor, StringMajorUnitForCore}, }; @@ -25,7 +21,11 @@ use super::{ payments::helpers, }; use crate::{ - consts, + consts::{ + self, DEFAULT_ALLOWED_DOMAINS, DEFAULT_BACKGROUND_COLOR, DEFAULT_DISPLAY_SDK_ONLY, + DEFAULT_ENABLE_SAVED_PAYMENT_METHOD, DEFAULT_HIDE_CARD_NICKNAME_FIELD, + DEFAULT_MERCHANT_LOGO, DEFAULT_PRODUCT_IMG, DEFAULT_SDK_LAYOUT, + }, errors::RouterResponse, get_payment_link_config_value, get_payment_link_config_value_based_on_priority, headers::ACCEPT_LANGUAGE, @@ -125,6 +125,7 @@ pub async fn form_payment_link_data( sdk_layout: DEFAULT_SDK_LAYOUT.to_owned(), display_sdk_only: DEFAULT_DISPLAY_SDK_ONLY, enabled_saved_payment_method: DEFAULT_ENABLE_SAVED_PAYMENT_METHOD, + hide_card_nickname_field: DEFAULT_HIDE_CARD_NICKNAME_FIELD, allowed_domains: DEFAULT_ALLOWED_DOMAINS, transaction_details: None, } @@ -265,6 +266,7 @@ pub async fn form_payment_link_data( merchant_description: payment_intent.description, sdk_layout: payment_link_config.sdk_layout.clone(), display_sdk_only: payment_link_config.display_sdk_only, + hide_card_nickname_field: payment_link_config.hide_card_nickname_field, locale, transaction_details: payment_link_config.transaction_details.clone(), }; @@ -322,6 +324,7 @@ pub async fn initiate_secure_payment_link_flow( PaymentLinkData::PaymentLinkDetails(link_details) => { let secure_payment_link_details = api_models::payments::SecurePaymentLinkDetails { enabled_saved_payment_method: payment_link_config.enabled_saved_payment_method, + hide_card_nickname_field: payment_link_config.hide_card_nickname_field, payment_link_details: *link_details.to_owned(), }; let js_script = format!( @@ -607,7 +610,15 @@ pub fn get_payment_link_config_based_on_priority( (default_domain_name, None, None) }; - let (theme, logo, seller_name, sdk_layout, display_sdk_only, enabled_saved_payment_method) = get_payment_link_config_value!( + let ( + theme, + logo, + seller_name, + sdk_layout, + display_sdk_only, + enabled_saved_payment_method, + hide_card_nickname_field, + ) = get_payment_link_config_value!( payment_create_link_config, business_theme_configs, (theme, DEFAULT_BACKGROUND_COLOR.to_string()), @@ -618,7 +629,8 @@ pub fn get_payment_link_config_based_on_priority( ( enabled_saved_payment_method, DEFAULT_ENABLE_SAVED_PAYMENT_METHOD - ) + ), + (hide_card_nickname_field, DEFAULT_HIDE_CARD_NICKNAME_FIELD) ); let payment_link_config = PaymentLinkConfig { theme, @@ -627,6 +639,7 @@ pub fn get_payment_link_config_based_on_priority( sdk_layout, display_sdk_only, enabled_saved_payment_method, + hide_card_nickname_field, allowed_domains, transaction_details: payment_create_link_config .and_then(|payment_link_config| payment_link_config.theme_config.transaction_details), @@ -729,6 +742,7 @@ pub async fn get_payment_link_status( sdk_layout: DEFAULT_SDK_LAYOUT.to_owned(), display_sdk_only: DEFAULT_DISPLAY_SDK_ONLY, enabled_saved_payment_method: DEFAULT_ENABLE_SAVED_PAYMENT_METHOD, + hide_card_nickname_field: DEFAULT_HIDE_CARD_NICKNAME_FIELD, allowed_domains: DEFAULT_ALLOWED_DOMAINS, transaction_details: None, } diff --git a/crates/router/src/core/payment_link/payment_link_initiate/payment_link_initiator.js b/crates/router/src/core/payment_link/payment_link_initiate/payment_link_initiator.js index 8d1183a2535d..1264915592d6 100644 --- a/crates/router/src/core/payment_link/payment_link_initiate/payment_link_initiator.js +++ b/crates/router/src/core/payment_link/payment_link_initiate/payment_link_initiator.js @@ -56,6 +56,7 @@ function initializeSDK() { height: 55, }, }, + hideCardNicknameField: false, }; // @ts-ignore unifiedCheckout = widgets.create("payment", unifiedCheckoutOptions); diff --git a/crates/router/src/core/payment_link/payment_link_initiate/secure_payment_link_initiator.js b/crates/router/src/core/payment_link/payment_link_initiate/secure_payment_link_initiator.js index c901148bbfae..5080970ce3c5 100644 --- a/crates/router/src/core/payment_link/payment_link_initiate/secure_payment_link_initiator.js +++ b/crates/router/src/core/payment_link/payment_link_initiate/secure_payment_link_initiator.js @@ -63,6 +63,7 @@ if (!isFramed) { : paymentDetails.sdk_layout; var enableSavedPaymentMethod = paymentDetails.enabled_saved_payment_method; + var hideCardNicknameField = paymentDetails.hide_card_nickname_field; var unifiedCheckoutOptions = { displaySavedPaymentMethodsCheckbox: enableSavedPaymentMethod, displaySavedPaymentMethods: enableSavedPaymentMethod, @@ -79,6 +80,7 @@ if (!isFramed) { height: 55, }, }, + hideCardNicknameField: hideCardNicknameField, }; // @ts-ignore unifiedCheckout = widgets.create("payment", unifiedCheckoutOptions); diff --git a/crates/router/src/core/payments/transformers.rs b/crates/router/src/core/payments/transformers.rs index b09034e28cb3..8a0983eccab0 100644 --- a/crates/router/src/core/payments/transformers.rs +++ b/crates/router/src/core/payments/transformers.rs @@ -3518,6 +3518,7 @@ impl ForeignFrom sdk_layout: config.sdk_layout, display_sdk_only: config.display_sdk_only, enabled_saved_payment_method: config.enabled_saved_payment_method, + hide_card_nickname_field: config.hide_card_nickname_field, transaction_details: config.transaction_details.map(|transaction_details| { transaction_details .iter() @@ -3570,6 +3571,7 @@ impl ForeignFrom sdk_layout: config.sdk_layout, display_sdk_only: config.display_sdk_only, enabled_saved_payment_method: config.enabled_saved_payment_method, + hide_card_nickname_field: config.hide_card_nickname_field, transaction_details: config.transaction_details.map(|transaction_details| { transaction_details .iter() diff --git a/crates/router/src/types/transformers.rs b/crates/router/src/types/transformers.rs index c97084a22977..36865f5ce09b 100644 --- a/crates/router/src/types/transformers.rs +++ b/crates/router/src/types/transformers.rs @@ -1987,6 +1987,7 @@ impl ForeignFrom sdk_layout: item.sdk_layout, display_sdk_only: item.display_sdk_only, enabled_saved_payment_method: item.enabled_saved_payment_method, + hide_card_nickname_field: item.hide_card_nickname_field, } } } @@ -2002,6 +2003,7 @@ impl ForeignFrom sdk_layout: item.sdk_layout, display_sdk_only: item.display_sdk_only, enabled_saved_payment_method: item.enabled_saved_payment_method, + hide_card_nickname_field: item.hide_card_nickname_field, transaction_details: None, } }