Swipe. Match. Order. Pay with Stellar.
Discoverly is a Tinder-style food ordering app where users swipe through food items, match with their cravings, and pay seamlessly using the Stellar blockchain.
Built with:
- ⚛️ Expo (React Native) – Mobile app
- 🟢 Express.js – Backend API
- ⭐ Stellar – On-chain payment processing
- 🍃 MongoDB – Data persistence
Discoverly reimagines food ordering with a swipe-based discovery experience.
Instead of scrolling through long menus:
- Users swipe right to like a dish
- Swipe left to skip
- Matched dishes go into their cart
- Payments are processed via Stellar blockchain
This allows:
- Fast crypto-native checkout
- Low transaction fees
- Borderless payments
- Transparent transaction tracking
discoverly/
│
├── mobile/ → Expo (React Native) app
├── backend/ → Express.js API
├── stellar/ → Stellar payment utilities & services
└── README.md
- Swipe UI (card stack)
- User authentication
- Wallet connection
- Order flow
- Payment confirmation
- Auth & session management
- Restaurant & food listing APIs
- Match & cart management
- Order creation
- Stellar payment verification
- Webhook/event listeners
- Wallet creation (optional custodial)
- Payment intent generation
- Transaction submission
- Transaction verification
- Payment status tracking
- Expo
- React Native
- React Navigation
- Axios
- Zustand (or preferred state manager)
- Node.js
- Express.js
- MongoDB + Mongoose
- Stellar SDK
- JWT Authentication
- Stellar Network
- Stellar SDK (JavaScript)
- Horizon API
- Register / Login
- Swipe-based food discovery
- Add to cart via match
- Checkout with Stellar
- View order history
- Track payment status
- Create food listings
- Manage availability
- Receive on-chain payments
- Create payment request
- User signs transaction
- Submit to Stellar network
- Verify on backend
- Confirm order after verification
import { Horizon, Networks } from "stellar-sdk";
const server = new Horizon.Server("https://horizon-testnet.stellar.org");
const networkPassphrase = Networks.TESTNET; -
User taps Checkout
-
Backend creates a payment intent
-
Backend returns:
- Destination address
- Amount
- Memo (order ID)
-
User signs transaction
-
Transaction submitted to Stellar
-
Backend verifies:
- Transaction hash
- Destination
- Memo
- Amount
-
Order marked as PAID
const tx = await server.transactions().transaction(txHash).call();
if (
tx.memo === orderId &&
tx.successful
) {
// Mark order as paid
}git clone https://github.com/your-username/discoverly.git
cd discoverlycd backend
npm installCreate .env:
PORT=5000
MONGO_URI=
JWT_SECRET=
STELLAR_SECRET_KEY=
STELLAR_NETWORK=testnet
Run:
npm run devcd mobile
npm install
npx expo startUpdate API base URL inside config.
| Variable | Description |
|---|---|
| PORT | API port |
| DATABASE_URL | PostgreSQL connection URL |
| JWT_SECRET | Auth signing secret |
| STELLAR_NETWORK | testnet / public |
| STELLAR_HORIZON_URL | Optional Horizon override |
| STELLAR_DESTINATION_ADDRESS | Merchant receiving wallet |
| PAYMENT_RECONCILIATION_INTERVAL_MS | Reconciliation interval |
| PAYMENT_RECONCILIATION_BATCH_SIZE | Reconciliation batch size |
| PAYMENT_RECONCILIATION_STALE_MS | Reconciliation staleness threshold |
| PAYMENT_LISTENER_INTERVAL_MS | Listener polling interval |
| PAYMENT_LISTENER_BATCH_SIZE | Listener page size |
| STELLAR_PAYMENTS_START_CURSOR | Initial cursor (now recommended) |
| PAYMENT_EVENT_PROCESSOR_INTERVAL_MS | Event worker interval |
| PAYMENT_EVENT_PROCESSOR_BATCH_SIZE | Event worker batch size |
| PAYMENT_EVENT_RETRY_BASE_MS | Retry base delay |
| PAYMENT_EVENT_RETRY_MAX_MS | Retry max delay |
Food cards are fetched from:
GET /api/foods/discover
Swipe Right:
POST /api/match
Creates:
- Match record
- Adds to cart
Swipe Left:
- No persistence (optional tracking)
Swipe → Match → Cart → Checkout → Stellar Payment → Verification → Order Confirmed
Order statuses:
- PENDING
- AWAITING_PAYMENT
- PAID
- PREPARING
- COMPLETED
- CANCELLED
- Never expose server secret key
- Verify all Stellar transactions on backend
- Validate memo & amount
- Use HTTPS in production
- Use rate limiting on payment endpoints
- Consider multi-sig for restaurant wallets (future improvement)
- AWS / Railway / Render / DigitalOcean
- Use production Stellar network
- Secure environment variables
- Deploy the backend with
PAYMENT_PROVIDERremoved and Stellar env vars populated. - Set
STELLAR_NETWORK=testnetand verify one end-to-end payment in staging. - Confirm async processors are running:
- Listener inserts rows into
payment_events - Event processor moves rows to
processed - Reconciliation updates
payment_transactionsfromsubmitted/pendingto terminal status
- Listener inserts rows into
- Run duplicate-event test by posting the same webhook payload twice to
/payments/webhooks/stellar; ensure only one event record is created. - Promote to production by switching
STELLAR_NETWORK=publicand (optionally)STELLAR_HORIZON_URL=https://horizon.stellar.org.
- Pause payment traffic at the API gateway/load balancer.
- Revert the backend deployment to the previous release artifact.
- Keep
payment_transactionsandpayment_eventstables intact for audit continuity. - Re-enable traffic and reconcile any in-flight orders manually from persisted tx hashes.
- Expo EAS build
- App Store / Play Store deployment
- Non-custodial wallet integration
- QR payment support
- Restaurant analytics dashboard
- Stablecoin support (USDC on Stellar)
- Subscription meal plans
- On-chain loyalty points
Use Stellar Testnet:
- Fund accounts via Friendbot
- Switch to PUBLIC only in production
- Fork the repo
- Create feature branch
- Commit changes
- Open PR
Please follow:
- Clean commit messages
- Consistent code style
- Proper API documentation
MIT License
Discoverly combines the addictive swipe UX of modern dating apps with the power of blockchain-based payments to create a frictionless, borderless food discovery experience.
Food meets finance. Discovery meets decentralization.