# Relworx Webhook Implementation Verification

## ✅ Implementation Status: COMPLETE

The webhook handler is fully implemented according to Relworx documentation.

## Webhook Endpoint

**URL:** `POST /api/mobile-money/webhook/relworx`  
**Full URL:** `https://debit.gmpayapp.site/api/mobile-money/webhook/relworx`

## Webhook Payload (From Relworx Docs)

```json
{
  "status": "success",
  "message": "Request payment completed successfully.",
  "customer_reference": "kemist656ehgvcd",
  "internal_reference": "fdd10a4c5d6b459d54ebc5f09d095101",
  "msisdn": "+256773454899",
  "amount": 500.0,
  "currency": "UGX",
  "provider": "mtn_mobile_money",
  "charge": 12.5,
  "completed_at": "2025-04-10T15:12:58.977+03:00"
}
```

## Implementation Details

### ✅ 1. Receives POST Request
- Endpoint: `relworxWebhook()` in `MobileMoney` controller
- Route: `POST /api/mobile-money/webhook/relworx`

### ✅ 2. Handles Status Values
- **"success"** → Maps to `SUCCESS` in database
- **"failed"** → Maps to `FAILED` in database
- Case-insensitive handling (handles any case variation)

### ✅ 3. Extracts All Fields
- ✅ `status` - "success" or "failed"
- ✅ `message` - Status message from Relworx
- ✅ `customer_reference` - Your transaction ID
- ✅ `internal_reference` - Relworx's internal reference
- ✅ `msisdn` - Phone number
- ✅ `amount` - Transaction amount
- ✅ `currency` - Currency code (UGX)
- ✅ `provider` - Payment provider (e.g., "mtn_mobile_money")
- ✅ `charge` - Transaction charge/fee
- ✅ `completed_at` - ISO 8601 timestamp

### ✅ 4. Responds with HTTP 200 OK
**Critical:** Always returns HTTP 200 OK to acknowledge receipt
- Prevents Relworx from retrying (10 times with exponential backoff)
- Returns 200 even if transaction not found (prevents retries)
- Returns 200 even if database update fails (prevents retries)

```php
// ALWAYS respond with HTTP 200 OK
return $this->respond([
    'success' => true,
    'message' => 'Webhook received and processed successfully'
], 200);
```

### ✅ 5. Database Updates

**Transaction Status:**
- Updates `status` field to SUCCESS or FAILED
- Sets `processed_at` timestamp
- Stores `failure_reason` if failed
- Updates `gateway_reference` with internal_reference

**Metadata Storage:**
- Stores complete webhook payload in `metadata.relworx_webhook`
- Preserves original status value from Relworx
- Includes all webhook fields for audit trail

### ✅ 6. Transaction Lookup

Finds transaction using:
1. `customer_reference` → Matches `transaction_id` field
2. `internal_reference` → Matches `reference` field

If not found:
- Logs warning
- Still returns HTTP 200 OK (prevents retries)

### ✅ 7. Webhook Forwarding

After processing:
- Forwards status update to your configured webhooks (from `webhooks` table)
- Includes complete transaction details
- Includes Relworx webhook data

### ✅ 8. Logging

Comprehensive logging:
- ✅ Webhook received (raw input)
- ✅ Transaction updated
- ✅ Transaction not found (warning)
- ✅ Database update failures (error)
- ✅ Invalid JSON input (error)

## Code Flow

```
1. Relworx sends webhook → POST /api/mobile-money/webhook/relworx
   ↓
2. Parse and validate JSON payload
   ↓
3. Extract all fields (status, references, amounts, etc.)
   ↓
4. Find transaction by customer_reference OR internal_reference
   ↓
5. Update database:
   - status: SUCCESS/FAILED
   - processed_at: timestamp
   - metadata: webhook data
   ↓
6. Forward to your webhooks
   ↓
7. ALWAYS return HTTP 200 OK
```

## Testing

### Test Webhook Manually

```bash
curl -X POST https://debit.gmpayapp.site/api/mobile-money/webhook/relworx \
  -H "Content-Type: application/json" \
  -d '{
    "status": "success",
    "message": "Request payment completed successfully.",
    "customer_reference": "MM_1728576000_a1b2c3d4e5f67890",
    "internal_reference": "fdd10a4c5d6b459d54ebc5f09d095101",
    "msisdn": "+256773454899",
    "amount": 500.0,
    "currency": "UGX",
    "provider": "mtn_mobile_money",
    "charge": 12.5,
    "completed_at": "2025-04-10T15:12:58.977+03:00"
  }'
```

**Expected Response:**
```json
{
  "success": true,
  "message": "Webhook received and processed successfully"
}
```

**HTTP Status:** `200 OK`

## Configuration in Relworx

1. Log into Relworx business account
2. Go to **Business Account Settings** → **Webhooks**
3. Add webhook URL:
   ```
   https://debit.gmpayapp.site/api/mobile-money/webhook/relworx
   ```
4. Save configuration

## Status Values

| Relworx Status | Database Status | Description |
|----------------|-----------------|-------------|
| `"success"` | `SUCCESS` | Payment completed successfully |
| `"failed"` | `FAILED` | Payment failed |
| Any other | `PENDING` | Unknown status (shouldn't happen) |

## Files Modified

- ✅ `app/Controllers/MobileMoney.php` - `relworxWebhook()` method
- ✅ `app/Config/Routes.php` - Route added

## Compliance Checklist

- ✅ Receives POST requests
- ✅ Handles "success" and "failed" status
- ✅ Extracts all documented fields
- ✅ Responds with HTTP 200 OK
- ✅ Prevents retries (always returns 200)
- ✅ Updates transaction status
- ✅ Stores webhook metadata
- ✅ Comprehensive logging
- ✅ Webhook forwarding

## Ready for Production ✅

The webhook implementation is complete and ready for use. Configure the webhook URL in your Relworx business account settings.

