# WhatsApp Integration & Payment Reminders - Usage Guide ## 🚀 Quick Start ### 1. Install Dependencies ```bash cd backend npm install ``` This installs: - `node-cron@^3.0.3` - Scheduled reminders - `moment-timezone@^0.5.43` - Date/time handling ### 2. Start Server ```bash npm run dev ``` You should see: ``` ⏰ Starting payment reminder scheduler... Payment reminder scheduler started (9:00 AM IST daily) 🚀 Server running on port 3000 📱 WhatsApp share: http://localhost:3000/api/share 🔔 Notifications: http://localhost:3000/api/notifications ``` --- ## 📱 **How to Use WhatsApp Sharing** ### Example 1: Share Payment Receipt (After Payment) **Scenario:** Member just made a payment, wants to share receipt #### Backend: ```javascript // In your payment controller, after recording payment const payment = await Payment.create({...}); // Send notification to member const WhatsAppHelper = require('../utils/whatsapp-helper'); const message = WhatsAppHelper.generatePaymentReceipt( payment, group, member ); await Notification.create({ type: 'payment_confirmation', user_id: member.id, group_id: group.id, payment_id: payment.id, channel: 'whatsapp', message: message, status: 'sent' }); ``` #### Flutter: ```dart // In payment success dialog import '../../core/utils/whatsapp_util.dart'; import '../../shared/widgets/payment_success_dialog.dart'; // After payment recorded PaymentSuccessDialog.show( context, paymentId: payment.id, amount: 5000, groupName: 'Family Chit Fund', transactionId: 'TXN123456', paymentDate: DateTime.now(), paymentMethod: 'UPI', ); // Or manually trigger share await WhatsAppUtil.sharePaymentReceipt(paymentId); ``` --- ### Example 2: Share Draw Result (After Draw Completion) **Scenario:** Manager completed a draw, wants to announce winner #### Backend: ```javascript // After draw completion const draw = await MonthlyDraw.create({...}); // Generate share link const message = WhatsAppHelper.generateDrawResult( group, winner, prizeAmount, month, totalMembers ); const whatsappUrl = WhatsAppHelper.generateShareLink( winner.mobile_number, message ); // Send to winner await Notification.create({ type: 'draw_result', user_id: winner.id, group_id: group.id, draw_id: draw.id, channel: 'whatsapp', message: message, status: 'sent' }); ``` #### Flutter: ```dart // In draw results screen import '../../core/utils/whatsapp_util.dart'; import '../../shared/widgets/whatsapp_share_button.dart'; // After draw completion WhatsAppShareButton( label: 'Share Results', onPressed: () async { await WhatsAppUtil.shareDrawResult(draw.id); }, ) // Or open share options sheet WhatsAppShareSheet.show( context, [ WhatsAppShareOption( title: 'Share with Winner', icon: Icons.emoji_events, color: Colors.green.shade600, onTap: () => WhatsAppUtil.shareDrawResult(draw.id), ), WhatsAppShareOption( title: 'Share with All Members', icon: Icons.group, color: Colors.blue.shade600, onTap: () => shareWithAllMembers(), ), ], ); ``` --- ### Example 3: Invite New Member **Scenario:** Manager wants to invite someone to join group #### Backend API Call: ```bash POST /api/share/group-invite Authorization: Bearer { "groupId": "group-uuid", "recipientPhone": "9876543210" } ``` #### Flutter: ```dart // In group details page or add member dialog TextFormField( controller: phoneController, decoration: InputDecoration(labelText: 'Phone Number'), ) WhatsAppShareButton( label: 'Send Invitation', onPressed: () async { await WhatsAppUtil.shareGroupInvite( groupId, phoneController.text, ); }, ) ``` --- ### Example 4: Manual Payment Reminder **Scenario:** Manager wants to remind specific member #### Flutter: ```dart // In member list, add action button IconButton( icon: Icon(Icons.whatsapp, color: Color(0xFF25D366)), onPressed: () async { await WhatsAppUtil.sendPaymentReminder(groupId, memberId); }, tooltip: 'Send WhatsApp Reminder', ) ``` --- ### Example 5: Bulk Reminders **Scenario:** Manager wants to remind all unpaid members #### Flutter: ```dart // In group details page ElevatedButton.icon( icon: Icon(Icons.send_rounded), label: Text('Send Reminders to All'), onPressed: () async { final result = await WhatsAppUtil.sendBulkReminders(groupId); if (result != null) { final count = result['total_reminders']; showDialog( context: context, builder: (context) => AlertDialog( title: Text('$count Reminders Generated'), content: Text('Open WhatsApp for each member?'), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: Text('Later'), ), ElevatedButton( onPressed: () { Navigator.pop(context); // Open each WhatsApp link // (User will need to manually send each) }, child: Text('Yes, Open'), ), ], ), ); } }, ) ``` --- ## ⏰ **Payment Reminder Schedule** ### Automatic Reminders: The system automatically sends reminders at: | Days Before/After Due | Type | Urgency | |----------------------|------|---------| | 7 days before | Upcoming payment | ⏰ Low | | 3 days before | Payment due soon | ⏰ Medium | | 1 day before | Payment due tomorrow | ⚠️ High | | 0 (On due date) | Payment due today | ⚠️ High | | 1 day overdue | Payment overdue | 🚨 Urgent | | 3 days overdue | Still overdue | 🚨 Urgent | | 7 days overdue | Seriously overdue | 🚨 Critical | | 14 days overdue | Very seriously overdue | 🚨 Critical | | 30 days overdue | Final reminder | 🚨 Critical | ### Reminder Logic: ``` For each active group: Calculate current month Calculate due date (start_date + months + draw_date) Get days until due If (days until due) in [7, 3, 1, 0]: For each member who hasn't paid: Create reminder notification Log in database If overdue (days < 0): If days overdue in [1, 3, 7, 14, 30]: For each member who hasn't paid: Create URGENT reminder Log in database ``` --- ## 📊 **Notification Types** ### Payment Related: - `payment_reminder` - Regular reminder (7, 3, 1, 0 days before) - `payment_overdue` - Overdue payment (1, 3, 7, 14, 30 days after) - `payment_confirmation` - Payment received successfully ### Draw Related: - `draw_result` - Draw completed, winner announced ### Member Related: - `member_joined` - New member added to group - `member_removed` - Member removed from group - `welcome_message` - Welcome new member ### Group Related: - `group_invite` - Invitation to join group - `group_started` - Group moved from forming to active - `group_completed` - Group completed all months ### System: - `manager_notification` - Important manager notifications - `system_alert` - Critical system alerts --- ## 🧪 **Testing Guide** ### Test 1: Manual Reminder Trigger ```bash # Create test script: backend/test-reminders.js const ReminderService = require('./src/services/reminder-service'); (async () => { console.log('Testing manual reminders...'); const result = await ReminderService.triggerManualReminders(); console.log(`Sent ${result} reminders`); process.exit(0); })(); # Run it: node test-reminders.js ``` ### Test 2: Share Payment Receipt ```bash curl -X POST http://localhost:3000/api/share/payment-receipt \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{"paymentId": "your-payment-id"}' ``` ### Test 3: Get Notifications ```bash curl -X GET http://localhost:3000/api/notifications \ -H "Authorization: Bearer YOUR_TOKEN" ``` ### Test 4: Get Unread Count ```bash curl -X GET http://localhost:3000/api/notifications/unread-count \ -H "Authorization: Bearer YOUR_TOKEN" ``` --- ## 📱 **Flutter Integration Examples** ### Add to Payment Recording Dialog ```dart // After payment is recorded successfully final payment = await recordPayment(...); if (payment != null) { // Show success dialog with WhatsApp share await PaymentSuccessDialog.show( context, paymentId: payment.id, amount: payment.amount, groupName: group.name, transactionId: payment.transactionId, paymentDate: payment.paymentDate, paymentMethod: payment.paymentMethod, ); } ``` ### Add to Draw Results Screen ```dart // After draw completion WhatsAppShareButton( label: 'Share Results on WhatsApp', onPressed: () async { await WhatsAppUtil.shareDrawResult(draw.id); }, ) ``` ### Add to Member List (Manager) ```dart // In member card actions Row( children: [ WhatsAppIconButton( onPressed: () async { await WhatsAppUtil.sendPaymentReminder( groupId, member.id, ); }, tooltip: 'Send Reminder', ), // Other actions... ], ) ``` ### Add Notifications to Bottom Nav ```dart BottomNavigationBar( items: [ BottomNavigationBarItem( icon: Icon(Icons.home), label: 'Home', ), BottomNavigationBarItem( icon: Obx(() => NotificationBadge( count: NotificationService.to.unreadCount.value, child: Icon(Icons.notifications), )), label: 'Notifications', ), // Other items... ], onTap: (index) { if (index == 1) { Get.to(() => NotificationCenterPage()); } }, ) ``` --- ## 🔔 **Notification Center Features** ### Features Implemented: - ✅ List all notifications - ✅ Show unread count badge - ✅ Mark as read on tap - ✅ Mark all as read - ✅ Swipe to delete - ✅ Pull to refresh - ✅ Infinite scroll pagination - ✅ Filter by type/status - ✅ Empty state when no notifications - ✅ Skeleton loader while loading ### Usage: ```dart // Navigate to notification center Get.to(() => NotificationCenterPage()); // Check unread count final count = NotificationService.to.unreadCount.value; // Refresh notifications await NotificationService.to.refresh(); // Mark all as read await NotificationService.to.markAllAsRead(); ``` --- ## 🎯 **Common Use Cases** ### Use Case 1: New Member Joins ```dart // In add member success callback await Notification.create({ type: 'member_joined', user_id: managerId, group_id: groupId, channel: 'in_app', message: '${memberName} joined ${groupName}', }); // Optionally send welcome WhatsApp to new member final welcomeMsg = WhatsAppHelper.generateWelcomeMessage( member, group, manager ); await openWhatsApp(member.phone, welcomeMsg); ``` ### Use Case 2: Manager Wants Quick Reminder ```dart // Add quick action in group details QuickActionCard( title: 'Send Payment Reminders', subtitle: 'Remind unpaid members', icon: Icons.send, color: Colors.orange.shade600, onTap: () async { final result = await WhatsAppUtil.sendBulkReminders(groupId); if (result != null) { final count = result['total_reminders']; SnackbarUtil.showSuccess('$count reminders generated!'); } }, ) ``` ### Use Case 3: Member Views Notifications ```dart // Member dashboard - show recent notifications Obx(() { final recentNotifications = NotificationService.to .notifications .take(3) .toList(); return Column( children: recentNotifications.map((n) => ListTile( leading: Icon(n.getIcon(), color: n.getColor()), title: Text(n.title), subtitle: Text(n.message, maxLines: 1), trailing: Text(n.getTimeAgo()), onTap: () => Get.to(() => NotificationCenterPage()), ) ).toList(), ); }) ``` --- ## 🔧 **Scheduler Configuration** ### Current Schedule: - **Time:** 9:00 AM IST daily - **Timezone:** Asia/Kolkata - **Cron:** `'0 9 * * *'` ### Customize Schedule: ```javascript // In reminder-service.js // Run every hour cron.schedule('0 * * * *', async () => { ... }); // Run twice daily (9 AM and 6 PM) cron.schedule('0 9,18 * * *', async () => { ... }); // Run every Monday at 9 AM cron.schedule('0 9 * * 1', async () => { ... }); // Multiple schedules cron.schedule('0 9 * * *', () => sendMorningReminders()); cron.schedule('0 18 * * *', () => sendEveningReminders()); ``` --- ## 📊 **Monitoring & Analytics** ### Get Reminder Statistics: ```javascript const stats = await ReminderService.getReminderStats(groupId, 30); console.log(stats); // { // total: 150, // sent: 145, // failed: 5, // success_rate: "96.67" // } ``` ### Get Upcoming Reminders (Preview): ```javascript const upcoming = await ReminderService.getUpcomingReminders(groupId); console.log(upcoming); // { // group_name: "Family Chit Fund", // current_month: 5, // due_date: "08 Nov 2025", // days_until_due: 3, // unpaid_members: 8, // unpaid_member_list: [...] // } ``` --- ## 🎨 **Message Customization** ### Customize WhatsApp Messages: Edit `backend/src/utils/whatsapp-helper.js`: ```javascript // Example: Add company branding static generatePaymentReceipt(payment, group, member) { return `🎉 *Payment Successful!*\n\n` + `👤 Name: ${member.full_name}\n` + `🏦 Group: ${group.name}\n` + `💰 Amount: ${this.formatCurrency(payment.amount)}\n` + // ... more details ... `\n\n` + `✅ Payment recorded successfully!\n` + `Thank you for your trust! 🙏\n\n` + `_Your Company Name_\n` + // Customize this `_Website: yourwebsite.com_\n` + // Add your link `_Support: +91-XXXXXXXXXX_`; // Add support number } // Example: Add regional language support static generatePaymentReminderHindi(member, group, ...) { return `⏰ *भुगतान अनुस्मारक*\n\n` + `प्रिय ${member.full_name},\n\n` + `आपकी मासिक किस्त ${daysLeft} दिनों में देय है।\n\n` + // ... rest in Hindi } ``` --- ## 🔐 **Security Considerations** ### Rate Limiting: ```javascript // Prevent spam const rateLimit = require('express-rate-limit'); const shareLimit = rateLimit({ windowMs: 15 * 60 * 1000, // 15 minutes max: 10, // Max 10 shares per 15 minutes message: 'Too many share requests' }); router.post('/payment-receipt', shareLimit, auth, async (req, res) => { // ... }); ``` ### Validation: ```javascript // Validate phone numbers const validatePhone = (phone) => { const cleaned = phone.replace(/\D/g, ''); return /^[0-9]{10}$/.test(cleaned); }; // Validate ownership if (payment.user_id !== req.user.id && req.user.role !== 'manager') { return res.status(403).json({ message: 'Not authorized' }); } ``` --- ## 💡 **Best Practices** ### 1. Always Log Notifications ```javascript // Every WhatsApp action should create a notification record await Notification.create({ type: 'payment_reminder', user_id: memberId, group_id: groupId, channel: 'whatsapp', message: message, status: 'sent' }); ``` ### 2. Handle Errors Gracefully ```javascript try { await WhatsAppUtil.shareReceipt(paymentId); } catch (e) { SnackbarUtil.showError('Could not open WhatsApp. Please try again.'); } ``` ### 3. Provide Feedback ```javascript // Show loading SnackbarUtil.showLoading('Generating receipt...'); // Dismiss on complete SnackbarUtil.dismiss(); SnackbarUtil.showSuccess('Opening WhatsApp...'); ``` ### 4. Respect User Preferences ```javascript // Check if user wants WhatsApp notifications if (user.preferences?.whatsapp_enabled) { await sendWhatsAppReminder(); } ``` --- ## 🚀 **Production Checklist** Before going live: - [ ] Test all WhatsApp share functions - [ ] Verify scheduler runs at correct time - [ ] Test reminder logic with various scenarios - [ ] Check timezone handling (IST) - [ ] Test with actual WhatsApp on mobile - [ ] Verify phone number formatting - [ ] Test bulk operations - [ ] Monitor server logs - [ ] Set up error alerts - [ ] Test on multiple devices - [ ] Verify database performance - [ ] Add rate limiting - [ ] Implement retry logic for failed sends - [ ] Set up monitoring dashboard --- ## 📞 **Support & Troubleshooting** ### WhatsApp not opening? - Check if WhatsApp is installed on device - Verify phone number format (10 digits) - Test URL in browser first - Check console for errors ### Reminders not sending? - Check server logs for cron execution - Verify timezone settings - Check database for notification records - Test manual trigger: `ReminderService.triggerManualReminders()` ### Notifications not showing? - Check API endpoint responses - Verify NotificationService is initialized - Check network connectivity - Look for errors in Flutter console --- ## 🎉 **You're Ready!** All WhatsApp integration and payment reminder features are now implemented! **Next:** Test the features, customize messages, and deploy to production! 🚀