feat(payout_link): add localisation support for payout link's templates (#5552)

Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
Kashif
2024-08-12 13:12:54 +05:30
committed by GitHub
parent f9c29b084b
commit b0346e08f4
40 changed files with 1077 additions and 84 deletions

View File

@ -142,6 +142,7 @@ where
let link_type = (boxed_generic_link_data).data.to_string();
match services::generic_link_response::build_generic_link_html(
boxed_generic_link_data.data,
boxed_generic_link_data.locale,
) {
Ok(rendered_html) => api::http_response_html_data(rendered_html, None),
Err(_) => {

View File

@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Payout Links</title>
<title>{{ i18n_payout_link_title }}</title>
</head>
{{ css_style_tag }}
<body>

View File

@ -14,7 +14,7 @@ try {
// Remove the script from DOM incase it's not iframed
if (!isFramed) {
function initializePayoutSDK() {
var errMsg = "You are not allowed to view this content.";
var errMsg = "{{i18n_not_allowed}}";
var contentElement = document.getElementById("payout-link");
if (contentElement instanceof HTMLDivElement) {
contentElement.innerHTML = errMsg;
@ -34,25 +34,25 @@ if (!isFramed) {
**/
function formatDate(date) {
var months = [
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December",
"{{i18n_january}}",
"{{i18n_february}}",
"{{i18n_march}}",
"{{i18n_april}}",
"{{i18n_may}}",
"{{i18n_june}}",
"{{i18n_july}}",
"{{i18n_august}}",
"{{i18n_september}}",
"{{i18n_october}}",
"{{i18n_november}}",
"{{i18n_december}}",
];
var hours = date.getHours();
var minutes = date.getMinutes();
// @ts-ignore
minutes = minutes < 10 ? "0" + minutes : minutes;
var suffix = hours > 11 ? "PM" : "AM";
var suffix = hours > 11 ? "{{i18n_pm}}" : "{{i18n_am}}";
hours = hours % 12;
hours = hours ? hours : 12;
var day = date.getDate();
@ -127,6 +127,7 @@ if (!isFramed) {
// @ts-ignore
var payoutDetails = window.__PAYOUT_DETAILS;
var clientSecret = payoutDetails.client_secret;
var locale = payoutDetails.locale;
var publishableKey = payoutDetails.publishable_key;
var appearance = {
variables: {
@ -143,6 +144,7 @@ if (!isFramed) {
widgets = hyper.widgets({
appearance: appearance,
clientSecret: clientSecret,
locale: locale,
});
// Create payment method collect widget

View File

@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Payout Status</title>
<title>{{ i18n_payout_link_status_title }}</title>
{{ css_style_tag }}
</head>
<body>

View File

@ -69,8 +69,8 @@ function renderStatusDetails(payoutDetails) {
var statusInfo = {
statusImageSrc:
"https://live.hyperswitch.io/payment-link-assets/success.png",
statusText: "Payout Successful",
statusMessage: "Your payout was made to selected payment method.",
statusText: "{{i18n_success_text}}",
statusMessage: "{{i18n_success_message}}",
};
switch (status) {
case "success":
@ -80,9 +80,8 @@ function renderStatusDetails(payoutDetails) {
case "pending":
statusInfo.statusImageSrc =
"https://live.hyperswitch.io/payment-link-assets/pending.png";
statusInfo.statusText = "Payout Processing";
statusInfo.statusMessage =
"Your payout should be processed within 2-3 business days.";
statusInfo.statusText = "{{i18n_pending_text}}";
statusInfo.statusMessage = "{{i18n_pending_message}}";
break;
case "failed":
case "cancelled":
@ -96,9 +95,8 @@ function renderStatusDetails(payoutDetails) {
default:
statusInfo.statusImageSrc =
"https://live.hyperswitch.io/payment-link-assets/failed.png";
statusInfo.statusText = "Payout Failed";
statusInfo.statusMessage =
"Failed to process your payout. Please check with your provider for more details.";
statusInfo.statusText = "{{i18n_failed_text}}";
statusInfo.statusMessage = "{{i18n_failed_message}}";
break;
}
@ -120,13 +118,13 @@ function renderStatusDetails(payoutDetails) {
}
var resourceInfo = {
"Ref Id": payoutDetails.payout_id,
"{{i18n_ref_id_text}}": payoutDetails.payout_id,
};
if (typeof payoutDetails.error_code === "string") {
resourceInfo["Error Code"] = payoutDetails.error_code;
resourceInfo["{{i18n_error_code_text}}"] = payoutDetails.error_code;
}
if (typeof payoutDetails.error_message === "string") {
resourceInfo["Error Message"] = payoutDetails.error_message;
resourceInfo["{{i18n_error_message}}"] = payoutDetails.error_message;
}
var resourceNode = document.createElement("div");
resourceNode.id = "resource-info-container";
@ -166,8 +164,10 @@ function redirectToEndUrl(returnUrl) {
var secondsLeft = timeout - j++;
var innerText =
secondsLeft === 0
? "Redirecting ..."
: "Redirecting in " + secondsLeft + " seconds ...";
? "{{i18n_redirecting_text}}"
: "{{i18n_redirecting_in_text}} " +
secondsLeft +
" {{i18n_seconds_text}} ...";
if (statusRedirectTextNode instanceof HTMLDivElement) {
statusRedirectTextNode.innerText = innerText;
}

View File

@ -7,8 +7,9 @@ use api_models::{
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_TRANSACTION_DETAILS,
DEFAULT_ENABLE_SAVED_PAYMENT_METHOD, DEFAULT_LOCALE, DEFAULT_MERCHANT_LOGO,
DEFAULT_PRODUCT_IMG, DEFAULT_SDK_LAYOUT, DEFAULT_SESSION_EXPIRY,
DEFAULT_TRANSACTION_DETAILS,
},
ext_traits::{OptionExt, ValueExt},
types::{AmountConvertor, MinorUnit, StringMajorUnitForCore},
@ -342,6 +343,7 @@ pub async fn initiate_secure_payment_link_flow(
let link_data = GenericLinks {
allowed_domains,
data: GenericLinksData::SecurePaymentLink(payment_link_data),
locale: DEFAULT_LOCALE.to_string(),
};
logger::info!(
"payment link data, for building secure payment link {:?}",

View File

@ -12,7 +12,7 @@ pub use api_models::enums::Connector;
use api_models::payment_methods;
#[cfg(feature = "payouts")]
pub use api_models::{enums::PayoutConnectors, payouts as payout_types};
use common_utils::{ext_traits::Encode, id_type::CustomerId};
use common_utils::{consts::DEFAULT_LOCALE, ext_traits::Encode, id_type::CustomerId};
use diesel_models::{
enums, GenericLinkNew, PaymentMethodCollectLink, PaymentMethodCollectLinkData,
};
@ -251,6 +251,7 @@ pub async fn render_pm_collect_link(
GenericLinks {
allowed_domains: HashSet::from([]),
data: GenericLinksData::ExpiredLink(expired_link_data),
locale: DEFAULT_LOCALE.to_string(),
},
)))
@ -312,8 +313,8 @@ pub async fn render_pm_collect_link(
Ok(services::ApplicationResponse::GenericLinkForm(Box::new(
GenericLinks {
allowed_domains: HashSet::from([]),
data: GenericLinksData::PaymentMethodCollect(generic_form_data),
locale: DEFAULT_LOCALE.to_string(),
},
)))
}
@ -357,8 +358,8 @@ pub async fn render_pm_collect_link(
Ok(services::ApplicationResponse::GenericLinkForm(Box::new(
GenericLinks {
allowed_domains: HashSet::from([]),
data: GenericLinksData::PaymentMethodCollectStatus(generic_status_data),
locale: DEFAULT_LOCALE.to_string(),
},
)))
}

View File

@ -30,6 +30,7 @@ pub async fn initiate_payout_link(
key_store: domain::MerchantKeyStore,
req: payouts::PayoutLinkInitiateRequest,
request_headers: &header::HeaderMap,
locale: String,
) -> RouterResponse<services::GenericLinkFormData> {
let db: &dyn StorageInterface = &*state.store;
let merchant_id = merchant_account.get_id();
@ -108,6 +109,7 @@ pub async fn initiate_payout_link(
GenericLinks {
allowed_domains: (link_data.allowed_domains),
data: GenericLinksData::ExpiredLink(expired_link_data),
locale,
},
)))
}
@ -187,6 +189,7 @@ pub async fn initiate_payout_link(
enabled_payment_methods,
amount,
currency: payout.destination_currency,
locale: locale.clone(),
};
let serialized_css_content = String::new();
@ -209,6 +212,7 @@ pub async fn initiate_payout_link(
GenericLinks {
allowed_domains: (link_data.allowed_domains),
data: GenericLinksData::PayoutLink(generic_form_data),
locale,
},
)))
}
@ -251,6 +255,7 @@ pub async fn initiate_payout_link(
GenericLinks {
allowed_domains: (link_data.allowed_domains),
data: GenericLinksData::PayoutLinkStatus(generic_status_data),
locale,
},
)))
}

View File

@ -300,6 +300,7 @@ pub async fn payouts_create_core(
merchant_account: domain::MerchantAccount,
key_store: domain::MerchantKeyStore,
req: payouts::PayoutCreateRequest,
locale: &String,
) -> RouterResponse<payouts::PayoutCreateResponse> {
// Validate create request
let (payout_id, payout_method_data, profile_id, customer) =
@ -314,6 +315,7 @@ pub async fn payouts_create_core(
&payout_id,
&profile_id,
payout_method_data.as_ref(),
locale,
customer.as_ref(),
)
.await?;
@ -2206,6 +2208,7 @@ pub async fn payout_create_db_entries(
payout_id: &String,
profile_id: &String,
stored_payout_method_data: Option<&payouts::PayoutMethodData>,
locale: &String,
customer: Option<&domain::Customer>,
) -> RouterResult<PayoutData> {
let db = &*state.store;
@ -2227,6 +2230,7 @@ pub async fn payout_create_db_entries(
merchant_id,
req,
payout_id,
locale,
)
.await?,
),
@ -2552,6 +2556,7 @@ pub async fn create_payout_link(
merchant_id: &common_utils::id_type::MerchantId,
req: &payouts::PayoutCreateRequest,
payout_id: &String,
locale: &String,
) -> RouterResult<PayoutLink> {
let payout_link_config_req = req.payout_link_config.to_owned();
@ -2595,8 +2600,9 @@ pub async fn create_payout_link(
.as_ref()
.map_or(default_config.expiry, |expiry| *expiry);
let url = format!(
"{base_url}/payout_link/{}/{payout_id}",
merchant_id.get_string_repr()
"{base_url}/payout_link/{}/{payout_id}?locale={}",
merchant_id.get_string_repr(),
locale
);
let link = url::Url::parse(&url)
.change_context(errors::ApiErrorResponse::InternalServerError)

View File

@ -11,6 +11,7 @@ pub mod core;
pub mod cors;
pub mod db;
pub mod env;
pub mod locale;
pub(crate) mod macros;
pub mod routes;
@ -44,6 +45,9 @@ use crate::{configs::settings, core::errors};
#[global_allocator]
static ALLOC: mimalloc::MiMalloc = mimalloc::MiMalloc;
// Import translate fn in root
use crate::locale::{_rust_i18n_t, _rust_i18n_try_translate};
/// Header Constants
pub mod headers {
pub const ACCEPT: &str = "Accept";

View File

@ -0,0 +1,3 @@
use rust_i18n::i18n;
i18n!("locales", fallback = "en");

View File

@ -28,6 +28,7 @@ pub mod metrics;
pub mod payment_link;
pub mod payment_methods;
pub mod payments;
#[cfg(feature = "payouts")]
pub mod payout_link;
#[cfg(feature = "payouts")]
pub mod payouts;

View File

@ -1,17 +1,17 @@
#[cfg(feature = "payouts")]
use actix_web::{web, Responder};
#[cfg(feature = "payouts")]
use api_models::payouts::PayoutLinkInitiateRequest;
#[cfg(feature = "payouts")]
use common_utils::consts::DEFAULT_LOCALE;
use router_env::Flow;
#[cfg(feature = "payouts")]
use crate::{
core::{api_locking, payout_link::*},
services::{api, authentication as auth},
headers::ACCEPT_LANGUAGE,
services::{
api,
authentication::{self as auth, get_header_value_by_key},
},
AppState,
};
#[cfg(feature = "payouts")]
pub async fn render_payout_link(
state: web::Data<AppState>,
req: actix_web::HttpRequest,
@ -24,13 +24,25 @@ pub async fn render_payout_link(
payout_id,
};
let headers = req.headers();
let locale = get_header_value_by_key(ACCEPT_LANGUAGE.into(), headers)
.ok()
.flatten()
.map(|val| val.to_string())
.unwrap_or(DEFAULT_LOCALE.to_string());
Box::pin(api::server_wrap(
flow,
state,
&req,
payload.clone(),
|state, auth, req, _| {
initiate_payout_link(state, auth.merchant_account, auth.key_store, req, headers)
initiate_payout_link(
state,
auth.merchant_account,
auth.key_store,
req,
headers,
locale.clone(),
)
},
&auth::MerchantIdAuth(merchant_id),
api_locking::LockAction::NotApplicable,

View File

@ -2,6 +2,7 @@ use actix_web::{
body::{BoxBody, MessageBody},
web, HttpRequest, HttpResponse, Responder,
};
use common_utils::consts;
use router_env::{instrument, tracing, Flow};
use super::app::AppState;
@ -9,7 +10,12 @@ use super::app::AppState;
use crate::types::api::payments as payment_types;
use crate::{
core::{api_locking, payouts::*},
services::{api, authentication as auth, authorization::permissions::Permission},
headers::ACCEPT_LANGUAGE,
services::{
api,
authentication::{self as auth, get_header_value_by_key},
authorization::permissions::Permission,
},
types::api::payouts as payout_types,
};
@ -21,13 +27,18 @@ pub async fn payouts_create(
json_payload: web::Json<payout_types::PayoutCreateRequest>,
) -> HttpResponse {
let flow = Flow::PayoutsCreate;
let locale = get_header_value_by_key(ACCEPT_LANGUAGE.into(), req.headers())
.ok()
.flatten()
.map(|val| val.to_string())
.unwrap_or(consts::DEFAULT_LOCALE.to_string());
Box::pin(api::server_wrap(
flow,
state,
&req,
json_payload.into_inner(),
|state, auth, req, _| {
payouts_create_core(state, auth.merchant_account, auth.key_store, req)
payouts_create_core(state, auth.merchant_account, auth.key_store, req, &locale)
},
&auth::HeaderAuth(auth::ApiKeyAuth),
api_locking::LockAction::NotApplicable,

View File

@ -982,7 +982,10 @@ where
Ok(ApplicationResponse::GenericLinkForm(boxed_generic_link_data)) => {
let link_type = boxed_generic_link_data.data.to_string();
match build_generic_link_html(boxed_generic_link_data.data) {
match build_generic_link_html(
boxed_generic_link_data.data,
boxed_generic_link_data.locale,
) {
Ok(rendered_html) => {
let headers = if !boxed_generic_link_data.allowed_domains.is_empty() {
let domains_str = boxed_generic_link_data

View File

@ -7,9 +7,11 @@ use tera::{Context, Tera};
use super::build_secure_payment_link_html;
use crate::core::errors;
pub mod context;
pub fn build_generic_link_html(
boxed_generic_link_data: GenericLinksData,
locale: String,
) -> CustomResult<String, errors::ApiErrorResponse> {
match boxed_generic_link_data {
GenericLinksData::ExpiredLink(link_data) => build_generic_expired_link_html(&link_data),
@ -20,10 +22,12 @@ pub fn build_generic_link_html(
GenericLinksData::PaymentMethodCollectStatus(pm_collect_data) => {
build_pm_collect_link_status_html(&pm_collect_data)
}
GenericLinksData::PayoutLink(payout_link_data) => build_payout_link_html(&payout_link_data),
GenericLinksData::PayoutLink(payout_link_data) => {
build_payout_link_html(&payout_link_data, locale.as_str())
}
GenericLinksData::PayoutLinkStatus(pm_collect_data) => {
build_payout_link_status_html(&pm_collect_data)
build_payout_link_status_html(&pm_collect_data, locale.as_str())
}
GenericLinksData::SecurePaymentLink(payment_link_data) => {
build_secure_payment_link_html(payment_link_data)
@ -52,7 +56,6 @@ pub fn build_generic_expired_link_html(
fn build_html_template(
link_data: &GenericLinkFormData,
document: &'static str,
script: &'static str,
styles: &'static str,
) -> CustomResult<(Tera, Context), errors::ApiErrorResponse> {
let mut tera: Tera = Tera::default();
@ -65,42 +68,43 @@ fn build_html_template(
let _ = tera.add_raw_template("document_styles", &final_css);
context.insert("color_scheme", &link_data.css_data);
// Insert dynamic context in JS
let js_dynamic_context = "{{ script_data }}";
let js_template = script.to_string();
let final_js = format!("{}\n{}", js_dynamic_context, js_template);
let _ = tera.add_raw_template("document_scripts", &final_js);
context.insert("script_data", &link_data.js_data);
let css_style_tag = tera
.render("document_styles", &context)
.map(|css| format!("<style>{}</style>", css))
.change_context(errors::ApiErrorResponse::InternalServerError)
.attach_printable("Failed to render CSS template")?;
let js_script_tag = tera
.render("document_scripts", &context)
.map(|js| format!("<script>{}</script>", js))
.change_context(errors::ApiErrorResponse::InternalServerError)
.attach_printable("Failed to render JS template")?;
// Insert HTML context
let html_template = document.to_string();
let _ = tera.add_raw_template("html_template", &html_template);
context.insert("css_style_tag", &css_style_tag);
context.insert("js_script_tag", &js_script_tag);
Ok((tera, context))
}
pub fn build_payout_link_html(
link_data: &GenericLinkFormData,
locale: &str,
) -> CustomResult<String, errors::ApiErrorResponse> {
let document = include_str!("../../core/generic_link/payout_link/initiate/index.html");
let script = include_str!("../../core/generic_link/payout_link/initiate/script.js");
let styles = include_str!("../../core/generic_link/payout_link/initiate/styles.css");
let (tera, mut context) = build_html_template(link_data, document, script, styles)
let (mut tera, mut context) = build_html_template(link_data, document, styles)
.attach_printable("Failed to build context for payout link's HTML template")?;
// Insert dynamic context in JS
let script = include_str!("../../core/generic_link/payout_link/initiate/script.js");
let js_template = script.to_string();
let js_dynamic_context = "{{ script_data }}";
let final_js = format!("{}\n{}", js_dynamic_context, js_template);
let _ = tera.add_raw_template("document_scripts", &final_js);
context.insert("script_data", &link_data.js_data);
context::insert_locales_in_context_for_payout_link(&mut context, locale);
let js_script_tag = tera
.render("document_scripts", &context)
.map(|js| format!("<script>{}</script>", js))
.change_context(errors::ApiErrorResponse::InternalServerError)
.attach_printable("Failed to render JS template")?;
context.insert("js_script_tag", &js_script_tag);
context.insert(
"hyper_sdk_loader_script_tag",
&format!(
@ -109,6 +113,7 @@ pub fn build_payout_link_html(
),
);
// Render HTML template
tera.render("html_template", &context)
.change_context(errors::ApiErrorResponse::InternalServerError)
.attach_printable("Failed to render payout link's HTML template")
@ -119,12 +124,25 @@ pub fn build_pm_collect_link_html(
) -> CustomResult<String, errors::ApiErrorResponse> {
let document =
include_str!("../../core/generic_link/payment_method_collect/initiate/index.html");
let script = include_str!("../../core/generic_link/payment_method_collect/initiate/script.js");
let styles = include_str!("../../core/generic_link/payment_method_collect/initiate/styles.css");
let (tera, mut context) = build_html_template(link_data, document, script, styles)
let (mut tera, mut context) = build_html_template(link_data, document, styles)
.attach_printable(
"Failed to build context for payment method collect link's HTML template",
)?;
// Insert dynamic context in JS
let script = include_str!("../../core/generic_link/payment_method_collect/initiate/script.js");
let js_template = script.to_string();
let js_dynamic_context = "{{ script_data }}";
let final_js = format!("{}\n{}", js_dynamic_context, js_template);
let _ = tera.add_raw_template("document_scripts", &final_js);
context.insert("script_data", &link_data.js_data);
let js_script_tag = tera
.render("document_scripts", &context)
.map(|js| format!("<script>{}</script>", js))
.change_context(errors::ApiErrorResponse::InternalServerError)
.attach_printable("Failed to render JS template")?;
context.insert("js_script_tag", &js_script_tag);
context.insert(
"hyper_sdk_loader_script_tag",
&format!(
@ -133,6 +151,7 @@ pub fn build_pm_collect_link_html(
),
);
// Render HTML template
tera.render("html_template", &context)
.change_context(errors::ApiErrorResponse::InternalServerError)
.attach_printable("Failed to render payment method collect link's HTML template")
@ -140,6 +159,7 @@ pub fn build_pm_collect_link_html(
pub fn build_payout_link_status_html(
link_data: &GenericLinkStatusData,
locale: &str,
) -> CustomResult<String, errors::ApiErrorResponse> {
let mut tera = Tera::default();
let mut context = Context::new();
@ -159,13 +179,13 @@ pub fn build_payout_link_status_html(
.attach_printable("Failed to render payout link status CSS template")?;
// Insert dynamic context in JS
let js_dynamic_context = "{{ collect_link_status_context }}";
let js_dynamic_context = "{{ script_data }}";
let js_template =
include_str!("../../core/generic_link/payout_link/status/script.js").to_string();
let final_js = format!("{}\n{}", js_dynamic_context, js_template);
let _ = tera.add_raw_template("payout_link_status_script", &final_js);
context.insert("collect_link_status_context", &link_data.js_data);
context.insert("script_data", &link_data.js_data);
context::insert_locales_in_context_for_payout_link_status(&mut context, locale);
let js_script_tag = tera
.render("payout_link_status_script", &context)
.map(|js| format!("<script>{}</script>", js))

View File

@ -0,0 +1,80 @@
use rust_i18n::t;
use tera::Context;
pub fn insert_locales_in_context_for_payout_link(context: &mut Context, locale: &str) {
let i18n_payout_link_title = t!("payout_link.initiate.title", locale = locale);
let i18n_january = t!("months.january", locale = locale);
let i18n_february = t!("months.february", locale = locale);
let i18n_march = t!("months.march", locale = locale);
let i18n_april = t!("months.april", locale = locale);
let i18n_may = t!("months.may", locale = locale);
let i18n_june = t!("months.june", locale = locale);
let i18n_july = t!("months.july", locale = locale);
let i18n_august = t!("months.august", locale = locale);
let i18n_september = t!("months.september", locale = locale);
let i18n_october = t!("months.october", locale = locale);
let i18n_november = t!("months.november", locale = locale);
let i18n_december = t!("months.december", locale = locale);
let i18n_not_allowed = t!("payout_link.initiate.not_allowed", locale = locale);
let i18n_am = t!("time.am", locale = locale);
let i18n_pm = t!("time.pm", locale = locale);
context.insert("i18n_payout_link_title", &i18n_payout_link_title);
context.insert("i18n_january", &i18n_january);
context.insert("i18n_february", &i18n_february);
context.insert("i18n_march", &i18n_march);
context.insert("i18n_april", &i18n_april);
context.insert("i18n_may", &i18n_may);
context.insert("i18n_june", &i18n_june);
context.insert("i18n_july", &i18n_july);
context.insert("i18n_august", &i18n_august);
context.insert("i18n_september", &i18n_september);
context.insert("i18n_october", &i18n_october);
context.insert("i18n_november", &i18n_november);
context.insert("i18n_december", &i18n_december);
context.insert("i18n_not_allowed", &i18n_not_allowed);
context.insert("i18n_am", &i18n_am);
context.insert("i18n_pm", &i18n_pm);
}
pub fn insert_locales_in_context_for_payout_link_status(context: &mut Context, locale: &str) {
let i18n_payout_link_status_title = t!("payout_link.status.title", locale = locale);
let i18n_success_text = t!("payout_link.status.text.success", locale = locale);
let i18n_success_message = t!("payout_link.status.message.success", locale = locale);
let i18n_pending_text = t!("payout_link.status.text.pending", locale = locale);
let i18n_pending_message = t!("payout_link.status.message.pending", locale = locale);
let i18n_failed_text = t!("payout_link.status.text.failed", locale = locale);
let i18n_failed_message = t!("payout_link.status.message.failed", locale = locale);
let i18n_ref_id_text = t!("payout_link.status.info.ref_id", locale = locale);
let i18n_error_code_text = t!("payout_link.status.info.error_code", locale = locale);
let i18n_error_message = t!("payout_link.status.info.error_message", locale = locale);
let i18n_redirecting_text = t!(
"payout_link.status.redirection_text.redirecting",
locale = locale
);
let i18n_redirecting_in_text = t!(
"payout_link.status.redirection_text.redirecting_in",
locale = locale
);
let i18n_seconds_text = t!(
"payout_link.status.redirection_text.seconds",
locale = locale
);
context.insert(
"i18n_payout_link_status_title",
&i18n_payout_link_status_title,
);
context.insert("i18n_success_text", &i18n_success_text);
context.insert("i18n_success_message", &i18n_success_message);
context.insert("i18n_pending_text", &i18n_pending_text);
context.insert("i18n_pending_message", &i18n_pending_message);
context.insert("i18n_failed_text", &i18n_failed_text);
context.insert("i18n_failed_message", &i18n_failed_message);
context.insert("i18n_ref_id_text", &i18n_ref_id_text);
context.insert("i18n_error_code_text", &i18n_error_code_text);
context.insert("i18n_error_message", &i18n_error_message);
context.insert("i18n_redirecting_text", &i18n_redirecting_text);
context.insert("i18n_redirecting_in_text", &i18n_redirecting_in_text);
context.insert("i18n_seconds_text", &i18n_seconds_text);
}