# Orders Module — API Documentation

Base URL: `http://localhost:PORT/api/v1`

---

## Table of Contents
1. [Create Order](#1-post-orders--create-order)
2. [Get All Orders (Admin)](#2-get-orders--all-orders-admin)
3. [Get My Orders (User)](#3-get-ordersmy-orders--own-orders-user)
4. [Get Single Order](#4-get-ordersid--single-order)
5. [Update Order](#5-patch-ordersid--update-order)
6. [Delete Order](#6-delete-ordersid--delete-order)
7. [Payment Methods & Card Charges](#7-payment-methods--card-charges)

---

## 1. POST `/orders` — Create Order

**Auth:** USER token required

**Headers:**
```
Authorization: Bearer <user_token>
Content-Type: application/json
```

**Request Body:**
```json
{
  "serviceId": "svc-uuid-1",
  "paymentMethod": "CREDIT_CARD",
  "clientNote": "Please process my EB-2 NIW case as soon as possible."
}
```

**Field Rules:**

| Field | Required | Type | Notes |
|---|---|---|---|
| `serviceId` | Yes | string | Service must be active |
| `paymentMethod` | No | string | See [Payment Methods](#7-payment-methods--card-charges). If omitted, `cardCharge = 0` |
| `clientNote` | No | string | Client's message to admin |

> `amount` is auto-snapshotted from `Service.price` — never sent by the client.
> `orderNumber` is auto-generated (e.g. `ORD-20260531-A3F2`).

**Response `201`:**
```json
{
  "success": true,
  "message": "Order created successfully",
  "data": {
    "id": "ord-uuid-1",
    "orderNumber": "ORD-20260531-A3F2",
    "userId": "user-uuid-1",
    "serviceId": "svc-uuid-1",
    "status": "PENDING",
    "paymentStatus": "UNPAID",
    "amount": 500.00,
    "cardCharge": 15.00,
    "totalAmount": 515.00,
    "currency": "USD",
    "paymentMethod": "CREDIT_CARD",
    "transactionId": null,
    "clientNote": "Please process my EB-2 NIW case as soon as possible.",
    "adminNote": null,
    "deletedAt": null,
    "createdAt": "2026-05-31T10:00:00.000Z",
    "updatedAt": "2026-05-31T10:00:00.000Z",
    "service": {
      "id": "svc-uuid-1",
      "title": "EB-2 NIW Green Card Package",
      "price": 500.00
    },
    "user": {
      "id": "user-uuid-1",
      "name": "John Doe",
      "email": "john@example.com"
    }
  }
}
```

**Error — Service not found `404`:**
```json
{
  "success": false,
  "message": "Service not found"
}
```

**Error — Service inactive `406`:**
```json
{
  "success": false,
  "message": "This service is not available"
}
```

---

## 2. GET `/orders` — All Orders (Admin)

Supports pagination, sorting, and multiple filters.

**Auth:** ADMIN token required

**Headers:**
```
Authorization: Bearer <admin_token>
```

**Query Parameters:**

| Param | Type | Description |
|---|---|---|
| `searchTerm` | string | Searches `orderNumber` |
| `status` | string | Filter by order status |
| `paymentStatus` | string | Filter by payment status |
| `userId` | string | Filter by user ID |
| `serviceId` | string | Filter by service ID |
| `page` | number | Page number (default: `1`) |
| `limit` | number | Items per page (default: `10`) |
| `sortBy` | string | Field to sort by (default: `createdAt`) |
| `sortOrder` | string | `asc` or `desc` (default: `desc`) |

---

#### Basic — `GET /orders`

**Response `200`:**
```json
{
  "success": true,
  "message": "Orders retrieved successfully",
  "meta": {
    "page": 1,
    "limit": 10,
    "total": 2
  },
  "data": [
    {
      "id": "ord-uuid-1",
      "orderNumber": "ORD-20260531-A3F2",
      "userId": "user-uuid-1",
      "status": "PENDING",
      "paymentStatus": "UNPAID",
      "amount": 500.00,
      "cardCharge": 15.00,
      "totalAmount": 515.00,
      "currency": "USD",
      "paymentMethod": "CREDIT_CARD",
      "createdAt": "2026-05-31T10:00:00.000Z",
      "service": {
        "id": "svc-uuid-1",
        "title": "EB-2 NIW Green Card Package",
        "price": 500.00
      },
      "user": {
        "id": "user-uuid-1",
        "name": "John Doe",
        "email": "john@example.com"
      }
    },
    {
      "id": "ord-uuid-2",
      "orderNumber": "ORD-20260530-B9K1",
      "userId": "user-uuid-2",
      "status": "CONFIRMED",
      "paymentStatus": "PAID",
      "amount": 300.00,
      "cardCharge": 0.00,
      "totalAmount": 300.00,
      "currency": "USD",
      "paymentMethod": "BANK_TRANSFER",
      "createdAt": "2026-05-30T09:00:00.000Z",
      "service": {
        "id": "svc-uuid-2",
        "title": "O-1 Visa Package",
        "price": 300.00
      },
      "user": {
        "id": "user-uuid-2",
        "name": "Jane Smith",
        "email": "jane@example.com"
      }
    }
  ]
}
```

---

#### Filter by status — `GET /orders?status=PENDING`

**Response `200`:**
```json
{
  "success": true,
  "message": "Orders retrieved successfully",
  "meta": { "page": 1, "limit": 10, "total": 1 },
  "data": [
    {
      "id": "ord-uuid-1",
      "orderNumber": "ORD-20260531-A3F2",
      "status": "PENDING",
      "paymentStatus": "UNPAID",
      "amount": 500.00,
      "cardCharge": 15.00,
      "totalAmount": 515.00,
      "paymentMethod": "CREDIT_CARD"
    }
  ]
}
```

---

#### Filter by paymentStatus — `GET /orders?paymentStatus=PAID`

**Response `200`:**
```json
{
  "success": true,
  "message": "Orders retrieved successfully",
  "meta": { "page": 1, "limit": 10, "total": 1 },
  "data": [
    {
      "id": "ord-uuid-2",
      "orderNumber": "ORD-20260530-B9K1",
      "status": "CONFIRMED",
      "paymentStatus": "PAID",
      "amount": 300.00,
      "cardCharge": 0.00,
      "totalAmount": 300.00
    }
  ]
}
```

---

#### Filter by userId — `GET /orders?userId=user-uuid-1`

**Response `200`:**
```json
{
  "success": true,
  "message": "Orders retrieved successfully",
  "meta": { "page": 1, "limit": 10, "total": 1 },
  "data": [
    {
      "id": "ord-uuid-1",
      "orderNumber": "ORD-20260531-A3F2",
      "status": "PENDING",
      "totalAmount": 515.00
    }
  ]
}
```

---

#### Search by orderNumber — `GET /orders?searchTerm=A3F2`

**Response `200`:**
```json
{
  "success": true,
  "message": "Orders retrieved successfully",
  "meta": { "page": 1, "limit": 10, "total": 1 },
  "data": [
    {
      "id": "ord-uuid-1",
      "orderNumber": "ORD-20260531-A3F2",
      "status": "PENDING"
    }
  ]
}
```

---

#### Combined + Pagination — `GET /orders?status=PENDING&paymentStatus=UNPAID&page=1&limit=5&sortBy=createdAt&sortOrder=asc`

**Response `200`:**
```json
{
  "success": true,
  "message": "Orders retrieved successfully",
  "meta": { "page": 1, "limit": 5, "total": 1 },
  "data": [
    {
      "id": "ord-uuid-1",
      "orderNumber": "ORD-20260531-A3F2",
      "status": "PENDING",
      "paymentStatus": "UNPAID",
      "totalAmount": 515.00
    }
  ]
}
```

---

## 3. GET `/orders/my-orders` — Own Orders (User)

Returns only the authenticated user's orders. Supports pagination.

**Auth:** USER token required

**Headers:**
```
Authorization: Bearer <user_token>
```

**Query Parameters:** `page`, `limit`, `sortBy`, `sortOrder`

**Response `200`:**
```json
{
  "success": true,
  "message": "My orders retrieved successfully",
  "meta": {
    "page": 1,
    "limit": 10,
    "total": 1
  },
  "data": [
    {
      "id": "ord-uuid-1",
      "orderNumber": "ORD-20260531-A3F2",
      "status": "PENDING",
      "paymentStatus": "UNPAID",
      "amount": 500.00,
      "cardCharge": 15.00,
      "totalAmount": 515.00,
      "currency": "USD",
      "paymentMethod": "CREDIT_CARD",
      "clientNote": "Please process my EB-2 NIW case as soon as possible.",
      "adminNote": null,
      "createdAt": "2026-05-31T10:00:00.000Z",
      "service": {
        "id": "svc-uuid-1",
        "title": "EB-2 NIW Green Card Package",
        "price": 500.00
      },
      "user": {
        "id": "user-uuid-1",
        "name": "John Doe",
        "email": "john@example.com"
      }
    }
  ]
}
```

---

## 4. GET `/orders/:id` — Single Order

**Auth:** ADMIN token required

**Headers:**
```
Authorization: Bearer <admin_token>
```

**Response `200`:**
```json
{
  "success": true,
  "message": "Order retrieved successfully",
  "data": {
    "id": "ord-uuid-1",
    "orderNumber": "ORD-20260531-A3F2",
    "userId": "user-uuid-1",
    "status": "PENDING",
    "paymentStatus": "UNPAID",
    "amount": 500.00,
    "cardCharge": 15.00,
    "totalAmount": 515.00,
    "currency": "USD",
    "paymentMethod": "CREDIT_CARD",
    "transactionId": null,
    "clientNote": "Please process my EB-2 NIW case as soon as possible.",
    "adminNote": null,
    "createdAt": "2026-05-31T10:00:00.000Z",
    "updatedAt": "2026-05-31T10:00:00.000Z",
    "service": {
      "id": "svc-uuid-1",
      "title": "EB-2 NIW Green Card Package",
      "price": 500.00
    },
    "user": {
      "id": "user-uuid-1",
      "name": "John Doe",
      "email": "john@example.com"
    }
  }
}
```

**Error `404`:**
```json
{
  "success": false,
  "message": "Order not found"
}
```

---

## 5. PATCH `/orders/:id` — Update Order

Admin updates order status, payment details, or internal notes.

**Auth:** ADMIN token required

**Headers:**
```
Authorization: Bearer <admin_token>
Content-Type: application/json
```

**Request Body (all fields optional):**
```json
{
  "status": "CONFIRMED",
  "paymentStatus": "PAID",
  "paymentMethod": "BANK_TRANSFER",
  "transactionId": "TXN-20260531-00123",
  "adminNote": "Payment confirmed via bank transfer. Processing started.",
  "amount": 500.00
}
```

**Field Rules:**

| Field | Type | Allowed Values |
|---|---|---|
| `status` | string | `PENDING` \| `CONFIRMED` \| `IN_PROGRESS` \| `COMPLETED` \| `CANCELLED` |
| `paymentStatus` | string | `UNPAID` \| `PARTIALLY_PAID` \| `PAID` \| `REFUNDED` \| `FAILED` |
| `paymentMethod` | string | See [Payment Methods](#7-payment-methods--card-charges) |
| `transactionId` | string | External gateway reference |
| `adminNote` | string | Internal admin note (not visible to user) |
| `amount` | number | Min 0 — override the base amount if needed |

> Changing `paymentMethod` or `amount` automatically recalculates `cardCharge` and `totalAmount` using the current rates from SiteSettings.

**Response `200` — Confirming a bank transfer payment:**
```json
{
  "success": true,
  "message": "Order updated successfully",
  "data": {
    "id": "ord-uuid-1",
    "orderNumber": "ORD-20260531-A3F2",
    "status": "CONFIRMED",
    "paymentStatus": "PAID",
    "amount": 500.00,
    "cardCharge": 0.00,
    "totalAmount": 500.00,
    "currency": "USD",
    "paymentMethod": "BANK_TRANSFER",
    "transactionId": "TXN-20260531-00123",
    "adminNote": "Payment confirmed via bank transfer. Processing started.",
    "updatedAt": "2026-05-31T12:00:00.000Z",
    "service": {
      "id": "svc-uuid-1",
      "title": "EB-2 NIW Green Card Package",
      "price": 500.00
    },
    "user": {
      "id": "user-uuid-1",
      "name": "John Doe",
      "email": "john@example.com"
    }
  }
}
```

**Response `200` — Switching to credit card (charge recalculated):**
```json
{
  "success": true,
  "message": "Order updated successfully",
  "data": {
    "id": "ord-uuid-1",
    "orderNumber": "ORD-20260531-A3F2",
    "status": "CONFIRMED",
    "paymentStatus": "UNPAID",
    "amount": 500.00,
    "cardCharge": 15.00,
    "totalAmount": 515.00,
    "paymentMethod": "CREDIT_CARD",
    "updatedAt": "2026-05-31T12:30:00.000Z"
  }
}
```

**Error `404`:**
```json
{
  "success": false,
  "message": "Order not found"
}
```

---

## 6. DELETE `/orders/:id` — Delete Order (Soft)

Sets `deletedAt` timestamp. Order is excluded from all queries but preserved in the database.

**Auth:** ADMIN token required

**Headers:**
```
Authorization: Bearer <admin_token>
```

**Response `200`:**
```json
{
  "success": true,
  "message": "Order deleted successfully",
  "data": {
    "id": "ord-uuid-1",
    "orderNumber": "ORD-20260531-A3F2",
    "status": "PENDING",
    "deletedAt": "2026-05-31T13:00:00.000Z"
  }
}
```

**Error `404`:**
```json
{
  "success": false,
  "message": "Order not found"
}
```

---

## 7. Payment Methods & Card Charges

### Supported Payment Methods

| Value | Label | Surcharge |
|---|---|---|
| `DEBIT_CARD` | Debit Card | Configurable — set in SiteSettings (`debitCardCharge` %) |
| `CREDIT_CARD` | Credit Card | Configurable — set in SiteSettings (`creditCardCharge` %) |
| `BANK_TRANSFER` | Bank Transfer | No surcharge |
| `SSLCOMMERZ` | SSLCommerz | No surcharge |
| `EPS` | Easy Payment System | No surcharge |
| `OTHER` | Other | No surcharge |

### Charge Calculation

Card charges are fetched live from `SiteSettings` at order creation and update time:

```
cardCharge  = amount × (rate / 100)
totalAmount = amount + cardCharge
```

**Example with `CREDIT_CARD` at 3%:**
```
amount      = 500.00
cardCharge  = 500.00 × 0.03 = 15.00
totalAmount = 515.00
```

**Example with `DEBIT_CARD` at 1.5%:**
```
amount      = 500.00
cardCharge  = 500.00 × 0.015 = 7.50
totalAmount = 507.50
```

> Admin can update the rates at any time via `PATCH /site-settings/card-charges`. Every new or updated order picks up the latest rates automatically.

### Update Card Charge Rates (Admin)

```
PATCH /api/v1/site-settings/card-charges
Authorization: Bearer <admin_token>
Content-Type: application/json
```
```json
{
  "debitCardCharge": 1.5,
  "creditCardCharge": 3.0
}
```

---

## Order Status Flow

```
PENDING → CONFIRMED → IN_PROGRESS → COMPLETED
                              ↘
                           CANCELLED
```

| Status | Meaning |
|---|---|
| `PENDING` | Order created, awaiting admin confirmation |
| `CONFIRMED` | Admin confirmed the order |
| `IN_PROGRESS` | Case is actively being processed |
| `COMPLETED` | Case completed |
| `CANCELLED` | Order cancelled |

## Payment Status Flow

```
UNPAID → PARTIALLY_PAID → PAID
       ↘ FAILED
PAID   → REFUNDED
```

| Status | Meaning |
|---|---|
| `UNPAID` | No payment received yet |
| `PARTIALLY_PAID` | Deposit or partial payment received |
| `PAID` | Full payment confirmed |
| `REFUNDED` | Payment refunded |
| `FAILED` | Payment attempt failed |

---

## Notes

- `amount` is snapshotted from `Service.price` at order creation — future price changes do not affect existing orders
- `orderNumber` format: `ORD-YYYYMMDD-XXXX` (e.g. `ORD-20260531-A3F2`)
- Soft-deleted orders are excluded from all list queries automatically
- A user cannot order an inactive service (`406 Not Acceptable`)
- Every order response includes `service` (id, title, price) and `user` (id, name, email)
