The first merchant wallet that allows charging with interoperable QR and receiving payments directly in cryptocurrencies
- π― Project Description
- οΏ½οΏ½ Key Features
- ποΈ System Architecture
- π§ Technologies Used
- π¦ Installation and Configuration
- π Complete User Flow
- πΌ Dashboard Overview
- π Wallet Creation with ChipiPay
- π Smart Contracts on Starknet
- π± ARS to USDT Conversion
- π Payment Flow and Percentages
- π API Endpoints
- π Security
- π Database Schema
- π Deployment
MidatoPay is a revolutionary Web3 payment solution designed specifically for Argentine merchants seeking protection from inflation. The platform allows merchants to receive payments in cryptocurrencies (USDT) through interoperable QR codes, while maintaining the simplicity of traditional payments.
- Argentine Inflation: Merchants lose value of their income due to inflation
- Entry Barriers: Existing crypto solutions are complex for traditional merchants
- Interoperability: Lack of interoperable QR standards in the crypto ecosystem
- Currency Conversion: Difficulty converting ARS to crypto efficiently
MidatoPay offers a complete platform that includes:
- ChipiPay Integration: Wallet creation using ChipiPay SDK (wallet creation only)
- Starknet Smart Contracts: Custom payment gateway contracts for transaction processing
- Automatic Wallet: Merchant wallet generation and management
- Interoperable QR Codes: EMVCo TLV standard implementation
- Real-time Price Oracle: ARS β USDT conversion using Starknet Oracle
- Intuitive Dashboard: User-friendly interface with QR generation as the primary feature
- Flexible Conversion: Merchants can choose what percentage of payment to convert to crypto
- Automatic ARS β USDT conversion using Starknet Oracle
- Real-time prices updated every 30 seconds
- Protection of merchant income value
- Flexible conversion percentages (100%, 90%, 80%, 70%)
- Direct integration with Starknet L2
- Fast confirmations (< 2 minutes)
- Minimal gas fees compared to Ethereum
- Custom smart contracts for payment processing
- EMVCo TLV standard implemented
- Compatible with any wallet that supports the standard
- Structured data: merchant address, amount, payment ID
- QR code displayed prominently in dashboard
- Intuitive dashboard with QR generation as the first card
- One-click QR generation
- Easy scanning from any device
- Real-time notifications
- Percentage-based conversion selection
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Frontend (Next.js) β
β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ β
β β Dashboard β β QR Generator β β QR Scanner β β
β β (Intuitive) β β (Primary) β β β β
β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Backend (Node.js/Express) β
β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ β
β β MidatoPay β β Oracle β β Payment β β
β β Service β β Service β β Gateway β β
β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββ΄ββββββββββββββββββββ
βΌ βΌ
ββββββββββββββββ ββββββββββββββββ
β ChipiPay β β Starknet β
β (Wallet β β (Smart β
β Creation) β β Contracts) β
ββββββββββββββββ ββββββββββββββββ
β β
βΌ βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Blockchain (Starknet Sepolia) β
β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ β
β β Oracle β β Payment β β USDT β β
β β Contract β β Gateway β β Token β β
β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Database (PostgreSQL) β
β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ β
β β Users β β Payments β β Transactions β β
β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
- Next.js 14 - React framework with App Router
- TypeScript - Static typing
- Tailwind CSS - Utility-first CSS framework
- Framer Motion - Animations
- React Hook Form - Form handling
- React Hot Toast - Notifications
- ChipiPay SDK - Wallet creation (
@chipi-stack/nextjs)
- Node.js - JavaScript runtime
- Express.js - Web framework
- Prisma - Database ORM
- WebSocket - Real-time communication
- Starkli - CLI for Starknet interactions
- Starknet Sepolia - Test network
- Cairo - Smart contract language
- OpenZeppelin - Contract libraries
- ChipiPay SDK - Wallet creation only (
@chipi-stack/backend)
- PostgreSQL - Relational database
- Prisma Migrate - Schema migrations
- Node.js 18+
- PostgreSQL 15+
- Git
- Starkli CLI
- ChipiPay API credentials
# ChipiPay - Wallet Creation Only
NEXT_PUBLIC_CHIPI_API_KEY=your_chipipay_api_key
NEXT_PUBLIC_CHIPI_SECRET_KEY=your_chipipay_secret_key
# Clerk Authentication
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=your_clerk_publishable_key
# Backend API
NEXT_PUBLIC_API_URL=http://localhost:3001
# Starknet Configuration
NEXT_PUBLIC_STARKNET_RPC_URL=https://starknet-sepolia.public.blastapi.io/rpc/v0_9
NEXT_PUBLIC_USDC_CONTRACT_ADDRESS=0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8
NEXT_PUBLIC_USDT_CONTRACT_ADDRESS=0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c7b7f451cd475# Database
DATABASE_URL=postgresql://user:password@localhost:5432/midatopay
# JWT
JWT_SECRET=your_jwt_secret
# Clerk
CLERK_SECRET_KEY=your_clerk_secret_key
CLERK_WEBHOOK_SECRET=your_webhook_secret
# ChipiPay (for wallet creation)
CHIPI_API_KEY=your_chipipay_api_key
CHIPI_SECRET_KEY=your_chipipay_secret_key
# Starknet
STARKNET_RPC_URL=https://starknet-sepolia.public.blastapi.io/rpc/v0_9
PAYMENT_GATEWAY_ADDRESS=your_payment_gateway_contract_address
ORACLE_CONTRACT_ADDRESS=your_oracle_contract_address- Clone the repository
git clone https://github.com/yourusername/midatopay.git
cd midatopay- Install frontend dependencies
cd frontend
npm install- Install backend dependencies
cd ../backend
npm install- Set up the database
npx prisma migrate dev
npx prisma generate- Start the development servers
# Terminal 1 - Backend
cd backend
npm run dev
# Terminal 2 - Frontend
cd frontend
npm run dev- Landing page with product information
- Call-to-action for registration
- Statistics and key features
- Registration: Email, name, phone, business name
- Login: JWT authentication or Clerk OAuth (Google)
- Roles: MERCHANT, ADMIN
- Onboarding: Business name collection for new users
- ChipiPay Integration: Uses ChipiPay SDK exclusively for wallet creation
- PIN Setup: User creates a 4+ character PIN for wallet encryption
- Automatic Generation: Wallet is created on Starknet Sepolia
- Storage: Wallet address and encrypted private key stored in database
- Note: After wallet creation, all transactions use our custom Starknet contracts
The dashboard is designed to be intuitive with the QR generation as the primary feature:
- Welcome Section: Personalized greeting with merchant name
- Total Balance Card: Shows USDT balance prominently
- QR Generation Card (First Card - Primary Feature):
- Quick access to generate payment QR codes
- One-click QR generation
- Displays current balance
- Wallet Information: ChipiPay wallet status and balance
- Recent Transactions: Transaction history
- Enter Amount: Merchant enters amount in ARS
- Select Conversion Percentage:
- 100%: Entire amount converted to USDT
- 90%: 90% converted to USDT, 10% remains in ARS
- 80%: 80% converted to USDT, 20% remains in ARS
- 70%: 70% converted to USDT, 30% remains in ARS
- Real-time Conversion: System calculates USDT amount based on:
- Oracle exchange rate (ARS β USDT)
- Selected percentage
- Shows remaining ARS amount if percentage < 100%
- Generate QR: Creates interoperable QR code with payment details
- Merchant wallet address (normalized to 66 characters)
- Amount in USDT (after percentage conversion)
- Payment ID (unique identifier)
- EMVCo TLV format for interoperability
- Camera: Automatic QR scanning
- Validation: EMVCo TLV data verification
- Processing: Starknet transaction execution using our custom contracts
- Confirmation: Transaction hash and link to Starkscan
- Status: Pending β Completed
- Hash: Link to blockchain explorer
- Details: Amount, merchant, timestamp
- Actions: Copy hash, scan another QR
The dashboard is the central hub for merchants, designed with simplicity and efficiency in mind:
-
QR Generation Card (Primary - First Card):
- Large, prominent card for quick QR generation
- Shows current USDT balance
- Direct link to create payment QR
- One-click access to payment creation
-
Balance Display:
- Real-time USDT balance from Starknet
- ChipiPay USDC balance (if wallet created)
- Total revenue statistics
-
Wallet Management:
- ChipiPay wallet status
- Wallet address (normalized to 66 characters)
- Balance information
-
Transaction History:
- Recent payments
- Transaction status
- Quick access to details
Dashboard β QR Generation Card β Create Payment β
Select Amount β Choose Percentage β Generate QR β
Display QR β Customer Scans β Transaction Processed
ChipiPay helps us with:
- β Wallet creation on Starknet
- β Wallet integration and setup
- β Initial wallet generation process
After wallet creation, everything else is our own implementation:
- β All payment transactions use our custom Starknet smart contracts
- β Our own payment gateway contract
- β Our own Oracle integration for ARS/USDT conversion
- β Our own QR code generation system
- β Our own transaction processing
- β Our own dashboard and user interface
- User Registration: Merchant registers and logs in
- ChipiPay Integration (Only for wallet creation):
- Frontend uses
@chipi-stack/nextjsSDK - Backend uses
@chipi-stack/backendSDK - ChipiPay handles wallet generation on Starknet
- Frontend uses
- PIN Setup: User creates a PIN (minimum 4 characters)
- Wallet Generation:
- ChipiPay creates wallet on Starknet Sepolia
- Returns wallet address and encrypted private key
- Address is normalized to 66 characters (0x + 64 hex)
- Storage:
- Wallet address saved to database
- Encrypted private key stored securely
- Wallet ready for transactions
- All transactions use our custom Starknet payment gateway contract
- No ChipiPay dependency for transaction processing
- Direct Starknet integration for payment execution
- Our Oracle-based conversion for ARS to USDT
- Our QR code system with EMVCo TLV standard
- Our dashboard with intuitive interface
Starknet addresses must be exactly 66 characters (0x + 64 hexadecimal characters). If a wallet address has fewer characters, it's automatically padded with leading zeros:
Example:
Original: 0x9f87f07fa85eb9ae6d50812ccb8afb389a83cf6bfbe5a5a0fce4da70aad87d (65 chars)
Normalized: 0x009f87f07fa85eb9ae6d50812ccb8afb389a83cf6bfbe5a5a0fce4da70aad87d (66 chars)
After wallet creation with ChipiPay, MidatoPay uses custom smart contracts deployed on Starknet for all payment processing:
#[contract]
mod PaymentGateway {
use starknet::ContractAddress;
use starknet::get_caller_address;
#[storage]
struct Storage {
admin: ContractAddress,
usdt_token: ContractAddress,
oracle: ContractAddress,
}
#[external(v0)]
fn pay(
ref self: ContractState,
merchant_address: ContractAddress,
amount: u256,
token_address: ContractAddress,
payment_id: felt252
) {
// Transfer USDT to merchant using our contract
// Register transaction
// Emit payment event
}
}#[contract]
mod PriceOracle {
use starknet::ContractAddress;
#[storage]
struct Storage {
scale: u256,
price_feed: ContractAddress,
}
#[external(v0)]
fn quote_ars_to_usdt(ref self: ContractState, amount_ars: u256) -> u256 {
// Oracle implementation for ARS β USDT conversion
let scaled_amount = amount_ars * self.scale.read();
// Return USDT amount
}
}- Gas Optimized: Efficient use of storage and compute
- Security: Validations and security checks
- Scalability: Designed for high transaction volume
- Interoperability: Compatible with ERC-20 standards
- Oracle Query: System queries Starknet Oracle contract for current ARS/USDT rate
- Real-time Rate: Oracle provides up-to-date exchange rate
- Percentage Application: Selected percentage (100%, 90%, 80%, 70%) is applied
- Calculation:
USDT Amount = (ARS Amount Γ Exchange Rate) Γ (Percentage / 100) Remaining ARS = ARS Amount Γ (100 - Percentage) / 100 - QR Generation: QR code contains calculated USDT amount
Merchant enters: 10,000 ARS
Oracle rate: 1 USDT = 1,000 ARS
Selected percentage: 90%
Calculation:
- USDT to receive: (10,000 / 1,000) Γ 0.90 = 9 USDT
- Remaining ARS: 10,000 Γ 0.10 = 1,000 ARS
QR contains: 9 USDT payment
- Source: Starknet Oracle contract on Sepolia
- Update Frequency: Every 30 seconds
- Fallback: Default rate if Oracle unavailable
- Margin: 2% safety margin applied
1. Merchant Dashboard
β
2. Click "Generate QR" (First Card)
β
3. Enter Amount in ARS
β
4. Select Conversion Percentage:
- 100%: Full conversion to USDT
- 90%: 90% USDT, 10% ARS
- 80%: 80% USDT, 20% ARS
- 70%: 70% USDT, 30% ARS
β
5. System Calculates:
- USDT amount (based on Oracle rate Γ percentage)
- Remaining ARS (if percentage < 100%)
β
6. Generate QR Code:
- Contains merchant address
- USDT amount (after percentage)
- Payment ID
- EMVCo TLV format
β
7. Customer Scans QR
β
8. Transaction Executed:
- Uses our Starknet payment gateway contract
- Transfers USDT to merchant
- Records transaction
β
9. Confirmation:
- Transaction hash displayed
- Link to Starkscan
- Status updated
The percentage selection is displayed prominently before QR generation:
- Visual Buttons: 100%, 90%, 80%, 70% options
- Real-time Preview: Shows USDT amount and remaining ARS
- Clear Indication: "You will receive X% (Y ARS) of the total amount"
- Default: 100% (full conversion)
POST /api/auth/register
POST /api/auth/login
GET /api/auth/profile
PUT /api/auth/profilePOST /api/chipipay/create-wallet
POST /api/chipipay/save-walletPOST /api/midatopay/generate-qr
POST /api/midatopay/scan-qr
GET /api/midatopay/history/:merchantId
GET /api/midatopay/stats/:merchantIdGET /api/oracle/price/ars-usdt
GET /api/oracle/quote/:amount
GET /api/prices/latest?currency=USDT&baseCurrency=ARSPOST /api/chipipay/transactions
GET /api/chipipay/transactions
GET /api/chipipay/transactions/:txHash- Private Keys: Encrypted with AES-256 (via ChipiPay)
- JWT Tokens: Signed with secure secret
- HTTPS: Encrypted communication
- PIN Protection: User PIN encrypts wallet private key
- Input Validation: Input sanitization
- Rate Limiting: Protection against spam
- CORS: Allowed domains configuration
- Address Normalization: Ensures valid Starknet addresses
- Prisma: ORM with SQL injection protection
- Migrations: Schema version control
- Backups: Automatic backups
- Encrypted Storage: Sensitive data encrypted at rest
-- Users (Merchants)
CREATE TABLE users (
id TEXT PRIMARY KEY,
email TEXT UNIQUE NOT NULL,
password TEXT NOT NULL,
name TEXT NOT NULL,
phone TEXT,
walletAddress TEXT, -- ChipiPay wallet address (normalized)
publicKey TEXT,
privateKey TEXT, -- Encrypted private key
walletCreatedAt TIMESTAMP,
clerkId TEXT, -- For Clerk OAuth users
role TEXT DEFAULT 'MERCHANT',
isActive BOOLEAN DEFAULT true,
createdAt TIMESTAMP DEFAULT NOW(),
updatedAt TIMESTAMP DEFAULT NOW()
);
-- Payments
CREATE TABLE payments (
id TEXT PRIMARY KEY,
amount DECIMAL(18,8) NOT NULL,
currency TEXT DEFAULT 'ARS',
concept TEXT,
orderId TEXT UNIQUE NOT NULL,
status TEXT DEFAULT 'PENDING',
qrCode TEXT UNIQUE NOT NULL,
expiresAt TIMESTAMP NOT NULL,
userId TEXT REFERENCES users(id),
createdAt TIMESTAMP DEFAULT NOW(),
updatedAt TIMESTAMP DEFAULT NOW()
);
-- ChipiPay Transactions
CREATE TABLE chipi_pay_transactions (
id TEXT PRIMARY KEY,
sessionId TEXT,
amountARS DECIMAL(18,8),
amountUSDC DECIMAL(18,8),
txHash TEXT UNIQUE,
fromAddress TEXT,
toAddress TEXT,
status TEXT DEFAULT 'pending',
userId TEXT REFERENCES users(id),
createdAt TIMESTAMP DEFAULT NOW()
);
-- Price Oracle
CREATE TABLE price_oracle (
id TEXT PRIMARY KEY,
currency TEXT NOT NULL,
baseCurrency TEXT NOT NULL,
price DECIMAL(18,8) NOT NULL,
source TEXT DEFAULT 'STARKNET_ORACLE',
timestamp TIMESTAMP DEFAULT NOW()
);- Build the application:
cd frontend
npm run build- Set environment variables in deployment platform
- Deploy to Vercel or Netlify
- Set up PostgreSQL database (AWS RDS, Heroku, etc.)
- Run migrations:
cd backend
npx prisma migrate deploy- Deploy to platform (Heroku, Railway, AWS, etc.)
- Set environment variables
- Compile contracts:
cd cairo-contracts
scarb build- Deploy to Starknet Sepolia:
starkli deploy payment_gateway.sierra.json --account your_account
starkli deploy oracle.sierra.json --account your_account- Update contract addresses in backend
.env
-
Hybrid Approach:
- Uses ChipiPay only for wallet creation and integration (simplifies onboarding)
- Everything else is our own implementation:
- Custom Starknet contracts for transactions (full control)
- Our own Oracle integration
- Our own payment processing system
- Our own QR code generation
-
Inflation Protection:
- Real-time ARS to USDT conversion
- Flexible percentage selection (merchants choose conversion rate)
-
User Experience:
- Intuitive dashboard with QR generation as primary feature
- One-click payment creation
- Simple percentage selection
-
Starknet Integration:
- Custom smart contracts for payment processing
- Oracle-based price conversion
- Gas-efficient transactions
-
Interoperability:
- EMVCo TLV standard QR codes
- Compatible with any wallet supporting the standard
- Address Normalization: Ensures all Starknet addresses are 66 characters
- Real-time Oracle: Updates every 30 seconds
- Percentage-based Conversion: Merchants control how much to convert
- Secure Storage: Encrypted private keys
- Scalable Architecture: Ready for production deployment
π MidatoPay - Protecting merchants from inflation with Web3 technology
Built with β€οΈ for the Starknet Hackathon