# 🚀 M-Pesa Production Deployment Guide

This guide provides step-by-step instructions for deploying the M-Pesa integration to production.

## 📋 Pre-Deployment Checklist

### ✅ Requirements
- [ ] Python 3.8+ installed
- [ ] Django application running
- [ ] MySQL/PostgreSQL database configured
- [ ] SSL certificate for your domain
- [ ] M-Pesa production credentials from Safaricom
- [ ] Domain name configured and accessible
- [ ] Backup strategy in place

### ✅ M-Pesa Prerequisites
- [ ] M-Pesa production account approved
- [ ] Consumer Key and Consumer Secret obtained
- [ ] Business Short Code (Paybill) active
- [ ] Passkey for STK Push (if needed)
- [ ] External validation enabled (if required)

## 🚀 Quick Deployment

### Option 1: Automated Deployment Script
```bash
# Make the script executable
chmod +x deploy_mpesa_production.py

# Run the deployment script
python deploy_mpesa_production.py
```

The script will guide you through:
1. Prerequisites checking
2. Database backup
3. Running migrations
4. M-Pesa configuration setup
5. URL registration with M-Pesa
6. SSL certificate testing
7. Service file creation
8. Monitoring setup

### Option 2: Manual Deployment

#### Step 1: Database Backup
```bash
# Create backup
mysqldump -u username -p database_name > backup_$(date +%Y%m%d_%H%M%S).sql
```

#### Step 2: Run Migrations
```bash
python manage.py migrate
```

#### Step 3: Collect Static Files
```bash
python manage.py collectstatic --noinput
```

#### Step 4: Configure M-Pesa Production
```bash
python manage.py setup_mpesa \
    --environment production \
    --consumer-key "YOUR_PRODUCTION_CONSUMER_KEY" \
    --consumer-secret "YOUR_PRODUCTION_CONSUMER_SECRET" \
    --business-short-code "YOUR_PAYBILL_NUMBER" \
    --base-url "https://yourdomain.com"
```

## 🔧 Production Configuration

### Environment Variables
Create a `.env` file or set environment variables:

```bash
# Django Settings
DJANGO_SETTINGS_MODULE=branch_system.settings
DEBUG=False
ALLOWED_HOSTS=yourdomain.com,www.yourdomain.com

# Database
DB_NAME=your_production_db
DB_USER=your_db_user
DB_PASSWORD=your_secure_password
DB_HOST=localhost
DB_PORT=3306

# M-Pesa Production
MPESA_ENVIRONMENT=production
MPESA_CONSUMER_KEY=your_production_consumer_key
MPESA_CONSUMER_SECRET=your_production_consumer_secret
MPESA_BUSINESS_SHORT_CODE=your_paybill_number
MPESA_PASSKEY=your_production_passkey

# Security
SECRET_KEY=your_very_secure_secret_key
```

### Django Settings for Production
Update `branch_system/settings.py`:

```python
# Production settings
DEBUG = False
ALLOWED_HOSTS = ['yourdomain.com', 'www.yourdomain.com']

# Security settings
SECURE_SSL_REDIRECT = True
SECURE_HSTS_SECONDS = 31536000
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_PRELOAD = True
SECURE_CONTENT_TYPE_NOSNIFF = True
SECURE_BROWSER_XSS_FILTER = True
X_FRAME_OPTIONS = 'DENY'

# Session security
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
SESSION_COOKIE_HTTPONLY = True
CSRF_COOKIE_HTTPONLY = True

# Logging
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'file': {
            'level': 'INFO',
            'class': 'logging.FileHandler',
            'filename': '/var/log/django/mpesa.log',
        },
    },
    'loggers': {
        'payments': {
            'handlers': ['file'],
            'level': 'INFO',
            'propagate': True,
        },
    },
}
```

## 🌐 Web Server Configuration

### Nginx Configuration
```nginx
server {
    listen 80;
    listen 443 ssl http2;
    server_name yourdomain.com www.yourdomain.com;
    
    # SSL Configuration
    ssl_certificate /etc/ssl/certs/yourdomain.com.crt;
    ssl_certificate_key /etc/ssl/private/yourdomain.com.key;
    
    # Security headers
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
    
    # Static files
    location /static/ {
        alias /path/to/your/project/staticfiles/;
        expires 1y;
        add_header Cache-Control "public, immutable";
    }
    
    # Media files
    location /media/ {
        alias /path/to/your/project/media/;
        expires 1y;
        add_header Cache-Control "public";
    }
    
    # M-Pesa callback endpoints (CRITICAL)
    location /payments/mpesa/ {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_connect_timeout 30s;
        proxy_send_timeout 30s;
        proxy_read_timeout 30s;
    }
    
    # All other requests
    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
    
    # Redirect HTTP to HTTPS
    if ($scheme != "https") {
        return 301 https://$host$request_uri;
    }
}
```

### Apache Configuration (Alternative)
```apache
<VirtualHost *:80>
    ServerName yourdomain.com
    ServerAlias www.yourdomain.com
    Redirect permanent / https://yourdomain.com/
</VirtualHost>

<VirtualHost *:443>
    ServerName yourdomain.com
    ServerAlias www.yourdomain.com
    
    # SSL Configuration
    SSLEngine on
    SSLCertificateFile /etc/ssl/certs/yourdomain.com.crt
    SSLCertificateKeyFile /etc/ssl/private/yourdomain.com.key
    
    # Static files
    Alias /static/ /path/to/your/project/staticfiles/
    Alias /media/ /path/to/your/project/media/
    
    # Django application
    ProxyPreserveHost On
    ProxyPass /static/ !
    ProxyPass /media/ !
    ProxyPass / http://127.0.0.1:8000/
    ProxyPassReverse / http://127.0.0.1:8000/
    
    # Security headers
    Header always set X-Frame-Options DENY
    Header always set X-Content-Type-Options nosniff
    Header always set X-XSS-Protection "1; mode=block"
    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
</VirtualHost>
```

## 🔄 Process Management

### Systemd Service
Create `/etc/systemd/system/branch-mpesa.service`:

```ini
[Unit]
Description=HAVEN GRAZURI INVESTMENT LIMITED- M-Pesa Integration
After=network.target

[Service]
Type=notify
User=www-data
Group=www-data
WorkingDirectory=/path/to/your/project
Environment=DJANGO_SETTINGS_MODULE=branch_system.settings
ExecStart=/usr/bin/python3 manage.py runserver 0.0.0.0:8000
ExecReload=/bin/kill -s HUP $MAINPID
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
```

Enable and start the service:
```bash
sudo systemctl daemon-reload
sudo systemctl enable branch-mpesa
sudo systemctl start branch-mpesa
sudo systemctl status branch-mpesa
```

### Gunicorn Configuration (Recommended)
Install Gunicorn:
```bash
pip install gunicorn
```

Create `gunicorn.conf.py`:
```python
bind = "127.0.0.1:8000"
workers = 4
worker_class = "sync"
worker_connections = 1000
max_requests = 1000
max_requests_jitter = 100
timeout = 30
keepalive = 2
preload_app = True
```

Update systemd service:
```ini
ExecStart=/usr/bin/gunicorn --config gunicorn.conf.py branch_system.wsgi:application
```

## 📊 Monitoring & Logging

### Log Configuration
Create log directories:
```bash
sudo mkdir -p /var/log/django
sudo chown www-data:www-data /var/log/django
```

### Monitoring Script
The deployment script creates `monitor_mpesa.py`. Add to crontab:
```bash
# Edit crontab
crontab -e

# Add monitoring (every 15 minutes)
*/15 * * * * /path/to/your/project/monitor_mpesa.py >> /var/log/mpesa_monitor.log 2>&1
```

### Health Check Endpoint
Add to your Django URLs:
```python
# urls.py
from django.http import JsonResponse
from payments.models import MpesaConfiguration

def health_check(request):
    config = MpesaConfiguration.get_active_config()
    return JsonResponse({
        'status': 'healthy',
        'mpesa_configured': bool(config),
        'environment': config.environment if config else None
    })

urlpatterns = [
    # ... other patterns
    path('health/', health_check, name='health_check'),
]
```

## 🔒 Security Considerations

### SSL Certificate
Ensure valid SSL certificate:
```bash
# Let's Encrypt (free)
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com

# Or use your commercial certificate
```

### Firewall Configuration
```bash
# UFW (Ubuntu)
sudo ufw allow 22/tcp    # SSH
sudo ufw allow 80/tcp    # HTTP
sudo ufw allow 443/tcp   # HTTPS
sudo ufw enable

# Or iptables
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
```

### Database Security
```sql
-- Create dedicated database user
CREATE USER 'mpesa_user'@'localhost' IDENTIFIED BY 'secure_password';
GRANT SELECT, INSERT, UPDATE, DELETE ON branch_system.* TO 'mpesa_user'@'localhost';
FLUSH PRIVILEGES;
```

## 🧪 Testing in Production

### 1. Small Test Transactions
Start with small amounts (KES 1-10) to verify:
- Callback URLs are reachable
- SSL certificate is valid
- Transactions are processed correctly
- Notifications are sent

### 2. Test Scenarios
- Single loan customer payment
- Multiple loan customer payment
- Partial payment
- Overpayment
- Invalid phone number
- Network timeout simulation

### 3. Monitoring Checklist
- [ ] Callback response times < 5 seconds
- [ ] Success rate > 95%
- [ ] No stuck transactions
- [ ] Proper error logging
- [ ] Notification delivery

## 🚨 Troubleshooting

### Common Issues

**1. Callback URLs not reachable**
- Check SSL certificate validity
- Verify firewall settings
- Test URL accessibility from external network

**2. Transactions not processing**
- Check Django logs for errors
- Verify M-Pesa credentials
- Ensure database connectivity

**3. High failure rate**
- Monitor callback response times
- Check for database locks
- Verify phone number formats

### Debug Commands
```bash
# Check M-Pesa configuration
python manage.py shell -c "from payments.models import MpesaConfiguration; print(MpesaConfiguration.get_active_config())"

# View recent transactions
python manage.py shell -c "from loans.models import MpesaTransaction; [print(t) for t in MpesaTransaction.objects.all()[:10]]"

# Test callback URL
curl -X POST https://yourdomain.com/payments/mpesa/validation/ \
  -H "Content-Type: application/json" \
  -d '{"test": "data"}'
```

## 📞 Support & Maintenance

### Regular Tasks
- [ ] Monitor transaction success rates daily
- [ ] Review error logs weekly
- [ ] Update SSL certificates before expiry
- [ ] Database backups (automated)
- [ ] Security updates

### Emergency Contacts
- M-Pesa Support: apisupport@safaricom.co.ke
- Technical Support: Your development team
- Hosting Provider: Your hosting support

### Rollback Plan
If issues occur:
1. Disable M-Pesa configuration in admin
2. Restore database from backup
3. Revert to previous code version
4. Investigate and fix issues
5. Re-deploy with fixes

---

## 🎉 Deployment Complete!

After following this guide, your M-Pesa integration will be live in production. Remember to:

1. **Start with test transactions**
2. **Monitor closely for the first 24 hours**
3. **Set up alerts for failures**
4. **Keep credentials secure**
5. **Regular backups and monitoring**

Your loan management system now has seamless, automatic M-Pesa payment processing! 🚀