Product architecture

How VerifyPay works

A QR-to-pay flow with digital age verification, Stripe checkout, and real-time tablet confirmation — built for UK retail.

End-to-end payment flow

1. Scan QR

Customer scans QR on display unit.

2. Verify age

OIDC flow with OneID / Yoti.

3. Pay

Stripe Checkout — Card / Apple / Google Pay.

4. Webhook

Stripe confirms payment to backend.

5. Tablet

WebSocket pushes green confirmation.

System components

Customer device

  • Camera (QR scan)
  • PWA — no install
  • OIDC redirect

VerifyPay backend

  • Node.js API
  • OIDC verifier
  • Stripe webhook handler
  • WebSocket gateway

Retail tablet

  • Android display
  • Persistent WebSocket
  • Green / red screen

Identity provider

  • OneID
  • Yoti
  • OIDC / OAuth2

Stripe

  • Checkout session
  • 3DS handling
  • Apple / Google Pay

PostgreSQL

  • Encrypted at rest
  • 7-year audit log
  • Hashed identifiers

Verification rules engine

Every transaction passes through a deterministic rules pipeline. Any failure short-circuits the flow.

age >= 18 (Challenge 25 enforced via document scan)

ID document not on revocation list

Liveness score >= 0.92

Outlet active and within trading hours

Stripe payment_intent.succeeded received within 60s

Customer hash not flagged in fraud register

Data model

Core entities. PII is hashed; only minimum required data is retained.

transactions

id

reference

outlet_id

product_id

amount

status

stripe_session_id

verification_id

created_at

verifications

id

provider (oneid|yoti)

customer_hash

age_band

liveness_score

verified_at

expires_at

outlets

id

name

city

tablet_id

trading_hours

active

audit_log

id

actor

action

entity

payload_hash

ip

created_at

Security & compliance

TLS 1.3 only

PCI-DSS via Stripe

AES-256 at rest

Signed webhooks