Hoppa till innehållet
Luxe Group

Case · Egen produkt

FolkPanelen: en enkätapp med BankID och Swish-utbetalningar

FolkPanelen är vår egen undersökningspanel. Användarna svarar på betalda enkäter i en app och tar ut pengarna via Swish. Vi har byggt och driver hela kedjan själva, från appen i butikerna till ekonomi och support.

Uppdaterad · Luxe Group AB

Plattform
iOS, Android och webb (landningssida och admin)
Byggt med
Expo/React Native, Next.js, ElysiaJS, PostgreSQL
Inloggning
BankID
Utbetalning
Swish
Status
Live i App Store och Google Play

Problemet

Enkätpaneler är en gammal bransch. Många av dem är webbsidor som inte gjorts om på länge, med utbetalningar som tar veckor och konton som lätt kan skapas i flera exemplar. För den som svarar blir det krångligt. För företagen som köper svaren blir det svårt att lita på att varje svar kommer från en riktig person.

Vi ville se om det gick att göra bättre med teknik som svenskar redan använder varje dag. Mobilen skulle vara huvudkanalen, BankID skulle visa vem man är och Swish skulle användas för att betala ut.

Vad vi byggde

FolkPanelen är en app för iOS och Android. Användaren skapar ett konto med BankID och fyller i en profil. Utifrån profilen får hen enkäter som passar. Man kan också tjäna pengar på att testa mobilspel, värva vänner och delta i veckotävlingar. När saldot räcker tar man ut pengarna med Swish. Appen finns på App Store och Google Play.

Bakom appen finns fyra delar som hänger ihop:

  • Mobilappen, byggd i Expo och React Native med Expo Router. Vi skriver en kodbas och den körs på båda plattformarna.
  • API:t, ett TypeScript-backend i ElysiaJS på Bun med PostgreSQL via Prisma. Här ligger affärslogik, schemalagda jobb och kopplingarna till enkätleverantörer.
  • Landningssidan i Next.js. Den har guider om betalda enkäter, screenouts och Swish-utbetalningar och fungerar som ingång från Google.
  • Adminsystemet, också i Next.js. Där sköter teamet användare, uttag, support, tävlingar, nyheter, notiser, leverantörer och ekonomi.

Tekniska utmaningar och hur vi löste dem

En kodbas, fyra appar

Allt ligger i ett monorepo med Turborepo och Bun. API:t exporterar sina typer och en delad klient (Eden Treaty) använder dem. Därför vet mobilappen, admin och landningssidan exakt vilka svar API:t ger, och kompilatorn hittar felet om ett fält byter namn. Inloggning, databas och e-postmallar ligger i delade paket som alla appar använder.

BankID som enda inloggning

En panel är bara värd något om varje konto motsvarar en riktig person. Därför kan man bara logga in med BankID. Inloggning med e-post är avstängd i API:t och inte bara dold i appen. Kontona bygger på Better Auth med ett eget BankID-tillägg. För att förhindra att samma person utnyttjar sådant som bara ska ske en gång per person sparar vi en icke-reversibel nyckel av personnumret i stället för personnumret i klartext. Det gäller också om personen raderar sitt konto och skapar ett nytt. Läs mer om upplägget i vår guide om BankID i appar.

Swish-utbetalningar som går att bokföra

Uttagen går via Swish utbetalnings-API, som skickar pengar direkt till användarens mobilnummer. Det svåra är inte själva anropet. Det svåra är allt runt omkring: att ett uttag aldrig kan skickas två gånger, att saldot alltid stämmer mot transaktionerna och att varje utbetalning hamnar rätt i bokföringen. Vi har schemalagda jobb som stämmer av saldon, en kö som för över underlag till bokföringssystemet och kvitton i PDF. Vi går igenom tekniken i guiden om Swish-integration.

Externa enkätleverantörer

Enkäterna kommer från flera externa leverantörer. Var och en meddelar genomförda svar till vårt API, ofta kallat postback. Varje sådant anrop verifieras innan något krediteras, och svar som leverantören senare drar tillbaka kan backas. Enkäterna rangordnas efter hur väl de matchar användarens profil, så att färre leder till en screenout.

Notiser som inte blir spam

Pushnotiser skickas via Expo och går genom en kö med regler för hur ofta och när en användare får meddelanden. Allt loggas så att vi kan se vad som skickats och vad som gav effekt. Schemalagda jobb sköter tävlingar, påminnelser och daglig statistik. Ett lås ser till att två serverinstanser aldrig kör samma jobb samtidigt.

Vad vi lärde oss

  • Pengar kräver mest arbete. Ett utbetalningsflöde ska klara dubbla anrop, fel hos banken och avstämning mot bokföringen. Där lägger vi mer tid än på gränssnittet, och det är rätt prioritering.
  • Adminverktyget är halva produkten. Utan bra verktyg för support, uttag och ekonomi blir varje fråga från en användare manuellt arbete i databasen.
  • Delade typer sparar tid. När app, webb och admin delar typer med API:t blir det färre buggar vid varje ändring.
  • Appbutikernas granskning är en egen process. Den behöver planeras in från början, inte efter att allt annat är klart.

Vad det betyder för dig som kund

Vill du bygga en app med inloggning, betalningar eller utbetalningar? Då har vi redan löst de problem som brukar dyka upp sent i ett projekt. Vi kan BankID, Swish, pushnotiser, publicering i appbutikerna och adminsystem som håller i drift, eftersom vi själva använder dem varje dag. Läs mer om apputveckling och betalningar och BankID, eller mejla info@luxegroup.se.

Vanliga frågor

Är FolkPanelen ett kundprojekt?

Nej. FolkPanelen är Luxe Group AB:s egen produkt. Vi har byggt den, vi driver den och vi står för drift, support och utbetalningar.

Kan ni bygga en liknande app med BankID och Swish åt oss?

Ja. Hos oss är BankID-inloggning, Swish-betalningar och Swish-utbetalningar beprövade delar som körs i drift. Hur mycket som går att återanvända beror på ditt projekt.

Varför Expo och React Native i stället för helt native-appar?

Med en kodbas för både iOS och Android blir utvecklingen och underhållet ungefär hälften så stort. Expo ger samtidigt tillgång till pushnotiser, säker lagring och de byggverktyg som behövs för att publicera i appbutikerna.

Ingår ett adminsystem när ni bygger en app?

Det beror på behovet, men de flesta appar med användare och pengar behöver ett. I FolkPanelen sköts användare, uttag, support, notiser och ekonomi helt i ett eget admin.

Läs vidare