Bug: [FEATURE] Add user roles for payouts



### Feature Description

Add respective variants and modules for managing permissions for payout operations.

PayoutRead,
PayoutWrite

Add these to user roles module.

### Possible Implementation

Add it similarly to existing roles.

### Have you spent some time checking if this feature request has been raised before?

- [X] I checked and didn't find a similar issue

### Have you read the Contributing Guidelines?

- [X] I have read the [Contributing Guidelines](https://github.com/juspay/hyperswitch/blob/main/docs/CONTRIBUTING.md)

### Are you willing to submit a PR?

None
diff --git a/crates/api_models/src/user_role.rs b/crates/api_models/src/user_role.rs
index 2e3d60024d3..31da8386ab6 100644
--- a/crates/api_models/src/user_role.rs
+++ b/crates/api_models/src/user_role.rs
@@ -32,6 +32,8 @@ pub enum Permission {
     UsersWrite,
     MerchantAccountCreate,
     WebhookEventRead,
+    PayoutWrite,
+    PayoutRead,
 }
 
 #[derive(Debug, serde::Serialize)]
@@ -48,6 +50,7 @@ pub enum PermissionModule {
     ThreeDsDecisionManager,
     SurchargeDecisionManager,
     AccountCreate,
+    Payouts,
 }
 
 #[derive(Debug, serde::Serialize)]
diff --git a/crates/router/src/routes/payouts.rs b/crates/router/src/routes/payouts.rs
index c8d1c05bb37..0eeb0f27f07 100644
--- a/crates/router/src/routes/payouts.rs
+++ b/crates/router/src/routes/payouts.rs
@@ -9,7 +9,7 @@ use super::app::AppState;
 use crate::types::api::payments as payment_types;
 use crate::{
     core::{api_locking, payouts::*},
-    services::{api, authentication as auth},
+    services::{api, authentication as auth, authorization::permissions::Permission},
     types::api::payouts as payout_types,
 };
 
@@ -77,7 +77,11 @@ pub async fn payouts_retrieve(
         &req,
         payout_retrieve_request,
         |state, auth, req| payouts_retrieve_core(state, auth.merchant_account, auth.key_store, req),
-        &auth::ApiKeyAuth,
+        auth::auth_type(
+            &auth::ApiKeyAuth,
+            &auth::JWTAuth(Permission::PayoutRead),
+            req.headers(),
+        ),
         api_locking::LockAction::NotApplicable,
     ))
     .await
@@ -225,7 +229,11 @@ pub async fn payouts_list(
         &req,
         payload,
         |state, auth, req| payouts_list_core(state, auth.merchant_account, req),
-        &auth::ApiKeyAuth,
+        auth::auth_type(
+            &auth::ApiKeyAuth,
+            &auth::JWTAuth(Permission::PayoutRead),
+            req.headers(),
+        ),
         api_locking::LockAction::NotApplicable,
     ))
     .await
@@ -259,7 +267,11 @@ pub async fn payouts_list_by_filter(
         &req,
         payload,
         |state, auth, req| payouts_filtered_list_core(state, auth.merchant_account, req),
-        &auth::ApiKeyAuth,
+        auth::auth_type(
+            &auth::ApiKeyAuth,
+            &auth::JWTAuth(Permission::PayoutRead),
+            req.headers(),
+        ),
         api_locking::LockAction::NotApplicable,
     ))
     .await
@@ -293,7 +305,11 @@ pub async fn payouts_list_available_filters(
         &req,
         payload,
         |state, auth, req| payouts_list_available_filters_core(state, auth.merchant_account, req),
-        &auth::ApiKeyAuth,
+        auth::auth_type(
+            &auth::ApiKeyAuth,
+            &auth::JWTAuth(Permission::PayoutRead),
+            req.headers(),
+        ),
         api_locking::LockAction::NotApplicable,
     ))
     .await
diff --git a/crates/router/src/services/authorization/info.rs b/crates/router/src/services/authorization/info.rs
index 7b82e84d64c..371087cc303 100644
--- a/crates/router/src/services/authorization/info.rs
+++ b/crates/router/src/services/authorization/info.rs
@@ -41,6 +41,7 @@ pub enum PermissionModule {
     ThreeDsDecisionManager,
     SurchargeDecisionManager,
     AccountCreate,
+    Payouts,
 }
 
 impl PermissionModule {
@@ -57,7 +58,8 @@ impl PermissionModule {
             Self::Disputes => "Everything related to disputes - like creating and viewing dispute related information are within this module",
             Self::ThreeDsDecisionManager => "View and configure 3DS decision rules configured for a merchant",
             Self::SurchargeDecisionManager =>"View and configure surcharge decision rules configured for a merchant",
-            Self::AccountCreate => "Create new account within your organization"
+            Self::AccountCreate => "Create new account within your organization",
+            Self::Payouts => "Everything related to payouts - like creating and viewing payout related information are within this module"
         }
     }
 }
