# M-Pesa Transaction Diagnosis and Fix

## 🔍 Problem: Transaction Shows "Not Linked" but Command Says All OK

This happens when:
1. Transaction has a `loan` field set (so it's not NULL in database)
2. But `repayment` was never created
3. Or transaction status is still "pending/confirmed" instead of "processed"

## 🚀 Solution: Run These Commands in Order

### Step 1: Check Transaction Status
```bash
cd /home/acbptxvs/public_html/branchbusinessadvance.co.ke
python manage.py check_mpesa_status
```

This will show you:
- All recent transactions
- Which ones are matched to borrower
- Which ones are matched to loan
- Which ones have repayments created
- Exact status of each transaction

### Step 2: Fix Unprocessed Transactions
```bash
python manage.py fix_mpesa_payments
```

This now checks for:
- ✅ Transactions with no loan
- ✅ Transactions with no repayment (NEW!)
- ✅ Failed transactions

### Step 3: Verify Fix
```bash
# Check status again
python manage.py check_mpesa_status

# Or check specific transaction
python manage.py check_mpesa_status --all
```

---

## 📋 New Commands Available

### 1. Check M-Pesa Status (NEW)
```bash
# Check last 7 days
python manage.py check_mpesa_status

# Check last 30 days
python manage.py check_mpesa_status --days 30

# Show all transactions (including processed)
python manage.py check_mpesa_status --all
```

**What it shows:**
- Transaction ID
- M-Pesa Trans ID
- Amount and phone number
- Borrower match status (✓ or ✗)
- Loan match status (✓ or ✗)
- Repayment creation status (✓ or ✗)
- Processing notes
- What needs to be done

### 2. Fix M-Pesa Payments (UPDATED)
```bash
# Dry run - see what would be fixed
python manage.py fix_mpesa_payments --dry-run

# Actually fix
python manage.py fix_mpesa_payments
```

**Now finds:**
- Transactions with no loan
- Transactions with no repayment ⭐ NEW
- Failed transactions

### 3. Reprocess Specific Transaction
```bash
# By transaction ID
python manage.py reprocess_mpesa_transaction <TRANSACTION_ID>

# All pending
python manage.py reprocess_mpesa_transaction --all-pending
```

---

## 🔧 Files to Upload (Updated)

### Critical Files:
1. **`loans/models.py`** - Fixed phone matching
2. **`payments/management/commands/reprocess_mpesa_transaction.py`** - Reprocess command
3. **`payments/management/commands/fix_mpesa_payments.py`** - UPDATED (now checks repayment)
4. **`payments/management/commands/check_mpesa_status.py`** - NEW diagnostic command

### Templates (if needed):
5. `templates/payments/callbacks.html`
6. `templates/payments/transaction_detail.html`
7. `templates/payments/reprocess_transaction.html`
8. `templates/payments/my_payments.html`

---

## 🎯 Complete Fix Workflow

```bash
# 1. Upload all 4 command files

# 2. Restart application
touch /home/acbptxvs/public_html/branchbusinessadvance.co.ke/passenger_wsgi.py

# 3. Check what's wrong
cd /home/acbptxvs/public_html/branchbusinessadvance.co.ke
python manage.py check_mpesa_status

# 4. Fix everything
python manage.py fix_mpesa_payments

# 5. Verify fix
python manage.py check_mpesa_status
```

---

## 📊 Expected Output from check_mpesa_status

```
======================================================================
M-Pesa Transaction Status Check
======================================================================

Found 1 transaction(s) in the last 7 days

======================================================================
Transaction ID: 1020ad2a-9134-4735-b5be-c55dd653deb8
M-Pesa Trans ID: SKH1234567
Amount: KES 100.00
Phone: 254114565176
Date: 2025-11-01 06:07:28
Status: confirmed
✓ Borrower: Phin Client (ID: 8b1bce3d286744498fdbeb27fca0819c)
✓ Loan: LOAN-000123 (ID: abc123...)
✗ Repayment: NOT CREATED

ACTION REQUIRED:
  → Need to create repayment record

To fix this transaction, run:
  python manage.py reprocess_mpesa_transaction 1020ad2a-9134-4735-b5be-c55dd653deb8

======================================================================
SUMMARY
======================================================================
Total Transactions: 1
Matched to Borrower: 1/1
Matched to Loan: 1/1
Repayment Created: 0/1

⚠ 1 transaction(s) need processing

To fix all unprocessed transactions:
  python manage.py fix_mpesa_payments
```

---

## 🐛 Common Scenarios

### Scenario 1: Transaction has loan but no repayment
**Symptom:** Shows "Not linked" in UI, but loan is matched
**Cause:** Repayment creation failed
**Fix:** `python manage.py fix_mpesa_payments`

### Scenario 2: Transaction status is "confirmed" not "processed"
**Symptom:** Everything looks matched but status wrong
**Cause:** process_payment() wasn't completed
**Fix:** `python manage.py fix_mpesa_payments`

### Scenario 3: Phone number doesn't match
**Symptom:** No borrower matched
**Cause:** Phone format mismatch
**Fix:** Upload updated `loans/models.py` then run fix command

### Scenario 4: No active loans for borrower
**Symptom:** Borrower matched but no loan
**Cause:** Borrower has no active loans
**Solution:** Check borrower's loans in admin

---

## 🔍 Manual Verification (Django Shell)

```python
# Check specific transaction
from loans.models import MpesaTransaction

# Find by date/time
t = MpesaTransaction.objects.filter(
    created_at__date='2025-11-01'
).first()

print(f"Transaction: {t.trans_id}")
print(f"Status: {t.status}")
print(f"Borrower: {t.borrower}")
print(f"Loan: {t.loan}")
print(f"Repayment: {t.repayment}")
print(f"Notes: {t.processing_notes}")

# If repayment is None, try to create it
if not t.repayment:
    print("\nAttempting to create repayment...")
    repayment = t.create_repayment()
    if repayment:
        print(f"✓ Repayment created: {repayment.receipt_number}")
    else:
        print(f"✗ Failed: {t.processing_notes}")
```

---

## ✅ Success Indicators

After running fix_mpesa_payments, you should see:

1. **In check_mpesa_status:**
   ```
   ✓ Borrower: Phin Client
   ✓ Loan: LOAN-000123
   ✓ Repayment: RCP-000456
   
   ✓ Transaction fully processed
   ```

2. **In /loans/repayments/:**
   - Payment appears with M-Pesa badge
   - Receipt number shown
   - Linked to correct loan

3. **In /loans/:**
   - Loan balance reduced
   - Repayment in history

4. **In /payments/transactions/:**
   - Status: "Processed"
   - Linked to borrower and loan
   - Repayment created

---

## 🆘 If Still Not Working

### Check 1: Is the transaction really in database?
```bash
python manage.py shell -c "
from loans.models import MpesaTransaction
from django.utils import timezone
from datetime import timedelta
recent = MpesaTransaction.objects.filter(
    created_at__gte=timezone.now() - timedelta(days=1)
)
print(f'Transactions in last 24h: {recent.count()}')
for t in recent:
    print(f'  {t.trans_id}: {t.status} - Loan: {t.loan} - Repayment: {t.repayment}')
"
```

### Check 2: What's the exact status?
```bash
python manage.py check_mpesa_status --days 1
```

### Check 3: Try force reprocess
```bash
# Get the transaction ID from check_mpesa_status output
python manage.py reprocess_mpesa_transaction <TRANSACTION_ID>
```

---

## 📞 Quick Support Commands

### Find transaction by phone number
```bash
python manage.py shell -c "
from loans.models import MpesaTransaction
t = MpesaTransaction.objects.filter(phone_number__contains='114565176').first()
if t:
    print(f'Found: {t.trans_id}')
    print(f'ID: {t.id}')
    print(f'Status: {t.status}')
    print(f'Borrower: {t.borrower}')
    print(f'Loan: {t.loan}')
    print(f'Repayment: {t.repayment}')
"
```

### Check borrower's active loans
```bash
python manage.py shell -c "
from users.models import User
from loans.models import Loan
user = User.objects.filter(phone_number__contains='114565176').first()
if user:
    print(f'Borrower: {user.get_full_name()}')
    loans = Loan.objects.filter(borrower=user, status='active')
    print(f'Active loans: {loans.count()}')
    for loan in loans:
        print(f'  {loan.loan_number}: KES {loan.outstanding_amount}')
"
```

---

## 🎯 Most Common Fix

For 99% of cases:

```bash
cd /home/acbptxvs/public_html/branchbusinessadvance.co.ke

# Check what's wrong
python manage.py check_mpesa_status

# Fix it
python manage.py fix_mpesa_payments

# Verify
python manage.py check_mpesa_status
```

Done! ✅
