Compare commits

...
Author SHA1 Message Date
posthog-eu[bot] 57e6c0e8c0 fix(checkout): skip Stripe.js embedded load on non-HTTPS origins
PaymentStage loaded Stripe.js unconditionally on mount via loadStripe(),
with no secure-context guard. Official builds ship a live publishable key
(pk_live_…), which makes Stripe.js throw "Live Stripe.js integrations must
use HTTPS" on plain-HTTP origins — hitting self-hosted instances served
over HTTP (LAN / .local / tailscale hosts) whenever they reach the payment
stage of the upgrade modal.

Gate the embedded load on canUseEmbeddedCheckout() — the same secure-context
guard the rest of the checkout already relies on. On non-HTTPS origins the
backend issues a hosted-checkout redirect via useCheckoutSession, so
embedded checkout is never used there; skipping loadStripe lets that
redirect take over cleanly instead of racing it and throwing.

Generated-By: PostHog Code
Task-Id: 6bfcdc15-77f4-48ed-aa74-ad6bdc36a82a
2026-07-22 04:32:46 +00:00
@@ -7,6 +7,7 @@ import {
EmbeddedCheckout,
} from "@stripe/react-stripe-js";
import { PlanTier } from "@app/services/licenseService";
import { canUseEmbeddedCheckout } from "@app/utils/protocolDetection";
const STRIPE_KEY = import.meta.env.VITE_STRIPE_PUBLISHABLE_KEY;
@@ -26,8 +27,16 @@ export const PaymentStage: React.FC<PaymentStageProps> = ({
// scope pulled the Stripe script into every page (CheckoutContext is in
// AppProviders), which triggered the dev "HTTPS required" warning on every
// non-payment route.
//
// Only load Stripe.js in a secure context. A live publishable key
// (pk_live_…) makes Stripe.js throw "Live Stripe.js integrations must use
// HTTPS" on plain-HTTP origins (common for self-hosted LAN deployments).
// On non-HTTPS origins the backend issues a hosted-checkout redirect via
// useCheckoutSession, so embedded checkout is never used here — skipping
// loadStripe lets that redirect take over cleanly.
const stripePromise = useMemo(
() => (STRIPE_KEY ? loadStripe(STRIPE_KEY) : null),
() =>
STRIPE_KEY && canUseEmbeddedCheckout() ? loadStripe(STRIPE_KEY) : null,
[],
);