@@ -168,6 +170,14 @@ impl ModuleInfo {
                     Permission::MerchantAccountCreate,
                 ]),
             },
+            PermissionModule::Payouts => Self {
+                module: module_name,
+                description,
+                permissions: get_permission_info_from_permissions(&[
+                    Permission::PayoutRead,
+                    Permission::PayoutWrite,
+                ]),
+            },
         }
     }
 }
@@ -184,10 +194,10 @@ fn get_group_info_from_permission_group(group: PermissionGroup) -> GroupInfo {
 fn get_group_description(group: PermissionGroup) -> &'static str {
     match group {
         PermissionGroup::OperationsView => {
-            "View Payments, Refunds, Mandates, Disputes and Customers"
+            "View Payments, Refunds, Payouts, Mandates, Disputes and Customers"
         }
         PermissionGroup::OperationsManage => {
-            "Create, modify and delete Payments, Refunds, Mandates, Disputes and Customers"
+            "Create, modify and delete Payments, Refunds, Payouts, Mandates, Disputes and Customers"
         }
         PermissionGroup::ConnectorsView => {
             "View connected Payment Processors, Payout Processors and Fraud & Risk Manager details"
diff --git a/crates/router/src/services/authorization/permission_groups.rs b/crates/router/src/services/authorization/permission_groups.rs
index 33647eb9a39..b68bef213cd 100644
--- a/crates/router/src/services/authorization/permission_groups.rs
+++ b/crates/router/src/services/authorization/permission_groups.rs
@@ -19,22 +19,24 @@ pub fn get_permissions_vec(permission_group: &PermissionGroup) -> &[Permission]
     }
 }
 
-pub static OPERATIONS_VIEW: [Permission; 6] = [
+pub static OPERATIONS_VIEW: [Permission; 7] = [
     Permission::PaymentRead,
     Permission::RefundRead,
     Permission::MandateRead,
     Permission::DisputeRead,
     Permission::CustomerRead,
     Permission::MerchantAccountRead,
+    Permission::PayoutRead,
 ];
 
-pub static OPERATIONS_MANAGE: [Permission; 6] = [
+pub static OPERATIONS_MANAGE: [Permission; 7] = [
     Permission::PaymentWrite,
     Permission::RefundWrite,
     Permission::MandateWrite,
     Permission::DisputeWrite,
     Permission::CustomerWrite,
     Permission::MerchantAccountRead,
+    Permission::PayoutWrite,
 ];
 
 pub static CONNECTORS_VIEW: [Permission; 2] = [
diff --git a/crates/router/src/services/authorization/permissions.rs b/crates/router/src/services/authorization/permissions.rs
index b5ba72df05e..997eff8274e 100644
--- a/crates/router/src/services/authorization/permissions.rs
+++ b/crates/router/src/services/authorization/permissions.rs
@@ -31,6 +31,8 @@ pub enum Permission {
     UsersWrite,
     MerchantAccountCreate,
     WebhookEventRead,
+    PayoutRead,
+    PayoutWrite,
 }
 
 impl Permission {
@@ -69,6 +71,8 @@ impl Permission {
             Self::UsersWrite => "Invite users, assign and update roles",
             Self::MerchantAccountCreate => "Create merchant account",
             Self::WebhookEventRead => "View webhook events",
+            Self::PayoutRead => "View all payouts",
+            Self::PayoutWrite => "Create payout, download payout data",
         }
     }
 }
diff --git a/crates/router/src/services/authorization/predefined_permissions.rs b/crates/router/src/services/authorization/predefined_permissions.rs
index bd0f37e2a0d..50f9a7196b8 100644
--- a/crates/router/src/services/authorization/predefined_permissions.rs
+++ b/crates/router/src/services/authorization/predefined_permissions.rs
@@ -64,6 +64,8 @@ pub static PREDEFINED_PERMISSIONS: Lazy<HashMap<&'static str, RoleInfo>> = Lazy:
                 Permission::UsersRead,
                 Permission::UsersWrite,
                 Permission::MerchantAccountCreate,
+                Permission::PayoutRead,
+                Permission::PayoutWrite,
             ],
             name: None,
             is_invitable: false,
@@ -88,6 +90,7 @@ pub static PREDEFINED_PERMISSIONS: Lazy<HashMap<&'static str, RoleInfo>> = Lazy:
                 Permission::MandateRead,
                 Permission::CustomerRead,
                 Permission::UsersRead,
+                Permission::PayoutRead,
             ],
             name: None,
             is_invitable: false,
@@ -126,6 +129,8 @@ pub static PREDEFINED_PERMISSIONS: Lazy<HashMap<&'static str, RoleInfo>> = Lazy:
                 Permission::UsersRead,
                 Permission::UsersWrite,
                 Permission::MerchantAccountCreate,
+                Permission::PayoutRead,
+                Permission::PayoutWrite,
             ],
             name: Some("Organization Admin"),
             is_invitable: false,
