Merge branch 'develop' into 'main'

Develop

See merge request witapp/aura-webapp!839
This commit is contained in:
Daniil Chemerkin 2025-12-24 19:13:10 +00:00
commit 62a5002fa6
2 changed files with 111 additions and 3 deletions

View File

@ -19,6 +19,8 @@ import { useNavigate } from "react-router-dom";
import { EUnleashFlags, useUnleash } from "@/hooks/ab/unleash/useUnleash";
import { IFunnelPaymentVariant } from "@/api/resources/Session";
import { useFunnel } from "@/hooks/funnel/useFunnel";
import { getSourceByPathname } from "@/utils/source.utils";
import { getStateParamForRedirect } from "@/services/url";
const environments = import.meta.env;
@ -197,11 +199,26 @@ function PaymentPage({
","
);
let redirectUrl = `${paymentUrl}?paywallId=${paywallId}&placementId=${placementId}&productId=${
// Build base params
const baseParams = `paywallId=${paywallId}&placementId=${placementId}&productId=${
activeProduct?.id
}&jwtToken=${token}&price=${(
(activeProduct?.trialPrice || 100) / 100
).toFixed(2)}&currency=${currency}&${getTrackingCookiesForRedirect()}`;
).toFixed(2)}&currency=${currency}`;
// Add sessionId
const source = getSourceByPathname();
const currentSessionId = localStorage.getItem(`${source}_sessionId`);
const sessionParam = currentSessionId ? `&sessionId=${currentSessionId}` : "";
// Add state param with current UTM (base64 encoded JSON)
const stateParam = getStateParamForRedirect();
const stateStr = stateParam ? `&state=${stateParam}` : "";
// Add tracking cookies
const trackingCookies = getTrackingCookiesForRedirect();
let redirectUrl = `${paymentUrl}?${baseParams}${sessionParam}${stateStr}&${trackingCookies}`;
if (fbPixels.length) {
redirectUrl += `&fb_pixels=${fbPixels}`;

View File

@ -13,4 +13,95 @@ export const parseQueryParams = () => {
}
return result;
}
}
// Params that should NOT be included in state (they are passed separately)
const EXCLUDED_STATE_PARAMS = [
"paywallId",
"placementId",
"productId",
"jwtToken",
"price",
"currency",
"fb_pixels",
"sessionId",
"state",
// Tracking cookies (passed separately)
"_fbc",
"_fbp",
"_ym_uid",
"_ym_d",
"_ym_isad",
"_ym_visorc",
"yandexuid",
"ymex",
];
/**
* Get current query params that should be passed between screens and to payment
* Includes ALL params except internal ones (productId, placementId, etc.)
* Works with utm_*, fbclid, gclid, and any other marketing params
*/
export const getCurrentQueryParams = (): Record<string, string> => {
if (typeof window === "undefined") return {};
const params = parseQueryParams();
const utmParams: Record<string, string> = {};
for (const [key, value] of Object.entries(params)) {
const isExcluded =
EXCLUDED_STATE_PARAMS.includes(key) ||
key.startsWith("_ga") ||
key.startsWith("_gid");
if (!isExcluded && value) {
utmParams[key] = value;
}
}
return utmParams;
};
/**
* Convert bytes to base64 string (handles UTF-8 properly)
* MDN recommended approach: https://developer.mozilla.org/en-US/docs/Web/API/Window/btoa#unicode_strings
*/
const bytesToBase64 = (bytes: Uint8Array): string => {
const binString = Array.from(bytes, (byte) =>
String.fromCodePoint(byte)
).join("");
return btoa(binString);
};
/**
* Encode params as base64 JSON for state parameter
* Uses URL-safe base64 encoding with UTF-8 support
* Handles Unicode characters (e.g., utm_campaign=)
*/
export const encodeStateParam = (params: Record<string, string>): string => {
if (Object.keys(params).length === 0) return "";
try {
const json = JSON.stringify(params);
// Encode string as UTF-8 bytes, then convert to base64
const bytes = new TextEncoder().encode(json);
const base64 = bytesToBase64(bytes)
.replace(/\+/g, "-")
.replace(/\//g, "_")
.replace(/=+$/, "");
return base64;
} catch {
return "";
}
};
/**
* Get base64-encoded state parameter with current query params
*/
export const getStateParamForRedirect = (): string => {
const params = getCurrentQueryParams();
return encodeStateParam(params);
};
// Backward compatibility alias
export const getCurrentUtmParams = getCurrentQueryParams;