Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

19 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

PayNey Capture

The Android companion app for PayNey β€” your effortless expense tracker.

Platform Kotlin Jetpack Compose Min SDK 26 Latest release License

PayNey Capture turns your phone into an automatic transaction sensor. It reads your bank/UPI SMS alerts and payment-app notifications the moment they arrive and forwards them to your PayNey account, so every expense lands in your tracker without a single manual entry. Snap a photo of a paper receipt and it pulls out the amount, merchant, and date for you too.

Think of it as the eyes and ears of PayNey on your device: the web app is where you review, categorize, and analyze; Capture is what feeds it in real time.

πŸ‘‰ Web app: payney.vercel.app Β β€’Β  Download the APK: latest release


Why it exists

Manually logging every coffee, cab, and grocery run is the reason most expense trackers get abandoned after a week. In India, though, almost every spend already announces itself: a bank SMS ("Rs. 450 debited...") or a UPI app notification from GPay, PhonePe, or Paytm. PayNey Capture listens for exactly those signals, filters out everything that isn't a real transaction, and streams the rest to your PayNey backend β€” so your ledger stays complete with zero effort.


Features

  • Automatic SMS capture β€” Listens for incoming bank/UPI SMS and forwards matching messages to PayNey in the background.
  • Notification capture β€” Reads notifications from allowlisted payment apps (Google Pay, PhonePe, Paytm, CRED) and forwards transaction alerts.
  • Receipt scanning β€” Photograph a paper receipt and the backend extracts the amount, merchant, date, and a suggested category for you to review, edit, and confirm into your PayNey queue.
  • Accurate transaction dates β€” Each capture is stamped with when the event actually happened (SMS delivery time, notification post time), not when it was uploaded β€” so a capture that waited in the offline queue is still dated correctly.
  • Privacy-first allowlisting β€” Only messages from a known list of bank sender IDs and payment-app packages ever leave the device. Arbitrary personal SMS and notifications are silently ignored.
  • Durable offline outbox β€” Captures made while offline (or during a server outage) are queued locally and retried automatically when connectivity returns, so a transaction is never lost.
  • Duplicate suppression β€” Apps that re-post the same notification won't create duplicate captures; repeats within a short window are dropped on-device.
  • Secure device pairing β€” Link the app to your PayNey account with a one-time pairing code from the web app; the resulting device token is kept in encrypted storage.
  • Live status dashboard β€” Permission state, capture on/off, queued-item count, and the time of your last successful sync, all at a glance β€” plus a manual sync button to flush the queue on demand.

How it works

 β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
 β”‚  Bank / UPI SMS     │──────▢ β”‚                      β”‚        β”‚                   β”‚
 β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€        β”‚   PayNey Capture     │──────▢ β”‚   PayNey Backend  β”‚
 β”‚  Payment-app        │──────▢ β”‚   (allowlist +       β”‚  HTTPS β”‚   /api/...        β”‚
 β”‚  notifications      β”‚        β”‚    offline outbox)   β”‚        β”‚                   β”‚
 β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€        β”‚                      β”‚        β”‚   Web expense     β”‚
 β”‚  Scanned receipt    │──────▢ β”‚                      β”‚        β”‚   tracker         β”‚
 β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
  1. Pair the device once using a code from the PayNey web app (POST /api/device/pair β†’ device token).
  2. SmsReceiver and NotificationCaptureService observe incoming events and check each one against AllowList.
  3. Matches are handed to a single CaptureRepository, which posts them to POST /api/transactions/ingest β€” or queues them in the local outbox and retries later if the network is down.
  4. Receipts are uploaded to POST /api/transactions/receipt for field extraction, then confirmed via POST /api/transactions/receipt/confirm.

Backend API

Endpoint Method Purpose
/api/device/pair POST Exchange a pairing code for a device token
/api/transactions/ingest POST Ingest a captured SMS / notification
/api/transactions/receipt POST (multipart) Extract fields from a receipt image
/api/transactions/receipt/confirm POST Persist a reviewed receipt to the review queue