@@ -164,6 +169,8 @@ pub static PREDEFINED_PERMISSIONS: Lazy<HashMap<&'static str, RoleInfo>> = Lazy:
                 Permission::Analytics,
                 Permission::UsersRead,
                 Permission::UsersWrite,
+                Permission::PayoutRead,
+                Permission::PayoutWrite,
             ],
             name: Some("Admin"),
             is_invitable: true,
@@ -188,6 +195,7 @@ pub static PREDEFINED_PERMISSIONS: Lazy<HashMap<&'static str, RoleInfo>> = Lazy:
                 Permission::CustomerRead,
                 Permission::Analytics,
                 Permission::UsersRead,
+                Permission::PayoutRead,
             ],
             name: Some("View Only"),
             is_invitable: true,
@@ -213,6 +221,7 @@ pub static PREDEFINED_PERMISSIONS: Lazy<HashMap<&'static str, RoleInfo>> = Lazy:
                 Permission::Analytics,
                 Permission::UsersRead,
                 Permission::UsersWrite,
+                Permission::PayoutRead,
             ],
             name: Some("IAM"),
             is_invitable: true,
@@ -238,6 +247,7 @@ pub static PREDEFINED_PERMISSIONS: Lazy<HashMap<&'static str, RoleInfo>> = Lazy:
                 Permission::CustomerRead,
                 Permission::Analytics,
                 Permission::UsersRead,
+                Permission::PayoutRead,
             ],
             name: Some("Developer"),
             is_invitable: true,
@@ -268,6 +278,8 @@ pub static PREDEFINED_PERMISSIONS: Lazy<HashMap<&'static str, RoleInfo>> = Lazy:
                 Permission::CustomerRead,
                 Permission::Analytics,
                 Permission::UsersRead,
+                Permission::PayoutRead,
+                Permission::PayoutWrite,
             ],
             name: Some("Operator"),
             is_invitable: true,
@@ -289,6 +301,7 @@ pub static PREDEFINED_PERMISSIONS: Lazy<HashMap<&'static str, RoleInfo>> = Lazy:
                 Permission::MandateRead,
                 Permission::CustomerRead,
                 Permission::Analytics,
+                Permission::PayoutRead,
             ],
             name: Some("Customer Support"),
             is_invitable: true,
diff --git a/crates/router/src/types/domain/user.rs b/crates/router/src/types/domain/user.rs
index 63272732e63..176b5810158 100644
--- a/crates/router/src/types/domain/user.rs
+++ b/crates/router/src/types/domain/user.rs
@@ -808,6 +808,7 @@ impl From<info::PermissionModule> for user_role_api::PermissionModule {
             info::PermissionModule::ThreeDsDecisionManager => Self::ThreeDsDecisionManager,
             info::PermissionModule::SurchargeDecisionManager => Self::SurchargeDecisionManager,
             info::PermissionModule::AccountCreate => Self::AccountCreate,
+            info::PermissionModule::Payouts => Self::Payouts,
         }
     }
 }
diff --git a/crates/router/src/utils/user_role.rs b/crates/router/src/utils/user_role.rs
index fa9eba8c27f..23b5bcf0f38 100644
--- a/crates/router/src/utils/user_role.rs
+++ b/crates/router/src/utils/user_role.rs
@@ -44,6 +44,8 @@ impl From<Permission> for user_role_api::Permission {
             Permission::UsersWrite => Self::UsersWrite,
             Permission::MerchantAccountCreate => Self::MerchantAccountCreate,
             Permission::WebhookEventRead => Self::WebhookEventRead,
+            Permission::PayoutRead => Self::PayoutRead,
+            Permission::PayoutWrite => Self::PayoutWrite,
         }
     }
 }
