// Pure, React-free helpers for the identity-proofing return flow (Phase 2, full-proxy hard-gate). // Kept dependency-free so it unit-tests without dragging the services/hooks barrel - mirrors // utils/paymentFlow.ts for the payment-checkout return flow, and lives here (rather than inside // services/ProofingService.tsx or hooks/useProofingReturn.tsx) specifically so BOTH of those can // import it without creating a services<->hooks circular import. const RETURN_MARKER_PARAM = 'proofing_return'; // Build the return URL handed to POST /proofing/session as `returnUrl`. Mirrors paymentFlow.ts // buildCheckoutUrls (origin + pathname + hash - the app is a HashRouter SPA, so the fragment must be // preserved for the browser to land back on the right in-app route after Stripe) with the // `proofing_return=1` marker appended so useProofingReturn can detect the return. If the current hash // already carries its own query (`#/profile?foo=bar`) the marker is appended with `&` instead of `?`. export const buildProofingReturnUrl = (origin: string, pathname: string, hash: string): string => { const separator = hash.includes('?') ? '&' : '?'; return `${origin}${pathname}${hash}${separator}${RETURN_MARKER_PARAM}=1`; }; // Detect the marker on return from Stripe Identity. export const hasProofingReturnMarker = (href: string): boolean => { return new RegExp(`[?&]${RETURN_MARKER_PARAM}=1(?:&|#|$)`).test(href ?? ''); }; // Strip the marker (and tidy any dangling separators it leaves behind) so a manual refresh mid-poll // doesn't restart the whole thing. export const stripProofingReturnMarker = (href: string): string => { let out = href ?? ''; out = out.replace(new RegExp(`([?&])${RETURN_MARKER_PARAM}=[^&#]*`, 'g'), '$1'); out = out.replace(/([?&])&+/g, '$1'); // collapse "?&""?" and "&&""&" out = out.replace(/[?&]$/g, ''); // drop a now-empty trailing "?" or "&" return out; };