Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 154 additions & 0 deletions submissions/team7_airpay/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
# airpay

**GSM-assisted offline payment infrastructure for Android.**
Built for the dead zones — no internet, no problem.

---

## Overview

airpay is a native Android application that rethinks the payment flow for environments where internet connectivity is unreliable or entirely absent. Instead of depending on data networks, airpay routes payment interactions through the GSM layer — the same infrastructure your carrier uses for voice and SMS — enabling users to complete transactions from virtually anywhere a cellular signal exists.

The project targets a real and underserved gap: hundreds of millions of users in India and emerging markets face dropped connections, high-latency networks, and intermittent data coverage daily. airpay treats offline-first as a hard constraint, not an afterthought.

---

## Team

**Team 7**

| Name | Role | GitHub |
|------|------|--------|
| Chirag Gupta | Developer | [@cgchiraggupta](https://github.com/cgchiraggupta) |
| Sparshika | Team Member | — |
| Meet Khurana | Team Member | — |

---

## Problem

Standard UPI and digital payment flows assume a stable data connection. When that connection degrades — patchy 2G, network congestion, rural dead zones — the entire payment stack fails. Users are left with no fallback, no feedback, and no transaction.

The infrastructure to solve this already exists in every device: GSM. airpay leverages it.

---

## Solution

airpay wraps a guided, minimal mobile interface around a GSM-assisted payment flow. The user experience is deliberately stripped down to reduce failure points. Payment information is reviewed on-device, the interaction is routed through the GSM channel, and the user receives confirmation — all without touching a data packet.

The frontend is engineered for low-cognitive-load operation: large tap targets, clear state transitions, and no dependency on real-time API calls for core payment steps.

---

## Tech Stack

| Layer | Technology |
|-------|------------|
| Platform | Android (native) |
| Language | Kotlin |
| Payment Transport | GSM-assisted flow |
| Frontend Reference | Web (hosted on Vercel) |

---

## Architecture

```
User Device
├── airpay Android App (Kotlin)
│ ├── Payment UI Layer ← guided screens, minimal state
│ ├── Input Validation ← on-device, no network required
│ └── GSM Interaction Module ← routes payment through carrier layer
└── GSM Network (carrier infrastructure)
└── Payment Processing
```

The GSM interaction module handles the transport layer entirely. No REST calls. No WebSocket. No dependency on the user's data plan.

---

## Payment Flow

```
1. Launch airpay
2. Enter payment details
(validated on-device)
3. Review transaction screen
4. Initiate GSM-assisted flow
5. Carrier routes interaction
6. Confirmation returned to device
```

---

## Links

| Resource | URL |
|----------|-----|
| Live Demo | [airpaywebsite.vercel.app/about](https://airpaywebsite.vercel.app/about) |
| Video Demo | [YouTube Shorts](https://youtube.com/shorts/viAPPQx1r9U?si=aYHEXjK7b6zZsqi7) |
| Presentation | [Google Drive](https://drive.google.com/file/d/1iFc6vUQjXlpI-kgZgBZYivRLXWyG0q9p/view?usp=sharing) |

---

## Screenshots

<p float="left">
<img src="./screenshots/airpay-1.jpeg" width="30%" />
<img src="./screenshots/airpay-2.jpeg" width="30%" />
<img src="./screenshots/airpay-3.jpeg" width="30%" />
</p>

---

## Running Locally

Demo assets, APK builds, and additional technical documentation are available through the links listed above.

Frontend reference files are located in the `app/` directory. These correspond to the public-facing website and can be served locally with any static file server:

```bash
cd app/
npx serve .
# or
python3 -m http.server 8080
```

For the Android application, build requirements and setup instructions will be published in a follow-up release.

---

## Why GSM

| Factor | Data-dependent apps | airpay |
|--------|---------------------|--------|
| Requires internet | Yes | No |
| Works on 2G | Partial | Yes |
| Works with zero data | No | Yes |
| Rural coverage | Poor | GSM coverage |
| Failure mode | Silent / timeout | Defined fallback |

GSM infrastructure in India covers regions where 4G and even 3G are inconsistent. By treating the carrier layer as the transport rather than IP networking, airpay inherits decades of telecom reliability.

---

## Status

Hackathon build. Core payment flow implemented. Active development ongoing.

---

*Built at [Hackathon Name] · Team 7*
16 changes: 16 additions & 0 deletions submissions/team7_airpay/app/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<!doctype html>
<html lang="en">

<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0, user-scalable=yes" />
<meta name="description" content="AirPay UPI - Offline-first payment platform bridging modern UPI with legacy GSM signaling" />
<title>AirPay UPI | Offline Payment Protocol</title>
</head>

<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>

</html>
39 changes: 39 additions & 0 deletions submissions/team7_airpay/app/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"name": "react-example",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite --port=3000 --host=0.0.0.0",
"build": "vite build",
"preview": "vite preview",
"clean": "rm -rf dist",
"lint": "tsc --noEmit"
},
"dependencies": {
"@google/genai": "^1.29.0",
"@tailwindcss/vite": "^4.1.14",
"@vitejs/plugin-react": "^5.0.4",
"clsx": "^2.1.1",
"dotenv": "^17.2.3",
"express": "^4.21.2",
"lenis": "^1.3.19",
"lucide-react": "^0.546.0",
"motion": "^12.23.24",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react-router-dom": "^7.13.2",
"recharts": "^3.8.0",
"tailwind-merge": "^3.5.0",
"vite": "^6.2.0"
},
"devDependencies": {
"@types/express": "^4.17.21",
"@types/node": "^22.14.0",
"autoprefixer": "^10.4.21",
"tailwindcss": "^4.1.14",
"tsx": "^4.21.0",
"typescript": "~5.8.2",
"vite": "^6.2.0"
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
78 changes: 78 additions & 0 deletions submissions/team7_airpay/app/src/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { BrowserRouter as Router, Routes, Route, Link, useLocation } from 'react-router-dom';
import { useEffect } from 'react';
import Lenis from 'lenis';
import { HeroSection } from './components/HeroSection';
import { FeaturesSection } from './components/FeaturesSection';
import { DownloadSection } from './components/DownloadSection';
import { HowToUseSection } from './components/HowToUseSection';
import { ContactSection } from './components/ContactSection';
import { Footer } from './components/Footer';
import { AboutPage } from './pages/AboutPage';

// This component can use useLocation because it's inside Router
function AppContent() {
const location = useLocation();
const showAboutButton = location.pathname === '/';

useEffect(() => {
const lenis = new Lenis({
duration: 1.2,
easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)),
orientation: 'vertical',
gestureOrientation: 'vertical',
smoothWheel: true,
wheelMultiplier: 1,
touchMultiplier: 2,
});

function raf(time: number) {
lenis.raf(time);
requestAnimationFrame(raf);
}

requestAnimationFrame(raf);

return () => {
lenis.destroy();
};
}, []);

return (
<main className="bg-background text-text-primary min-h-screen font-mono selection:bg-accent selection:text-background">
{/* Show button only on home page */}
{showAboutButton && (
<div className="fixed top-6 right-6 z-50">
<Link
to="/about"
className="px-4 py-2 text-sm font-mono border border-divider rounded-full text-text-secondary hover:text-text-primary hover:border-flow-shell-start/30 transition-all duration-300 backdrop-blur-sm bg-surface/30"
>
About
</Link>
</div>
)}

<Routes>
<Route path="/" element={
<>
<HeroSection />
<FeaturesSection />
<DownloadSection />
<HowToUseSection />
<ContactSection />
<Footer />
</>
} />
<Route path="/about" element={<AboutPage />} />
</Routes>
</main>
);
}

// Main App component just wraps everything with Router
export default function App() {
return (
<Router>
<AppContent />
</Router>
);
}
Loading