Tech stack

  • Language: Kotlin 2.1
  • UI: Jetpack Compose + Material 3
  • Architecture: MVVM (ViewModel + Compose state), Navigation Compose
  • Networking: Retrofit 2 + OkHttp, kotlinx.serialization JSON
  • Concurrency: Kotlin Coroutines
  • Security: AndroidX Security Crypto (encrypted token storage)
  • Capture: BroadcastReceiver (SMS) + NotificationListenerService
  • Min SDK: 26 (Android 8.0) Β β€’Β  Target/Compile SDK: 36

Download & install

Grab the signed APK from the latest release and install it on any device running Android 8.0 (API 26) or newer. You'll need to allow installs from your browser/file manager the first time, since the app is distributed outside the Play Store.

Release builds always target the deployed backend at payney.vercel.app β€” no configuration required. Just install, open, and pair.


Building from source

Prerequisites

  • Android Studio (latest stable)
  • JDK 17
  • An Android device or emulator running API 26+
  • A running PayNey backend (local or deployed)

Setup

  1. Clone the repo

    git clone https://github.com/othzer/payney-capture.git
    cd payney-capture
  2. Point the app at your backend. Copy the example and edit as needed:

    cp local.properties.example local.properties
    • Emulator (default): no changes needed β€” it uses http://10.0.2.2:3000.
    • Physical device: run adb reverse tcp:3000 tcp:3000 and set PAYNEY_API_BASE_URL=http://127.0.0.1:3000, or point it at your deployed backend URL.
  3. Build & run from Android Studio, or from the command line:

    ./gradlew installDebug

Debug vs. release URLs. Debug builds use PAYNEY_API_BASE_URL (default http://10.0.2.2:3000) so you can develop against a local backend. Release builds ignore that and use PAYNEY_RELEASE_API_BASE_URL (default https://payney.vercel.app) instead, so a distributed APK can never accidentally ship pointing at localhost.

Usage

  1. Open PayNey Capture and enter the pairing code shown in the PayNey web app.
  2. Grant SMS permission and enable Notification access (Settings β†’ Notification access) from the in-app Status screen.
  3. Leave capture on β€” transactions now flow to PayNey automatically.
  4. Tap Scan a receipt to photograph a bill and confirm the extracted details.

Permissions & privacy

PayNey Capture is deliberately conservative about what leaves your device:

Permission Why it's needed
RECEIVE_SMS / READ_SMS Detect incoming bank/UPI transaction SMS
Notification access Read notifications from allowlisted payment apps
CAMERA Photograph receipts for scanning
INTERNET / ACCESS_NETWORK_STATE Send captures and retry the offline queue

Only messages matching the bank sender IDs and payment-app packages defined in AllowList are ever transmitted. Everything else β€” personal texts, unrelated notifications β€” is discarded on-device and never sent anywhere. The device token is kept in encrypted storage, and allowBackup is disabled.


Project structure

app/src/main/java/com/otzrlabs/payney/capture/
β”œβ”€β”€ capture/                    # SMS receiver, notification listener, allowlist
β”‚   β”œβ”€β”€ AllowList.kt
β”‚   β”œβ”€β”€ NotificationCaptureService.kt
β”‚   └── SmsReceiver.kt
β”œβ”€β”€ data/                       # Repository, outbox, prefs, token store
β”‚   β”œβ”€β”€ CaptureRepository.kt
β”‚   β”œβ”€β”€ CaptureOutbox.kt
β”‚   β”œβ”€β”€ CapturePrefs.kt
β”‚   β”œβ”€β”€ TokenStore.kt
β”‚   └── network/                # Retrofit service + models
β”œβ”€β”€ ui/                         # Compose screens (pair, status, scan receipt)
β”‚   β”œβ”€β”€ pair/  status/  receipt/
β”‚   β”œβ”€β”€ brand/  nav/  theme/
└── util/                       # Camera capture helper

🀝 Contributing

Contributions are always welcome.

  1. Star the repository
  2. Fork the repository
  3. Create a feature branch
  4. Commit your changes
  5. Open a Pull Request

⭐ Support

If you found it useful,

please consider giving the repository a ⭐.

It helps more than you think.


License

Proprietary β€” Β© OtzrLabs. All rights reserved.

About

πŸ“² Android companion for PayNey. Automatically captures bank/UPI SMS & payment-app notifications, scans receipts, and syncs every expense to your tracker β€” zero manual entry. Built with Kotlin & Jetpack Compose.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages