Skip to content
jny0444Public

About

BLE based UPI payments

Resources

Stars

2 stars

Watchers

0 watching

Forks

Repository files navigation

dPika logo

dPika

Share a UPI payment link over Bluetooth Low Energy.
No QR codes. No phone numbers. Just discover a nearby device and receive their upi:// URI.

dPika does not process payments — it only transfers a UPI URI over BLE.
Any actual payment happens in your UPI app (GPay, PhonePe, Paytm, etc.).

GitHub


What is dPika?

dPika is a cross-platform desktop and mobile app that transfers a UPI URI over Bluetooth Low Energy (BLE) — nothing more. It replaces scanning a QR code or manually sharing a payment link when two devices are nearby.

What dPika does:

  • Receive mode — broadcast your upi://pay?pa=... URI to nearby devices over BLE
  • Send mode — discover nearby receivers, read their UPI URI over BLE, then optionally hand it off to your UPI app

What dPika does not do:

  • Move money or initiate transactions
  • Talk to banks, PSPs, or NPCI
  • Store balances, PINs, or payment credentials

The BLE link carries a plain-text UPI deep link. If the sender chooses to pay, they complete the transaction entirely inside their own UPI app after dPika opens the URI.

How it works

Receive flow

sequenceDiagram
    participant User as Receiver
    participant App as dPika (Receive)
    participant BLE as BLE Peripheral
    participant Sender as dPika (Send)

    User->>App: Enter UPI ID or scan QR
    App->>App: Build upi://pay?pa=... URI
    App->>BLE: Start GATT advertising
    Note over BLE: Advertises custom UPI service UUID<br/>with payee name in local name

    Sender->>BLE: Scan for UPI service
    BLE-->>Sender: Device discovered
    Sender->>BLE: Connect & read characteristic
    BLE-->>Sender: Return UPI URI (text only)
    Sender->>Sender: Confirm payee / URI
    Note over Sender: Optional — opens UPI app<br/>Payment happens outside dPika
Loading

Send flow

sequenceDiagram
    participant User as Sender
    participant App as dPika (Send)
    participant Rust as Tauri / Rust BLE
    participant Peer as Nearby Receiver

    User->>App: Switch to Send mode
    loop Every ~4s
        App->>Rust: discover_nearby_devices
        Rust->>Peer: BLE scan (filter by service UUID)
        Peer-->>Rust: Matching peripherals
        Rust-->>App: Device list (name / UPI ID)
    end

    User->>App: Select a device
    App->>Rust: connect_and_read_upi
    Rust->>Peer: GATT connect → read UPI characteristic
    Peer-->>Rust: upi://pay?pa=...
    Rust-->>App: UPI URI (text only)
    App->>User: Show received URI / payee
    User->>App: Confirm handoff
    App->>App: Open UPI app with URI
    Note over App: No payment in dPika —<br/>user pays in UPI app if they choose
Loading

Architecture

flowchart TB
    subgraph UI["React UI (TypeScript)"]
        Setup[UPI setup / QR scan]
        Send[Send — device scan]
        Receive[Receive — broadcast panel]
        Confirm[URI confirmation & handoff]
    end

    subgraph Tauri["Tauri bridge"]
        IPC[invoke / commands]
    end

    subgraph Rust["Rust BLE layer"]
        Central[central.rs — btleplug]
        Peripheral[peripheral.rs — ble-peripheral-rust]
    end

    subgraph Protocol["Custom GATT service"]
        Svc["UPI Service UUID"]
        Char["UPI Characteristic UUID<br/>payload: upi://pay?pa=..."]
    end

    Setup --> IPC
    Send --> IPC
    Receive --> IPC
    Confirm --> IPC

    IPC --> Central
    IPC --> Peripheral

    Central -->|scan, connect, read| Svc
    Peripheral -->|advertise, respond to read| Svc
    Svc --> Char
Loading

BLE protocol

dPika uses a private GATT service to carry a standard UPI deep link as a UTF-8 string. No payment data, tokens, or transaction state crosses the BLE link — only the URI.

Item Value
Service UUID 12345678-1234-5678-1234-567812345678
Characteristic UUID abcdef01-abcd-ef01-abcd-abcdef01abcd
Payload UTF-8 upi://pay?pa=<payee>@<psp>

The receiver advertises with their UPI ID as the local BLE name when possible, so senders see a recognizable label in the device list.

Tech stack

Layer Stack
UI React 19, TypeScript, Vite, GSAP
Shell Tauri 2
BLE central (scan / read) btleplug
BLE peripheral (advertise) ble-peripheral-rust (vendored)

Getting started

Prerequisites

  • Bun (package manager — used by Tauri config)
  • Rust (stable)
  • Tauri prerequisites for your OS (Xcode on macOS/iOS, etc.)
  • Bluetooth adapter with BLE support

Development

# Install frontend dependencies
bun install

# Run the app in dev mode (Vite + Tauri)
bun run tauri dev

Production build

bun run tauri build

Artifacts are written under src-tauri/target/release/bundle/.

Project layout

dpika/
├── src/                    # React frontend
│   ├── components/         # UI (send scan, receive, setup, sheets)
│   └── lib/                # UPI parsing, local storage, GSAP helpers
├── src-tauri/
│   ├── src/
│   │   ├── lib.rs          # Tauri entry & command registration
│   │   └── transport/      # BLE central + peripheral implementations
│   └── icons/              # App icon (also used in this README)
└── public/

Platform notes

  • macOS / Windows / Linux — desktop builds via Tauri; BLE central and peripheral roles are supported where the OS allows.
  • iOS — Xcode project is generated under src-tauri/gen/apple/; BLE permissions and entitlements apply.
  • Bluetooth must be enabled, and both devices need to be within BLE range (~10 m unobstructed).

Security & privacy

  • No payments in dPika — the app only reads or writes a upi://pay URI over BLE. Money never flows through dPika.
  • URI transfer only — the BLE payload is a plain UPI deep link string, not a transaction, token, or bank message.
  • No backend — nothing is sent to a dPika server; data stays on-device and over the local Bluetooth link.
  • Always verify the payee UPI ID on the confirmation sheet before handing the URI to your UPI app.

License

See repository license file. Third-party ble-peripheral-rust is MIT licensed.

About

BLE based UPI payments

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages