# Money Transfer API Documentation

## Overview

The Money Transfer API allows distributors to transfer money to other users. Distributors can search for users by name, email, or phone number, select a user from the list, and transfer money to them. The transfer is processed immediately and both wallets are updated.

**Note:** Only users with `user_type = 'distributor'` can transfer money.

---

## Base URL

```
https://api.alldigtalseva.com/api
```

**Authentication:** All endpoints require User Bearer Token (Distributor)

---

## API Endpoints

### 1. Search Users for Transfer

Search for users by name, email, or phone number. Returns a list of verified users that can receive transfers.

**Endpoint:** `GET /transfer/search-users`

**Headers:**
```
Authorization: Bearer {user_token}
Content-Type: application/json
```

**Query Parameters:**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| search | string | Yes | Search term (minimum 2 characters) - searches in name, email, or phone number |

**Response (Success - 200):**
```json
{
    "success": true,
    "count": 3,
    "data": [
        {
            "id": 2,
            "name": "John Doe",
            "email": "john@example.com",
            "phone_number": "1234567890",
            "user_type": "user"
        },
        {
            "id": 3,
            "name": "Jane Smith",
            "email": "jane@example.com",
            "phone_number": "9876543210",
            "user_type": "user"
        },
        {
            "id": 4,
            "name": "Johnny Depp",
            "email": "johnny@example.com",
            "phone_number": "5555555555",
            "user_type": "distributor"
        }
    ]
}
```

**Response (Unauthorized - 401):**
```json
{
    "success": false,
    "message": "Unauthorized. Please login first."
}
```

**Response (Forbidden - 403):**
```json
{
    "success": false,
    "message": "Only distributors can transfer money."
}
```

**Response (Validation Error - 422):**
```json
{
    "success": false,
    "message": "Validation error",
    "errors": {
        "search": [
            "The search field is required.",
            "The search must be at least 2 characters."
        ]
    }
}
```

**cURL Example:**
```bash
curl -X GET "https://api.alldigtalseva.com/api/transfer/search-users?search=john" \
  -H "Authorization: Bearer {user_token}" \
  -H "Content-Type: application/json"
```

**Notes:**
- Only verified users are returned
- Current user (distributor) is excluded from results
- Maximum 20 results returned
- Search is case-insensitive and matches partial strings

---

### 2. Transfer Money

Transfer money from distributor's wallet to another user's wallet.

**Endpoint:** `POST /transfer`

**Headers:**
```
Authorization: Bearer {user_token}
Content-Type: application/json
```

**Request Body:**
```json
{
    "to_user_id": 2,
    "amount": 500.00,
    "note": "Payment for services"
}
```

**Request Parameters:**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| to_user_id | integer | Yes | ID of the user to receive the transfer |
| amount | decimal | Yes | Amount to transfer (minimum 0.01) |
| note | string | No | Optional note for the transfer (max 500 characters) |

**Response (Success - 200):**
```json
{
    "success": true,
    "message": "Money transferred successfully",
    "data": {
        "transfer_id": 1,
        "from_user": {
            "id": 1,
            "email": "distributor@example.com",
            "name": "Distributor Name"
        },
        "to_user": {
            "id": 2,
            "email": "john@example.com",
            "name": "John Doe"
        },
        "amount": 500.00,
        "note": "Payment for services",
        "remaining_balance": 1500.00,
        "transferred_at": "2025-12-07T10:00:00.000000Z"
    }
}
```

**Response (Unauthorized - 401):**
```json
{
    "success": false,
    "message": "Unauthorized. Please login first."
}
```

**Response (Forbidden - 403):**
```json
{
    "success": false,
    "message": "Only distributors can transfer money."
}
```

**Response (Insufficient Balance - 400):**
```json
{
    "success": false,
    "message": "Insufficient wallet balance",
    "data": {
        "required_amount": 500.00,
        "current_balance": 300.00,
        "shortage": 200.00
    }
}
```

**Response (Validation Error - 422):**
```json
{
    "success": false,
    "message": "Validation error",
    "errors": {
        "to_user_id": ["The to user id field is required."],
        "amount": ["The amount must be at least 0.01."]
    }
}
```

**Response (User Not Found - 404):**
```json
{
    "success": false,
    "message": "Recipient user not found"
}
```

