A modern creator monetization platform for receiving tips, setting fundraising goals, and managing withdrawals seamlessly.
- ✅ Custom Profile Pages - Personalized pages with your username (e.g.,
tipcup.adedeji.xyz/yourname) - ✅ Fundraising Goals - Set and track progress toward financial goals
- ✅ Multiple Support Tiers - Create custom tip amounts with emojis and descriptions
- ✅ Bank Account Management - Add multiple bank accounts, set primary accounts
- ✅ Automated Withdrawals - Instant withdrawals to Nigerian bank accounts via Flutterwave
- ✅ Earnings Dashboard - Track total earnings, current balance, and transaction history
- ✅ Withdrawal History - Complete audit trail of all payouts
- ✅ Quick & Easy Payments - Support creators with just a few clicks
- ✅ Secure Transactions - Powered by Flutterwave's secure payment gateway
- ✅ Custom Messages - Send personalized messages with your tips
- ✅ Goal Contributions - Help creators reach their fundraising goals
- Nuxt 4 - The Intuitive Vue Framework
- Vue 3 - Composition API with
<script setup> - Tailwind CSS - Utility-first CSS framework
- Headless UI - Unstyled, accessible UI components
- Chart.js - Beautiful charts for analytics
- Lucide Icons - Clean, customizable icons
- Firebase Auth - User authentication
- Firestore - Real-time NoSQL database
- Firebase Admin SDK - Server-side operations
- Flutterwave - Payment gateway and transfers
- Payment initialization & verification
- Bank account resolution
- Automated transfers/withdrawals
- Webhook handling
Before you begin, ensure you have:
- Node.js (v18 or higher)
- npm or yarn
- Firebase Project (Create one here)
- Flutterwave Account (Sign up here)
git clone https://github.com/devadedeji/tipcup.git
cd tipcupnpm install
# or
yarn installCreate a .env file in the root directory:
# Firebase Configuration
FIREBASE_API_KEY=your_firebase_api_key
FIREBASE_AUTH_DOMAIN=your_project.firebaseapp.com
FIREBASE_PROJECT_ID=your_project_id
FIREBASE_STORAGE_BUCKET=your_project.appspot.com
FIREBASE_MESSAGING_SENDER_ID=your_sender_id
FIREBASE_APP_ID=your_app_id
# Firebase Admin SDK (Server-side)
FIREBASE_SERVICE_ACCOUNT={"type":"service_account","project_id":"..."}
# Flutterwave
FLUTTERWAVE_SECRET_KEY=your_flutterwave_secret_key
FLUTTERWAVE_SECRET_HASH=your_webhook_secret_hash📘 Note: Get your Firebase Service Account JSON from Firebase Console → Project Settings → Service Accounts → Generate New Private Key
Copy the security rules from firestore_rules.md artifact and apply them in Firebase Console:
- Go to Firestore Database → Rules
- Paste the rules
- Publish
Create a composite index for payments:
- Collection:
payments - Fields:
toUserId(Ascending),createdAt(Descending)
Create a composite index for withdrawals:
- Collection:
withdrawals - Fields:
userId(Ascending),createdAt(Descending)
npm run devVisit http://localhost:4444 🎉
npm run buildnpm run preview- Push your code to GitHub
- Import project on Vercel
- Add environment variables in Vercel dashboard
- Deploy! 🚀
tipcup/
├── app/
│ ├── components/
│ │ ├── dashboard/ # Dashboard-specific components
│ │ │ ├── BankModal.vue
│ │ │ ├── GoalModal.vue
│ │ │ ├── WithdrawalModal.vue
│ │ │ └── ...
│ │ └── ui/ # Reusable UI components
│ │ ├── Button.vue
│ │ ├── Input.vue
│ │ ├── Select.vue
│ │ ├── Table.vue
│ │ └── ...
│ ├── composables/ # Vue composables
│ │ ├── useAuth.ts
│ │ ├── useBankDetails.ts
│ │ ├── usePayments.ts
│ │ └── useWithdrawals.ts
│ ├── layouts/ # App layouts
│ │ ├── default.vue
│ │ └── dashboard.vue
│ ├── pages/ # File-based routing
│ │ ├── [username].vue # Creator profile page
│ │ ├── dashboard/
│ │ │ ├── index.vue
│ │ │ └── earnings.vue
│ │ ├── login.vue
│ │ ├── signup.vue
│ │ └── onboarding.vue
│ └── utils/ # Utility functions
│ ├── format.ts
│ └── cn.ts
├── server/
│ ├── api/
│ │ └── flutterwave/ # Flutterwave API endpoints
│ │ ├── banks.get.ts
│ │ ├── initialize.post.ts
│ │ ├── verify.post.ts
│ │ ├── resolve-account.post.ts
│ │ ├── withdraw.post.ts
│ │ └── webhook.post.ts
│ └── utils/
│ ├── admin.ts # Firebase Admin SDK
│ └── flutterwave.ts # Flutterwave utilities
├── public/ # Static assets
├── firebase.ts # Firebase client config
└── nuxt.config.ts # Nuxt configuration
User clicks "Support" → Flutterwave Checkout → Payment Success →
Webhook updates Firestore → Dashboard shows transaction
Creator requests withdrawal → Backend validates balance →
Flutterwave transfers to bank → Withdrawal record created →
Balance updated
- Uses Flutterwave's account resolution API
- Verifies account number and bank code
- Returns account holder name for confirmation
- Test Mode: Only Access Bank (044) supported with test keys
- Bank: Access Bank
- Bank Code: 044
- Account Number: 0690000031
- Account Name: Pastor Bright
⚠️ Important: Flutterwave test environment only allows bank code044for account resolution. Use production keys to test with all banks.
- ✅ Webhook signature verification implemented
- ✅ Firestore security rules enforce user permissions
- ✅ Server-side validation for all transactions
- ✅ Firebase Admin SDK used for privileged operations
- ✅ Environment variables for sensitive credentials
- ✅ Debounced search in Select component (150ms)
- ✅ Limited render for large option lists (max 100 items)
- ✅ Real-time listeners for payments and withdrawals
- ✅ Paginated tables for transaction history
- ✅ Lazy-loaded components where applicable
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the project
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
This project is licensed under the MIT License.