diff --git a/openapi/openapi_spec.json b/openapi/openapi_spec.json
index 28b8f9ef796..1868eb9b4d9 100644
--- a/openapi/openapi_spec.json
+++ b/openapi/openapi_spec.json
@@ -3866,64 +3866,6 @@
         ]
       }
     },
-    "/payouts/list": {
-      "get": {
-        "tags": [
-          "Payouts"
-        ],
-        "summary": "Payouts - List",
-        "description": "Payouts - List",
-        "operationId": "List payouts",
-        "responses": {
-          "200": {
-            "description": "Payouts listed",
-            "content": {
-              "application/json": {
-                "schema": {
-                  "$ref": "#/components/schemas/PayoutListResponse"
-                }
-              }
-            }
-          },
-          "404": {
-            "description": "Payout not found"
-          }
-        },
-        "security": [
-          {
-            "api_key": []
-          }
-        ]
-      },
-      "post": {
-        "tags": [
-          "Payouts"
-        ],
-        "summary": "Payouts - Filter",
-        "description": "Payouts - Filter",
-        "operationId": "Filter payouts",
-        "responses": {
-          "200": {
-            "description": "Payouts filtered",
-            "content": {
-              "application/json": {
-                "schema": {
-                  "$ref": "#/components/schemas/PayoutListResponse"
-                }
-              }
-            }
-          },
-          "404": {
-            "description": "Payout not found"
-          }
-        },
-        "security": [
-          {
-            "api_key": []
-          }
-        ]
-      }
-    },
     "/payouts/{payout_id}": {
       "get": {
         "tags": [
@@ -4116,6 +4058,64 @@
         ]
       }
     },