**Response (Self Transfer - 400):**
```json
{
    "success": false,
    "message": "You cannot transfer money to yourself"
}
```

**Response (User Not Verified - 400):**
```json
{
    "success": false,
    "message": "Recipient user is not verified"
}
```

**cURL Example:**
```bash
curl -X POST https://api.alldigtalseva.com/api/transfer \
  -H "Authorization: Bearer {user_token}" \
  -H "Content-Type: application/json" \
  -d '{
    "to_user_id": 2,
    "amount": 500.00,
    "note": "Payment for services"
  }'
```

**Notes:**
- Transfer is processed immediately using database transaction
- Both wallets are updated atomically
- Transfer record is created for history
- Distributor cannot transfer to themselves
- Only verified users can receive transfers

---

### 3. Get Transfer History

Get all money transfers made by the distributor.

**Endpoint:** `GET /transfer/history`

**Headers:**
```
Authorization: Bearer {user_token}
Content-Type: application/json
```

**Query Parameters:**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| start_date | date | No | Filter by start date (YYYY-MM-DD) |
| end_date | date | No | Filter by end date (YYYY-MM-DD) |
| sort_by | string | No | Sort by field (default: `created_at`) |
| sort_order | string | No | Sort order: `asc` or `desc` (default: `desc`) |
| per_page | integer | No | Items per page (1-100, default: 15) |

**Response (Success - 200):**
```json
{
    "success": true,
    "summary": {
        "total_transfers": 10,
        "total_amount_transferred": 5000.00
    },
    "data": [
        {
            "id": 1,
            "from_user_id": 1,
            "to_user_id": 2,
            "amount": "500.00",
            "note": "Payment for services",
            "created_at": "2025-12-07T10:00:00.000000Z",
            "updated_at": "2025-12-07T10:00:00.000000Z",
            "to_user": {
                "id": 2,
                "name": "John Doe",
                "email": "john@example.com",
                "phone_number": "1234567890"
            }
        }
    ],
    "pagination": {
        "current_page": 1,
        "per_page": 15,
        "total": 10,
        "last_page": 1
    }
}
```

**Response (Unauthorized - 401):**
```json
{
    "success": false,
    "message": "Unauthorized. Please login first."
}
```

**Response (Forbidden - 403):**
```json
{
    "success": false,
    "message": "Only distributors can view transfer history."
}
```

**cURL Example:**
```bash
curl -X GET "https://api.alldigtalseva.com/api/transfer/history?start_date=2025-12-01&end_date=2025-12-31" \
  -H "Authorization: Bearer {user_token}" \
  -H "Content-Type: application/json"
```

---

## JavaScript/Angular Examples

### Search Users

```typescript
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class TransferService {
  private apiUrl = 'https://api.alldigtalseva.com/api';
  private headers: HttpHeaders;

  constructor(private http: HttpClient) {
    const token = localStorage.getItem('user_token');
    this.headers = new HttpHeaders({
      'Authorization': `Bearer ${token}`,
      'Content-Type': 'application/json'
    });
  }

  searchUsers(searchTerm: string): Observable<any> {
    const params = new HttpParams().set('search', searchTerm);
    return this.http.get(`${this.apiUrl}/transfer/search-users`, {
      headers: this.headers,
      params: params
    });
  }
}

// Usage in component
this.transferService.searchUsers('john').subscribe(
  (response) => {
    if (response.success) {
      console.log('Found users:', response.data);
      // Display list of users for selection
      this.usersList = response.data;
    }
  },
  (error) => {
    console.error('Error:', error);
  }
);
```

### Transfer Money

```typescript
transferMoney(toUserId: number, amount: number, note?: string): Observable<any> {
  return this.http.post(`${this.apiUrl}/transfer`, {
    to_user_id: toUserId,
    amount: amount,
    note: note || ''
  }, {
    headers: this.headers
  });
}

// Usage in component
// User selects a user from the list and transfers money
onTransfer(userId: number, amount: number) {
  this.transferService.transferMoney(userId, amount, 'Payment for services').subscribe(
    (response) => {
      if (response.success) {
        console.log('Transfer successful');
        console.log('Remaining balance:', response.data.remaining_balance);
        // Show success message
        // Refresh wallet balance
      }
    },
    (error) => {
      if (error.error.message === 'Insufficient wallet balance') {
        console.error('Insufficient balance');
        // Show error message with shortage amount
      } else {
        console.error('Error:', error);
      }
    }
  );
}
```

