mirror of
				https://github.com/juspay/hyperswitch.git
				synced 2025-11-01 02:57:02 +08:00 
			
		
		
		
	feat(core): [Payment Link] add dynamic merchant fields (#5512)
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
		| @ -8,7 +8,7 @@ use common_utils::{ | ||||
|     consts::{ | ||||
|         DEFAULT_ALLOWED_DOMAINS, DEFAULT_BACKGROUND_COLOR, DEFAULT_DISPLAY_SDK_ONLY, | ||||
|         DEFAULT_ENABLE_SAVED_PAYMENT_METHOD, DEFAULT_MERCHANT_LOGO, DEFAULT_PRODUCT_IMG, | ||||
|         DEFAULT_SDK_LAYOUT, DEFAULT_SESSION_EXPIRY, | ||||
|         DEFAULT_SDK_LAYOUT, DEFAULT_SESSION_EXPIRY, DEFAULT_TRANSACTION_DETAILS, | ||||
|     }, | ||||
|     ext_traits::{OptionExt, ValueExt}, | ||||
|     types::{AmountConvertor, MinorUnit, StringMajorUnitForCore}, | ||||
| @ -109,6 +109,7 @@ pub async fn form_payment_link_data( | ||||
|                 display_sdk_only: DEFAULT_DISPLAY_SDK_ONLY, | ||||
|                 enabled_saved_payment_method: DEFAULT_ENABLE_SAVED_PAYMENT_METHOD, | ||||
|                 allowed_domains: DEFAULT_ALLOWED_DOMAINS, | ||||
|                 transaction_details: DEFAULT_TRANSACTION_DETAILS, | ||||
|             } | ||||
|         }; | ||||
|  | ||||
| @ -219,36 +220,41 @@ pub async fn form_payment_link_data( | ||||
|             theme: payment_link_config.theme.clone(), | ||||
|             return_url: return_url.clone(), | ||||
|             locale: locale.clone(), | ||||
|             transaction_details: payment_link_config.transaction_details.clone(), | ||||
|         }; | ||||
|  | ||||
|         return Ok(( | ||||
|             payment_link, | ||||
|             PaymentLinkData::PaymentLinkStatusDetails(payment_details), | ||||
|             PaymentLinkData::PaymentLinkStatusDetails(Box::new(payment_details)), | ||||
|             payment_link_config, | ||||
|         )); | ||||
|     }; | ||||
|  | ||||
|     let payment_link_details = | ||||
|         PaymentLinkData::PaymentLinkDetails(api_models::payments::PaymentLinkDetails { | ||||
|             amount, | ||||
|             currency, | ||||
|             payment_id: payment_intent.payment_id, | ||||
|             merchant_name, | ||||
|             order_details, | ||||
|             return_url, | ||||
|             session_expiry, | ||||
|             pub_key: merchant_account.publishable_key, | ||||
|             client_secret, | ||||
|             merchant_logo: payment_link_config.logo.clone(), | ||||
|             max_items_visible_after_collapse: 3, | ||||
|             theme: payment_link_config.theme.clone(), | ||||
|             merchant_description: payment_intent.description, | ||||
|             sdk_layout: payment_link_config.sdk_layout.clone(), | ||||
|             display_sdk_only: payment_link_config.display_sdk_only, | ||||
|             locale, | ||||
|         }); | ||||
|     let payment_link_details = api_models::payments::PaymentLinkDetails { | ||||
|         amount, | ||||
|         currency, | ||||
|         payment_id: payment_intent.payment_id, | ||||
|         merchant_name, | ||||
|         order_details, | ||||
|         return_url, | ||||
|         session_expiry, | ||||
|         pub_key: merchant_account.publishable_key, | ||||
|         client_secret, | ||||
|         merchant_logo: payment_link_config.logo.clone(), | ||||
|         max_items_visible_after_collapse: 3, | ||||
|         theme: payment_link_config.theme.clone(), | ||||
|         merchant_description: payment_intent.description, | ||||
|         sdk_layout: payment_link_config.sdk_layout.clone(), | ||||
|         display_sdk_only: payment_link_config.display_sdk_only, | ||||
|         locale, | ||||
|         transaction_details: payment_link_config.transaction_details.clone(), | ||||
|     }; | ||||
|  | ||||
|     Ok((payment_link, payment_link_details, payment_link_config)) | ||||
|     Ok(( | ||||
|         payment_link, | ||||
|         PaymentLinkData::PaymentLinkDetails(Box::new(payment_link_details)), | ||||
|         payment_link_config, | ||||
|     )) | ||||
| } | ||||
|  | ||||
| pub async fn initiate_secure_payment_link_flow( | ||||
| @ -297,7 +303,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, | ||||
|                 payment_link_details: link_details.to_owned(), | ||||
|                 payment_link_details: *link_details.to_owned(), | ||||
|             }; | ||||
|             let js_script = format!( | ||||
|                 "window.__PAYMENT_DETAILS = {}", | ||||
| @ -602,6 +608,24 @@ pub fn get_payment_link_config_based_on_priority( | ||||
|         display_sdk_only, | ||||
|         enabled_saved_payment_method, | ||||
|         allowed_domains, | ||||
|         transaction_details: payment_create_link_config.and_then(|payment_link_config| { | ||||
|             payment_link_config | ||||
|                 .theme_config | ||||
|                 .transaction_details | ||||
|                 .and_then(|transaction_details| { | ||||
|                     match serde_json::to_string(&transaction_details).change_context( | ||||
|                         errors::ApiErrorResponse::InvalidDataValue { | ||||
|                             field_name: "transaction_details", | ||||
|                         }, | ||||
|                     ) { | ||||
|                         Ok(details) => Some(details), | ||||
|                         Err(err) => { | ||||
|                             logger::error!("Failed to serialize transaction details: {:?}", err); | ||||
|                             None | ||||
|                         } | ||||
|                     } | ||||
|                 }) | ||||
|         }), | ||||
|     }; | ||||
|  | ||||
|     Ok((payment_link_config, domain_name)) | ||||
| @ -689,6 +713,7 @@ pub async fn get_payment_link_status( | ||||
|             display_sdk_only: DEFAULT_DISPLAY_SDK_ONLY, | ||||
|             enabled_saved_payment_method: DEFAULT_ENABLE_SAVED_PAYMENT_METHOD, | ||||
|             allowed_domains: DEFAULT_ALLOWED_DOMAINS, | ||||
|             transaction_details: DEFAULT_TRANSACTION_DETAILS, | ||||
|         } | ||||
|     }; | ||||
|  | ||||
| @ -748,8 +773,11 @@ pub async fn get_payment_link_status( | ||||
|         theme: payment_link_config.theme.clone(), | ||||
|         return_url, | ||||
|         locale, | ||||
|         transaction_details: payment_link_config.transaction_details, | ||||
|     }; | ||||
|     let js_script = get_js_script(&PaymentLinkData::PaymentLinkStatusDetails(payment_details))?; | ||||
|     let js_script = get_js_script(&PaymentLinkData::PaymentLinkStatusDetails(Box::new( | ||||
|         payment_details, | ||||
|     )))?; | ||||
|     let payment_link_status_data = services::PaymentLinkStatusData { | ||||
|         js_script, | ||||
|         css_script, | ||||
|  | ||||
| @ -90,10 +90,21 @@ body { | ||||
| .content-details-wrap { | ||||
|   display: flex; | ||||
|   flex-flow: row; | ||||
|   margin: 20px 20px 30px 20px; | ||||
|   margin: 20px 20px 10px 20px; | ||||
|   justify-content: space-between; | ||||
| } | ||||
|  | ||||
| #hyper-checkout-payment-merchant-dynamic-details { | ||||
|   margin: 20px 20px 10px 20px; | ||||
| } | ||||
|  | ||||
| .hyper-checkout-payment-horizontal-line { | ||||
|   margin: 0px 20px; | ||||
|   height: 2px;   | ||||
|   background-color: #e5e5e5;   | ||||
|   border: none;  | ||||
| } | ||||
|  | ||||
| .hyper-checkout-payment-price { | ||||
|   font-weight: 700; | ||||
|   font-size: 40px; | ||||
| @ -111,6 +122,11 @@ body { | ||||
|   font-size: 19px; | ||||
| } | ||||
|  | ||||
| .hyper-checkout-payment-merchant-dynamic-data { | ||||
|   font-size: 12px; | ||||
|   margin-top: 5px; | ||||
| } | ||||
|  | ||||
| .hyper-checkout-payment-ref { | ||||
|   font-size: 12px; | ||||
|   margin-top: 5px; | ||||
| @ -694,6 +710,18 @@ body { | ||||
|     margin: 0; | ||||
|   } | ||||
|  | ||||
|   #hyper-checkout-payment-merchant-dynamic-details { | ||||
|     flex-flow: column; | ||||
|     flex-direction: column-reverse; | ||||
|     margin: 0; | ||||
|   } | ||||
|    | ||||
|   .hyper-checkout-payment-horizontal-line { | ||||
|     margin: 10px 0px; | ||||
|     height: 2px;   | ||||
|     border: none;  | ||||
|   } | ||||
|  | ||||
|   #hyper-checkout-merchant-image { | ||||
|     background-color: white; | ||||
|   } | ||||
|  | ||||
| @ -225,6 +225,8 @@ | ||||
|                 </div> | ||||
|               </div> | ||||
|             </div> | ||||
|             <div id="hyper-checkout-payment-horizontal-line-container"></div> | ||||
|             <div id="hyper-checkout-payment-merchant-dynamic-details"></div> | ||||
|             <div id="hyper-checkout-payment-footer"></div> | ||||
|           </div> | ||||
|         </div> | ||||
|  | ||||
| @ -238,6 +238,7 @@ function boot() { | ||||
|   } | ||||
|   else{ | ||||
|     renderPaymentDetails(paymentDetails); | ||||
|     renderDynamicMerchantDetails(paymentDetails); | ||||
|     renderCart(paymentDetails); | ||||
|     renderSDKHeader(paymentDetails); | ||||
|   } | ||||
| @ -605,6 +606,42 @@ function renderPaymentDetails(paymentDetails) { | ||||
|   } | ||||
| } | ||||
|  | ||||
| function renderDynamicMerchantDetails(paymentDetails) { | ||||
|   var merchantDynamicDetails = document.getElementById( | ||||
|     "hyper-checkout-payment-merchant-dynamic-details" | ||||
|   ); | ||||
|   if (merchantDynamicDetails instanceof HTMLDivElement) { | ||||
|     // add dynamic merchant details in the payment details section if present | ||||
|     appendMerchantDetails(paymentDetails, merchantDynamicDetails); | ||||
|   } | ||||
| } | ||||
|  | ||||
| function appendMerchantDetails(paymentDetails, merchantDynamicDetails) { | ||||
|   if (Object.keys(paymentDetails.transaction_details).length === 0) { | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   // render a horizontal line above dynamic merchant details | ||||
|   let horizontalLineContainer = document.getElementById("hyper-checkout-payment-horizontal-line-container"); | ||||
|   let horizontalLine = document.createElement("hr"); | ||||
|   horizontalLine.className = "hyper-checkout-payment-horizontal-line"; | ||||
|   horizontalLineContainer.append(horizontalLine); | ||||
|  | ||||
|   // max number of items to show in the merchant details | ||||
|   let maxItemsInDetails = 5; | ||||
|   let merchantDetailsObject = JSON.parse(paymentDetails.transaction_details); | ||||
|   for(const key in merchantDetailsObject) { | ||||
|     var merchantData = document.createElement("div"); | ||||
|     merchantData.className = "hyper-checkout-payment-merchant-dynamic-data"; | ||||
|     merchantData.innerHTML = key+": "+merchantDetailsObject[key].bold(); | ||||
|  | ||||
|     merchantDynamicDetails.append(merchantData); | ||||
|     if(--maxItemsInDetails === 0) { | ||||
|       break; | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Trigger - on boot | ||||
|  * Uses | ||||
|  | ||||
| @ -1740,6 +1740,7 @@ impl ForeignFrom<diesel_models::business_profile::PaymentLinkConfigRequest> | ||||
|             sdk_layout: item.sdk_layout, | ||||
|             display_sdk_only: item.display_sdk_only, | ||||
|             enabled_saved_payment_method: item.enabled_saved_payment_method, | ||||
|             transaction_details: None, | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Sakil Mostak
					Sakil Mostak