Fix checkout loop by preventing logout during Stripe navigation
Critical fix: Don't clear cart or logout when navigating to Stripe checkout. The issue was: 1. User clicks 'Continue to payment' 2. API call to /api/checkout succeeds 3. Client redirects to Stripe URL with window.location.href 4. This triggers beforeunload event 5. LogoutOnUnload component logs out and clears cart 6. User is logged out and cart is empty during checkout Solution: - Detect when /api/checkout is being called - Set isCheckingOut flag - Skip logout/cart-clear in beforeunload if checkout in progress - User stays logged in and cart persists through Stripe flow This allows logout on browser close but not during payment navigation. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Haiku 4.5
parent
15e1f92490
commit
c9f5626984
@@ -1,17 +1,40 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { useEffect } from 'react';
|
import { useEffect, useRef } from 'react';
|
||||||
import { useCart } from '@/lib/cartStore';
|
import { useCart } from '@/lib/cartStore';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs out the user when they close/leave the page
|
* Logs out the user when they close/leave the page
|
||||||
* Works for both admin and customer sessions
|
* Works for both admin and customer sessions
|
||||||
|
* Skips logout when navigating to external checkout (Stripe, etc)
|
||||||
*/
|
*/
|
||||||
export default function LogoutOnUnload() {
|
export default function LogoutOnUnload() {
|
||||||
const clearCart = useCart((s) => s.clear);
|
const clearCart = useCart((s) => s.clear);
|
||||||
|
const isCheckingOut = useRef(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// Mark when checkout is being initiated
|
||||||
|
const origFetch = window.fetch;
|
||||||
|
window.fetch = function(...args) {
|
||||||
|
const url = typeof args[0] === 'string' ? args[0] : (args[0] as Request).url;
|
||||||
|
if (url?.includes('/api/checkout')) {
|
||||||
|
isCheckingOut.current = true;
|
||||||
|
}
|
||||||
|
return origFetch.apply(this, args);
|
||||||
|
};
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
window.fetch = origFetch;
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handleUnload = () => {
|
const handleUnload = () => {
|
||||||
|
// Don't logout if we're in the middle of checkout (navigating to Stripe)
|
||||||
|
if (isCheckingOut.current) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Clear cart on logout
|
// Clear cart on logout
|
||||||
clearCart();
|
clearCart();
|
||||||
// Use sendBeacon to reliably send logout even when page is closing
|
// Use sendBeacon to reliably send logout even when page is closing
|
||||||
|
|||||||
Reference in New Issue
Block a user