Bug: [BUG] styling for elements in payment links using dynamic classes



### Bug Description

`payment_link_ui_rules` has a set of CSS selectors and CSS properties defined - which are selected using JS after rendering the elements and CSS styles are applied directly to the elements. This is only done once. Whenever something is added dynamically (after interaction with the elements) - it does not re-apply those styles.

### Expected Behavior

Styling for UI elements in the payment links should work when using dynamic classes as well.

### Actual Behavior

Styling for UI elements in the payment links does not work when using dynamic classes.

### Context For The Bug

This bug exists since the `payment_link_ui_rules` are directly being applied to the elements which can be selected using the query selectors.

Instead of doing this, these rules can directly be appended to the `style` tag.

### Have you spent some time checking if this bug has been raised before?

- [x] I checked and didn't find a similar issue

### Have you read the Contributing Guidelines?

- [x] I have read the [Contributing Guidelines](https://github.com/juspay/hyperswitch/blob/main/docs/CONTRIBUTING.md)

### Are you willing to submit a PR?

Yes, I am willing to submit a PR!
diff --git a/api-reference-v2/openapi_spec.json b/api-reference-v2/openapi_spec.json
index c68771b7170..f3d1eb16998 100644
--- a/api-reference-v2/openapi_spec.json
+++ b/api-reference-v2/openapi_spec.json
@@ -15633,6 +15633,11 @@
             "type": "boolean",
             "description": "Boolean to control payment button text for setup mandate calls",
             "nullable": true
+          },
+          "color_icon_card_cvc_error": {
+            "type": "string",
+            "description": "Hex color for the CVC icon during error state",
+            "nullable": true
           }
         }
       },
@@ -15801,6 +15806,11 @@
             "type": "boolean",
             "description": "Boolean to control payment button text for setup mandate calls",
             "nullable": true
+          },
+          "color_icon_card_cvc_error": {
+            "type": "string",
+            "description": "Hex color for the CVC icon during error state",
+            "nullable": true
           }
         }
       },
diff --git a/crates/api_models/src/admin.rs b/crates/api_models/src/admin.rs
index f4435b08fcd..1dbc372de79 100644
--- a/crates/api_models/src/admin.rs
+++ b/crates/api_models/src/admin.rs
@@ -2958,6 +2958,8 @@ pub struct PaymentLinkConfigRequest {
     pub show_card_terms: Option<api_enums::PaymentLinkShowSdkTerms>,
     /// Boolean to control payment button text for setup mandate calls
     pub is_setup_mandate_flow: Option<bool>,
+    /// Hex color for the CVC icon during error state
+    pub color_icon_card_cvc_error: Option<String>,
 }
 
 #[derive(Clone, Debug, serde::Deserialize, serde::Serialize, PartialEq, ToSchema)]
@@ -3055,6 +3057,8 @@ pub struct PaymentLinkConfig {
     pub show_card_terms: Option<api_enums::PaymentLinkShowSdkTerms>,
     /// Boolean to control payment button text for setup mandate calls
     pub is_setup_mandate_flow: Option<bool>,
+    /// Hex color for the CVC icon during error state
+    pub color_icon_card_cvc_error: Option<String>,
 }
 
 #[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 adbfb56c0fa..f9999ff25dc 100644
