NEXT_PUBLIC_STRIPE_KEY is copied into the JavaScript sent to browsers at build time, so anyone can read it. STRIPE_SECRET_KEY is only available on the serverAt build time, Next.js replaces every process.env.NEXT_PUBLIC_... in client code with its value. The value is then plain text in the bundle. Without the prefix, a variable stays on the server. Client code that reads it just gets undefined. So only put keys meant to be public, like Stripe's publishable key, behind NEXT_PUBLIC_.
"Both stay secret, because .env is never sent" is the tempting wrong answer. The file isn't sent, but NEXT_PUBLIC_ values are copied into the JavaScript. "Fetched at runtime" is wrong. They are fixed at build time, so changing one needs a rebuild.