Philip Sloth
All work
Payments / Checkout·2025·Full-Stack Developer

PayFlow

Full-control checkout — every method, page, and redirect built from scratch instead of a hosted PSP page

Demo · reference build
PayFlow — Full-control checkout — every method, page, and redirect built from scratch instead of a hosted PSP page

A reference build that demonstrates owning the entire checkout UX surface end-to-end. Most integrations drop in Stripe Checkout's hosted page or Mollie's redirect flow and call it done — fast to ship, but the merchant gives up the brand, the method ordering, the redirect flow, and the receipt design. PayFlow is the opposite: every method picker, input field, redirect, success state, and confirmation screen was built from scratch across five rails — card, Klarna, Apple Pay, Google Pay, MobilePay — covering the primary methods for both Danish and international SMBs.

Built to prove I can own every page of a checkout, not just embed an iframe. Card input runs Luhn validation client-side and detects Visa vs Mastercard from the IIN as the user types digit six; expiry validates MM/YY, CVC is length-checked. Klarna offers the full trio (Pay Now / Pay Later / Installments) with a radio selector and smooth transitions. Apple Pay and Google Pay use the real PaymentRequest API — capability-gated to iOS Safari and Android Chrome so the buttons never render where the device can't honour them. MobilePay carries a Danish-language flow with +45 phone-number validation and a confirmation screen that matches the production MobilePay UX. Why both markets are covered: cards + Apple Pay + Google Pay + Klarna are the primary international rails (US, UK, EU, Nordics). MobilePay is added for Denmark — it's the rail most international devs skip when shipping a Danish project, and adding it requires understanding the +45 number flow plus the local UX conventions. A unified internal payment-result shape means the post-checkout code (analytics, receipts, order-state machine) doesn't branch per rail. Every transaction generates a jsPDF receipt rendered client-side — no server round trip, no email pipeline to fail. There's a demo-autofill button per method so reviewers can walk the flow without typing real card numbers. Status: reference build, not a deployed SaaS. PSP responses are mocked. Real merchant onboarding, webhook handling for refunds and chargebacks, settlement reconciliation, PCI-scope handling, and per-tenant isolation would all need to be added before this takes live cards. Treat it as proof I can own the entire checkout UX surface — not as a checkout you can sign up for today. The architecture diagram below traces the request path — checkout form, validation router (Luhn + IIN + amount cap + idempotency key), the chosen PSP, and the receipt — and the methods diagram pulls each rail apart so a merchant can decide which to enable based on their actual customer mix.

  • Every checkout page, redirect, and confirmation screen built from scratch — full control of the UX surface, not a hosted-PSP iframe
  • Five rails covering both Danish and international SMB customer mixes — card, Klarna, Apple Pay, Google Pay, MobilePay
  • MobilePay first-class for Denmark — the rail most international devs skip — with +45 validation and the production-spec confirmation UX
  • Apple Pay + Google Pay via PaymentRequest API, capability-gated to iOS Safari and Android Chrome
  • Full Klarna trio (Pay Now / Pay Later / Installments) with a radio selector and smooth mode transitions
  • Unified internal payment-result shape — analytics, receipts, and order-state code never branches per rail
Gallery

See it in action.

The live demo — five rails surfaced behind one selector, with the order summary, method picker, and demo-autofill button right where a real Danish SMB checkout would put them
How it works, end to end — the customer picks a method, validation runs client and server, the right PSP fires, and every rail returns the same payment-result shape so the receipt code never branches
The five rails up close — each card carries the validation, completion UX, and reach footprint, so an SMB can pick what their customers actually use without redoing the integration