mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-29 09:07:09 +08:00
feat(payment-link): emit intent status to parent before rendering payment link UI (#7531)
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
@ -7944,6 +7944,7 @@ pub struct PaymentLinkDetails {
|
||||
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,
|
||||
}
|
||||
|
||||
|
||||
@ -191,7 +191,7 @@ pub async fn form_payment_link_data(
|
||||
let merchant_name = capitalize_first_char(&payment_link_config.seller_name);
|
||||
let payment_link_status = check_payment_link_status(session_expiry);
|
||||
|
||||
let is_terminal_state = check_payment_link_invalid_conditions(
|
||||
let is_payment_link_terminal_state = check_payment_link_invalid_conditions(
|
||||
payment_intent.status,
|
||||
&[
|
||||
storage_enums::IntentStatus::Cancelled,
|
||||
@ -201,9 +201,11 @@ pub async fn form_payment_link_data(
|
||||
storage_enums::IntentStatus::RequiresMerchantAction,
|
||||
storage_enums::IntentStatus::Succeeded,
|
||||
storage_enums::IntentStatus::PartiallyCaptured,
|
||||
storage_enums::IntentStatus::RequiresCustomerAction,
|
||||
],
|
||||
);
|
||||
if is_terminal_state || payment_link_status == api_models::payments::PaymentLinkStatus::Expired
|
||||
if is_payment_link_terminal_state
|
||||
|| payment_link_status == api_models::payments::PaymentLinkStatus::Expired
|
||||
{
|
||||
let status = match payment_link_status {
|
||||
api_models::payments::PaymentLinkStatus::Active => {
|
||||
@ -211,7 +213,7 @@ pub async fn form_payment_link_data(
|
||||
PaymentLinkStatusWrap::IntentStatus(payment_intent.status)
|
||||
}
|
||||
api_models::payments::PaymentLinkStatus::Expired => {
|
||||
if is_terminal_state {
|
||||
if is_payment_link_terminal_state {
|
||||
logger::info!("displaying status page as the requested payment link has reached terminal state with payment status as {:?}", payment_intent.status);
|
||||
PaymentLinkStatusWrap::IntentStatus(payment_intent.status)
|
||||
} else {
|
||||
@ -292,6 +294,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(),
|
||||
status: payment_intent.status,
|
||||
enable_button_only_on_form_ready: payment_link_config.enable_button_only_on_form_ready,
|
||||
};
|
||||
|
||||
|
||||
@ -181,6 +181,30 @@ var hyper = null;
|
||||
|
||||
const translations = getTranslations(window.__PAYMENT_DETAILS.locale);
|
||||
|
||||
var isFramed = false;
|
||||
try {
|
||||
isFramed = window.parent.location !== window.location;
|
||||
|
||||
// If parent's window object is restricted, DOMException is
|
||||
// thrown which concludes that the webpage is iframed
|
||||
} catch (err) {
|
||||
isFramed = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger - on boot
|
||||
* Use - emit latest payment status to parent window
|
||||
*/
|
||||
function emitPaymentStatus(paymentDetails) {
|
||||
var message = {
|
||||
payment: {
|
||||
status: paymentDetails.status,
|
||||
}
|
||||
};
|
||||
|
||||
window.parent.postMessage(message, "*");
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger - init function invoked once the script tag is loaded
|
||||
* Use
|
||||
@ -190,13 +214,16 @@ const translations = getTranslations(window.__PAYMENT_DETAILS.locale);
|
||||
* - Initialize event listeners for updating UI on screen size changes
|
||||
* - Initialize SDK
|
||||
**/
|
||||
|
||||
|
||||
function boot() {
|
||||
|
||||
// @ts-ignore
|
||||
var paymentDetails = window.__PAYMENT_DETAILS;
|
||||
|
||||
// Emit latest payment status
|
||||
if (isFramed) {
|
||||
emitPaymentStatus(paymentDetails);
|
||||
}
|
||||
|
||||
if (paymentDetails.display_sdk_only) {
|
||||
hide(".checkout-page")
|
||||
var sdkDisplayWidth = document.querySelector('.hyper-checkout-sdk');
|
||||
|
||||
@ -137,6 +137,10 @@ body > div {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ellipsis-container-2 {
|
||||
height: 2.5em;
|
||||
overflow: hidden;
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
{{ rendered_js }}
|
||||
</script>
|
||||
</head>
|
||||
<body onload="boot()">
|
||||
<body onload="boot()" class="hidden">
|
||||
<div>
|
||||
<div class="hyper-checkout-status-wrap">
|
||||
<div id="hyper-checkout-status-header"></div>
|
||||
|
||||
@ -52,8 +52,8 @@ function invertToBW(color, bw, asArr) {
|
||||
? hexToRgbArray(options.black)
|
||||
: options.black
|
||||
: asArr
|
||||
? hexToRgbArray(options.white)
|
||||
: options.white;
|
||||
? hexToRgbArray(options.white)
|
||||
: options.white;
|
||||
}
|
||||
function invert(color, bw) {
|
||||
if (bw === void 0) {
|
||||
@ -87,6 +87,31 @@ window.state = {
|
||||
};
|
||||
|
||||
const translations = getTranslations(window.__PAYMENT_DETAILS.locale);
|
||||
|
||||
var isFramed = false;
|
||||
try {
|
||||
isFramed = window.parent.location !== window.location;
|
||||
|
||||
// If parent's window object is restricted, DOMException is
|
||||
// thrown which concludes that the webpage is iframed
|
||||
} catch (err) {
|
||||
isFramed = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger - on boot
|
||||
* Use - emit latest payment status to parent window
|
||||
*/
|
||||
function emitPaymentStatus(paymentDetails) {
|
||||
var message = {
|
||||
payment: {
|
||||
status: paymentDetails.status,
|
||||
}
|
||||
};
|
||||
|
||||
window.parent.postMessage(message, "*");
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger - init function invoked once the script tag is loaded
|
||||
* Use
|
||||
@ -100,20 +125,43 @@ function boot() {
|
||||
// @ts-ignore
|
||||
var paymentDetails = window.__PAYMENT_DETAILS;
|
||||
|
||||
// Attach document icon
|
||||
if (paymentDetails.merchant_logo) {
|
||||
var link = document.createElement("link");
|
||||
link.rel = "icon";
|
||||
link.href = paymentDetails.merchant_logo;
|
||||
link.type = "image/x-icon";
|
||||
document.head.appendChild(link);
|
||||
// Emit latest payment status
|
||||
if (isFramed) {
|
||||
emitPaymentStatus(paymentDetails);
|
||||
}
|
||||
|
||||
// Render status details
|
||||
renderStatusDetails(paymentDetails);
|
||||
if (shouldRenderUI(paymentDetails)) {
|
||||
removeClass("body", "hidden");
|
||||
// Attach document icon
|
||||
if (paymentDetails.merchant_logo) {
|
||||
var link = document.createElement("link");
|
||||
link.rel = "icon";
|
||||
link.href = paymentDetails.merchant_logo;
|
||||
link.type = "image/x-icon";
|
||||
document.head.appendChild(link);
|
||||
}
|
||||
|
||||
// Add event listeners
|
||||
initializeEventListeners(paymentDetails);
|
||||
// Render status details
|
||||
renderStatusDetails(paymentDetails);
|
||||
|
||||
// Add event listeners
|
||||
initializeEventListeners(paymentDetails);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger - on boot
|
||||
* Use - Check if UI should be rendered based on some conditions
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
function shouldRenderUI(paymentDetails) {
|
||||
var status = paymentDetails.status;
|
||||
if (isFramed) {
|
||||
switch (status) {
|
||||
case "requires_customer_action": return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -158,6 +206,7 @@ function renderStatusDetails(paymentDetails) {
|
||||
).toTimeString();
|
||||
break;
|
||||
|
||||
case "requires_customer_action":
|
||||
case "processing":
|
||||
statusDetails.imageSource = "https://live.hyperswitch.io/payment-link-assets/pending.png";
|
||||
statusDetails.message = translations.paymentTakingLonger;
|
||||
@ -279,7 +328,7 @@ function renderStatusDetails(paymentDetails) {
|
||||
var innerText =
|
||||
secondsLeft === 0
|
||||
? translations.redirecting
|
||||
: translations.redirectingIn + secondsLeft + " "+translations.seconds;
|
||||
: translations.redirectingIn + secondsLeft + " " + translations.seconds;
|
||||
// @ts-ignore
|
||||
statusRedirectTextNode.innerText = innerText;
|
||||
if (secondsLeft === 0) {
|
||||
@ -341,5 +390,18 @@ function initializeEventListeners(paymentDetails) {
|
||||
if (statusRedirectTextNode instanceof HTMLDivElement) {
|
||||
statusRedirectTextNode.style.color = contrastBWColor;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
function addClass(id, className) {
|
||||
var element = document.querySelector(id);
|
||||
if (element instanceof HTMLElement) {
|
||||
element.classList.add(className);
|
||||
}
|
||||
}
|
||||
|
||||
function removeClass(id, className) {
|
||||
var element = document.querySelector(id);
|
||||
if (element instanceof HTMLElement) {
|
||||
element.classList.remove(className);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user