OAuth/OIDC login — federated, auto-discovered, zero config.
Your app delegates authentication to idp.payez.net. The MVP wires up NextAuth.js with automatic provider discovery. You never write login logic.
The MVP's NextAuth.js config calls your IDP tenant's discovery endpoint on startup. It auto-discovers which OAuth providers (Google, GitHub, Microsoft, custom SAML) are enabled for your tenant.
When a user clicks "Sign in with Google," they're redirected to the IDP, which handles the OAuth flow with the upstream provider. The IDP issues a JWT with the user's identity, roles, and tenant claims.
The JWT comes back to your app via NextAuth.js callback. Session is created in Redis, user record is upserted in vibe_app.users, and the user lands in your app — authenticated, with roles attached.
Subsequent requests carry the session token. Middleware validates it on every route. If the session expires or is revoked (e.g. from the admin panel), the user is redirected to login.
The IDP is the single source of truth for identity. Your app never stores passwords. It never handles OAuth token exchange. It never manages provider-specific quirks (Google vs. GitHub vs. SAML). The IDP normalizes all of that into a standard JWT with consistent claims. This means you can add a new OAuth provider (say, Microsoft) by toggling it in the IDP admin panel. Your app picks it up automatically on the next login screen render — no code change, no redeployment.
Every JWT issued by the IDP includes: user ID (sub), email, display name, roles array, tenant/client ID, and standard OIDC claims (iss, aud, exp, iat). Custom claims can be added per-tenant. The roles array drives the entire RBAC system downstream — middleware reads it, the admin dashboard renders based on it, and your custom code can check it via helpers like hasSystemAdminRole().
// JWT payload from idp.payez.net
{
"sub": "42",
"email": "jane@acme.com",
"name": "Jane Chen",
"roles": [
"vibe_app_admin",
"custom_schemas_admin"
],
"client_id": "8",
"iss": "https://idp.payez.net",
"aud": "your-client-id",
"exp": 1735689600,
"iat": 1735686000
}The IDP exposes a provider discovery endpoint. When NextAuth.js initializes, it fetches the list of enabled providers for your tenant and dynamically registers them. No hardcoded provider config in your app. This is how the login screen shows "Sign in with Google" and "Sign in with GitHub" without you writing provider-specific code. Enable a provider in the IDP admin → it appears on your login screen.
// This is all the auth config you write
// in app/api/auth/[...nextauth]/route.ts
import { createAuthHandler } from '@payez/next-mvp';
// Auto-discovers providers from your IDP tenant
// Handles callbacks, session creation, user upsert
const handler = createAuthHandler();
export { handler as GET, handler as POST };Sessions are created on successful auth and stored in Redis with configurable TTL. The session includes the user's ID, roles, email, and tenant context. Redis-backed sessions mean: instant revocation from the admin panel, concurrent session tracking (see all devices), and distributed session sharing across multiple app instances. The user's session works the same whether they hit server A or server B.
- No login/signup form handling (the IDP handles the UI or you use the pre-built screens) - No password hashing, salt management, or credential storage - No OAuth callback handling or token exchange - No provider-specific configuration (Google client ID, GitHub app secrets — those live in the IDP) - No session token generation or validation - No "forgot password" flow (the IDP handles it) - No email verification flow (the IDP handles it) - No account linking (Google + email for same user — the IDP handles it)
// middleware.ts — one import, one line
import { createSlimMiddleware } from '@payez/next-mvp';
export default createSlimMiddleware({
publicRoutes: ['/', '/about', '/pricing'],
// Everything else requires authentication
});
export const config = {
matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
};Authentication ships with every @payez/next-mvp install. 10K MAU free. No credit card required.