Sitemap

Documenting My Journey in Building an Offline Payment System

4 min readSep 8, 2026

--

I wanted to take a moment to reflect on my journey in developing an offline payment system and the lessons I’ve learned along the way.

Project Inspiration

My project was inspired by a 3-week internship at a fintech-focused company, where I learned Spring Boot. This immersive experience sparked my desire to create something meaningful.

During this time, I came across posts by Ram Rastogi on the evolving fintech ecosystem. One post, The Next UPI Movement, particularly caught my attention and pushed me to explore what an offline payment system could look like.

The Concept

I decided to explore the development of an offline payment system, which required deeper research into key technologies, including UPI Lite X, digital e-rupee, and UPI123PAY. Here’s a brief overview:

• UPI Lite X: Enables offline payments using a pre-loaded UPI Lite balance, with NFC-based communication allowing supported devices to transact when they are in proximity.

• UPI123PAY: Enables UPI payments on feature phones without requiring a smartphone or mobile data, using channels such as IVR and other assisted modes.

• Digital rupee (e₹): India’s central bank digital currency, issued by the Reserve Bank of India.

The Solution

This offline payment mechanism uses a JWT-based offline spending token signed with a shared secret (HS512). Funds are never moved offline, and the user’s available balance is reserved when the token is issued and deducted only when transactions settle. This keeps funds within the banking system and gives banks visibility and control over every transaction. A separate RS256 key pair is used for session authentication at the API Gateway.

Implementation Strategy

The planned merchant acceptance flow supports three methods: QR Code, NFC, and Bluetooth. The planned flow is for the merchant application to verify the signed payment proof and return a confirmation.

Note: The backend for issuance, settlement, and fraud is implemented and tested end-to-end, while the merchant-facing apps (QR/NFC/Bluetooth) are the upcoming stage of the build.

Get Diyarjoshy’s stories in your inbox

Join Medium for free to get updates from this writer.

Technologies such as Kafka and Redis are critical in this process. Kafka channels transactions for asynchronous processing and batching through the synchronization service, while Redis is used for idempotency checks to prevent duplicate settlement attempts.

Mitigating Risks

Given that the merchant does not receive actual money immediately, I considered potential risks related to this model:

  1. The risk of the payer attempting fraud by reusing the same token multiple times.
  2. Possible technical glitches during payment processing.

The system addresses these concerns by retaining failed synchronization transactions as “received” but “not settled”, allowing them to be retried in the next batch. Additionally, the user’s funds are reserved (with a per-user cap of ₹500) before any offline spending is allowed, instead of being moved. Fraud is assessed automatically through rule-based scoring before settlement, while flagged cases can be reviewed manually through a human-in-the-loop process rather than blocking every payment.

Microservices Architecture

The project is organized around five microservices:

  1. Fraud Service: Performs rule-based risk scoring using transaction velocity, transfer-time patterns, amount, token reuse, and temporal impossibility. The check occurs when the user comes back online, before settlement.
  2. Sync Service: Tracks offline transactions and pushes them to Kafka for settlement, configured to batch up to 100 transactions every 30 seconds and process them in chunks of 50. It also involves a call to the Ledger service for transferring money and to the Fraud service for detecting fraud.
  3. Token Service: Generates signed JWT-based offline spending authorizations for users within a predefined cap (say ₹500). The token contains information such as the user ID, reservation ID, expiry time, and maximum authorized amount.
  4. Ledger: Handles the actual movement of funds during settlement. The user’s reserved amount is deducted from the account here, ensuring transactional integrity and rollback in case of errors. It effectively acts as the reservation and settlement engine. Using @Transactional ensures that operations within the database transaction are committed atomically or rolled back if an error occurs.
  5. API Gateway: Serves as the entry point for all services, managing HTTP requests, authentication, and rate limiting. It validates each caller’s session JWT (RS256) by verifying its signature with the public key.

Conclusion

While this offline payment system presents an innovative approach, it does encounter challenges, particularly the double-spending issue, where a payer might attempt to use the same token across multiple transactions. This risk is mitigated through signed, constrained spending authorizations, Redis-backed idempotency checks, and a per-user reservation cap.

The system does not claim to eliminate offline double-spending at the device level; instead, it limits financial exposure and detects replay or suspicious activity during synchronization and settlement.

Overall, this project has enhanced my understanding of various fintech solutions and the intricacies of offline payment processing. This was indeed a fun ride!

--

--