Journal

iDEAL QR Scanner Payment UI for iOS: How to Build It

The scan routes the user to their own bank to authorize. Here is the iOS scanner UI: capture, confirmation, handoff, honest states.

iDEAL QR Scanner Payment UI for iOS: How to Build It: a reflective 3D App Store icon on a blue and purple gradient

TL;DR

An iDEAL QR scanner UI captures a payment request and routes the user into their own bank to authorize it, so the app never processes money or touches credentials. Build it as three surfaces: a fast scanner on VisionKit or AVFoundation, a non-skippable confirmation showing the parsed payee and amount, and a result screen that reflects the provider-verified outcome rather than assuming success. Treat the scanned code as untrusted input, design the pending and abandoned states deliberately, and verify outcomes server-side. A free VP0 payment-flow design gives an agent like Claude Code or Cursor the screens to extend from its source page while you wire the capture and the bank handoff.

What an iDEAL QR payment scan actually does

Scanning an iDEAL QR does not pay anyone; it carries the user to the place where they authorize the payment, their own bank. iDEAL is the Dutch bank-to-bank payment method, and an iDEAL QR encodes a payment request, the payee, the amount, the reference, which resolves into an authorization flow inside the user’s own banking environment. The scale is hard to overstate for a Dutch audience: iDEAL handled about 70% of Dutch online payments in 2023, so for users in the Netherlands this is not an alternative payment method, it is the default.

That defines the scanner UI’s real job. It is a trust handoff: capture the code quickly, show the user exactly what they are about to approve and to whom, and route them into the bank flow without ever looking like it wants their credentials. The app that renders the scan never processes the money, and a design that is honest about that, routing rather than collecting, is both safer and easier to get right. The checkout-side cousin of this flow, choosing your bank before authorizing, is covered in the iDEAL bank selector UI.

How does the scanner itself work on iOS?

Two Apple routes cover the capture. The modern one is DataScannerViewController from VisionKit, which gives you live QR recognition with system-quality guidance overlays for very little code on iOS 16 and later. The lower-level route is an AVFoundation capture session with a metadata output, which costs more code but gives full control over the session, the torch, and the recognition cadence, the same machinery behind any serious QR ticket scanner.

Whichever route captures the code, the scanning screen has a small, well-known grammar: a camera view with a clear aim region, a torch toggle for dark cafes and market stalls, a manual-entry fallback for damaged codes, and instant feedback the moment recognition lands, a haptic plus a freeze of the detected frame. Speed matters more than decoration here. A payment scan happens standing up, often with someone waiting, so the screen should recognize in well under a second and never make the user wonder whether anything happened.

The manual-entry fallback earns a second mention because it is also the accessibility path. A camera-only flow excludes users who cannot aim a viewfinder, so the same screen that rescues a damaged code, typing or pasting the payment reference, makes the feature usable with VoiceOver and Switch Control, and the detection feedback should be announced, not just flashed.

The three surfaces of a scan-to-pay flow

The scanner is one of three screens, and the middle one carries the trust.

SurfaceIts one jobWhat it must show
ScannerCapture the code fastAim region, torch, instant detection feedback
ConfirmationShow what is about to be approvedPayee name, amount, reference, the bank that will open
ResultReflect the bank’s answer honestlyPaid, pending, failed, or abandoned, never assumed

The confirmation screen between scan and bank is the difference between a tool and a trap. A scanned code is untrusted content from the physical world, and sticker fraud, a scam QR pasted over a real one, is the classic attack, so the user must see the payee and amount in plain text before anything opens. Format that amount the way a Dutch user expects, euro sign and comma decimals, because money rendered in a foreign format reads as wrong exactly where trust matters most. For the screens themselves, a free VP0 payment-flow design is the strongest starting point: real scanner, confirmation, and result layouts with a machine-readable source page that an agent like Claude Code or Cursor reads from a pasted link and extends, while you wire the capture session and the handoff. The same display-side discipline, rendering a payment QR large and scannable, is covered in the PromptPay QR generator.

How do you hand off to the bank, and get the answer back?

The handoff opens the payment request in the user’s banking environment, their bank’s app when installed, and the return path tells you what happened. Practically that is URL-driven: the decoded request resolves to a flow the bank app picks up, your app moves to the background, the user authorizes with their own bank’s authentication, and control returns to your app through its return URL with a result to verify. The deep-link mechanics, including the cold reality that the return can arrive after your app was killed, are the same ones in the UPI deep linking guide.

Two rules keep the round trip honest. Verify the outcome server-side with your payment provider rather than trusting the return URL alone, because a URL is an envelope and not a receipt; merchants integrate iDEAL through a licensed payment service provider, and that provider’s status is the truth your result screen reflects. And design the limbo state deliberately: the user who switched to their bank and never came back should find the payment marked pending with a refresh path, not a screen pretending nothing started.

What does the user see while the bank decides?

A waiting state that names what is happening: “waiting for your bank,” with the payee and amount still visible, a quiet spinner, and a way out. Bank authorizations usually return in seconds, but the design has to survive the slow cases, a bank app that needs an update, a user who got distracted, a network dip, without escalating anxiety about money in flight.

Resist the optimistic shortcut here the way you would in any payment flow. Marking the payment as done because the bank app opened is the classic generated-code mistake, and it is worse than slow truth, because a false “paid” on a payment screen destroys exactly the confidence the whole flow exists to build. Paid means your provider confirmed it; everything before that is pending, stated calmly. A short delay with the truth reads as solid; instant fiction reads as broken the first time it is wrong.

Common mistakes when vibe coding the scanner flow

The recurring one is scanning as the whole feature: the agent builds a beautiful camera screen that toasts “payment complete” on detection, skipping the confirmation screen, the bank handoff, and the verified result entirely. Pin the prompt to the three-surface structure, scan, confirm, result, and to the rule that detection is the beginning of a payment, not the end.

Three more show up reliably. The decoded payload gets trusted blindly, when it is physical-world input that deserves parsing, validation, and a visible payee before anything opens. The capture session stays hot on every screen, draining battery, when it should start on appear and stop the moment a code is found. And the failure grammar gets collapsed into one generic error, when a declined authorization, an abandoned bank flow, and an unreadable code are three different stories the user needs told differently. None of these are exotic; they are exactly where a generated happy path ends and a payment product begins.

Key takeaways: an iDEAL QR scanner UI

  • Scanning routes, it never pays. The user authorizes in their own bank; the app captures, confirms, and reflects.
  • Three surfaces, one spine. Scanner, confirmation, result, with the confirmation carrying the trust.
  • Treat the code as untrusted. Parse, validate, and show payee and amount before any handoff.
  • Paid means provider-confirmed. The return URL is an envelope; the status is server truth.
  • Start from a free VP0 payment-flow design. The screens arrive shaped; you wire capture and handoff.

The practical build

Build the three surfaces around the handoff, in that order of care: confirmation first, because it carries the trust; result second, because honest states are what make money feel safe; scanner last, because VisionKit has already solved most of it. Start the screens from a free VP0 payment-flow design, extended by your agent from the source page, and spend your attention on the parsing, the provider verification, and the limbo states no template can know. If your product is the merchant side, showing a code rather than reading one, the work inverts toward rendering and polling, and if your users are outside the Netherlands, this same structure serves whichever local rail they trust instead; the scan-confirm-authorize-verify spine is the durable part.

Frequently asked questions

How do I build an iDEAL QR scanner payment UI for iOS? Structure it as three surfaces: a scanner using VisionKit’s DataScannerViewController or an AVFoundation capture session, a confirmation screen showing the parsed payee, amount, and reference, and a result screen that reflects the provider-verified outcome. The scan hands off to the user’s own bank for authorization and your app receives the return, so the UI’s job is capture, clarity, and honest states. A free VP0 payment-flow design gives an agent those screens to extend while you wire the capture and the handoff.

Does the app process the iDEAL payment itself? No. iDEAL is a bank-to-bank method, the user authorizes inside their own banking environment, and merchants integrate it through a licensed payment service provider. Your app captures the request, shows what is about to be approved, routes to the bank, and reflects the verified result. That split is a feature: the app never touches credentials or funds, which keeps both the security surface and the review story small. Any design that asks for banking credentials inside your own screens is wrong by construction.

Which scanning API should I use, VisionKit or AVFoundation? Reach for VisionKit’s DataScannerViewController first: live QR recognition, system-quality guidance, and very little code on iOS 16 and later. Drop to an AVFoundation capture session when you need what it does not give you, full control of the session, custom recognition cadence, or support for older iOS versions. Either way the capture is the easy third of the feature; the confirmation screen and the verified result are where the real product lives.

How do I prevent users being scammed by fake payment QR codes? Make the confirmation screen non-skippable and explicit. A scanned code is untrusted physical-world content, and the classic attack is a fraudulent sticker pasted over a legitimate code, so parse the payload, validate its shape, and show the payee name and amount in plain text before anything opens. Users who see “you are paying Bakkerij Jansen €4.50” catch substitution in a way no silent fast path allows. Refuse to auto-open anything straight from detection.

What should the screen show while the bank confirms the payment? A calm pending state that keeps the payee and amount visible, names the step (“waiting for your bank”), and offers a refresh and a way back. Mark the payment paid only when your payment provider confirms it server-side, never because the bank app opened or the return URL arrived. And design for the user who never comes back from the bank app: on next launch the payment shows as pending with its true status one tap away, not silently forgotten.

Other questions from VP0 builders

How do I build an iDEAL QR scanner payment UI for iOS?

Structure it as three surfaces: a scanner using VisionKit's DataScannerViewController or an AVFoundation capture session, a confirmation screen showing the parsed payee, amount, and reference, and a result screen that reflects the provider-verified outcome. The scan hands off to the user's own bank for authorization and your app receives the return, so the UI's job is capture, clarity, and honest states. A free VP0 payment-flow design gives an agent those screens to extend while you wire the capture and the handoff.

Does the app process the iDEAL payment itself?

No. iDEAL is a bank-to-bank method, the user authorizes inside their own banking environment, and merchants integrate it through a licensed payment service provider. Your app captures the request, shows what is about to be approved, routes to the bank, and reflects the verified result. That split is a feature: the app never touches credentials or funds, which keeps both the security surface and the review story small. Any design that asks for banking credentials inside your own screens is wrong by construction.

Which scanning API should I use, VisionKit or AVFoundation?

Reach for VisionKit's DataScannerViewController first: live QR recognition, system-quality guidance, and very little code on iOS 16 and later. Drop to an AVFoundation capture session when you need what it does not give you, full control of the session, custom recognition cadence, or support for older iOS versions. Either way the capture is the easy third of the feature; the confirmation screen and the verified result are where the real product lives.

How do I prevent users being scammed by fake payment QR codes?

Make the confirmation screen non-skippable and explicit. A scanned code is untrusted physical-world content, and the classic attack is a fraudulent sticker pasted over a legitimate code, so parse the payload, validate its shape, and show the payee name and amount in plain text before anything opens. Users who see "you are paying Bakkerij Jansen €4.50" catch substitution in a way no silent fast path allows. Refuse to auto-open anything straight from detection.

What should the screen show while the bank confirms the payment?

A calm pending state that keeps the payee and amount visible, names the step ("waiting for your bank"), and offers a refresh and a way back. Mark the payment paid only when your payment provider confirms it server-side, never because the bank app opened or the return URL arrived. And design for the user who never comes back from the bank app: on next launch the payment shows as pending with its true status one tap away, not silently forgotten.

Part of the Payments, Monetization & Regional Fintech hub. Browse all VP0 topics →

Keep reading

iDEAL Bank Selector UI for iOS: The Right Pattern: a vivid neon 3D App Store icon on an orange, pink and blue gradient
Guides 5 min read

iDEAL Bank Selector UI for iOS: The Right Pattern

The iDEAL bank selector is a redirect picker, not a card form. Here is how to build it on iOS, where the bank list comes from, and the iDEAL 2.0 change to watch.

Lawrence Arya · June 4, 2026
UPI and Paytm Deep Linking in SwiftUI: The Safe Pattern: a glass photo icon surrounded by chat, music, heart, camera and shopping app icons on a pastel gradient
Guides 5 min read

UPI and Paytm Deep Linking in SwiftUI: The Safe Pattern

How UPI and Paytm deep linking works in a SwiftUI app: upi:// links, canOpenURL setup, PSP status verification, and the four screens the flow needs.

Lawrence Arya · June 4, 2026
Freemium vs Free Trial: Paywall Design Compared: a glass app tile showing the VP0 logo on a pink and blue gradient
Guides 4 min read

Freemium vs Free Trial: Paywall Design Compared

Freemium and free trials lead to different paywalls and different users. A clear comparison of the two models and how to build either from a free VP0 design.

Lawrence Arya · May 31, 2026
Municipal Parking Ticket Scanner Payment App UI: a reflective 3D App Store icon on a blue and purple gradient
Guides 4 min read

Municipal Parking Ticket Scanner Payment App UI

Build a parking ticket pay-by-scan app in SwiftUI: scan the citation, see the details, and pay, from a free VP0 design. Certified payments, honest fees.

Lawrence Arya · May 31, 2026
Stripe Connect Onboarding Flow UI Template: the App Store logo as a frosted glass icon on a pink and blue gradient with bubbles
Guides 4 min read

Stripe Connect Onboarding Flow UI Template

Build a marketplace seller onboarding flow with Stripe Connect: account setup, verification status, and payouts, from a free VP0 design. Stripe owns KYC.

Lawrence Arya · May 31, 2026
Subscription Manager Dashboard UI for iOS: the App Store logo as a glossy glass icon on a purple and blue gradient with floating bubbles
Guides 4 min read

Subscription Manager Dashboard UI for iOS

Build a subscription manager dashboard in SwiftUI: all your recurring costs, renewal dates, and totals, from a free VP0 design. Read-only and honest.

Lawrence Arya · May 31, 2026