### Get Transfer History

```typescript
getTransferHistory(params?: {
  start_date?: string;
  end_date?: string;
  sort_by?: string;
  sort_order?: string;
  per_page?: number;
}): Observable<any> {
  let queryParams = new HttpParams();
  
  if (params) {
    Object.keys(params).forEach(key => {
      if (params[key] !== undefined) {
        queryParams = queryParams.set(key, params[key].toString());
      }
    });
  }

  return this.http.get(`${this.apiUrl}/transfer/history`, {
    headers: this.headers,
    params: queryParams
  });
}

// Usage
this.transferService.getTransferHistory({
  start_date: '2025-12-01',
  end_date: '2025-12-31'
}).subscribe(
  (response) => {
    if (response.success) {
      console.log('Summary:', response.summary);
      console.log('Transfers:', response.data);
    }
  }
);
```

---

## React/Next.js Examples

### Search Users

```javascript
const searchUsers = async (userToken, searchTerm) => {
  try {
    const response = await fetch(`https://api.alldigtalseva.com/api/transfer/search-users?search=${encodeURIComponent(searchTerm)}`, {
      method: 'GET',
      headers: {
        'Authorization': `Bearer ${userToken}`,
        'Content-Type': 'application/json',
      },
    });

    const data = await response.json();
    
    if (data.success) {
      return {
        success: true,
        count: data.count,
        data: data.data
      };
    } else {
      return {
        success: false,
        message: data.message
      };
    }
  } catch (error) {
    console.error('Error:', error);
    return {
      success: false,
      message: 'An error occurred'
    };
  }
};

// Usage in component
const [usersList, setUsersList] = useState([]);

const handleSearch = async (searchTerm) => {
  const userToken = localStorage.getItem('user_token');
  const result = await searchUsers(userToken, searchTerm);
  
  if (result.success) {
    setUsersList(result.data);
  }
};
```

### Transfer Money

```javascript
const transferMoney = async (userToken, toUserId, amount, note) => {
  try {
    const response = await fetch('https://api.alldigtalseva.com/api/transfer', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${userToken}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        to_user_id: toUserId,
        amount: amount,
        note: note || ''
      }),
    });

    const data = await response.json();
    
    if (data.success) {
      return {
        success: true,
        data: data.data
      };
    } else {
      return {
        success: false,
        message: data.message,
        data: data.data
      };
    }
  } catch (error) {
    console.error('Error:', error);
    return {
      success: false,
      message: 'An error occurred'
    };
  }
};

// Usage
const handleTransfer = async (userId, amount) => {
  const userToken = localStorage.getItem('user_token');
  const result = await transferMoney(userToken, userId, amount, 'Payment for services');
  
  if (result.success) {
    console.log('Transfer successful');
    console.log('Remaining balance:', result.data.remaining_balance);
    // Show success message
    // Refresh wallet balance
  } else {
    if (result.message === 'Insufficient wallet balance') {
      console.error('Insufficient balance. Shortage:', result.data.shortage);
    } else {
      console.error('Error:', result.message);
    }
  }
};
```

### Get Transfer History

```javascript
const getTransferHistory = async (userToken, params = {}) => {
  try {
    const queryString = new URLSearchParams(params).toString();
    const url = `https://api.alldigtalseva.com/api/transfer/history${queryString ? `?${queryString}` : ''}`;
    
    const response = await fetch(url, {
      method: 'GET',
      headers: {
        'Authorization': `Bearer ${userToken}`,
        'Content-Type': 'application/json',
      },
    });

    const data = await response.json();
    
    if (data.success) {
      return {
        success: true,
        summary: data.summary,
        data: data.data,
        pagination: data.pagination
      };
    } else {
      return {
        success: false,
        message: data.message
      };
    }
  } catch (error) {
    console.error('Error:', error);
    return {
      success: false,
      message: 'An error occurred'
    };
  }
};