+    "/payouts/list": {
+      "get": {
+        "tags": [
+          "Payouts"
+        ],
+        "summary": "Payouts - List",
+        "description": "Payouts - List",
+        "operationId": "List payouts",
+        "responses": {
+          "200": {
+            "description": "Payouts listed",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/PayoutListResponse"
+                }
+              }
+            }
+          },
+          "404": {
+            "description": "Payout not found"
+          }
+        },
+        "security": [
+          {
+            "api_key": []
+          }
+        ]
+      },
+      "post": {
+        "tags": [
+          "Payouts"
+        ],
+        "summary": "Payouts - Filter",
+        "description": "Payouts - Filter",
+        "operationId": "Filter payouts",
+        "responses": {
+          "200": {
+            "description": "Payouts filtered",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/PayoutListResponse"
+                }
+              }
+            }
+          },
+          "404": {
+            "description": "Payout not found"
+          }
+        },
+        "security": [
+          {
+            "api_key": []
+          }
+        ]
+      }
+    },
     "/api_keys/{merchant_id)": {
       "post": {
         "tags": [

## Type of Change
<!-- Put an `x` in the boxes that apply -->

- [ ] Bugfix
- [ ] New feature
- [x] Enhancement
- [ ] Refactoring
- [ ] Dependency updates
- [ ] Documentation
- [ ] CI/CD

## Description
<!-- Describe your changes in detail -->
This PR introduces user roles for `Payouts`. `PayoutRead` and `PayoutWrite` are added as permission under payout persmissions. This permission are added to list(get/post), retrieval and filter api's for payouts. 

### Additional Changes

- [ ] This PR modifies the API contract
- [ ] This PR modifies the database schema
- [ ] This PR modifies application configuration/environment variables

<!--
Provide links to the files with corresponding changes.

Following are the paths where you can find config files:
1. `config`
2. `crates/router/src/configs`
3. `loadtest/config`
-->


## Motivation and Context
<!--
Why is this change required? What problem does it solve?
If it fixes an open issue, please link to the issue here.

If you don't have an issue, we'd recommend starting with one first so the PR
can focus on the implementation (unless it is an obvious bug or documentation fix
that will have little conversation).
-->
User permissions are used while user accessing the payout data via dashboard. `PayoutRead` and `PayoutWrite` are added as permission under payout persmissions. This permission are added to list(get/post), retrieval and filter api's of payouts. 


## How did you test it?
<!--
Did you write an integration/unit/API test to verify the code changes?
Or did you test this change manually (provide relevant screenshots)?
-->
1) User with `org_admin`, `internal_admin`, `merchant_admin`, `merchant_operator` will have PayoutRead and PayourWrite. All other user roles will have only `PayoutRead`. This below curl will get information of user role permissions.
```
curl --location --request GET '{{base_url}}/user/permission_info' \
--header 'Authorization: {{user_token}}' \
--header 'Content-Type: application/json' \
--data-raw '{
    "email": "email@gmail.com"
}'
```
2) View all permissions from below curl 

```
curl --location --request GET '{{base_url}}/user/role/list' \
--header 'Authorization: {{user_token}}'
```
Response : 
```
[
    {
        "role_id": "merchant_view_only",
        "permissions": [
            "PayoutRead",
            "CustomerRead",
            "MerchantConnectorAccountRead",
            "MandateRead",
            "PaymentRead",
            "SurchargeDecisionManagerRead",
            "Analytics",
            "DisputeRead",
            "MerchantAccountRead",
            "RoutingRead",
            "UsersRead",
            "RefundRead",
            "ThreeDsDecisionManagerRead"
        ],
        "role_name": "view_only",
        "role_scope": "organization"
    },
    {
        "role_id": "merchant_iam_admin",
        "permissions": [
            "UsersWrite",
            "Analytics",
            "UsersRead",
            "PaymentRead",
            "MerchantAccountRead",
            "MandateRead",
            "DisputeRead",
            "PayoutRead",
            "RefundRead",
            "CustomerRead"
        ],
        "role_name": "iam",
        "role_scope": "organization"
    },
    {
        "role_id": "merchant_developer",
        "permissions": [
            "RefundRead",
            "PayoutRead",
            "MerchantAccountWrite",
            "ApiKeyWrite",
            "PaymentRead",
            "MerchantConnectorAccountRead",
            "UsersRead",
            "MandateRead",
            "DisputeRead",
            "MerchantAccountRead",
            "CustomerRead",
            "ApiKeyRead",
            "Analytics",
            "WebhookEventRead"
        ],
        "role_name": "developer",
        "role_scope": "organization"
    },
    {
        "role_id": "merchant_customer_support",
        "permissions": [
            "MandateRead",
            "PaymentRead",
            "DisputeRead",
            "PayoutRead",
            "MerchantAccountRead",
            "Analytics",
            "RefundRead",
            "CustomerRead",
            "UsersRead"
        ],
        "role_name": "customer_support",
        "role_scope": "organization"
    },
    {
        "role_id": "merchant_admin",
        "permissions": [
            "PayoutRead",
            "MandateWrite",
            "RoutingRead",
            "PayoutWrite",
            "RefundWrite",
            "MerchantConnectorAccountWrite",
            "SurchargeDecisionManagerRead",
            "DisputeRead",
            "RoutingWrite",
            "SurchargeDecisionManagerWrite",
            "Analytics",
            "ThreeDsDecisionManagerWrite",
            "MerchantAccountRead",
            "UsersRead",
            "MerchantConnectorAccountRead",
            "UsersWrite",
            "MandateRead",
            "MerchantAccountWrite",
            "ApiKeyRead",
            "ApiKeyWrite",
            "RefundRead",
            "WebhookEventRead",
            "PaymentWrite",
            "PaymentRead",
            "CustomerRead",
            "DisputeWrite",
            "ThreeDsDecisionManagerRead",
            "CustomerWrite"
        ],
        "role_name": "admin",
        "role_scope": "organization"
    },
    {
        "role_id": "merchant_operator",
        "permissions": [
            "RoutingRead",
            "PayoutWrite",
            "MerchantAccountRead",
            "SurchargeDecisionManagerRead",
            "PaymentWrite",
            "CustomerWrite",
            "MandateWrite",
            "DisputeWrite",
            "RefundWrite",
            "DisputeRead",
            "CustomerRead",
            "MerchantConnectorAccountRead",
            "ThreeDsDecisionManagerRead",
            "UsersRead",
            "PaymentRead",
            "MandateRead",
            "PayoutRead",
            "RefundRead",
            "Analytics"
        ],
        "role_name": "operator",
        "role_scope": "organization"
    }
]
```




## Checklist
<!-- Put an `x` in the boxes that apply -->

- [x] I formatted the code `cargo +nightly fmt --all`
- [x] I addressed lints thrown by `cargo clippy`
- [x] I reviewed the submitted code
- [ ] I added unit tests for my changes where possible
- [ ] I added a [CHANGELOG](/CHANGELOG.md) entry if applicable
