diff --git a/api-reference-v2/openapi_spec.json b/api-reference-v2/openapi_spec.json index 62d6ba5000..c33e65a082 100644 --- a/api-reference-v2/openapi_spec.json +++ b/api-reference-v2/openapi_spec.json @@ -14798,6 +14798,27 @@ "enable_button_only_on_form_ready": { "type": "boolean", "description": "Flag to enable the button only when the payment form is ready for submission" + }, + "payment_form_header_text": { + "type": "string", + "description": "Optional header for the SDK's payment form", + "nullable": true + }, + "payment_form_label_type": { + "allOf": [ + { + "$ref": "#/components/schemas/PaymentLinkSdkLabelType" + } + ], + "nullable": true + }, + "show_card_terms": { + "allOf": [ + { + "$ref": "#/components/schemas/PaymentLinkShowSdkTerms" + } + ], + "nullable": true } } }, @@ -14940,6 +14961,27 @@ "type": "boolean", "description": "Flag to enable the button only when the payment form is ready for submission", "nullable": true + }, + "payment_form_header_text": { + "type": "string", + "description": "Optional header for the SDK's payment form", + "nullable": true + }, + "payment_form_label_type": { + "allOf": [ + { + "$ref": "#/components/schemas/PaymentLinkSdkLabelType" + } + ], + "nullable": true + }, + "show_card_terms": { + "allOf": [ + { + "$ref": "#/components/schemas/PaymentLinkShowSdkTerms" + } + ], + "nullable": true } } }, @@ -14987,6 +15029,22 @@ } } }, + "PaymentLinkSdkLabelType": { + "type": "string", + "enum": [ + "above", + "floating", + "never" + ] + }, + "PaymentLinkShowSdkTerms": { + "type": "string", + "enum": [ + "always", + "auto", + "never" + ] + }, "PaymentLinkStatus": { "type": "string", "description": "Status Of the Payment Link", diff --git a/api-reference/openapi_spec.json b/api-reference/openapi_spec.json index 0389ef35c5..6e9d3b12a7 100644 --- a/api-reference/openapi_spec.json +++ b/api-reference/openapi_spec.json @@ -17229,6 +17229,27 @@ "enable_button_only_on_form_ready": { "type": "boolean", "description": "Flag to enable the button only when the payment form is ready for submission" + }, + "payment_form_header_text": { + "type": "string", + "description": "Optional header for the SDK's payment form", + "nullable": true + }, + "payment_form_label_type": { + "allOf": [ + { + "$ref": "#/components/schemas/PaymentLinkSdkLabelType" + } + ], + "nullable": true + }, + "show_card_terms": { + "allOf": [ + { + "$ref": "#/components/schemas/PaymentLinkShowSdkTerms" + } + ], + "nullable": true } } }, @@ -17371,6 +17392,27 @@ "type": "boolean", "description": "Flag to enable the button only when the payment form is ready for submission", "nullable": true + }, + "payment_form_header_text": { + "type": "string", + "description": "Optional header for the SDK's payment form", + "nullable": true + }, + "payment_form_label_type": { + "allOf": [ + { + "$ref": "#/components/schemas/PaymentLinkSdkLabelType" + } + ], + "nullable": true + }, + "show_card_terms": { + "allOf": [ + { + "$ref": "#/components/schemas/PaymentLinkShowSdkTerms" + } + ], + "nullable": true } } }, @@ -17418,6 +17460,22 @@ } } }, + "PaymentLinkSdkLabelType": { + "type": "string", + "enum": [ + "above", + "floating", + "never" + ] + }, + "PaymentLinkShowSdkTerms": { + "type": "string", + "enum": [ + "always", + "auto", + "never" + ] + }, "PaymentLinkStatus": { "type": "string", "description": "Status Of the Payment Link", diff --git a/crates/api_models/src/admin.rs b/crates/api_models/src/admin.rs index f27a09ffe8..ae66147b10 100644 --- a/crates/api_models/src/admin.rs +++ b/crates/api_models/src/admin.rs @@ -2895,6 +2895,14 @@ pub struct PaymentLinkConfigRequest { pub payment_link_ui_rules: Option>>, /// Flag to enable the button only when the payment form is ready for submission pub enable_button_only_on_form_ready: Option, + /// Optional header for the SDK's payment form + pub payment_form_header_text: Option, + /// Label type in the SDK's payment form + #[schema(value_type = Option, example = "floating")] + pub payment_form_label_type: Option, + /// Boolean for controlling whether or not to show the explicit consent for storing cards + #[schema(value_type = Option, example = "always")] + pub show_card_terms: Option, } #[derive(Clone, Debug, serde::Deserialize, serde::Serialize, PartialEq, ToSchema)] @@ -2982,6 +2990,14 @@ pub struct PaymentLinkConfig { pub payment_link_ui_rules: Option>>, /// Flag to enable the button only when the payment form is ready for submission pub enable_button_only_on_form_ready: bool, + /// Optional header for the SDK's payment form + pub payment_form_header_text: Option, + /// Label type in the SDK's payment form + #[schema(value_type = Option, example = "floating")] + pub payment_form_label_type: Option, + /// Boolean for controlling whether or not to show the explicit consent for storing cards + #[schema(value_type = Option, example = "always")] + pub show_card_terms: 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 859dba9b59..61efe59c66 100644 --- a/crates/api_models/src/payments.rs +++ b/crates/api_models/src/payments.rs @@ -8023,6 +8023,9 @@ pub struct PaymentLinkDetails { pub payment_link_ui_rules: Option>>, pub status: api_enums::IntentStatus, pub enable_button_only_on_form_ready: bool, + pub payment_form_header_text: Option, + pub payment_form_label_type: Option, + pub show_card_terms: Option, } #[derive(Debug, serde::Serialize, Clone)] @@ -8041,6 +8044,9 @@ pub struct SecurePaymentLinkDetails { pub sdk_ui_rules: Option>>, pub payment_link_ui_rules: Option>>, pub enable_button_only_on_form_ready: bool, + pub payment_form_header_text: Option, + pub payment_form_label_type: Option, + pub show_card_terms: Option, } #[derive(Debug, serde::Serialize)] diff --git a/crates/common_enums/src/enums/ui.rs b/crates/common_enums/src/enums/ui.rs index aec6c7ed64..eaa63e89e3 100644 --- a/crates/common_enums/src/enums/ui.rs +++ b/crates/common_enums/src/enums/ui.rs @@ -90,6 +90,54 @@ pub enum PaymentLinkDetailsLayout { Layout2, } +#[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 PaymentLinkSdkLabelType { + #[default] + Above, + Floating, + Never, +} + +#[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 PaymentLinkShowSdkTerms { + Always, + #[default] + Auto, + Never, +} + impl<'de> Deserialize<'de> for ElementSize { fn deserialize(deserializer: D) -> Result where diff --git a/crates/diesel_models/src/business_profile.rs b/crates/diesel_models/src/business_profile.rs index 1f7d2b0981..001673872c 100644 --- a/crates/diesel_models/src/business_profile.rs +++ b/crates/diesel_models/src/business_profile.rs @@ -687,6 +687,9 @@ pub struct PaymentLinkConfigRequest { pub sdk_ui_rules: Option>>, pub payment_link_ui_rules: Option>>, pub enable_button_only_on_form_ready: Option, + pub payment_form_header_text: Option, + pub payment_form_label_type: Option, + pub show_card_terms: Option, } #[derive(Clone, Debug, serde::Deserialize, serde::Serialize, PartialEq)] diff --git a/crates/diesel_models/src/payment_intent.rs b/crates/diesel_models/src/payment_intent.rs index 445cc6eab3..634626a4b1 100644 --- a/crates/diesel_models/src/payment_intent.rs +++ b/crates/diesel_models/src/payment_intent.rs @@ -196,6 +196,12 @@ pub struct PaymentLinkConfigRequestForPayments { Option>>, /// Flag to enable the button only when the payment form is ready for submission pub enable_button_only_on_form_ready: Option, + /// Optional header for the SDK's payment form + pub payment_form_header_text: Option, + /// Label type in the SDK's payment form + pub payment_form_label_type: Option, + /// Boolean for controlling whether or not to show the explicit consent for storing cards + pub show_card_terms: 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 a488c5aaa5..73f42dbd15 100644 --- a/crates/hyperswitch_domain_models/src/lib.rs +++ b/crates/hyperswitch_domain_models/src/lib.rs @@ -422,6 +422,9 @@ impl ApiModelToDieselModelConvertor sdk_ui_rules: item.sdk_ui_rules, payment_link_ui_rules: item.payment_link_ui_rules, enable_button_only_on_form_ready: item.enable_button_only_on_form_ready, + payment_form_header_text: item.payment_form_header_text, + payment_form_label_type: item.payment_form_label_type, + show_card_terms: item.show_card_terms, } } fn convert_back(self) -> api_models::admin::PaymentLinkConfigRequest { @@ -446,6 +449,9 @@ impl ApiModelToDieselModelConvertor sdk_ui_rules, payment_link_ui_rules, enable_button_only_on_form_ready, + payment_form_header_text, + payment_form_label_type, + show_card_terms, } = self; api_models::admin::PaymentLinkConfigRequest { theme, @@ -474,6 +480,9 @@ impl ApiModelToDieselModelConvertor sdk_ui_rules, payment_link_ui_rules, enable_button_only_on_form_ready, + payment_form_header_text, + payment_form_label_type, + show_card_terms, } } } diff --git a/crates/openapi/src/openapi.rs b/crates/openapi/src/openapi.rs index 47a5ad25f7..40cedb1e40 100644 --- a/crates/openapi/src/openapi.rs +++ b/crates/openapi/src/openapi.rs @@ -329,6 +329,8 @@ Never share your secret api keys. Keep them guarded and secure. api_models::enums::FeatureStatus, api_models::enums::MerchantProductType, api_models::enums::CtpServiceProvider, + api_models::enums::PaymentLinkSdkLabelType, + api_models::enums::PaymentLinkShowSdkTerms, api_models::admin::MerchantConnectorCreate, api_models::admin::AdditionalMerchantData, api_models::admin::ConnectorWalletDetails, diff --git a/crates/openapi/src/openapi_v2.rs b/crates/openapi/src/openapi_v2.rs index efc9dc9076..ead503d1bb 100644 --- a/crates/openapi/src/openapi_v2.rs +++ b/crates/openapi/src/openapi_v2.rs @@ -295,6 +295,8 @@ Never share your secret api keys. Keep them guarded and secure. api_models::enums::UIWidgetFormLayout, api_models::enums::MerchantProductType, api_models::enums::CtpServiceProvider, + api_models::enums::PaymentLinkSdkLabelType, + api_models::enums::PaymentLinkShowSdkTerms, api_models::admin::MerchantConnectorCreate, api_models::admin::AdditionalMerchantData, api_models::admin::CardTestingGuardConfig, diff --git a/crates/router/src/core/payment_link.rs b/crates/router/src/core/payment_link.rs index 48004dd740..c2945335b5 100644 --- a/crates/router/src/core/payment_link.rs +++ b/crates/router/src/core/payment_link.rs @@ -139,6 +139,9 @@ pub async fn form_payment_link_data( sdk_ui_rules: None, payment_link_ui_rules: None, enable_button_only_on_form_ready: DEFAULT_ENABLE_BUTTON_ONLY_ON_FORM_READY, + payment_form_header_text: None, + payment_form_label_type: None, + show_card_terms: None, } }; @@ -296,6 +299,9 @@ pub async fn form_payment_link_data( payment_link_ui_rules: payment_link_config.payment_link_ui_rules.clone(), status: payment_intent.status, enable_button_only_on_form_ready: payment_link_config.enable_button_only_on_form_ready, + payment_form_header_text: payment_link_config.payment_form_header_text.clone(), + payment_form_label_type: payment_link_config.payment_form_label_type, + show_card_terms: payment_link_config.show_card_terms, }; Ok(( @@ -356,6 +362,9 @@ pub async fn initiate_secure_payment_link_flow( payment_link_ui_rules: payment_link_config.payment_link_ui_rules, enable_button_only_on_form_ready: payment_link_config .enable_button_only_on_form_ready, + payment_form_header_text: payment_link_config.payment_form_header_text, + payment_form_label_type: payment_link_config.payment_form_label_type, + show_card_terms: payment_link_config.show_card_terms, }; let js_script = format!( "window.__PAYMENT_DETAILS = {}", @@ -674,6 +683,9 @@ pub fn get_payment_link_config_based_on_priority( payment_button_text_colour, sdk_ui_rules, payment_link_ui_rules, + payment_form_header_text, + payment_form_label_type, + show_card_terms, ) = get_payment_link_config_value!( payment_create_link_config, business_theme_configs, @@ -688,6 +700,9 @@ pub fn get_payment_link_config_based_on_priority( (payment_button_text_colour), (sdk_ui_rules), (payment_link_ui_rules), + (payment_form_header_text), + (payment_form_label_type), + (show_card_terms), ); let payment_link_config = @@ -716,6 +731,9 @@ pub fn get_payment_link_config_based_on_priority( sdk_ui_rules, payment_link_ui_rules, enable_button_only_on_form_ready, + payment_form_header_text, + payment_form_label_type, + show_card_terms, }; Ok((payment_link_config, domain_name)) @@ -827,6 +845,9 @@ pub async fn get_payment_link_status( sdk_ui_rules: None, payment_link_ui_rules: None, enable_button_only_on_form_ready: DEFAULT_ENABLE_BUTTON_ONLY_ON_FORM_READY, + payment_form_header_text: None, + payment_form_label_type: None, + show_card_terms: 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 f9b0fe892c..effd27cc64 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 @@ -12,6 +12,7 @@ function initializeSDK() { var paymentDetails = window.__PAYMENT_DETAILS; var clientSecret = paymentDetails.client_secret; var sdkUiRules = paymentDetails.sdk_ui_rules; + var labelType = paymentDetails.payment_form_label_type; var appearance = { variables: { colorPrimary: paymentDetails.theme || "rgb(0, 109, 249)", @@ -25,9 +26,12 @@ function initializeSDK() { colorBackground: "rgb(255, 255, 255)", }, }; - if (sdkUiRules !== null && typeof sdkUiRules === "object" && Object.getPrototypeOf(sdkUiRules) === Object.prototype) { + if (isObject(sdkUiRules)) { appearance.rules = sdkUiRules; } + if (labelType !== null && typeof labelType === "string") { + appearance.labels = labelType; + } // @ts-ignore hyper = window.Hyper(pub_key, { isPreloadEnabled: false, @@ -70,11 +74,18 @@ function initializeSDK() { hideCardNicknameField: hideCardNicknameField, customMessageForCardTerms: paymentDetails.custom_message_for_card_terms, }; - // @ts-ignore + var showCardTerms = paymentDetails.show_card_terms; + if (showCardTerms !== null && typeof showCardTerms === "string") { + unifiedCheckoutOptions.terms = { + card: showCardTerms + }; + } + var paymentMethodsHeaderText = paymentDetails.payment_form_header_text; + if (paymentMethodsHeaderText !== null && typeof paymentMethodsHeaderText === "string") { + unifiedCheckoutOptions.paymentMethodsHeaderText = paymentMethodsHeaderText; + } unifiedCheckout = widgets.create("payment", unifiedCheckoutOptions); - // @ts-ignore mountUnifiedCheckout("#unified-checkout"); - // @ts-ignore showSDK(paymentDetails.display_sdk_only, paymentDetails.enable_button_only_on_form_ready); let shimmer = document.getElementById("payment-details-shimmer"); 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 12ae76a208..446428e6ff 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 @@ -33,6 +33,7 @@ if (!isFramed) { var paymentDetails = window.__PAYMENT_DETAILS; var clientSecret = paymentDetails.client_secret; var sdkUiRules = paymentDetails.sdk_ui_rules; + var labelType = paymentDetails.payment_form_label_type; var appearance = { variables: { colorPrimary: paymentDetails.theme || "rgb(0, 109, 249)", @@ -46,9 +47,12 @@ if (!isFramed) { colorBackground: "rgb(255, 255, 255)", }, }; - if (sdkUiRules !== null && typeof sdkUiRules === "object" && Object.getPrototypeOf(sdkUiRules) === Object.prototype) { + if (isObject(sdkUiRules)) { appearance.rules = sdkUiRules; } + if (labelType !== null && typeof labelType === "string") { + appearance.labels = labelType; + } // @ts-ignore hyper = window.Hyper(pub_key, { isPreloadEnabled: false, @@ -93,11 +97,19 @@ if (!isFramed) { showCardFormByDefault: paymentDetails.show_card_form_by_default, customMessageForCardTerms: paymentDetails.custom_message_for_card_terms, }; - // @ts-ignore + var showCardTerms = paymentDetails.show_card_terms; + if (showCardTerms !== null && typeof showCardTerms === "string") { + unifiedCheckoutOptions.terms = { + card: showCardTerms + }; + } + var paymentMethodsHeaderText = paymentDetails.payment_form_header_text; + if (paymentMethodsHeaderText !== null && typeof paymentMethodsHeaderText === "string") { + unifiedCheckoutOptions.paymentMethodsHeaderText = paymentMethodsHeaderText; + } + unifiedCheckout = widgets.create("payment", unifiedCheckoutOptions); - // @ts-ignore mountUnifiedCheckout("#unified-checkout"); - // @ts-ignore showSDK(paymentDetails.display_sdk_only, paymentDetails.enable_button_only_on_form_ready); let shimmer = document.getElementById("payment-details-shimmer"); diff --git a/crates/router/src/core/payments/transformers.rs b/crates/router/src/core/payments/transformers.rs index 5b6b014aca..d801476871 100644 --- a/crates/router/src/core/payments/transformers.rs +++ b/crates/router/src/core/payments/transformers.rs @@ -4529,6 +4529,9 @@ impl ForeignFrom sdk_ui_rules: config.sdk_ui_rules, payment_link_ui_rules: config.payment_link_ui_rules, enable_button_only_on_form_ready: config.enable_button_only_on_form_ready, + payment_form_header_text: config.payment_form_header_text, + payment_form_label_type: config.payment_form_label_type, + show_card_terms: config.show_card_terms, } } } @@ -4600,6 +4603,9 @@ impl ForeignFrom sdk_ui_rules: config.sdk_ui_rules, payment_link_ui_rules: config.payment_link_ui_rules, enable_button_only_on_form_ready: config.enable_button_only_on_form_ready, + payment_form_header_text: config.payment_form_header_text, + payment_form_label_type: config.payment_form_label_type, + show_card_terms: config.show_card_terms, } } } diff --git a/crates/router/src/routes/customers.rs b/crates/router/src/routes/customers.rs index c9ff466af0..b889c41e7b 100644 --- a/crates/router/src/routes/customers.rs +++ b/crates/router/src/routes/customers.rs @@ -152,7 +152,7 @@ pub async fn customers_list( let flow = Flow::CustomersList; let payload = query.into_inner(); - api::server_wrap( + Box::pin(api::server_wrap( flow, state, &req, @@ -174,7 +174,7 @@ pub async fn customers_list( req.headers(), ), api_locking::LockAction::NotApplicable, - ) + )) .await } #[cfg(all(any(feature = "v1", feature = "v2"), not(feature = "customer_v2")))] diff --git a/crates/router/src/types/transformers.rs b/crates/router/src/types/transformers.rs index 6d529b1280..0469046546 100644 --- a/crates/router/src/types/transformers.rs +++ b/crates/router/src/types/transformers.rs @@ -2188,6 +2188,9 @@ impl ForeignFrom sdk_ui_rules: item.sdk_ui_rules, payment_link_ui_rules: item.payment_link_ui_rules, enable_button_only_on_form_ready: item.enable_button_only_on_form_ready, + payment_form_header_text: item.payment_form_header_text, + payment_form_label_type: item.payment_form_label_type, + show_card_terms: item.show_card_terms, } } } @@ -2219,6 +2222,9 @@ impl ForeignFrom sdk_ui_rules: item.sdk_ui_rules, payment_link_ui_rules: item.payment_link_ui_rules, enable_button_only_on_form_ready: item.enable_button_only_on_form_ready, + payment_form_header_text: item.payment_form_header_text, + payment_form_label_type: item.payment_form_label_type, + show_card_terms: item.show_card_terms, } } }