# Flutterwave Integration - Testing Guide

## Testing the Integration

### 1. Unit Testing Setup

Create test class: `tests/Feature/PaymentControllerTest.php`

```php
<?php

namespace Tests\Feature;

use Tests\TestCase;
use App\Models\Package;
use App\Models\Booking;
use App\Models\Payment;

class PaymentControllerTest extends TestCase
{
    private Package $package;
    private Booking $booking;
    private Payment $payment;

    protected function setUp(): void
    {
        parent::setUp();
        
        // Create test data
        $this->package = Package::factory()->create();
        $this->booking = Booking::factory()->create(['package_id' => $this->package->id]);
        $this->payment = Payment::factory()->create(['booking_id' => $this->booking->id]);
    }

    public function testPaymentMethodsEndpoint()
    {
        $response = $this->getJson(route('payment.methods'));
        
        $response->assertStatus(200)
            ->assertJsonStructure([
                'methods' => [
                    '*' => ['id', 'name', 'description', 'enabled']
                ]
            ]);
    }

    public function testInitializePaymentWithValidReference()
    {
        $response = $this->post(
            route('payment.initialize', ['reference' => $this->payment->payment_reference]),
            []
        );
        
        // Should redirect to payment page if credentials are valid
        $response->assertStatus(302);
    }

    public function testPaymentCallbackWithValidTransaction()
    {
        $response = $this->get(route('payment.callback'), [
            'status' => 'successful',
            'transaction_id' => '123456',
            'tx_ref' => $this->payment->payment_reference
        ]);
        
        $response->assertStatus(302);
    }

    public function testWebhookSignatureVerification()
    {
        $payload = json_encode(['data' => ['tx_ref' => 'TEST123']]);
        $signature = hash_hmac('sha256', $payload, config('flutterwave.secret_key'));
        
        $response = $this->post(
            route('webhook.flutterwave'),
            json_decode($payload, true),
            ['verif-hash' => $signature]
        );
        
        $response->assertStatus(200);
    }
}
```

### 2. Integration Testing

#### Test Case 1: Complete Booking with Flutterwave Payment

```bash
# 1. Navigate to package booking page
GET /packages/test-package/book

# 2. Fill booking form
POST /bookings
{
    "package_id": 1,
    "first_name": "John",
    "last_name": "Doe",
    "email": "john@example.com",
    "phone": "+234901234567",
    "country": "Nigeria",
    "travel_date": "2026-06-15",
    "number_of_people": 2,
    "payment_method": "flutterwave",
    "agree_terms": true
}

# Expected: Redirect to payment initialization
Response: 302 to /payment/{reference}/initialize

# 3. Initialize payment
POST /payment/PAY{reference}/initialize

# Expected: Redirect to Flutterwave payment page
Response: 302 to https://checkout.flutterwave.com/...

# 4. Complete payment on Flutterwave
(User completes payment in Flutterwave UI)

# 5. Flutterwave redirects to callback
GET /payment/callback?status=successful&transaction_id=123&tx_ref=PAY{reference}

# Expected: Payment confirmed and booking success page shown
Response: 302 to /booking/success/{booking_reference}
```

#### Test Case 2: WhatsApp Payment Fallback

```bash
# Same as above but with payment_method: "whatsapp"

POST /bookings
{
    ...
    "payment_method": "whatsapp",
    ...
}

# Expected: Redirect to booking success with WhatsApp link
Response: 302 to /booking/success/{booking_reference}
         with session['whatsapp_url']
```

#### Test Case 3: Webhook Processing

```bash
# Simulate Flutterwave webhook

POST /api/webhooks/flutterwave
Headers:
  verif-hash: <webhook_signature>
  Content-Type: application/json

Body:
{
    "data": {
        "id": 123456,
        "tx_ref": "PAYXXXXXXXX2026",
        "status": "successful",
        "amount": 50000,
        "currency": "NGN",
        "customer": {
            "email": "john@example.com"
        },
        "payment_type": "card",
        "processor_response": "Approved"
    }
}

# Expected: Payment updated to completed, booking confirmed
Response: 200 OK
{
    "success": true
}
```

### 3. Manual Testing Checklist

#### Setup
- [ ] Flutterwave test API keys configured
- [ ] Webhook URL is accessible
- [ ] Database migrated
- [ ] Cache cleared
- [ ] HTTPS enabled (or test in HTTPS-like environment)

#### Payment Initialization
- [ ] Can access booking form
- [ ] Payment method selection visible
- [ ] Flutterwave option selectable
- [ ] Form validation works
- [ ] Redirects to Flutterwave payment page

#### Payment Processing
- [ ] Test card payment completes
- [ ] Webhook received and processed
- [ ] Payment status updated to "completed"
- [ ] Booking status updated to "confirmed"
- [ ] Confirmation email sent
- [ ] User redirected to success page

