mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-03 13:30:39 +08:00
feat(payment-link): add config for enabling form button only when form is complete (#7517)
This commit is contained in:
@ -152,6 +152,9 @@ pub const DEFAULT_DISPLAY_SDK_ONLY: bool = false;
|
||||
/// Default bool to enable saved payment method
|
||||
pub const DEFAULT_ENABLE_SAVED_PAYMENT_METHOD: bool = false;
|
||||
|
||||
/// [PaymentLink] Default bool for enabling button only when form is ready
|
||||
pub const DEFAULT_ENABLE_BUTTON_ONLY_ON_FORM_READY: bool = false;
|
||||
|
||||
/// Default Merchant Logo Link
|
||||
pub const DEFAULT_MERCHANT_LOGO: &str =
|
||||
"https://live.hyperswitch.io/payment-link-assets/Merchant_placeholder.png";
|
||||
|
||||
@ -23,8 +23,9 @@ use super::{
|
||||
use crate::{
|
||||
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, DEFAULT_SHOW_CARD_FORM,
|
||||
DEFAULT_ENABLE_BUTTON_ONLY_ON_FORM_READY, DEFAULT_ENABLE_SAVED_PAYMENT_METHOD,
|
||||
DEFAULT_HIDE_CARD_NICKNAME_FIELD, DEFAULT_MERCHANT_LOGO, DEFAULT_PRODUCT_IMG,
|
||||
DEFAULT_SDK_LAYOUT, DEFAULT_SHOW_CARD_FORM,
|
||||
},
|
||||
errors::RouterResponse,
|
||||
get_payment_link_config_value, get_payment_link_config_value_based_on_priority,
|
||||
@ -137,6 +138,7 @@ pub async fn form_payment_link_data(
|
||||
payment_button_text_colour: None,
|
||||
sdk_ui_rules: None,
|
||||
payment_link_ui_rules: None,
|
||||
enable_button_only_on_form_ready: DEFAULT_ENABLE_BUTTON_ONLY_ON_FORM_READY,
|
||||
}
|
||||
};
|
||||
|
||||
@ -290,6 +292,7 @@ pub async fn form_payment_link_data(
|
||||
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(),
|
||||
enable_button_only_on_form_ready: payment_link_config.enable_button_only_on_form_ready,
|
||||
};
|
||||
|
||||
Ok((
|
||||
@ -348,6 +351,8 @@ pub async fn initiate_secure_payment_link_flow(
|
||||
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,
|
||||
};
|
||||
let js_script = format!(
|
||||
"window.__PAYMENT_DETAILS = {}",
|
||||
@ -634,6 +639,7 @@ pub fn get_payment_link_config_based_on_priority(
|
||||
enabled_saved_payment_method,
|
||||
hide_card_nickname_field,
|
||||
show_card_form_by_default,
|
||||
enable_button_only_on_form_ready,
|
||||
) = get_payment_link_config_value!(
|
||||
payment_create_link_config,
|
||||
business_theme_configs,
|
||||
@ -647,7 +653,11 @@ pub fn get_payment_link_config_based_on_priority(
|
||||
DEFAULT_ENABLE_SAVED_PAYMENT_METHOD
|
||||
),
|
||||
(hide_card_nickname_field, DEFAULT_HIDE_CARD_NICKNAME_FIELD),
|
||||
(show_card_form_by_default, DEFAULT_SHOW_CARD_FORM)
|
||||
(show_card_form_by_default, DEFAULT_SHOW_CARD_FORM),
|
||||
(
|
||||
enable_button_only_on_form_ready,
|
||||
DEFAULT_ENABLE_BUTTON_ONLY_ON_FORM_READY
|
||||
)
|
||||
);
|
||||
|
||||
let (
|
||||
@ -702,6 +712,7 @@ pub fn get_payment_link_config_based_on_priority(
|
||||
payment_button_text_colour,
|
||||
sdk_ui_rules,
|
||||
payment_link_ui_rules,
|
||||
enable_button_only_on_form_ready,
|
||||
};
|
||||
|
||||
Ok((payment_link_config, domain_name))
|
||||
@ -812,6 +823,7 @@ pub async fn get_payment_link_status(
|
||||
payment_button_text_colour: None,
|
||||
sdk_ui_rules: None,
|
||||
payment_link_ui_rules: None,
|
||||
enable_button_only_on_form_ready: DEFAULT_ENABLE_BUTTON_ONLY_ON_FORM_READY,
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -652,6 +652,10 @@ body {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
#submit.not-ready {
|
||||
background-color: #C2C2C2 !important;
|
||||
}
|
||||
|
||||
#submit-spinner {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
|
||||
@ -290,9 +290,9 @@
|
||||
<div></div>
|
||||
</div>
|
||||
</div>
|
||||
<form id="payment-form" onclick="handleSubmit(); return false;">
|
||||
<form id="payment-form">
|
||||
<div id="unified-checkout"></div>
|
||||
<button id="submit" class="hidden">
|
||||
<button type="submit" id="submit" class="hidden">
|
||||
<span id="submit-spinner" class="hidden"></span>
|
||||
<span id="submit-button-text"></span>
|
||||
</button>
|
||||
|
||||
@ -257,7 +257,7 @@ function boot() {
|
||||
|
||||
// Update payment link styles
|
||||
var paymentLinkUiRules = paymentDetails.payment_link_ui_rules;
|
||||
if (paymentLinkUiRules !== null && typeof paymentLinkUiRules === "object" && Object.getPrototypeOf(paymentLinkUiRules) === Object.prototype) {
|
||||
if (isObject(paymentLinkUiRules)) {
|
||||
updatePaymentLinkUi(paymentLinkUiRules);
|
||||
}
|
||||
|
||||
@ -279,7 +279,18 @@ function boot() {
|
||||
boot();
|
||||
|
||||
/**
|
||||
* Use - add event listeners for changing UI on screen resize
|
||||
* Use - checks if a given value is an object
|
||||
* @param {any} val
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isObject(val) {
|
||||
return val !== null && typeof val === "object" && Object.getPrototypeOf(val) === Object.prototype
|
||||
}
|
||||
|
||||
/**
|
||||
* Use - add event listeners for changing UI on
|
||||
* - Screen resize
|
||||
* - Form inputs
|
||||
* @param {PaymentDetails} paymentDetails
|
||||
*/
|
||||
function initializeEventListeners(paymentDetails) {
|
||||
@ -384,17 +395,58 @@ function initializeEventListeners(paymentDetails) {
|
||||
// @ts-ignore
|
||||
window.state.isMobileView = currentWidth <= 1199;
|
||||
});
|
||||
|
||||
var paymentForm = document.getElementById("payment-form");
|
||||
if (paymentForm instanceof HTMLFormElement) {
|
||||
paymentForm.addEventListener("submit", function (event) {
|
||||
event.preventDefault();
|
||||
handleSubmit(event);
|
||||
})
|
||||
}
|
||||
|
||||
if (paymentDetails.enable_button_only_on_form_ready) {
|
||||
handleFormReadyForSubmission();
|
||||
}
|
||||
}
|
||||
|
||||
function handleFormReadyForSubmission() {
|
||||
window.addEventListener("message", function (event) {
|
||||
// Event listener for updating the button rules
|
||||
if (isObject(event.data) && event.data["isFormReadyForSubmission"] !== null) {
|
||||
let isFormReadyForSubmission = event.data["isFormReadyForSubmission"];
|
||||
var submitButtonNode = document.getElementById("submit");
|
||||
if (submitButtonNode instanceof HTMLButtonElement) {
|
||||
if (isFormReadyForSubmission === false) {
|
||||
submitButtonNode.disabled = true;
|
||||
addClass("#submit", "not-ready");
|
||||
addClass("#submit", "disabled");
|
||||
} else if (isFormReadyForSubmission === true) {
|
||||
submitButtonNode.disabled = false;
|
||||
removeClass("#submit", "not-ready");
|
||||
removeClass("#submit", "disabled");
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger - post mounting SDK
|
||||
* Use - set relevant classes to elements in the doc for showing SDK
|
||||
**/
|
||||
function showSDK(display_sdk_only) {
|
||||
function showSDK(display_sdk_only, enable_button_only_on_form_ready) {
|
||||
if (!display_sdk_only) {
|
||||
show("#hyper-checkout-details");
|
||||
}
|
||||
show("#hyper-checkout-sdk");
|
||||
if (enable_button_only_on_form_ready) {
|
||||
addClass("#submit", "not-ready");
|
||||
addClass("#submit", "disabled");
|
||||
var submitButtonNode = document.getElementById("submit");
|
||||
if (submitButtonNode instanceof HTMLButtonElement) {
|
||||
submitButtonNode.disabled = true;
|
||||
}
|
||||
}
|
||||
show("#submit");
|
||||
show("#unified-checkout");
|
||||
hide("#sdk-spinner");
|
||||
@ -426,10 +478,11 @@ function handleSubmit(e) {
|
||||
// Update button loader
|
||||
hide("#submit-button-text");
|
||||
show("#submit-spinner");
|
||||
addClass("#submit", "processing");
|
||||
addClass("#submit", "disabled");
|
||||
var submitButtonNode = document.getElementById("submit");
|
||||
if (submitButtonNode instanceof HTMLButtonElement) {
|
||||
submitButtonNode.disabled = true;
|
||||
submitButtonNode.classList.add("disabled");
|
||||
}
|
||||
|
||||
hyper
|
||||
@ -472,11 +525,12 @@ function handleSubmit(e) {
|
||||
console.error("Error confirming payment_intent", error);
|
||||
})
|
||||
.finally(() => {
|
||||
removeClass("#submit", "processing");
|
||||
hide("#submit-spinner");
|
||||
show("#submit-button-text");
|
||||
removeClass("#submit", "disabled");
|
||||
if (submitButtonNode instanceof HTMLButtonElement) {
|
||||
submitButtonNode.disabled = false;
|
||||
submitButtonNode.classList.remove("disabled");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -75,7 +75,7 @@ function initializeSDK() {
|
||||
// @ts-ignore
|
||||
mountUnifiedCheckout("#unified-checkout");
|
||||
// @ts-ignore
|
||||
showSDK(paymentDetails.display_sdk_only);
|
||||
showSDK(paymentDetails.display_sdk_only, paymentDetails.enable_button_only_on_form_ready);
|
||||
|
||||
let shimmer = document.getElementById("payment-details-shimmer");
|
||||
shimmer.classList.add("reduce-opacity");
|
||||
|
||||
@ -98,7 +98,7 @@ if (!isFramed) {
|
||||
// @ts-ignore
|
||||
mountUnifiedCheckout("#unified-checkout");
|
||||
// @ts-ignore
|
||||
showSDK(paymentDetails.display_sdk_only);
|
||||
showSDK(paymentDetails.display_sdk_only, paymentDetails.enable_button_only_on_form_ready);
|
||||
|
||||
let shimmer = document.getElementById("payment-details-shimmer");
|
||||
shimmer.classList.add("reduce-opacity");
|
||||
|
||||
@ -4532,6 +4532,7 @@ impl ForeignFrom<api_models::admin::PaymentLinkConfigRequest>
|
||||
payment_button_text_colour: config.payment_button_text_colour,
|
||||
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,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4602,6 +4603,7 @@ impl ForeignFrom<diesel_models::PaymentLinkConfigRequestForPayments>
|
||||
payment_button_text_colour: config.payment_button_text_colour,
|
||||
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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2174,6 +2174,7 @@ impl ForeignFrom<api_models::admin::PaymentLinkConfigRequest>
|
||||
payment_button_text_colour: item.payment_button_text_colour,
|
||||
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,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2204,6 +2205,7 @@ impl ForeignFrom<diesel_models::business_profile::PaymentLinkConfigRequest>
|
||||
payment_button_text_colour: item.payment_button_text_colour,
|
||||
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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user