--- a/crates/api_models/src/payments.rs
+++ b/crates/api_models/src/payments.rs
@@ -8120,7 +8120,6 @@ pub struct PaymentLinkDetails {
     pub payment_button_text_colour: Option<String>,
     pub background_colour: Option<String>,
     pub sdk_ui_rules: Option<HashMap<String, HashMap<String, String>>>,
-    pub payment_link_ui_rules: Option<HashMap<String, HashMap<String, String>>>,
     pub status: api_enums::IntentStatus,
     pub enable_button_only_on_form_ready: bool,
     pub payment_form_header_text: Option<String>,
@@ -8129,6 +8128,7 @@ pub struct PaymentLinkDetails {
     pub is_setup_mandate_flow: Option<bool>,
     pub capture_method: Option<common_enums::CaptureMethod>,
     pub setup_future_usage_applied: Option<common_enums::FutureUsage>,
+    pub color_icon_card_cvc_error: Option<String>,
 }
 
 #[derive(Debug, serde::Serialize, Clone)]
@@ -8145,11 +8145,11 @@ pub struct SecurePaymentLinkDetails {
     pub payment_button_text_colour: Option<String>,
     pub background_colour: Option<String>,
     pub sdk_ui_rules: Option<HashMap<String, HashMap<String, String>>>,
-    pub payment_link_ui_rules: Option<HashMap<String, HashMap<String, String>>>,
     pub enable_button_only_on_form_ready: bool,
     pub payment_form_header_text: Option<String>,
     pub payment_form_label_type: Option<api_enums::PaymentLinkSdkLabelType>,
     pub show_card_terms: Option<api_enums::PaymentLinkShowSdkTerms>,
+    pub color_icon_card_cvc_error: Option<String>,
 }
 
 #[derive(Debug, serde::Serialize)]
diff --git a/crates/diesel_models/src/business_profile.rs b/crates/diesel_models/src/business_profile.rs
index 0bc52b33189..9f13c720e49 100644
--- a/crates/diesel_models/src/business_profile.rs
+++ b/crates/diesel_models/src/business_profile.rs
@@ -770,6 +770,7 @@ pub struct PaymentLinkConfigRequest {
     pub payment_form_label_type: Option<common_enums::PaymentLinkSdkLabelType>,
     pub show_card_terms: Option<common_enums::PaymentLinkShowSdkTerms>,
     pub is_setup_mandate_flow: Option<bool>,
+    pub color_icon_card_cvc_error: Option<String>,
 }
 
 #[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 ae2710c50e9..fe28ee27369 100644
--- a/crates/diesel_models/src/payment_intent.rs
+++ b/crates/diesel_models/src/payment_intent.rs
@@ -209,6 +209,8 @@ pub struct PaymentLinkConfigRequestForPayments {
     pub show_card_terms: Option<common_enums::PaymentLinkShowSdkTerms>,
     /// Boolean to control payment button text for setup mandate calls
     pub is_setup_mandate_flow: Option<bool>,
+    /// Hex color for the CVC icon during error state
+    pub color_icon_card_cvc_error: Option<String>,
 }
 
 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 eb37f8f45da..99ef5e3581f 100644
--- a/crates/hyperswitch_domain_models/src/lib.rs
+++ b/crates/hyperswitch_domain_models/src/lib.rs
@@ -432,6 +432,7 @@ impl ApiModelToDieselModelConvertor<api_models::admin::PaymentLinkConfigRequest>
             payment_form_label_type: item.payment_form_label_type,
             show_card_terms: item.show_card_terms,
             is_setup_mandate_flow: item.is_setup_mandate_flow,
+            color_icon_card_cvc_error: item.color_icon_card_cvc_error,
         }
     }
     fn convert_back(self) -> api_models::admin::PaymentLinkConfigRequest {
@@ -460,6 +461,7 @@ impl ApiModelToDieselModelConvertor<api_models::admin::PaymentLinkConfigRequest>
             payment_form_label_type,
             show_card_terms,
             is_setup_mandate_flow,
+            color_icon_card_cvc_error,
         } = self;
         api_models::admin::PaymentLinkConfigRequest {
             theme,
@@ -492,6 +494,7 @@ impl ApiModelToDieselModelConvertor<api_models::admin::PaymentLinkConfigRequest>
             payment_form_label_type,
             show_card_terms,
             is_setup_mandate_flow,
+            color_icon_card_cvc_error,
         }
     }
 }
diff --git a/crates/router/src/core/payment_link.rs b/crates/router/src/core/payment_link.rs
index 545966968bd..923a7af9da8 100644
--- a/crates/router/src/core/payment_link.rs
+++ b/crates/router/src/core/payment_link.rs
@@ -1,4 +1,6 @@
 pub mod validator;
+use std::collections::HashMap;
+
 use actix_web::http::header;
 use api_models::{
     admin::PaymentLinkConfig,
@@ -142,6 +144,7 @@ pub async fn form_payment_link_data(
                 payment_form_label_type: None,
                 show_card_terms: None,
                 is_setup_mandate_flow: None,
+                color_icon_card_cvc_error: None,
             }
         };
 
