end of tickets

This commit is contained in:
Thomas Demirdjian
2025-11-17 15:54:54 +01:00
parent c7cbd85088
commit 016f7c27ac
8 changed files with 159 additions and 71 deletions
+100 -40
View File
@@ -30,6 +30,49 @@ const stripePromise = loadStripe(
isStripeTesting ? STRIPE_PUBLISHABLE_KEY_TEST : STRIPE_PUBLISHABLE_KEY_LIVE,
);
const isSafariBrowser = () => {
if (
typeof navigator !== "object" ||
typeof navigator.userAgent !== "string"
) {
return false;
}
return (
/safari/i.test(navigator.userAgent) &&
!/(chrome|crios|android|fxios|edgios|opr|ucbrowser)/i.test(
navigator.userAgent,
)
);
};
const openSafariCheckoutWindow = () => {
if (!isWeb || typeof window === "undefined") {
return null;
}
if (!isSafariBrowser()) {
return null;
}
try {
const placeholder = window.open("", "_blank", "noopener,noreferrer");
if (!placeholder) {
return null;
}
try {
placeholder.document.write(
"<p style='font-family: sans-serif; color: #111; padding: 16px;'>Chargement du paiement Stripe...</p>",
);
placeholder.document.title = "Stripe Checkout";
} catch {
// Ignore failures when the window gets reused or is cross-domain.
}
placeholder.focus?.();
return placeholder;
} catch (error) {
console.warn("[StripeProvider] Safari window pre-open failed", error);
return null;
}
};
export const StripeContext = React.createContext(null);
export const useStripe = () => {
@@ -68,56 +111,70 @@ const StripeProvider = ({ children }) => {
setClientSecret(null);
}, []);
const redirectToCheckout = React.useCallback(async (checkoutUrl) => {
if (!checkoutUrl) {
throw new Error("Session Stripe introuvable.");
}
const redirectToCheckout = React.useCallback(
async (checkoutUrl, { safariWindow } = {}) => {
if (!checkoutUrl) {
throw new Error("Session Stripe introuvable.");
}
if (isWeb) {
if (typeof window !== "undefined") {
const openedTab = window.open(
checkoutUrl,
"_blank",
"noopener,noreferrer",
);
// Fallback to same-tab navigation if the popup is blocked.
if (!openedTab) {
window.location.assign(checkoutUrl);
if (isWeb) {
if (safariWindow && !safariWindow.closed) {
try {
safariWindow.location.replace(checkoutUrl);
} catch (navigationError) {
safariWindow.location.href = checkoutUrl;
}
safariWindow.focus?.();
return;
}
if (typeof window !== "undefined") {
const openedTab = window.open(
checkoutUrl,
"_blank",
"noopener,noreferrer",
);
if (openedTab) {
return;
}
}
await Linking.openURL(checkoutUrl);
return;
}
throw new Error("Navigation Stripe impossible dans cet environnement.");
}
const isMobileApp =
Platform.OS === "ios" || Platform.OS === "android";
const isMobileApp =
Platform.OS === "ios" || Platform.OS === "android";
if (isMobileApp) {
try {
await WebBrowser.openBrowserAsync(checkoutUrl, {
enableDefaultShareMenu: false,
dismissButtonStyle: "close",
presentationStyle:
WebBrowser?.WebBrowserPresentationStyle?.PAGE_SHEET,
});
return;
} catch (webBrowserError) {
console.warn(
"[StripeProvider] WebBrowser checkout fallback",
webBrowserError,
);
if (isMobileApp) {
try {
await WebBrowser.openBrowserAsync(checkoutUrl, {
enableDefaultShareMenu: false,
dismissButtonStyle: "close",
presentationStyle:
WebBrowser?.WebBrowserPresentationStyle?.PAGE_SHEET,
});
return;
} catch (webBrowserError) {
console.warn(
"[StripeProvider] WebBrowser checkout fallback",
webBrowserError,
);
}
}
}
const canOpen = await Linking.canOpenURL(checkoutUrl);
if (!canOpen) {
throw new Error("Impossible d'ouvrir l'URL de paiement.");
}
await Linking.openURL(checkoutUrl);
}, []);
const canOpen = await Linking.canOpenURL(checkoutUrl);
if (!canOpen) {
throw new Error("Impossible d'ouvrir l'URL de paiement.");
}
await Linking.openURL(checkoutUrl);
},
[],
);
const runCheckoutSession = React.useCallback(
async ({ callableName, payload, logTag }) => {
const safariWindow = openSafariCheckoutWindow();
try {
const callable = getFunctionsClient(FUNCTIONS_REGION).httpsCallable(
callableName,
@@ -127,8 +184,11 @@ const StripeProvider = ({ children }) => {
if (!checkoutUrl) {
throw new Error("Session Stripe introuvable.");
}
await redirectToCheckout(checkoutUrl);
await redirectToCheckout(checkoutUrl, { safariWindow });
} catch (error) {
if (safariWindow && !safariWindow.closed) {
safariWindow.close();
}
console.error(`[StripeProvider] ${logTag}`, error);
throw new Error(
error?.message ||