#### Payment Failure
- [ ] Failed payment shows error
- [ ] Booking remains in "pending" status
- [ ] User can retry payment
- [ ] Error notifications are clear

#### WhatsApp Payment
- [ ] WhatsApp option visible in form
- [ ] WhatsApp message generated correctly
- [ ] WhatsApp link opens correctly
- [ ] Manual confirmation flow works

#### Webhook Processing
- [ ] Valid webhook processed successfully
- [ ] Invalid signature rejected
- [ ] Duplicate webhooks handled
- [ ] Missing fields handled gracefully

#### Edge Cases
- [ ] Concurrent payment attempts
- [ ] Network timeout handling
- [ ] Invalid payment reference
- [ ] Transaction amount mismatch
- [ ] Refund processing
- [ ] Booking cancellation with paid status

### 4. Load Testing

```bash
# Using Apache Bench
ab -n 100 -c 10 https://your-domain.com/payment/methods

# Using k6
k6 run load-test.js
```

### 5. Security Testing

#### OWASP Checks
- [ ] No sensitive data in logs
- [ ] API keys not in error messages
- [ ] CSRF protection (except webhook)
- [ ] Input validation on all endpoints
- [ ] Output encoding for XSS prevention
- [ ] SQL injection prevention (use ORM)
- [ ] Rate limiting on payment endpoints
- [ ] Proper error handling

#### SSL/TLS
- [ ] HTTPS enforced
- [ ] Certificate valid
- [ ] Mixed content warnings
- [ ] HSTS header set

#### Data Protection
- [ ] PCI compliance
- [ ] Payment data not stored unnecessarily
- [ ] Customer data encrypted
- [ ] Webhook signature verification

### 6. Performance Testing

#### Response Times
- Payment methods endpoint: < 100ms
- Payment initialization: < 500ms
- Webhook processing: < 200ms
- Callback handling: < 300ms

#### Database Queries
- Use Laravel Debugbar to check:
  - Number of queries per request
  - Query execution time
  - N+1 query detection

#### Example
```php
// Test response time
$start = microtime(true);
$response = $this->getJson(route('payment.methods'));
$time = (microtime(true) - $start) * 1000;

$this->assertLessThan(100, $time, "Payment methods took ${time}ms");
```

### 7. Monitoring in Production

#### Key Metrics to Monitor
```
- Payment success rate
- Average payment processing time
- Webhook delivery failures
- Payment status distributions
- Error rates by type
- Transaction amounts
```

#### Logging Strategy
```php
// Payment initialization
Log::info('Payment initialized', [
    'payment_id' => $payment->id,
    'booking_id' => $booking->id,
    'amount' => $payment->amount,
    'method' => 'flutterwave'
]);

// Webhook received
Log::info('Webhook received', [
    'tx_ref' => $data['tx_ref'],
    'status' => $data['status'],
    'transaction_id' => $data['id']
]);

// Payment failed
Log::error('Payment failed', [
    'payment_id' => $payment->id,
    'reason' => $reason,
    'user_id' => $booking->user_id
]);
```

### 8. Debugging

#### Enable Debug Mode
```env
APP_DEBUG=true
LOG_LEVEL=debug
```

#### Check Logs
```bash
# Tail logs
tail -f storage/logs/laravel.log

# Search for errors
grep -i "flutterwave\|payment\|webhook" storage/logs/laravel.log
```

#### Use Debugbar
```blade
@dd($payment)  // Dump and die
```

#### API Testing Tools
- Postman
- Insomnia
- Thunder Client
- curl

### 9. Test Data

#### Test Booking
```php
$booking = Booking::create([
    'package_id' => 1,
    'first_name' => 'Test',
    'last_name' => 'User',
    'email' => 'test@example.com',
    'phone' => '+234901234567',
    'country' => 'Nigeria',
    'travel_date' => now()->addDay(),
    'number_of_people' => 1,
    'total_price' => 50000,
    'currency' => 'NGN'
]);

$payment = Payment::create([
    'booking_id' => $booking->id,
    'amount' => 50000,
    'currency' => 'NGN',
    'payment_method' => 'flutterwave',
    'status' => 'pending'
]);
```

### 10. Running Tests

```bash
# All tests
php artisan test

# Specific test file
php artisan test tests/Feature/PaymentControllerTest.php

# Specific test
php artisan test tests/Feature/PaymentControllerTest.php::testPaymentMethodsEndpoint

# With coverage
php artisan test --coverage

# Watch mode (if available)
php artisan test --watch
```

---

**Testing Status**: Complete integration test suite recommended
**Documentation Version**: 1.0