@@ -316,13 +319,13 @@ pub async fn form_payment_link_data(
         background_colour: payment_link_config.background_colour.clone(),
         payment_button_text_colour: payment_link_config.payment_button_text_colour.clone(),
         sdk_ui_rules: payment_link_config.sdk_ui_rules.clone(),
-        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,
         is_setup_mandate_flow: payment_link_config.is_setup_mandate_flow,
+        color_icon_card_cvc_error: payment_link_config.color_icon_card_cvc_error.clone(),
         capture_method: payment_attempt.capture_method,
         setup_future_usage_applied: payment_attempt.setup_future_usage_applied,
     };
@@ -350,7 +353,7 @@ pub async fn initiate_secure_payment_link_flow(
         &payment_link_config,
     )?;
 
-    let css_script = get_color_scheme_css(&payment_link_config);
+    let css_script = get_payment_link_css_script(&payment_link_config)?;
 
     match payment_link_details {
         PaymentLinkData::PaymentLinkStatusDetails(ref status_details) => {
@@ -380,12 +383,12 @@ pub async fn initiate_secure_payment_link_flow(
                 background_colour: payment_link_config.background_colour,
                 payment_button_text_colour: payment_link_config.payment_button_text_colour,
                 sdk_ui_rules: payment_link_config.sdk_ui_rules,
-                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,
+                color_icon_card_cvc_error: payment_link_config.color_icon_card_cvc_error,
             };
             let payment_details_str = serde_json::to_string(&secure_payment_link_details)
                 .change_context(errors::ApiErrorResponse::InternalServerError)
@@ -446,7 +449,7 @@ pub async fn initiate_payment_link_flow(
     let (_, payment_details, payment_link_config) =
         form_payment_link_data(&state, merchant_context, merchant_id, payment_id).await?;
 
-    let css_script = get_color_scheme_css(&payment_link_config);
+    let css_script = get_payment_link_css_script(&payment_link_config)?;
     let js_script = get_js_script(&payment_details)?;
 
     match payment_details {
@@ -494,6 +497,85 @@ fn get_js_script(payment_details: &PaymentLinkData) -> RouterResult<String> {
     Ok(format!("window.__PAYMENT_DETAILS = '{url_encoded_str}';"))
 }
 
+fn camel_to_kebab(s: &str) -> String {
+    let mut result = String::new();
+    if s.is_empty() {
+        return result;
+    }
+
+    let chars: Vec<char> = s.chars().collect();
+
+    for (i, &ch) in chars.iter().enumerate() {
+        if ch.is_uppercase() {
+            let should_add_dash = i > 0
+                && (chars.get(i - 1).map(|c| c.is_lowercase()).unwrap_or(false)
+                    || (i + 1 < chars.len()
+                        && chars.get(i + 1).map(|c| c.is_lowercase()).unwrap_or(false)
+                        && chars.get(i - 1).map(|c| c.is_uppercase()).unwrap_or(false)));
+
+            if should_add_dash {
+                result.push('-');
+            }
+            result.push(ch.to_ascii_lowercase());
+        } else {
+            result.push(ch);
+        }
+    }
+    result
+}
+
+fn generate_dynamic_css(
+    rules: &HashMap<String, HashMap<String, String>>,
+) -> Result<String, errors::ApiErrorResponse> {
+    if rules.is_empty() {
+        return Ok(String::new());
+    }
+
+    let mut css_string = String::new();
+    css_string.push_str("/* Dynamically Injected UI Rules */\n");
+
+    for (selector, styles_map) in rules {
+        if selector.trim().is_empty() {
+            return Err(errors::ApiErrorResponse::InvalidRequestData {
+                message: "CSS selector cannot be empty.".to_string(),
+            });
+        }
+
+        css_string.push_str(selector);
+        css_string.push_str(" {\n");
+
+        for (prop_camel_case, css_value) in styles_map {
+            let css_property = camel_to_kebab(prop_camel_case);
+
+            css_string.push_str("  ");
+            css_string.push_str(&css_property);
+            css_string.push_str(": ");
+            css_string.push_str(css_value);
+            css_string.push_str(";\n");
+        }
+        css_string.push_str("}\n");
+    }
+    Ok(css_string)
+}
+
+fn get_payment_link_css_script(
+    payment_link_config: &PaymentLinkConfig,
+) -> Result<String, errors::ApiErrorResponse> {
+    let custom_rules_css_option = payment_link_config
+        .payment_link_ui_rules
+        .as_ref()
+        .map(generate_dynamic_css)
+        .transpose()?;
+
+    let color_scheme_css = get_color_scheme_css(payment_link_config);
+
+    if let Some(custom_rules_css) = custom_rules_css_option {
+        Ok(format!("{}\n{}", color_scheme_css, custom_rules_css))
+    } else {
+        Ok(color_scheme_css)
+    }
+}
+
 fn get_color_scheme_css(payment_link_config: &PaymentLinkConfig) -> String {
     let background_primary_color = payment_link_config
         .background_colour
@@ -706,6 +788,7 @@ pub fn get_payment_link_config_based_on_priority(
         payment_form_label_type,
         show_card_terms,
         is_setup_mandate_flow,
+        color_icon_card_cvc_error,
     ) = get_payment_link_config_value!(
         payment_create_link_config,
         business_theme_configs,
@@ -724,6 +807,7 @@ pub fn get_payment_link_config_based_on_priority(
         (payment_form_label_type),
         (show_card_terms),
         (is_setup_mandate_flow),
+        (color_icon_card_cvc_error),
     );
 
     let payment_link_config =
@@ -756,6 +840,7 @@ pub fn get_payment_link_config_based_on_priority(
             payment_form_label_type,
             show_card_terms,
             is_setup_mandate_flow,
+            color_icon_card_cvc_error,
         };
 
     Ok((payment_link_config, domain_name))
@@ -870,6 +955,7 @@ pub async fn get_payment_link_status(
             payment_form_label_type: None,
             show_card_terms: None,
             is_setup_mandate_flow: None,
+            color_icon_card_cvc_error: 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 f58617261d6..37d132fff3a 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
@@ -653,7 +653,7 @@ body {
 }
 
 #submit.not-ready {
-  background-color: #C2C2C2 !important;
+  background-color: #C2C2C2;
 }
 
 #submit-spinner {
diff --git a/crates/router/src/core/payment_link/payment_link_initiate/payment_link.js b/crates/router/src/core/payment_link/payment_link_initiate/payment_link.js
index 1e96731402f..81bda59a0d5 100644
--- a/crates/router/src/core/payment_link/payment_link_initiate/payment_link.js
+++ b/crates/router/src/core/payment_link/payment_link_initiate/payment_link.js
@@ -291,12 +291,6 @@ function boot() {
   // Add event listeners
   initializeEventListeners(paymentDetails);
 
-  // Update payment link styles
-  var paymentLinkUiRules = paymentDetails.payment_link_ui_rules;
-  if (isObject(paymentLinkUiRules)) {
-    updatePaymentLinkUi(paymentLinkUiRules);
-  }
-
   // Initialize SDK
   // @ts-ignore
   if (window.Hyper) {
@@ -358,11 +352,11 @@ function initializeEventListeners(paymentDetails) {
   if (payNowButtonText) {
     if (paymentDetails.payment_button_text) {
       payNowButtonText.textContent = paymentDetails.payment_button_text;
-    } else if (paymentDetails.is_setup_mandate_flow || (paymentDetails.amount==="0.00" && paymentDetails.setup_future_usage_applied ==="off_session")) {
+    } else if (paymentDetails.is_setup_mandate_flow || (paymentDetails.amount === "0.00" && paymentDetails.setup_future_usage_applied === "off_session")) {
       payNowButtonText.textContent = translations.addPaymentMethod;
     } else {
-      payNowButtonText.textContent = capture_type === "manual" ? translations.authorizePayment: translations.payNow;
-      
+      payNowButtonText.textContent = capture_type === "manual" ? translations.authorizePayment : translations.payNow;
+
     }
   }
 
@@ -1214,25 +1208,4 @@ function renderSDKHeader(paymentDetails) {
     // sdkHeaderNode.append(sdkHeaderLogoNode);
     sdkHeaderNode.append(sdkHeaderItemNode);
   }
-}
-
-/**
- * Trigger - post UI render
- * Use - add CSS rules for the payment link
- * @param {Object} paymentLinkUiRules
- */
-function updatePaymentLinkUi(paymentLinkUiRules) {
-  Object.keys(paymentLinkUiRules).forEach(function (selector) {
-    try {
-      var node = document.querySelector(selector);
-      if (node instanceof HTMLElement) {
-        var styles = paymentLinkUiRules[selector];
-        Object.keys(styles).forEach(function (property) {
-          node.style[property] = styles[property];
-        });
-      }
-    } catch (error) {
-      console.error("Failed to apply styles to selector", selector, error);
-    }
-  })
 }
\ No newline at end of file
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 33758131aa2..3c4e0d2549a 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
@@ -14,6 +14,7 @@ function initializeSDK() {
   var clientSecret = paymentDetails.client_secret;
   var sdkUiRules = paymentDetails.sdk_ui_rules;
   var labelType = paymentDetails.payment_form_label_type;
+  var colorIconCardCvcError = paymentDetails.color_icon_card_cvc_error;
   var appearance = {
     variables: {
       colorPrimary: paymentDetails.theme || "rgb(0, 109, 249)",
@@ -33,6 +34,9 @@ function initializeSDK() {
   if (labelType !== null && typeof labelType === "string") {
     appearance.labels = labelType;
   }
+  if (colorIconCardCvcError !== null && typeof colorIconCardCvcError === "string") {
+    appearance.variables.colorIconCardCvcError = colorIconCardCvcError;
+  }
   // @ts-ignore
   hyper = window.Hyper(pub_key, {
     isPreloadEnabled: false,
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 3db5eb94de2..c539363c102 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
@@ -34,6 +34,7 @@ if (!isFramed) {
     var clientSecret = paymentDetails.client_secret;
     var sdkUiRules = paymentDetails.sdk_ui_rules;
     var labelType = paymentDetails.payment_form_label_type;
+    var colorIconCardCvcError = paymentDetails.color_icon_card_cvc_error;
     var appearance = {
       variables: {
         colorPrimary: paymentDetails.theme || "rgb(0, 109, 249)",
@@ -53,6 +54,9 @@ if (!isFramed) {
     if (labelType !== null && typeof labelType === "string") {
       appearance.labels = labelType;
     }
+    if (colorIconCardCvcError !== null && typeof colorIconCardCvcError === "string") {
+      appearance.variables.colorIconCardCvcError = colorIconCardCvcError;
+    }
     // @ts-ignore
     hyper = window.Hyper(pub_key, {
       isPreloadEnabled: false,
diff --git a/crates/router/src/core/payments/transformers.rs b/crates/router/src/core/payments/transformers.rs
index 4dff52acb4c..b9f6e6e5efe 100644
--- a/crates/router/src/core/payments/transformers.rs
+++ b/crates/router/src/core/payments/transformers.rs
@@ -4967,6 +4967,7 @@ impl ForeignFrom<api_models::admin::PaymentLinkConfigRequest>
             payment_form_label_type: config.payment_form_label_type,
             show_card_terms: config.show_card_terms,
             is_setup_mandate_flow: config.is_setup_mandate_flow,
+            color_icon_card_cvc_error: config.color_icon_card_cvc_error,
         }
     }
 }
@@ -5042,6 +5043,7 @@ impl ForeignFrom<diesel_models::PaymentLinkConfigRequestForPayments>
             payment_form_label_type: config.payment_form_label_type,
             show_card_terms: config.show_card_terms,
             is_setup_mandate_flow: config.is_setup_mandate_flow,
+            color_icon_card_cvc_error: config.color_icon_card_cvc_error,
         }
     }
 }
diff --git a/crates/router/src/types/transformers.rs b/crates/router/src/types/transformers.rs
index e1607c3b6b2..7e504413e57 100644
--- a/crates/router/src/types/transformers.rs
+++ b/crates/router/src/types/transformers.rs
@@ -2235,6 +2235,7 @@ impl ForeignFrom<api_models::admin::PaymentLinkConfigRequest>
             payment_form_label_type: item.payment_form_label_type,
             show_card_terms: item.show_card_terms,
             is_setup_mandate_flow: item.is_setup_mandate_flow,
+            color_icon_card_cvc_error: item.color_icon_card_cvc_error,
         }
     }
 }
@@ -2270,6 +2271,7 @@ impl ForeignFrom<diesel_models::business_profile::PaymentLinkConfigRequest>
             payment_form_label_type: item.payment_form_label_type,
             show_card_terms: item.show_card_terms,
             is_setup_mandate_flow: item.is_setup_mandate_flow,
+            color_icon_card_cvc_error: item.color_icon_card_cvc_error,
         }
     }
 }

## Type of Change
<!-- Put an `x` in the boxes that apply -->

- [x] Bugfix
- [ ] New feature
- [ ] Enhancement
- [ ] Refactoring
- [ ] Dependency updates
- [ ] Documentation
- [ ] CI/CD

## Description
This PR introduces
- modification of the behavior of appending the `payment_link_ui_rules` to the CSS instead of selecting and applying it to the retrieved elements at runtime.
- expose `color_icon_card_cvc_error` via API for SDK variables

### Additional Changes

- [ ] This PR modifies the API contract
- [ ] This PR modifies the database schema
- [ ] This PR modifies application configuration/environment variables

<!--
Provide links to the files with corresponding changes.

Following are the paths where you can find config files:
1. `config`
2. `crates/router/src/configs`
3. `loadtest/config`
-->


## Motivation and Context
This change allows for styling the payment link UI elements using CSS rules.

## How did you test it?

Steps for testing -

<details>
    <summary>1. Create a payment link with dynamic selectors in `payment_link_ui_rules`</summary>

cURL

    curl --location --request POST 'http://localhost:8080/payments' \
        --header 'Content-Type: application/json' \
        --header 'Accept: application/json' \
        --header 'api-key: dev_mCD2MU1TfvKQkyMLkTKg6aeNkN8JHVGSllEqGrC0wbSnWNMtGmzrgYPFMwlx8Atl' \
        --data-raw '{"authentication_type":"three_ds","customer_id":"cus_Qy5sr7VpE3tRoUh7M1W1","profile_id":"pro_A69LEikrut4ROWAXoTnm","customer_acceptance":{"acceptance_type":"online","accepted_at":"1963-05-03T04:07:52.723Z","online":{"ip_address":"127.0.0.1","user_agent":"amet irure esse"}},"amount":0,"currency":"USD","confirm":false,"payment_link":true,"session_expiry":12600,"billing":{"address":{},"email":"random@juspay.in"},"return_url":"https://www.example.com","payment_link_config":{"logo":"https://hyperswitch.io/favicon.ico","display_sdk_only":true,"payment_button_text":"Save Card","enable_button_only_on_form_ready":true,"color_icon_card_cvc_error":"#CB4B40","payment_link_ui_rules":{"#submit":{"color":"#ffffff !important","border":"1px solid #b2b2b2 !important","borderRadius":"0 !important","fontSize":"13px !important","backgroundColor":"#b2b2b2 !important","height":"25px !important","width":"max-content !important","padding":"0 8px","margin":"0 4px 0 auto"},"#submit.not-ready":{"color":"#b2b2b2 !important","border":"1px solid #b2b2b2 !important","backgroundColor":"#ffffff !important"},"#submit-spinner":{"width":"20px !important","height":"20px !important","border":"2px solid #fff !important","borderBottomColor":"#c2c2c2 !important"}},"background_image":{"url":"https://img.freepik.com/free-photo/abstract-blue-geometric-shapes-background_24972-1841.jpg","position":"bottom","size":"cover"}}}'

</details>


<details>
    <summary>2. Open the payment link and fill in the form (Save Card button's color should update)</summary>

<img width="589" alt="Screenshot 2025-06-06 at 1 49 47 PM" src="https://github.com/user-attachments/assets/918e152b-0ac0-4a81-860f-2a7740ef8d6b" />
<img width="605" alt="Screenshot 2025-06-06 at 1 49 53 PM" src="https://github.com/user-attachments/assets/e243b8a0-3be8-45b7-ae40-dd37dbacf15a" />

</details>

## Checklist
<!-- Put an `x` in the boxes that apply -->

- [x] I formatted the code `cargo +nightly fmt --all`
- [x] I addressed lints thrown by `cargo clippy`
- [x] I reviewed the submitted code
- [ ] I added unit tests for my changes where possible
