diff --git a/api-reference-v2/openapi_spec.json b/api-reference-v2/openapi_spec.json index 6f84c486b5..790bb0d3a6 100644 --- a/api-reference-v2/openapi_spec.json +++ b/api-reference-v2/openapi_spec.json @@ -14908,6 +14908,11 @@ } ], "nullable": true + }, + "is_setup_mandate_flow": { + "type": "boolean", + "description": "Boolean to control payment button text for setup mandate calls", + "nullable": true } } }, @@ -15071,6 +15076,11 @@ } ], "nullable": true + }, + "is_setup_mandate_flow": { + "type": "boolean", + "description": "Boolean to control payment button text for setup mandate calls", + "nullable": true } } }, diff --git a/api-reference/openapi_spec.json b/api-reference/openapi_spec.json index 8c70afc104..19a05ed630 100644 --- a/api-reference/openapi_spec.json +++ b/api-reference/openapi_spec.json @@ -17340,6 +17340,11 @@ } ], "nullable": true + }, + "is_setup_mandate_flow": { + "type": "boolean", + "description": "Boolean to control payment button text for setup mandate calls", + "nullable": true } } }, @@ -17503,6 +17508,11 @@ } ], "nullable": true + }, + "is_setup_mandate_flow": { + "type": "boolean", + "description": "Boolean to control payment button text for setup mandate calls", + "nullable": true } } }, diff --git a/crates/api_models/src/admin.rs b/crates/api_models/src/admin.rs index ae66147b10..ec016039b8 100644 --- a/crates/api_models/src/admin.rs +++ b/crates/api_models/src/admin.rs @@ -2903,6 +2903,8 @@ pub struct PaymentLinkConfigRequest { /// 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, + /// Boolean to control payment button text for setup mandate calls + pub is_setup_mandate_flow: Option, } #[derive(Clone, Debug, serde::Deserialize, serde::Serialize, PartialEq, ToSchema)] @@ -2998,6 +3000,8 @@ pub struct PaymentLinkConfig { /// 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, + /// Boolean to control payment button text for setup mandate calls + pub is_setup_mandate_flow: 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 b83aa00490..8e87f893cf 100644 --- a/crates/api_models/src/payments.rs +++ b/crates/api_models/src/payments.rs @@ -8081,6 +8081,9 @@ pub struct PaymentLinkDetails { pub payment_form_header_text: Option, pub payment_form_label_type: Option, pub show_card_terms: Option, + pub is_setup_mandate_flow: Option, + pub capture_method: Option, + pub setup_future_usage_applied: Option, } #[derive(Debug, serde::Serialize, Clone)] @@ -8123,6 +8126,8 @@ pub struct PaymentLinkStatusDetails { pub transaction_details: Option>, pub unified_code: Option, pub unified_message: Option, + pub capture_method: Option, + pub setup_future_usage_applied: Option, } #[derive(Clone, Debug, serde::Deserialize, ToSchema, serde::Serialize)] diff --git a/crates/diesel_models/src/business_profile.rs b/crates/diesel_models/src/business_profile.rs index bb6bb0f1a5..6a0854e180 100644 --- a/crates/diesel_models/src/business_profile.rs +++ b/crates/diesel_models/src/business_profile.rs @@ -721,6 +721,7 @@ pub struct PaymentLinkConfigRequest { pub payment_form_header_text: Option, pub payment_form_label_type: Option, pub show_card_terms: Option, + pub is_setup_mandate_flow: 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 840c8e085b..5b23147356 100644 --- a/crates/diesel_models/src/payment_intent.rs +++ b/crates/diesel_models/src/payment_intent.rs @@ -205,6 +205,8 @@ pub struct PaymentLinkConfigRequestForPayments { 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, + /// Boolean to control payment button text for setup mandate calls + pub is_setup_mandate_flow: 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 a231a4b42f..4872eac408 100644 --- a/crates/hyperswitch_domain_models/src/lib.rs +++ b/crates/hyperswitch_domain_models/src/lib.rs @@ -427,6 +427,7 @@ impl ApiModelToDieselModelConvertor 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, + is_setup_mandate_flow: item.is_setup_mandate_flow, } } fn convert_back(self) -> api_models::admin::PaymentLinkConfigRequest { @@ -454,6 +455,7 @@ impl ApiModelToDieselModelConvertor payment_form_header_text, payment_form_label_type, show_card_terms, + is_setup_mandate_flow, } = self; api_models::admin::PaymentLinkConfigRequest { theme, @@ -485,6 +487,7 @@ impl ApiModelToDieselModelConvertor payment_form_header_text, payment_form_label_type, show_card_terms, + is_setup_mandate_flow, } } } diff --git a/crates/router/src/core/payment_link.rs b/crates/router/src/core/payment_link.rs index c2945335b5..b34ecb1dd1 100644 --- a/crates/router/src/core/payment_link.rs +++ b/crates/router/src/core/payment_link.rs @@ -142,6 +142,7 @@ pub async fn form_payment_link_data( payment_form_header_text: None, payment_form_label_type: None, show_card_terms: None, + is_setup_mandate_flow: None, } }; @@ -207,6 +208,17 @@ pub async fn form_payment_link_data( storage_enums::IntentStatus::RequiresCustomerAction, ], ); + + let attempt_id = payment_intent.active_attempt.get_id().clone(); + let payment_attempt = db + .find_payment_attempt_by_payment_id_merchant_id_attempt_id( + &payment_intent.payment_id, + &merchant_id, + &attempt_id.clone(), + merchant_account.storage_scheme, + ) + .await + .to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?; if is_payment_link_terminal_state || payment_link_status == api_models::payments::PaymentLinkStatus::Expired { @@ -230,16 +242,6 @@ pub async fn form_payment_link_data( } }; - let attempt_id = payment_intent.active_attempt.get_id().clone(); - let payment_attempt = db - .find_payment_attempt_by_payment_id_merchant_id_attempt_id( - &payment_intent.payment_id, - &merchant_id, - &attempt_id.clone(), - merchant_account.storage_scheme, - ) - .await - .to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?; let payment_details = api_models::payments::PaymentLinkStatusDetails { amount, currency, @@ -257,6 +259,8 @@ pub async fn form_payment_link_data( transaction_details: payment_link_config.transaction_details.clone(), unified_code: payment_attempt.unified_code, unified_message: payment_attempt.unified_message, + capture_method: payment_attempt.capture_method, + setup_future_usage_applied: payment_attempt.setup_future_usage_applied, }; return Ok(( @@ -302,6 +306,9 @@ pub async fn form_payment_link_data( 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, + capture_method: payment_attempt.capture_method, + setup_future_usage_applied: payment_attempt.setup_future_usage_applied, }; Ok(( @@ -686,6 +693,7 @@ pub fn get_payment_link_config_based_on_priority( payment_form_header_text, payment_form_label_type, show_card_terms, + is_setup_mandate_flow, ) = get_payment_link_config_value!( payment_create_link_config, business_theme_configs, @@ -703,6 +711,7 @@ pub fn get_payment_link_config_based_on_priority( (payment_form_header_text), (payment_form_label_type), (show_card_terms), + (is_setup_mandate_flow), ); let payment_link_config = @@ -734,6 +743,7 @@ pub fn get_payment_link_config_based_on_priority( payment_form_header_text, payment_form_label_type, show_card_terms, + is_setup_mandate_flow, }; Ok((payment_link_config, domain_name)) @@ -848,6 +858,7 @@ pub async fn get_payment_link_status( payment_form_header_text: None, payment_form_label_type: None, show_card_terms: None, + is_setup_mandate_flow: None, } }; @@ -930,6 +941,8 @@ pub async fn get_payment_link_status( transaction_details: payment_link_config.transaction_details, unified_code: Some(unified_code), unified_message: unified_translated_message, + capture_method: payment_attempt.capture_method, + setup_future_usage_applied: payment_attempt.setup_future_usage_applied, }; let js_script = get_js_script(&PaymentLinkData::PaymentLinkStatusDetails(Box::new( payment_details, diff --git a/crates/router/src/core/payment_link/locale.js b/crates/router/src/core/payment_link/locale.js index 114376bf9f..f70d9cefbd 100644 --- a/crates/router/src/core/payment_link/locale.js +++ b/crates/router/src/core/payment_link/locale.js @@ -25,6 +25,8 @@ const locales = { refId: "Ref Id: ", requestedBy: "Requested by ", payNow: "Pay now", + addPaymentMethod: "Add Payment Method", + authorizePayment: "Authorize Payment", yourCart: "Your Cart", quantity: "Quantity", showLess: "Show Less", @@ -56,6 +58,8 @@ const locales = { refId: "מזהה הפניה: ", requestedBy: "ביקש על ידי ", payNow: "שלם עכשיו", + addPaymentMethod: "הוסף אמצעי תשלום", + authorizePayment: "אשר תשלום", yourCart: "העגלה שלך", quantity: "כמות", showLess: "הצג פחות", @@ -87,6 +91,8 @@ const locales = { refId: "ID de référence: ", requestedBy: "Demandé par ", payNow: "Payer maintenant", + addPaymentMethod: "Ajouter un mode de paiement", + authorizePayment: "Autoriser le paiement", yourCart: "Votre panier", quantity: "Quantité", showLess: "Afficher moins", @@ -118,6 +124,8 @@ const locales = { refId: "Ref Id: ", requestedBy: "Requested by ", payNow: "Pay now", + addPaymentMethod: "Add Payment Method", + authorizePayment: "Authorise Payment", yourCart: "Your Basket", quantity: "Quantity", showLess: "Show Less", @@ -150,6 +158,8 @@ const locales = { refId: "معرف المرجع: ", requestedBy: "طلب بواسطة ", payNow: "ادفع الآن", + addPaymentMethod: "إضافة طريقة دفع", + authorizePayment: "تفويض الدفع", yourCart: "سلة التسوق الخاصة بك", quantity: "الكمية", showLess: "عرض أقل", @@ -181,6 +191,8 @@ const locales = { refId: "参照 ID: ", requestedBy: "リクエスト者 ", payNow: "今すぐ支払う", + addPaymentMethod: "支払い方法を追加", + authorizePayment: "支払いを承認する", yourCart: "あなたのカート", quantity: "数量", showLess: "表示を減らす", @@ -212,6 +224,8 @@ const locales = { refId: "Referenz-ID: ", requestedBy: "Angefordert von ", payNow: "Jetzt bezahlen", + addPaymentMethod: "Zahlungsmethode hinzufügen", + authorizePayment: "Zahlung autorisieren", yourCart: "Ihr Warenkorb", quantity: "Menge", showLess: "Weniger anzeigen", @@ -243,6 +257,8 @@ const locales = { refId: "ID de référence: ", requestedBy: "Demandé par ", payNow: "Payer maintenant", + addPaymentMethod: "Ajouter un mode de paiement", + authorizePayment: "Autoriser le paiement", yourCart: "Votre panier", quantity: "Quantité", showLess: "Afficher moins", @@ -275,6 +291,8 @@ const locales = { refId: "ID de referencia: ", requestedBy: "Solicitado por ", payNow: "Pagar ahora", + addPaymentMethod: "Agregar método de pago", + authorizePayment: "Autorizar pago", yourCart: "Tu carrito", quantity: "Cantidad", showLess: "Mostrar menos", @@ -306,6 +324,8 @@ const locales = { refId: "ID de referència: ", requestedBy: "Sol·licitat per ", payNow: "Paga ara", + addPaymentMethod: "Afegir mètode de pagament", + authorizePayment: "Autoritza el pagament", yourCart: "El teu carret", quantity: "Quantitat", showLess: "Mostrar menys", @@ -337,6 +357,8 @@ const locales = { refId: "ID de referência: ", requestedBy: "Solicitado por ", payNow: "Pagar agora", + addPaymentMethod: "Adicionar método de pagamento", + authorizePayment: "Autorizar pagamento", yourCart: "Seu Carrinho", quantity: "Quantidade", showLess: "Mostrar menos", @@ -369,6 +391,8 @@ const locales = { refId: "ID di riferimento: ", requestedBy: "Richiesto da ", payNow: "Paga ora", + addPaymentMethod: "Aggiungi metodo di pagamento", + authorizePayment: "Autorizza il pagamento", yourCart: "Il tuo carrello", quantity: "Quantità", showLess: "Mostra meno", @@ -400,6 +424,8 @@ const locales = { refId: "Identyfikator referencyjny: ", requestedBy: "Zażądane przez ", payNow: "Zapłać teraz", + addPaymentMethod: "Dodaj metodę płatności", + authorizePayment: "Autoryzuj płatność", yourCart: "Twój koszyk", quantity: "Ilość", showLess: "Pokaż mniej", @@ -431,6 +457,8 @@ const locales = { refId: "Ref Id: ", requestedBy: "Aangevraagd door ", payNow: "Nu betalen", + addPaymentMethod: "Betaalmethode toevoegen", + authorizePayment: "Betaling autoriseren", yourCart: "Je winkelwagen", quantity: "Hoeveelheid", showLess: "Toon minder", @@ -462,6 +490,8 @@ const locales = { refId: "Referens-ID: ", requestedBy: "Begärd av ", payNow: "Betala nu", + addPaymentMethod: "Lägg till betalningsmetod", + authorizePayment: "Auktorisera betalning", yourCart: "Din varukorg", quantity: "Antal", showLess: "Visa mindre", @@ -493,6 +523,8 @@ const locales = { refId: "ID ссылки: ", requestedBy: "Запрошено ", payNow: "Оплатить сейчас", + addPaymentMethod: "Добавить способ оплаты", + authorizePayment: "Авторизовать платеж", yourCart: "Ваша корзина", quantity: "Количество", showLess: "Показать меньше", @@ -524,6 +556,8 @@ const locales = { refId: "参考编号: ", requestedBy: "请求者: ", payNow: "立即付款", + addPaymentMethod: "添加支付方式", + authorizePayment: "授权付款", yourCart: "您的购物车", quantity: "数量", showLess: "显示较少", @@ -555,6 +589,8 @@ const locales = { refId: "參考編號:", requestedBy: "請求者 ", payNow: "立即付款", + addPaymentMethod: "新增付款方式", + authorizePayment: "授權付款", yourCart: "你的購物車", quantity: "數量", showLess: "顯示較少", 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 5c6f3a6b37..bdfdfa8a8b 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 @@ -345,8 +345,16 @@ function initializeEventListeners(paymentDetails) { // Get locale for pay now var payNowButtonText = document.createElement("div"); var payNowButtonText = document.getElementById('submit-button-text'); + var capture_type = paymentDetails.capture_method; if (payNowButtonText) { - payNowButtonText.textContent = paymentDetails.payment_button_text || translations.payNow; + 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")) { + payNowButtonText.textContent = translations.addPaymentMethod; + } else { + payNowButtonText.textContent = capture_type === "manual" ? translations.authorizePayment: translations.payNow; + + } } if (submitButtonNode instanceof HTMLButtonElement) { diff --git a/crates/router/src/core/payments/transformers.rs b/crates/router/src/core/payments/transformers.rs index 6ae4cf4ec7..fc7a9becaf 100644 --- a/crates/router/src/core/payments/transformers.rs +++ b/crates/router/src/core/payments/transformers.rs @@ -4767,6 +4767,7 @@ impl ForeignFrom 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, + is_setup_mandate_flow: config.is_setup_mandate_flow, } } } @@ -4841,6 +4842,7 @@ impl ForeignFrom 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, + is_setup_mandate_flow: config.is_setup_mandate_flow, } } } diff --git a/crates/router/src/types/transformers.rs b/crates/router/src/types/transformers.rs index 187f0c864d..760c30359d 100644 --- a/crates/router/src/types/transformers.rs +++ b/crates/router/src/types/transformers.rs @@ -2191,6 +2191,7 @@ impl ForeignFrom 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, + is_setup_mandate_flow: item.is_setup_mandate_flow, } } } @@ -2225,6 +2226,7 @@ impl ForeignFrom 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, + is_setup_mandate_flow: item.is_setup_mandate_flow, } } }