ServicesWorkContact Start a project →
Back to work
Android App Loyalty Wallet Privacy-First

Loy
ca

A native Android loyalty-card wallet. Scan a card's barcode once, then pull it up on screen at the till instead of digging through a keyring of plastic. No account, no server, no network permission.

8+
Barcode formats
1
Permission (camera)
0
Network calls
100%
On-device
9:41●●●
Scan card ML Kit
Point the camera at the barcode
Code 128 · EAN · QR · PDF417
Enter it manually
9:41●●●
Supermarket ★ Favorite
4 012345 678901
Format
EAN-13
Screen brightness
Max
Boosted so the scanner can read it
9:41●●●
Wallet + Add
Supermarket
★
EAN-13 · front & back photo
Pharmacy
★
Code 128
Coffee shop
QR
Bookstore
Hold & drag to reorder

A wallet full of plastic you only need for four seconds

Loyalty cards are a solved problem in the worst possible way: everyone carries a stack of them, uses each one for the few seconds it takes to be scanned, and carries them the rest of the year for nothing. The apps that replace them mostly want an account, a marketing opt-in, and a network connection.

Loyca started life as Cardly, a Laravel + NativePHP for Mobile build — a PHP runtime and a WebView packaged into an Android shell. It proved the product quickly, but it shipped a whole interpreter just to render a barcode. The brief for v2 was simple: same features, same on-disk data, a fraction of the weight.

Rewrite it native, keep the data intact

  • Full rewrite from Laravel + NativePHP to pure Kotlin — no PHP runtime, no WebView
  • Kept the exported-backup format compatible so libraries from the original build still import
  • Scanning moved to CameraX + ML Kit; rendering to ZXing drawing straight into a bitmap
  • Declared no INTERNET permission at all, so "it never phones home" is enforced by the manifest rather than promised in a policy
  • Renamed to Loyca before launch — "Cardly" was already an established wallet on Play and a live trademark

Four screens, and you're at the till

📷
Scan the barcode, or type the number in
🗂️
Wallet with favorites, search, and drag-to-reorder
🎟️
Full-screen barcode with the brightness boosted
💾
Export and import the whole library as JSON

Everything a plastic card does, minus the plastic

📷
Scan Anything
ML Kit reads Code 128, EAN-13/8, UPC-A/E, ITF, QR, Data Matrix, Aztec and PDF417 — 1D and 2D alike. Won't scan? Type the number and pick the format.
🔆
Brightness Boost
Opening a card ramps the screen to full brightness and restores it on exit, so a till scanner reads the phone as reliably as it reads the card.
📸
Front & Back Photos
Some cards carry a member number or terms printed only on the plastic. Photograph both sides and view them full screen.
✋
Hold & Drag Ordering
Press and hold a card to pick it up and drag it where you want it. Favorites and the rest reorder within their own section, so moving one never shuffles the other.
💾
JSON Backup
Export the entire library — photos inlined — to a single self-contained file. Re-import skips duplicates, and the format is shared with the original web build.
🔒
No Network, By Design
The app declares no internet permission. There is no account, no sync, no analytics SDK and no ad network — the OS itself would block a network call.

Pure Kotlin, no runtime in the box

Loyca is a single-module Android app in Kotlin 2.4, built with Jetpack Compose and Material 3. Room owns the card library, DataStore holds preferences such as the light / dark / follow-system theme, and Navigation Compose ties the screens together.

The camera path is CameraX feeding ML Kit's on-device barcode scanner; the render path is ZXing drawing the code into a bitmap. Release builds are minified and resource-shrunk through R8, and the version name lives in a single Gradle property that the version code is derived from, so the two can never drift.

Kotlin 2.4 Jetpack Compose Material 3 Room DataStore CameraX ML Kit ZXing Coroutines / Flow kotlinx.serialization Gradle / KSP R8

What going native bought

0
Embedded PHP runtimes — the WebView shell is gone entirely
100%
Backup compatibility with the original web build
API 26
Minimum supported Android, targeting API 36
3
ABIs shipped — arm64-v8a, armeabi-v7a, x86_64

More work

Start a project

Got a mobile idea?
Let's ship it.

From concept to Play Store, we build mobile apps that people actually use.

Get in touch More work