// Usage
const userToken = localStorage.getItem('user_token');
getTransferHistory(userToken, {
  start_date: '2025-12-01',
  end_date: '2025-12-31'
}).then(result => {
  if (result.success) {
    console.log('Summary:', result.summary);
    console.log('Transfers:', result.data);
  }
});
```

---

## Complete Flow Example

### Step 1: Search for Users

```javascript
// Distributor searches for users by name, email, or phone
GET /api/transfer/search-users?search=john

// Response: List of users matching the search
{
  "success": true,
  "count": 3,
  "data": [
    {
      "id": 2,
      "name": "John Doe",
      "email": "john@example.com",
      "phone_number": "1234567890",
      "user_type": "user"
    }
  ]
}
```

### Step 2: Select User and Transfer

```javascript
// Distributor selects a user from the list and transfers money
POST /api/transfer
{
  "to_user_id": 2,
  "amount": 500.00,
  "note": "Payment for services"
}

// Response: Transfer successful
{
  "success": true,
  "message": "Money transferred successfully",
  "data": {
    "transfer_id": 1,
    "amount": 500.00,
    "remaining_balance": 1500.00
  }
}
```

### Step 3: View Transfer History

```javascript
// Distributor views their transfer history
GET /api/transfer/history

// Response: List of all transfers
{
  "success": true,
  "summary": {
    "total_transfers": 10,
    "total_amount_transferred": 5000.00
  },
  "data": [...]
}
```

---

## UI Flow Example

1. **Search Screen**: Distributor enters search term (name, email, or phone)
2. **User List**: Display list of matching users
3. **Select User**: Distributor selects a user from the list
4. **Transfer Form**: Show transfer form with:
   - Selected user details
   - Amount input
   - Optional note input
   - Current wallet balance
5. **Confirm Transfer**: Show confirmation dialog
6. **Process Transfer**: Call transfer API
7. **Success**: Show success message and update wallet balance
8. **History**: Show transfer in history

---

## Error Handling

### Common Error Scenarios

1. **Unauthorized (401)**
   - Status: 401
   - Message: "Unauthorized. Please login first."
   - Solution: Ensure valid user token is provided

2. **Forbidden (403)**
   - Status: 403
   - Message: "Only distributors can transfer money."
   - Solution: User must be a distributor

3. **Insufficient Balance (400)**
   - Status: 400
   - Message: "Insufficient wallet balance"
   - Solution: Check current balance and required amount

4. **User Not Found (404)**
   - Status: 404
   - Message: "Recipient user not found"
   - Solution: Verify user ID exists

5. **Self Transfer (400)**
   - Status: 400
   - Message: "You cannot transfer money to yourself"
   - Solution: Select a different user

6. **User Not Verified (400)**
   - Status: 400
   - Message: "Recipient user is not verified"
   - Solution: Only verified users can receive transfers

---

## Best Practices

1. **Search Before Transfer**: Always search for users before transferring
2. **Verify User Details**: Show user details before confirming transfer
3. **Check Balance**: Display current balance and check before transfer
4. **Confirm Transfer**: Show confirmation dialog before processing
5. **Update Balance**: Refresh wallet balance after successful transfer
6. **Error Handling**: Handle all error scenarios gracefully
7. **Transaction History**: Show transfer in history immediately after success

---

## Security Considerations

1. **Distributor Only**: Only distributors can transfer money
2. **Verified Users**: Only verified users can receive transfers
3. **Self Transfer Prevention**: Distributors cannot transfer to themselves
4. **Balance Validation**: Check balance before processing transfer
5. **Atomic Transactions**: Transfer uses database transaction for data integrity
6. **Authentication**: All endpoints require user authentication

---

## Integration Checklist

- [ ] Implement user search functionality
- [ ] Display user list with selection
- [ ] Create transfer form with amount and note
- [ ] Show current wallet balance
- [ ] Implement balance validation
- [ ] Add confirmation dialog
- [ ] Handle transfer success/error
- [ ] Update wallet balance after transfer
- [ ] Show transfer history
- [ ] Test with various scenarios
- [ ] Verify distributor-only access
- [ ] Test insufficient balance scenario

---

## Support

For issues or questions regarding the Money Transfer API, please contact the development team.

---

**Last Updated:** December 2025

