SwiftCause User Flows: As-Is vs To-Be

Visual walkthrough of every donor and admin journey · Code-verified against YNVSolutions/SwiftCause_Mono · 12 April 2026 Refreshed — was 30 Mar

Flow Summary

SwiftCause handles donations through three primary channels. Since 30 March, significant code has shipped: Magic Link token infrastructure (PR #622), Stripe Tap-to-Pay on Android (PR #619), server-side donation exports (PR #623), and CSV security hardening (PR #626). The kiosk and magic link channels now work end-to-end on device (APK validated 12 Apr). The consent ledger and web portal remain the critical gaps with 27 days to GTM (9 May 2026).

What Changed Since 30 March 2026

Flow 1: Kiosk Tap-to-Pay

Shipped
Stripe Terminal + Tap-to-Pay on Android (PR #619). Full flow validated on APK: campaign list → amount → payment → QR → Gift Aid. Thank You screen with QR code + countdown working.

Flow 2: QR / Magic Link

Shipped
PR #622 merged. Token generation (SHA-256), /link/[token] validation page, Gift Aid declaration form on donor's phone. APK recording confirms QR → phone flow works end-to-end.

Flow 3: Web Portal

Not Built
Direct URL to /donate/[campaignId] still missing. Shares components with Flow 2 but needs its own entry point, Payment Element integration, and checkout page.

Flow 4: Recurring Donations

Partial
Stripe subscriptions work on kiosk. But recurring + Gift Aid declaration linking still unhandled. Only possible via Payment Element (web portal).

Flow 5: Returning Donor

Partial
Email lookup + auto-fill exists. But auto-submits consent without re-confirming — legal risk. Needs confirmation screen. No change since 30 Mar.

Admin Flows

Partial
Server-side donation export (PR #623) + CSV security (PR #626) + admin pagination (PR #617) shipped. But no Gift Aid dashboard, HMRC claim batch UI, or flow configuration screens yet.
Exists / Shipped
Newly shipped (since 30 Mar)
New — to be built
Changed — needs modification
Gap — blocking compliance
Decision point

Possible Outcomes per Flow

FlowGift Aid Eligible?GASDS Eligible?Recurring Possible?Donor Identity?
Kiosk Tap-to-Pay (Option A) Yes — on-screen form Yes — ≤£30 anonymous No — Terminal can't store PM Only if Option A completed
Kiosk Tap-to-Pay (Option B+) Via QR follow-up — NOW WORKING Yes — ≤£30 anonymous No Via magic link on phone
QR / Magic Link Checkout Yes — form on donor's phone Yes — if ≤£30 Yes — Payment Element stores PM Yes — wallet pre-fill + form
Web Portal Yes — inline form Yes — if ≤£30 Yes — Payment Element stores PM Yes — wallet pre-fill + form
Recurring (any Payment Element flow) Yes — one declaration covers all Yes — per-invoice if ≤£30 Yes — built-in Yes

GTM Readiness: 27 Days to Launch (9 May 2026)

10-Step Donor JourneyStatusIssue/PRNotes
1. Kiosk displays campaignSHIPPEDWorking on Android APK
2. Donor taps to paySHIPPEDPR #619Stripe Tap-to-Pay on Android
3. Webhook processes paymentSHIPPEDPR #615Idempotency + atomicity fixed
4. Magic link generatedSHIPPEDPR #622SHA-256 tokens, 30-day expiry
5. Donor opens link on phoneSHIPPEDPR #622/link/[token] page + validation API
6. Gift Aid form displayedSHIPPEDPR #622Declaration form on phone, APK-validated
7. Consent recordedNOT BUILT#609ConsentEvents Cloud Function — UNASSIGNED 15 days
8. Donor reconciliationNOT BUILT#611Unassigned 15 days
9. Recurring optionDEFERRED#592Phase 3, not in go-live scope
10. HMRC exportSHIPPEDPR #623, #626Server-side export + CSV injection fix

Flow 1: Kiosk Tap-to-Pay

The primary high-footfall flow. Donor walks up to a kiosk (Android handset or fixed device), selects a campaign, chooses amount, and taps their card or phone. Gift Aid is captured either before payment (Option A) or after via QR (Option B+). APK build validated 12 April — full flow works end-to-end on Android device.

Built
Newly Shipped
Changed
Gap
AS-IS — What Exists Today (12 Apr 2026)
1Campaign List ScreenBUILT
Kiosk campaign list. Donor browses available campaigns. Working on Android APK.
2Campaign Detail + Amount SelectionBUILT
Predefined amounts or custom £1–£10,000. APK shows £5/£10/£25/£50/Other.
3Gift Aid Boost PanelBUILT
GiftAidBoostPanel.tsx — “Turn your £X into £Y for free”. Two CTAs: Yes / No.
Donor taps “Yes, Boost”?
Yes
4aEmail GateBUILT
GiftAidPage.tsx checks for saved profile by email.
4bGift Aid Details FormBUILT
GiftAidDetailsPanel.tsx — name, address, postcode, HMRC declaration checkbox.
No
Skips Gift Aid. Goes straight to payment. Donation becomes GASDS-eligible if ≤£30.
5Stripe Terminal / Tap-to-Pay PaymentSHIPPED PR #619
Stripe Tap-to-Pay on Android via Stripe SDK. Payment processing with “Processing your donation...” screen. Returns NO donor identity data.
6Webhook + Token CreationSHIPPED PR #622
handlePaymentCompletedStripeWebhook. If isGiftAidCaptured: false, creates giftAidFollowUpToken with SHA-256 crypto token, donationId, 30-day expiry. Atomic batch writes. Idempotent (PR #615).
7Thank You Screen with QRSHIPPED — APK VALIDATED
ThankYouScreen shows: celebration header, QR code encoding magic link URL, “I've scanned the QR code” button, auto-return countdown. APK recording (12 Apr) confirms this works. Countdown currently 29s — Issue #627 proposes configurable timer (pending PM agreement).
8Donor Scans QR → Flow 2SHIPPED PR #622
Opens /link/[token] on donor’s phone. Validation API checks token, returns donation context. APK recording confirms full flow: QR scan → Gift Aid form → auto-return.
Gift Aid: Option A (instant) or Option B+ (via QR) — BOTH WORKING GASDS: If ≤£30 and no Gift Aid Identity: Via QR checkout on phone
REMAINING GAPS — Still Needed for Production
1–5Core Kiosk FlowCOMPLETE
Campaign list → amount → Gift Aid boost → form → payment. All working on APK.
6Production HardeningBLOCKER SC-B004
Firestore rules currently open for dev. Must tighten security rules, deploy indexes, configure TTL policies, deploy Cloud Functions before production use.
7Consent Ledger IntegrationUNASSIGNED 15 DAYS
#609 ConsentEvents Cloud Function — computes DonorRecord.currentConsent from ConsentEvents subcollection. Not built. This is the #1 GTM risk.
8IP Address CaptureUNASSIGNED #610
HMRC audit trail requires IP address on declarations. Server-side capture not implemented. 15 days unassigned.
9Donor ReconciliationUNASSIGNED #611
Link magic link declarations back to donor profiles. Merge/dedup donor records. 15 days unassigned.
10QR-to-Submit Funnel AnalyticsUNASSIGNED #612
Track QR scan rate, form completion rate, drop-off points. Critical for measuring magic link ROI. 15 days unassigned.
11APK Cleanup for DemosBLOCKER SC-B009
Remove “Feed the devs” test campaign. Verify Stripe live key toggle. Reduce auto-return from 29s (Issue #627). Record polished demo video.
CRITICAL: 4 Sprint 04 tasks (#609–#612) unassigned 15 days. This is the #1 GTM risk.

Flow 2: QR / Magic Link Checkout

Donor scans the QR code displayed on the kiosk Thank You screen. This opens a checkout page on their own phone. This flow was entirely missing on 30 March. It now exists — PR #622 shipped the magic link token infrastructure, /link/[token] page, validation API, and Gift Aid declaration form. APK recording (12 Apr) confirms end-to-end flow on device.

CURRENT STATE — What's Shipped (PR #622, 9 Apr)
1Donor Scans QR / Taps Magic LinkSHIPPED
QR on kiosk Thank You screen encodes URL: /link/[tokenId]. Opens on donor’s phone browser. APK recording confirms this works.
2Token ValidationSHIPPED
GET /api/link/[token] validates token exists, not expired (<30 days), status is “pending”. Returns donation context (amount, campaign name). SHA-256 hashed storage. Deterministic doc IDs for idempotency.
Post-payment follow-up (from kiosk QR)
3Gift Aid Declaration FormSHIPPED
On donor’s phone (responsive). HMRC-required fields: name, address, postcode, declaration checkbox. APK recording shows form completing successfully with auto-return to kiosk.
4Declaration Created + Token ConsumedSHIPPED
POST /api/link/[token]/complete creates declaration in Firestore linked to original donationId. Sets captureMethod: POST_DONATION_QR. Marks token as “completed”. Atomic batch writes.
5Confirmation + Auto-ReturnSHIPPED
Kiosk detects QR scan completion and auto-returns to campaign list after countdown. Donor sees confirmation on their phone.
Gift Aid: Full capture via phone form — WORKING Identity: Captured via form on donor's phone
REMAINING GAPS — Consent Ledger Not Built
AConsentEvents Cloud Function (#609)UNASSIGNED
Each Gift Aid declaration should create a ConsentEvent in the donor's subcollection. Cloud Function computes DonorRecord.currentConsent from event history. Not built — 15 days unassigned.
BIP Address Capture (#610)UNASSIGNED
HMRC audit trail requires IP address on every declaration. Server-side capture needed on the /api/link/[token]/complete endpoint. Not implemented.
CDonor Reconciliation (#611)UNASSIGNED
Link magic link declarations back to donor profiles. Handle merge/dedup when same email appears across multiple donations.
DQR-to-Submit Analytics (#612)UNASSIGNED
Track: QR displayed count, QR scanned count, form started, form completed, drop-off points. Essential for proving magic link ROI to charities.
EFresh Checkout Path (not just post-payment)NOT BUILT
Flow 2 currently only handles post-payment follow-up (Gift Aid only, no second payment). A fresh checkout path where QR leads to full Payment Element checkout is not yet built — that's Flow 3.
FConfirmation Email (GA-04)NOT BUILT
SendGrid not set up (#605, 16+ days unassigned). Cannot send Gift Aid confirmation emails until email infrastructure exists.
The core flow works. The compliance layer (consent ledger, IP capture, reconciliation) does not. These are the gating items for GTM.

Flow 3: Web Portal Checkout

Direct URL to /donate/[campaignId] — shared via email, social media, or charity website. Responsive page serving both desktop and mobile. Uses the same Payment Element + Gift Aid form components as Flow 2. This flow is still not built — no change since 30 March.

AS-IS — What Exists Today
1Campaign Page (app/campaign/[id])BUILT
Public campaign detail page exists. Shows title, description, progress bar.
2Payment Page (app/payment/[id])BUILT
Payment route exists BUT currently routes to kiosk-bound flow (requires kiosk context, Stripe Terminal).
No web checkout capability
No Payment Element integration. No way to pay without a physical kiosk terminal. No Gift Aid capture on web. This is unchanged since 30 March.
TO-BE — Target State
1Campaign Landing PageEXISTS
Same public campaign page. Add “Donate Online” CTA button.
2Web Checkout: Amount + Gift AidNEW BUILD
/donate/[campaignId] — responsive page. Amount selector, one-time/recurring toggle, Gift Aid boost panel, full declaration form. Can reuse components from PR #622.
3Stripe Payment ElementNEW BUILD
Payment Element with requestPayerName + requestPayerEmail. Supports Apple Pay, Google Pay, card entry. Wallet pre-fills donor identity into Gift Aid form.
4createWebPaymentIntentNEW BACKEND
New Cloud Function. Creates PaymentIntent with automatic_payment_methods. For recurring: creates Stripe customer + subscription.
5Webhook ProcessingEXISTING
Same handlePaymentCompletedStripeWebhook (now hardened via PR #615). Reads declarationId from metadata.
6Web Thank You + EmailNEW
Confirmation page with Gift Aid summary. Confirmation email (blocked by #605 SendGrid). Social sharing prompt.
Gift Aid: Full inline capture Recurring: Yes, via Payment Element Identity: Full (wallet + typed)
Architecture Note: Flows 2 and 3 share 90% of their codebase. The Gift Aid form, validation logic, and confirmation page from PR #622 can be reused. They differ only in entry point: Flow 2 validates a follow-up token; Flow 3 looks up a campaign by ID and adds Payment Element. Build once, route twice.

Flow 4: Recurring Donations

Recurring donations require a stored payment method, which Stripe Terminal cannot provide. Recurring is only possible through Payment Element flows (web portal). One Gift Aid declaration with declarationType: “past_and_future” covers all future invoices. No change since 30 March — recurring + Gift Aid linking is still unhandled.

AS-IS — What Exists Today
1Kiosk Recurring SelectionBUILT
Campaign config has enableRecurring, recurringIntervals (monthly/quarterly/yearly). Donor selects on kiosk.
2Stripe Subscription CreationBUILT
createKioskPaymentIntent creates Stripe customer, attaches payment method, creates subscription.
3handleInvoicePaid WebhookBUILT
Processes each recurring invoice. Creates donation doc per invoice. Now with idempotency (PR #615).
!Gift Aid + Recurring = UnhandledGAP
handleInvoicePaid doesn’t check for existing Gift Aid declarations. Each invoice would create a new declaration instead of reusing the original. No declarationType support. No change since 30 March.
Recurring: Works on kiosk Gift Aid + Recurring: Still Broken
TO-BE — Target State (Deferred to Phase 3)
1Web/QR Recurring SelectionNEW
On Payment Element checkout (Flow 3), donor selects “Make this recurring” with interval selector.
2Gift Aid Form with declarationTypeUPDATED
If recurring selected, declarationType defaults to “past_and_future”. Single declaration covers all future invoices.
3Subscription via Payment ElementNEW
Payment Element stores payment method for future charges.
4handleInvoicePaid (Updated)UPDATED
On each invoice: check for existing active Gift Aid declaration with past_and_future type. Link donation to existing declaration. No duplicates.
5Per-Invoice Gift Aid TrackingNEW
Each recurring invoice creates a donation doc with giftAidDeclarationId pointing to the original declaration. CSV export includes all linked invoices.
Gift Aid: One declaration, all invoices Recurring: Payment Element only

Flow 5: Returning Donor Recognition

When a donor who has previously completed a Gift Aid declaration returns, the system should recognise them by email and pre-fill their details. The current implementation has a smart shortcut that auto-submits, but it has a legal risk. No change since 30 March.

AS-IS — What Exists Today
1Email Gate ScreenBUILT
GiftAidPage.tsx shows email input after donor taps “Yes, Boost.”
2Profile LookupBUILT
getReusableGiftAidProfileByEmail() queries giftAidDeclarations by normalized email.
Profile found with consent?
Yes — Returning Donor
!Auto-Submit (Legal Risk)RISK
GiftAidPage.tsx auto-creates GiftAidDetails from profile and calls onAcceptGiftAid() directly. Hardcodes dataProcessingConsent: true, homeAddressConfirmed: true. No confirmation screen. No “still correct?” prompt.
No — New Donor
Falls through to full Gift Aid details form.
3Details Form Pre-FillBUILT
GiftAidDetailsPanel.tsx also has its own email-blur lookup. If profile found, pre-fills all fields.
TO-BE — Target State (with OTP — 13 Apr decision)
1Email Gate ScreenNO CHANGE
2Email OTP VerificationNEW — 13 Apr
6-digit OTP sent to entered email (Firebase Auth). Donor enters code on same page. If verified → proceed to profile lookup. If skipped → treat as new donor (blank form only, no stored data shown). Gift Aid still claimable without OTP — HMRC doesn't require email verification.
3Profile Lookup (verified email only)UPDATED
Only runs after email OTP verified. Prevents data exposure to unverified users.
Profile found with consent?
Yes — Returning Donor (verified)
!Confirmation ScreenNEW
“We have your Gift Aid details from [date]. Is this still correct?” Shows name + address summary. Two options: “Yes, use these details” or “Update my details”.
No — New Donor
Same: full details form.
3Details Form (if updating)UPDATED
Pre-filled from saved profile. Donor can edit any field. Old declaration marked as superseded.
4Donor Profile UpdatedNEW
If details changed, update donorProfiles collection. Future lookups return latest address.

Admin Flows

Charity treasurers and SwiftCause admins need visibility into Gift Aid declarations, HMRC claim status, and GASDS tracking. Since 30 March, three key admin improvements shipped: server-side donation export (PR #623), CSV formula injection hardening (PR #626), and admin panel pagination (PR #617). But Gift Aid admin screens remain unbuilt.

AS-IS — Admin Today (12 Apr 2026)
1Admin DashboardBUILT
Basic overview. Campaign stats, donation totals.
2Campaign ManagementBUILT
Create/edit campaigns. giftAidEnabled toggle exists but no flow config.
3Donations ListUPDATED PR #617
View donations with pagination (PR #617). No Gift Aid status column yet. No HMRC claim tracking.
4Server-Side Donation ExportNEW PR #623
Server-side CSV export for all donations (not just visible page). Export batches + history + re-download. CSV formula injection hardened (PR #626).
5Kiosk ManagementBUILT
6User ManagementBUILT
No Gift Aid admin screens
No declaration viewer. No HMRC batch generator UI. No GASDS tracker. No flow configuration. Gift Aid CSV lib function exists but no admin UI wrapping it.
TO-BE — Admin Target
1Admin DashboardUPDATED
Add Gift Aid summary cards: total claimed, pending, GASDS pool, conversion rate.
2Gift Aid Dashboard (GA-07)NEW
Declarations table with filters (status, date, campaign). Validation flags. GASDS tab.
3HMRC Claim Batches (GA-08)NEW
Select period → preview → generate R68 CSV → download → mark submitted → mark paid. Server-side export infrastructure (PR #623) can be extended for this.
4Flow Configuration (GA-14)NEW
Per-campaign: flow type (Option A / B+ / Hybrid), Thank You screen timeout (Issue #627), QR toggle, custom messaging.
5GASDS InsightsNEW
Annual cap tracker (£8,000). 10× matching rule calculator. “Lost money” figure for donors who could convert to full Gift Aid.
6Donor Management (DI-01)NEW
Donor profiles list. Declaration history per donor. Address update workflow. Depends on #611 (donor reconciliation).

HMRC Claim Submission Flow (Treasurer)

Treasurer: Quarterly HMRC Claim Workflow
1Open HMRC Claims tab
See pending declarations count and estimated claim value.
2Select claim period
Tax year filter + date range. System pre-selects declarations with hmrcClaimStatus: “pending”.
3Preview & validate
Validation flags: missing postcode, invalid name, suspicious amounts. Treasurer can exclude individual records.
4Generate R68 CSVPARTIALLY SHIPPED
giftAidCsv.ts exists and is HMRC-compliant. CSV formula injection hardened (PR #626). Server-side export infrastructure built (PR #623). But no admin UI for triggering Gift Aid-specific export yet.
5Upload to Charities Online
Treasurer uploads CSV to HMRC Charities Online portal manually.
6Mark as submitted
Updates all declarations in batch to hmrcClaimStatus: “submitted”.
7Mark as paid
When HMRC payment arrives (5–6 weeks), mark paid with actual amount received.

Data Capture Matrix

What each flow captures vs what HMRC requires. Updated 12 April 2026 to reflect shipped code. The QR Follow-Up column now shows actual state from PR #622 (not aspirational).

Data Field HMRC Required? Kiosk Option A
(as-is)
Kiosk Option B+
(as-is via QR)
QR Follow-Up
(SHIPPED PR #622)
Web Portal
(to-be)
First NameYesFormVia QR formForm — SHIPPEDForm + Wallet
SurnameYesFormVia QR formForm — SHIPPEDForm + Wallet
EmailRecommendedFormVia QR formForm — SHIPPEDForm + Wallet
House NumberRecommendedFormVia QR formForm — SHIPPEDForm
Address Line 1YesFormVia QR formForm — SHIPPEDForm
Address Line 2OptionalFormVia QR formForm — SHIPPEDForm
TownYesFormVia QR formForm — SHIPPEDForm
PostcodeYesFormVia QR formForm — SHIPPEDForm
Gift Aid ConsentYesCheckboxVia QR formCheckbox — SHIPPEDCheckbox
UK Taxpayer ConfirmYesCombinedVia QR formCheckbox — SHIPPEDCheckbox
HMRC Declaration TextYes (Ch.3)ShownVia QR formShown — SHIPPEDShown
Declaration TypeYesMissingMissingNeeds verificationRadio
GDPR ConsentGDPR req.MissingMissingNeeds verificationCheckbox
Future ConsentOptionalMissingMissingNeeds verificationCheckbox
Home Address ConfirmedYesMissingMissingNeeds verificationCheckbox
IP AddressAudit trailMissingMissingMissing — #610 unassignedServer-side
Capture MethodAudit trailMissingPOST_DONATION_QRPOST_DONATION_QR — SHIPPEDON_SCREEN
Donation AmountYes (pence)AutoAutoAuto — SHIPPEDAuto
Tax YearYesBug (GA-01)BugNeeds verificationFixed helper
Key Takeaway (Updated 12 Apr): The QR Follow-Up flow now captures most HMRC-required fields (PR #622 shipped). The critical remaining gaps are: IP address capture (#610, unassigned), and verification needed on whether declarationType, GDPR consent, and homeAddressConfirmed fields are included in the PR #622 form. The consent ledger (#609) is the compliance gating item — without it, declarations exist but aren't properly tracked in the donor record.

APK Build Review — 12 April 2026

Jitesh Singh delivered the first Android APK (app-debug.apk, 70.1 MB) to #charity_project at 10:35 BST. This review is based on PM screen recording analysis of the complete donation flow. Kiosk credentials: ID hz0vffcVAQELv4NoAo5I, access code 12345.

Overall Verdict: PASS — The core donation flow works end-to-end on Android device. This is the first time kiosk → payment → QR → Gift Aid has been validated on real hardware. Ready for internal alpha testing with cleanup items noted below.

7-Step Flow Walkthrough

Each step observed in the screen recording, mapped to the donor journey.

Step 1
Kiosk Login
Pass
Step 2
Campaign List
Pass
Step 3
Amount Select
Pass
Step 4
Payment
Pass
Step 5
QR + Thank You
Pass
Step 6
Gift Aid Form
Pass
Step 7
Auto-Return
Timer Issue

Detailed Step Analysis

Steps 1–4: Login → Campaign → Amount → Payment
1Kiosk Login ScreenPASS
SwiftCause branded splash. Kiosk ID + access code entry. Clean UI, responsive input fields. Successfully authenticates to Firebase.
2Campaign ListPASS
Displays campaigns from Firebase. Card layout with campaign images, titles, progress bars. Includes test campaign “Feed the devs” (needs removal before demo). Skeleton loaders working (PR #618).
3Campaign Detail + Amount SelectionPASS
Campaign description with rich text rendering. Amount presets: £5, £10, £25, £50, Other (custom). Sticky amount panel at bottom. “Donate Now” CTA prominent. Amount validation working.
4Stripe Tap-to-Pay PaymentPASS
“Processing your donation...” screen shown during Stripe Terminal interaction. Payment simulation completes successfully. Spinner animation smooth. Transitions cleanly to Thank You screen.
Steps 5–7: QR Code → Gift Aid → Auto-Return
5Thank You Screen with QR CodePASS
Celebration header: “Thank you for your donation!” QR code rendered clearly at centre of screen. Encodes magic link URL (/link/[token]). “I've scanned the QR code” button below QR. Auto-return countdown visible at bottom.
6Gift Aid Declaration Form (on phone)PASS
Donor scans QR with phone camera. /link/[token] page loads. Token validated via API. Gift Aid form displays with: first name, surname, email, house number, address, town, postcode, declaration checkbox. Form submits successfully → declaration created in Firestore.
7Auto-Return to Campaign ListTIMER WARNING
Kiosk detects QR scan completion and shows countdown. Auto-returns to campaign list after countdown expires. Issue: Countdown is 29 seconds — too long for a shared kiosk. Donor stands watching a timer instead of walking away. Issue #627 proposes configurable timer (org + campaign level, 15s default). Pending PM agreement.

Findings

GOOD End-to-End Flow Works

First time the full kiosk → payment → QR → Gift Aid → return flow has been validated on real Android hardware. This is a major milestone. The donation journey from campaign selection to Gift Aid capture works without errors.

GOOD Stripe Tap-to-Pay Integration Solid

Payment processing via Stripe SDK on Android works cleanly (PR #619). Processing screen, spinner, and success transition are smooth. No payment failures observed during testing.

GOOD Magic Link QR → Phone Handoff Works

QR code on Thank You screen encodes the correct magic link URL. Phone camera scans it successfully. /link/[token] page loads, validates the token, and displays the Gift Aid form. The cross-device handoff (kiosk → phone) works as designed (PR #622).

GOOD UI Quality Strong for Alpha

Skeleton loaders (PR #618), image caching, rich text campaign descriptions, sticky amount panel. Polish is above typical alpha level. Branding consistent. Animations smooth.

WARNING Test Data Visible — “Feed the devs” Campaign

The campaign list includes a test campaign titled “Feed the devs” with casual copy. This must be removed or hidden before any external demo. Consider adding a campaign visibility flag (draft/published) or using a separate demo Firebase project. Impact: demo readiness.

WARNING 29-Second Auto-Return Countdown Too Long

After QR scan completion, the kiosk shows a 29-second countdown before returning to the campaign list. In a high-footfall charity shop, this means the kiosk is unavailable for nearly 30 seconds between donors. Recommendation: reduce to 15 seconds default, make configurable per org/campaign. Issue #627 created with 2-tier Firestore config proposal.

WARNING Payment Simulation Mode — Stripe Live Key Toggle Needed

Current build uses Stripe test mode (simulated payments). Before any production or customer demo with real cards, must verify the Stripe live/test key toggle works correctly. Need environment config that switches cleanly between test and production Stripe keys.

ACTION REQUIRED Known Issues from Jitesh

Jitesh flagged three known issues in his Slack post: (1) YouTube video playback restricted in-app, (2) auto-refresh kiosk data mechanism not implemented, (3) no secure logout mechanism (can't have a simple logout button as any donor could tap it). These are acknowledged and non-blocking for alpha testing, but items 2–3 need resolution before production.

ACTION REQUIRED Gift Aid Form Missing Compliance Fields

The Gift Aid declaration form captures core HMRC fields (name, address, postcode, declaration). However, the following compliance fields need verification against PR #622 code: declarationType (past_only / past_and_future radio), GDPR consent checkbox, future contact consent, home address confirmation checkbox, and IP address capture (#610, unassigned). Without these, declarations are usable but not fully HMRC-compliant.

APK Review Summary

AreaStatusNotes
Kiosk LoginPassFirebase auth working
Campaign ListPassTest data needs cleanup
Amount SelectionPassPresets + custom working
Stripe Tap-to-PayPassTest mode — live key toggle needed
QR Code GenerationPassMagic link URL encoded correctly
Phone HandoffPassCross-device flow works
Gift Aid FormPassCore fields — compliance fields need verification
Auto-Return TimerWarning29s too long — Issue #627 created
Demo ReadinessWarningTest data + payment mode need cleanup
Consent LedgerNot Built#609–#612 unassigned 15 days
IP CaptureNot Built#610 unassigned
Production HardeningNot DoneFirestore rules, indexes, TTL, deployment
PM Recommendation: Acknowledge this milestone publicly in #charity_project — the team needs to see PM engagement after delivering a working end-to-end flow. Then focus on the three cleanup items (test data, timer, Stripe keys) and the four unassigned consent ledger tasks. The APK proves the architecture works; now it needs the compliance layer to be production-ready.