How do you build BankID login in Next.js and React?
BankID login in a web app is built against BankID's relying-party API from your server, never from the browser. The server starts an order, shows the user an animated QR code that changes every second (or opens the BankID app directly on the same device), polls BankID for the status, and creates its own session only when the order is complete. The certificate that identifies you to BankID stays on the server, and the personal identity number you get back is personal data to protect. We run BankID login in Autofixter, alongside Stripe, Klarna and Swish in one checkout.
How the flow works
Start the order on the server
Your API route calls BankID's auth endpoint with the end user's IP address and gets an order reference plus the values needed for the QR code and the app link.
Show an animated QR code or open the app
The server generates a fresh QR code every second from those values, and the page fetches and shows it. On the same device, the page opens the BankID app with the autostart token instead.
Poll for the status
The server calls BankID's collect for the order about every two seconds and maps each hintCode to BankID's recommended user messages, such as asking the user to start the app. If the QR code isn't scanned in time, the order fails and the user needs a new one.
Create your own session
When collect returns complete, the server checks that the order belongs to the browser session that started it (keep the orderRef server-side and never accept one from the page), then creates its own session and stores only the identity data it needs.
Cancel abandoned orders
If the user cancels or leaves the page while the order is pending, call cancel, so the next attempt starts cleanly.
Common mistakes
Calling BankID from the browser
The relying-party certificate must never leave the server. Every call to BankID goes through your backend.
A static QR code
BankID requires an animated QR code; static QR codes are no longer supported. Each new code is generated on the server from the order's secret and the seconds since the order started, so a copied code, for example in a screenshot, quickly stops working. Keep the secret on the server and send the page only the finished code.
Treating login as permission
BankID tells you who the person is, not what they may access. That is your access model's job, enforced in the backend and, ideally, in the database.
Personal identity numbers in logs
The personal identity number is personal data, and under the Swedish Data Protection Act (chapter 3, section 10) it may be processed without consent only when clearly justified by the purpose, the importance of secure identification or another considerable reason. Write down why you need it, keep it out of logs, analytics and URLs, key accounts on your own internal ID, and store the number only where you need it.
Calling BankID from the Edge runtime
BankID identifies your service by its client certificate over mutual TLS, which the Edge runtime can't present. Keep the calls in Route Handlers or Server Actions on the Node.js runtime (the default), and take endUserIp from your proxy's forwarded header, not the server's own address.
Identity and payments in one checkout
Autofixter has BankID login and Stripe, Klarna and Swish in one checkout. If you are building the same combination, a sound general pattern is to identify the user first, keep the purchase as one order on the server, and put each payment provider behind the same server-side interface, so adding or swapping one doesn't touch the login.
Questions
- What do we need to use BankID in production?
- An agreement with a bank that offers BankID to companies, which gives you a production certificate, or an identity service provider that handles the integration for you. Development and testing use BankID's test environment, a test certificate and a test BankID.
- Should we integrate directly or use an identity provider?
- An identity provider is faster to start with and handles the certificate and API for you, for a fee. A direct integration gives you full control, but you own the certificate and its security.
- Can an AI agent or chatbot use BankID?
- BankID can verify who the person is before an agent acts for them, for example before it shows order history. The agent should then get only the permissions the verified user has, checked in your backend.
- Does BankID work on both mobile and desktop?
- Yes. On a computer the user scans the animated QR code with the BankID app on their phone; on a phone the page opens the BankID app directly.
Want this set up in your codebase?
Start with a free 30-minute intro call. We'll look at your repos and tell you honestly where to begin.
Book intro call