> ## Documentation Index
> Fetch the complete documentation index at: https://docs-paymentgateway.redahaloubi.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Merchant API

> Merchant account management, team collaboration, and business settings

# Merchant Service API

The Merchant Service manages business accounts, team members, and merchant configurations. It provides multi-merchant support, role-based team management, and centralized settings control.

<Info>
  **Base URL:** `https://paymentgateway.redahaloubi.com/api/v1`

  All endpoints require JWT authentication unless noted otherwise.
</Info>

***

## Authentication

All Merchant API endpoints require authentication via JWT Bearer token:

```http theme={null}
Authorization: Bearer {access_token}
```

<Warning>
  **Permission Requirements:**

  Most endpoints also require specific permissions based on your role in the merchant:

  * **Read operations:** All team members
  * **Create operations:** Owner, Admin, Manager
  * **Update operations:** Owner, Admin
  * **Delete operations:** Owner only
</Warning>

***

## Rate Limits

<CardGroup cols={2}>
  <Card title="Standard Endpoints" icon="gauge">
    **100 requests per second** per user

    Applied to most merchant operations
  </Card>

  <Card title="Team Management" icon="users">
    **20 requests per second** per merchant

    Invitation and team modification endpoints
  </Card>
</CardGroup>

***

## Merchant Endpoints

### Create Merchant

<ParamField path="POST" type="endpoint">
  `/merchants`
</ParamField>

Create a new merchant account. Users can only create one merchant account. The user becomes the Owner with full access.

**Request Body**

<ParamField body="business_name" type="string" required>
  Public-facing business name

  **Example:** "Acme Corporation"
</ParamField>

<ParamField body="legal_name" type="string">
  Legal business name (if different from business name)

  **Example:** "Acme Corp LLC"
</ParamField>

<ParamField body="email" type="string" required>
  Business contact email

  **Format:** Valid email address
</ParamField>

<ParamField body="phone" type="string">
  Business phone number

  **Example:** "+1-555-123-4567"
</ParamField>

<ParamField body="website" type="string">
  Business website URL

  **Example:** "[https://acme.com](https://acme.com)"
</ParamField>

<ParamField body="business_type" type="string" required>
  Type of business entity

  **Options:** `individual`, `sole_proprietor`, `partnership`, `corporation`, `non_profit`
</ParamField>

**Example Request**

```bash theme={null}
curl -X POST https://paymentgateway.redahaloubi.com/api/v1/merchants \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json" \
  -d '{
    "business_name": "Acme Corporation",
    "legal_name": "Acme Corp LLC",
    "email": "contact@acme.com",
    "phone": "+1-555-123-4567",
    "website": "https://acme.com",
    "business_type": "corporation"
  }'
```

**Response (201 Created)**

```json theme={null}
{
  "success": true,
  "data": {
    "merchant": {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "merchant_code": "mch_abc123def456",
      "owner_id": "user_abc123",
      "business_name": "Acme Corporation",
      "legal_name": "Acme Corp LLC",
      "email": "contact@acme.com",
      "phone": "+1-555-123-4567",
      "website": "https://acme.com",
      "status": "pending_review",
      "business_type": "corporation",
      "country_code": "US",
      "currency_code": "USD",
      "timezone": "America/New_York",
      "created_at": "2026-01-24T10:00:00Z",
      "updated_at": "2026-01-24T10:00:00Z"
    }
  },
  "message": "Merchant created successfully"
}
```

<Accordion title="Error Responses">
  **409 Conflict - User Already Has Merchant**

  ```json theme={null}
  {
    "success": false,
    "error": "user already has a merchant"
  }
  ```

  **400 Bad Request - Invalid Business Type**

  ```json theme={null}
  {
    "success": false,
    "error": "business_type must be one of: individual, sole_proprietor, partnership, corporation, non_profit"
  }
  ```

  **400 Bad Request - Invalid Email**

  ```json theme={null}
  {
    "success": false,
    "error": "email must be a valid email address"
  }
  ```
</Accordion>

<Info>
  **Merchant Status:**

  * `pending_review`: Newly created, awaiting verification
  * `active`: Verified and can process payments
  * `suspended`: Temporarily disabled
  * `closed`: Permanently deactivated
</Info>

***

### List User Merchants

<ParamField path="GET" type="endpoint">
  `/merchants`
</ParamField>

Get all merchants where the authenticated user is a team member (including owned merchants).

**Example Request**

```bash theme={null}
curl -X GET https://paymentgateway.redahaloubi.com/api/v1/merchants \
  -H "Authorization: Bearer {access_token}"
```

**Response (200 OK)**

```json theme={null}
{
  "success": true,
  "data": {
    "merchants": [
      {
        "id": "merchant_abc123",
        "merchant_code": "mch_abc123def456",
        "owner_id": "user_abc123",
        "business_name": "Acme Corporation",
        "legal_name": "Acme Corp LLC",
        "email": "contact@acme.com",
        "phone": "+1-555-123-4567",
        "website": "https://acme.com",
        "status": "active",
        "business_type": "corporation",
        "country_code": "US",
        "currency_code": "USD",
        "timezone": "America/New_York",
        "created_at": "2026-01-24T10:00:00Z",
        "updated_at": "2026-01-24T10:00:00Z"
      },
      {
        "id": "merchant_xyz789",
        "merchant_code": "mch_xyz789uvw012",
        "owner_id": "user_def456",
        "business_name": "Tech Startup Inc",
        "email": "billing@techstartup.io",
        "status": "active",
        "business_type": "corporation",
        "created_at": "2026-01-20T14:00:00Z",
        "updated_at": "2026-01-23T09:30:00Z"
      }
    ],
    "count": 2
  }
}
```

<Info>
  **Multi-Merchant Support:** Users can be members of multiple merchants with different roles. The response includes all merchants where the user has any level of access.
</Info>

***

### Get Merchant

<ParamField path="GET" type="endpoint">
  `/merchants/:id`
</ParamField>

Get basic information about a specific merchant.

**Path Parameters**

<ParamField path="id" type="string" required>
  Merchant ID (UUID)
</ParamField>

**Required Permission:** `read` in the merchant

**Example Request**

```bash theme={null}
curl -X GET https://paymentgateway.redahaloubi.com/api/v1/merchants/{merchant_id} \
  -H "Authorization: Bearer {access_token}"
```

**Response (200 OK)**

```json theme={null}
{
  "success": true,
  "data": {
    "merchant": {
      "id": "merchant_abc123",
      "merchant_code": "mch_abc123def456",
      "owner_id": "user_abc123",
      "business_name": "Acme Corporation",
      "legal_name": "Acme Corp LLC",
      "email": "contact@acme.com",
      "phone": "+1-555-123-4567",
      "website": "https://acme.com",
      "status": "active",
      "business_type": "corporation",
      "country_code": "US",
      "currency_code": "USD",
      "timezone": "America/New_York",
      "created_at": "2026-01-24T10:00:00Z",
      "updated_at": "2026-01-24T10:00:00Z"
    }
  }
}
```

<Accordion title="Error Responses">
  **403 Forbidden - Access Denied**

  ```json theme={null}
  {
    "success": false,
    "error": "access denied"
  }
  ```

  **404 Not Found**

  ```json theme={null}
  {
    "success": false,
    "error": "merchant not found"
  }
  ```
</Accordion>

***

### Get Merchant Details

<ParamField path="GET" type="endpoint">
  `/merchants/:id/details`
</ParamField>

Get comprehensive merchant information including settings, business info, branding, and verification status.

**Path Parameters**

<ParamField path="id" type="string" required>
  Merchant ID (UUID)
</ParamField>

**Required Permission:** `read` in the merchant

**Example Request**

```bash theme={null}
curl -X GET https://paymentgateway.redahaloubi.com/api/v1/merchants/{merchant_id}/details \
  -H "Authorization: Bearer {access_token}"
```

**Response (200 OK)**

```json theme={null}
{
  "success": true,
  "data": {
    "merchant": {
      "id": "merchant_abc123",
      "merchant_code": "mch_abc123def456",
      "business_name": "Acme Corporation",
      "status": "active",
      "created_at": "2026-01-24T10:00:00Z"
    },
    "settings": {
      "default_currency": "USD",
      "auto_settle": true,
      "settle_schedule": "daily",
      "webhook_url": "https://acme.com/webhooks/payment",
      "notification_email": "billing@acme.com",
      "send_email_receipts": true
    },
    "business_info": {
      "address_line1": "123 Main St",
      "address_line2": "Suite 100",
      "city": "San Francisco",
      "state": "CA",
      "postal_code": "94102",
      "country": "US",
      "tax_id": "12-3456789"
    },
    "branding": {
      "logo_url": "https://cdn.acme.com/logo.png",
      "brand_color": "#FF6B35",
      "favicon_url": "https://cdn.acme.com/favicon.ico"
    },
    "verification": {
      "status": "verified",
      "verified_at": "2026-01-25T08:00:00Z",
      "kyc_status": "approved",
      "document_status": "approved"
    }
  }
}
```

***

### Update Merchant

<ParamField path="PATCH" type="endpoint">
  `/merchants/:id`
</ParamField>

Update merchant information. Only specified fields will be updated.

**Path Parameters**

<ParamField path="id" type="string" required>
  Merchant ID (UUID)
</ParamField>

**Required Permission:** `update` (Owner or Admin)

**Request Body**

<ParamField body="business_name" type="string">
  Updated business name
</ParamField>

<ParamField body="email" type="string">
  Updated business email

  **Format:** Valid email address
</ParamField>

<ParamField body="phone" type="string">
  Updated phone number
</ParamField>

<ParamField body="website" type="string">
  Updated website URL
</ParamField>

**Example Request**

```bash theme={null}
curl -X PATCH https://paymentgateway.redahaloubi.com/api/v1/merchants/{merchant_id} \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json" \
  -d '{
    "business_name": "Acme Inc",
    "website": "https://acmeinc.com"
  }'
```

**Response (200 OK)**

```json theme={null}
{
  "success": true,
  "message": "Merchant updated successfully"
}
```

<Accordion title="Error Responses">
  **403 Forbidden - Insufficient Permissions**

  ```json theme={null}
  {
    "success": false,
    "error": "access denied"
  }
  ```

  **400 Bad Request - Invalid Email**

  ```json theme={null}
  {
    "success": false,
    "error": "email must be a valid email address"
  }
  ```
</Accordion>

***

### Delete Merchant

<ParamField path="DELETE" type="endpoint">
  `/merchants/:id`
</ParamField>

Soft delete a merchant account. This action can only be performed by the Owner.

**Path Parameters**

<ParamField path="id" type="string" required>
  Merchant ID (UUID)
</ParamField>

**Required Permission:** `delete` (Owner only)

**Example Request**

```bash theme={null}
curl -X DELETE https://paymentgateway.redahaloubi.com/api/v1/merchants/{merchant_id} \
  -H "Authorization: Bearer {access_token}"
```

**Response (200 OK)**

```json theme={null}
{
  "success": true,
  "message": "Merchant deleted successfully"
}
```

<Warning>
  **Soft Delete:** Merchants are soft-deleted, meaning:

  * Data is not permanently removed
  * Account can be restored by support
  * All team members lose access immediately
  * Active subscriptions/payments are cancelled
  * API keys are immediately deactivated
</Warning>

<Accordion title="Error Responses">
  **403 Forbidden - Only Owner Can Delete**

  ```json theme={null}
  {
    "success": false,
    "error": "only the merchant owner can delete the merchant"
  }
  ```
</Accordion>

***

## Team Management Endpoints

### Get Team Members

<ParamField path="GET" type="endpoint">
  `/merchants/:id/team`
</ParamField>

List all team members in a merchant with their roles and status.

**Path Parameters**

<ParamField path="id" type="string" required>
  Merchant ID (UUID)
</ParamField>

**Required Permission:** `read` in the merchant

**Example Request**

```bash theme={null}
curl -X GET https://paymentgateway.redahaloubi.com/api/v1/merchants/{merchant_id}/team \
  -H "Authorization: Bearer {access_token}"
```

**Response (200 OK)**

```json theme={null}
{
  "success": true,
  "data": {
    "team_members": [
      {
        "id": "member_abc123",
        "user_id": "user_abc123",
        "email": "john@acme.com",
        "name": "John Doe",
        "role_id": "role_owner_123",
        "role_name": "Owner",
        "status": "active",
        "joined_at": "2026-01-24T10:00:00Z",
        "last_active_at": "2026-01-25T15:30:00Z"
      },
      {
        "id": "member_def456",
        "user_id": "user_def456",
        "email": "jane@acme.com",
        "name": "Jane Smith",
        "role_id": "role_admin_456",
        "role_name": "Admin",
        "status": "active",
        "joined_at": "2026-01-25T09:00:00Z",
        "last_active_at": "2026-01-25T14:45:00Z"
      },
      {
        "id": "member_ghi789",
        "user_id": "user_ghi789",
        "email": "bob@acme.com",
        "name": "Bob Johnson",
        "role_id": "role_staff_012",
        "role_name": "Staff",
        "status": "pending",
        "joined_at": null,
        "invited_at": "2026-01-25T10:00:00Z"
      }
    ],
    "count": 3
  }
}
```

<Info>
  **Team Member Status:**

  * `active`: User has accepted invitation and has access
  * `pending`: Invitation sent but not yet accepted
  * `suspended`: Access temporarily revoked
</Info>

***

### Invite Team Member

<ParamField path="POST" type="endpoint">
  `/merchants/:id/team/invite`
</ParamField>

Send an invitation to join the merchant team. The invitee receives an email with an invitation token.

**Path Parameters**

<ParamField path="id" type="string" required>
  Merchant ID (UUID)
</ParamField>

**Required Permission:** `create` (Owner, Admin, or Manager)

**Request Body**

<ParamField body="email" type="string" required>
  Email address of the person to invite

  **Format:** Valid email address
</ParamField>

<ParamField body="role_id" type="string" required>
  Role ID to assign (from Auth Service roles)

  **Format:** UUID
</ParamField>

<ParamField body="role_name" type="string" required>
  Role name for display

  **Options:** Owner, Admin, Manager, Staff
</ParamField>

**Example Request**

```bash theme={null}
curl -X POST https://paymentgateway.redahaloubi.com/api/v1/merchants/{merchant_id}/team/invite \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "newmember@acme.com",
    "role_id": "role_manager_789",
    "role_name": "Manager"
  }'
```

**Response (201 Created)**

```json theme={null}
{
  "success": true,
  "data": {
    "invitation": {
      "id": "invitation_abc123",
      "email": "newmember@acme.com",
      "status": "pending",
      "role_name": "Manager",
      "invitation_token": "inv_abc123def456ghi789jkl012",
      "expires_at": "2026-01-31T10:00:00Z",
      "created_at": "2026-01-24T10:00:00Z"
    }
  },
  "message": "Invitation sent successfully"
}
```

<Accordion title="Error Responses">
  **400 Bad Request - User Already in Team**

  ```json theme={null}
  {
    "success": false,
    "error": "user is already a member of this merchant"
  }
  ```

  **400 Bad Request - Pending Invitation Exists**

  ```json theme={null}
  {
    "success": false,
    "error": "pending invitation already exists for this email"
  }
  ```

  **403 Forbidden - Insufficient Permissions**

  ```json theme={null}
  {
    "success": false,
    "error": "you do not have permission to invite team members"
  }
  ```
</Accordion>

<Info>
  **Invitation Lifecycle:**

  * Invitations expire after **7 days**
  * User must have an account to accept (or register first)
  * One invitation per email per merchant at a time
  * Invitation token is single-use
</Info>

***

### Accept Invitation

<ParamField path="POST" type="endpoint">
  `/invitations/:token/accept`
</ParamField>

Accept a team invitation using the invitation token received via email.

**Path Parameters**

<ParamField path="token" type="string" required>
  Invitation token from email

  **Example:** `inv_abc123def456ghi789jkl012`
</ParamField>

**Example Request**

```bash theme={null}
curl -X POST https://paymentgateway.redahaloubi.com/api/v1/invitations/inv_abc123def456/accept \
  -H "Authorization: Bearer {access_token}"
```

**Response (200 OK)**

```json theme={null}
{
  "success": true,
  "message": "Invitation accepted successfully"
}
```

<Accordion title="Error Responses">
  **400 Bad Request - Invalid Token**

  ```json theme={null}
  {
    "success": false,
    "error": "invalid or expired invitation token"
  }
  ```

  **400 Bad Request - Email Mismatch**

  ```json theme={null}
  {
    "success": false,
    "error": "invitation email does not match your account email"
  }
  ```

  **409 Conflict - Already Accepted**

  ```json theme={null}
  {
    "success": false,
    "error": "invitation has already been accepted"
  }
  ```
</Accordion>

***

### Update Team Member Role

<ParamField path="PATCH" type="endpoint">
  `/merchants/:id/team/:user_id`
</ParamField>

Change a team member's role. Cannot modify the Owner's role.

**Path Parameters**

<ParamField path="id" type="string" required>
  Merchant ID (UUID)
</ParamField>

<ParamField path="user_id" type="string" required>
  User ID of the team member to update (UUID)
</ParamField>

**Required Permission:** `update` (Owner or Admin)

**Request Body**

<ParamField body="role_id" type="string" required>
  New role ID (UUID)
</ParamField>

<ParamField body="role_name" type="string" required>
  New role name

  **Options:** Admin, Manager, Staff
</ParamField>

**Example Request**

```bash theme={null}
curl -X PATCH https://paymentgateway.redahaloubi.com/api/v1/merchants/{merchant_id}/team/{user_id} \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json" \
  -d '{
    "role_id": "role_admin_456",
    "role_name": "Admin"
  }'
```

**Response (200 OK)**

```json theme={null}
{
  "success": true,
  "message": "Team member role updated successfully"
}
```

<Accordion title="Error Responses">
  **400 Bad Request - Cannot Modify Owner**

  ```json theme={null}
  {
    "success": false,
    "error": "cannot modify the owner's role"
  }
  ```

  **403 Forbidden - Insufficient Permissions**

  ```json theme={null}
  {
    "success": false,
    "error": "only owner and admin can update team member roles"
  }
  ```
</Accordion>

***

### Remove Team Member

<ParamField path="DELETE" type="endpoint">
  `/merchants/:id/team/:user_id`
</ParamField>

Remove a team member from the merchant. Cannot remove the Owner.

**Path Parameters**

<ParamField path="id" type="string" required>
  Merchant ID (UUID)
</ParamField>

<ParamField path="user_id" type="string" required>
  User ID of the team member to remove (UUID)
</ParamField>

**Required Permission:** `delete` (Owner only)

**Example Request**

```bash theme={null}
curl -X DELETE https://paymentgateway.redahaloubi.com/api/v1/merchants/{merchant_id}/team/{user_id} \
  -H "Authorization: Bearer {access_token}"
```

**Response (200 OK)**

```json theme={null}
{
  "success": true,
  "message": "Team member removed successfully"
}
```

<Accordion title="Error Responses">
  **400 Bad Request - Cannot Remove Owner**

  ```json theme={null}
  {
    "success": false,
    "error": "cannot remove the merchant owner"
  }
  ```

  **403 Forbidden - Only Owner Can Remove**

  ```json theme={null}
  {
    "success": false,
    "error": "only the owner can remove team members"
  }
  ```
</Accordion>

<Warning>
  **Immediate Effect:** Removing a team member immediately revokes all access to the merchant, including:

  * Dashboard access
  * API permissions
  * Payment data visibility
  * Reports and analytics
</Warning>

***

### Get Pending Invitations

<ParamField path="GET" type="endpoint">
  `/merchants/:id/invitations`
</ParamField>

List all pending (not yet accepted) invitations for a merchant.

**Path Parameters**

<ParamField path="id" type="string" required>
  Merchant ID (UUID)
</ParamField>

**Required Permission:** `read` in the merchant

**Example Request**

```bash theme={null}
curl -X GET https://paymentgateway.redahaloubi.com/api/v1/merchants/{merchant_id}/invitations \
  -H "Authorization: Bearer {access_token}"
```

**Response (200 OK)**

```json theme={null}
{
  "success": true,
  "data": {
    "invitations": [
      {
        "id": "invitation_abc123",
        "email": "newmember@acme.com",
        "role_name": "Manager",
        "status": "pending",
        "invited_by": "user_abc123",
        "invited_by_name": "John Doe",
        "created_at": "2026-01-24T10:00:00Z",
        "expires_at": "2026-01-31T10:00:00Z"
      },
      {
        "id": "invitation_def456",
        "email": "designer@acme.com",
        "role_name": "Staff",
        "status": "pending",
        "invited_by": "user_abc123",
        "invited_by_name": "John Doe",
        "created_at": "2026-01-25T09:00:00Z",
        "expires_at": "2026-02-01T09:00:00Z"
      }
    ],
    "count": 2
  }
}
```

***

### Cancel Invitation

<ParamField path="DELETE" type="endpoint">
  `/invitations/:id`
</ParamField>

Cancel a pending invitation before it's accepted.

**Path Parameters**

<ParamField path="id" type="string" required>
  Invitation ID (UUID)
</ParamField>

**Required Permission:** `delete` (Owner) or invitation creator

**Example Request**

```bash theme={null}
curl -X DELETE https://paymentgateway.redahaloubi.com/api/v1/invitations/{invitation_id} \
  -H "Authorization: Bearer {access_token}"
```

**Response (200 OK)**

```json theme={null}
{
  "success": true,
  "message": "Invitation cancelled successfully"
}
```

<Accordion title="Error Responses">
  **400 Bad Request - Already Accepted**

  ```json theme={null}
  {
    "success": false,
    "error": "cannot cancel an accepted invitation"
  }
  ```

  **403 Forbidden**

  ```json theme={null}
  {
    "success": false,
    "error": "only the invitation creator or owner can cancel invitations"
  }
  ```
</Accordion>

***

## Settings Endpoints

### Get Settings

<ParamField path="GET" type="endpoint">
  `/merchants/:id/settings`
</ParamField>

Get merchant settings including payment configuration, webhooks, and preferences.

**Path Parameters**

<ParamField path="id" type="string" required>
  Merchant ID (UUID)
</ParamField>

**Required Permission:** `read` in the merchant

**Example Request**

```bash theme={null}
curl -X GET https://paymentgateway.redahaloubi.com/api/v1/merchants/{merchant_id}/settings \
  -H "Authorization: Bearer {access_token}"
```

**Response (200 OK)**

```json theme={null}
{
  "success": true,
  "data": {
    "settings": {
      "id": "settings_abc123",
      "merchant_id": "merchant_abc123",
      "default_currency": "USD",
      "auto_settle": true,
      "settle_schedule": "daily",
      "webhook_url": "https://acme.com/webhooks/payment",
      "webhook_secret": "whsec_abc123def456",
      "notification_email": "billing@acme.com",
      "send_email_receipts": true,
      "receipt_email_from": "noreply@acme.com",
      "payment_methods_enabled": ["card", "bank_transfer"],
      "supported_currencies": ["USD", "EUR", "MAD"],
      "created_at": "2026-01-24T10:00:00Z",
      "updated_at": "2026-01-25T14:30:00Z"
    }
  }
}
```

***

### Update Settings

<ParamField path="PATCH" type="endpoint">
  `/merchants/:id/settings`
</ParamField>

Update merchant settings. Only specified fields will be updated.

**Path Parameters**

<ParamField path="id" type="string" required>
  Merchant ID (UUID)
</ParamField>

**Required Permission:** `update` (Owner or Admin)

**Request Body**

<ParamField body="default_currency" type="string">
  Default currency for transactions

  **Format:** ISO 4217 currency code (3 letters)

  **Example:** "USD", "EUR", "MAD"
</ParamField>

<ParamField body="auto_settle" type="boolean">
  Enable automatic settlement

  **Default:** true
</ParamField>

<ParamField body="settle_schedule" type="string">
  Settlement frequency

  **Options:** `daily`, `weekly`, `monthly`
</ParamField>

<ParamField body="webhook_url" type="string">
  URL to receive webhook notifications

  **Format:** Valid HTTPS URL
</ParamField>

<ParamField body="notification_email" type="string">
  Email for important notifications

  **Format:** Valid email address
</ParamField>

<ParamField body="send_email_receipts" type="boolean">
  Send email receipts to customers

  **Default:** true
</ParamField>

**Example Request**

```bash theme={null}
curl -X PATCH https://paymentgateway.redahaloubi.com/api/v1/merchants/{merchant_id}/settings \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json" \
  -d '{
    "default_currency": "EUR",
    "webhook_url": "https://acme.com/api/webhooks",
    "auto_settle": false
  }'
```

**Response (200 OK)**

```json theme={null}
{
  "success": true,
  "message": "Settings updated successfully"
}
```

<Accordion title="Error Responses">
  **400 Bad Request - Invalid Currency**

  ```json theme={null}
  {
    "success": false,
    "error": "default_currency must be exactly 3 characters"
  }
  ```

  **400 Bad Request - Invalid Webhook URL**

  ```json theme={null}
  {
    "success": false,
    "error": "webhook_url must be a valid URL"
  }
  ```

  **400 Bad Request - Invalid Schedule**

  ```json theme={null}
  {
    "success": false,
    "error": "settle_schedule must be one of: daily, weekly, monthly"
  }
  ```
</Accordion>

<Info>
  **Webhook Configuration:**

  When setting a webhook URL, the system will:

  1. Automatically generate a webhook secret (`whsec_...`)
  2. Send a test webhook to verify the endpoint
  3. Store the secret for HMAC signature verification

  Include the webhook secret in your webhook handler to verify authenticity.
</Info>

***

## API Key Endpoints

<Note>
  **API Key Management:**

  These endpoints are in the Merchant Service but communicate with the Auth Service for actual key creation and storage. They require Owner permissions.
</Note>

### Create API Key

<ParamField path="POST" type="endpoint">
  `/merchants/api-keys`
</ParamField>

Generate a new API key for payment processing. Requires Owner permissions.

**Request Body**

<ParamField body="merchant_id" type="string" required>
  Merchant ID for which to create the API key (UUID)
</ParamField>

<ParamField body="name" type="string" required>
  Descriptive name for the API key

  **Example:** "Production Server", "Staging Environment"
</ParamField>

**Example Request**

```bash theme={null}
curl -X POST https://paymentgateway.redahaloubi.com/api/v1/merchants/api-keys \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json" \
  -d '{
    "merchant_id": "merchant_abc123",
    "name": "Production API Key"
  }'
```

**Response (201 Created)**

```json theme={null}
{
  "success": true,
  "data": {
    "api_key": {
      "id": "apikey_abc123",
      "name": "Production API Key",
      "key_prefix": "pk_live_",
      "created_at": "2026-01-24T10:00:00Z"
    },
    "plain_key": "pk_live_abc123def456ghi789jkl012mno345pqr678stu901vwx234yz"
  },
  "message": "⚠️ Save this API key! It won't be shown again."
}
```

<Warning>
  **Save Your API Key:**

  The `plain_key` is only shown once. Store it securely in environment variables or a secrets manager. You cannot retrieve it later.
</Warning>

***

### List Merchant API Keys

<ParamField path="GET" type="endpoint">
  `/merchants/api-keys/merchant/:merchant_id`
</ParamField>

List all API keys for a merchant (without revealing actual key values).

**Path Parameters**

<ParamField path="merchant_id" type="string" required>
  Merchant ID (UUID)
</ParamField>

**Required Permission:** Owner

**Example Request**

```bash theme={null}
curl -X GET https://paymentgateway.redahaloubi.com/api/v1/merchants/api-keys/merchant/{merchant_id} \
  -H "Authorization: Bearer {access_token}"
```

**Response (200 OK)**

```json theme={null}
{
  "success": true,
  "data": {
    "api_keys": [
      {
        "id": "apikey_abc123",
        "name": "Production API Key",
        "key_prefix": "pk_live_",
        "is_active": true,
        "last_used_at": "2026-01-25T15:30:00Z",
        "created_at": "2026-01-24T10:00:00Z"
      },
      {
        "id": "apikey_def456",
        "name": "Staging API Key",
        "key_prefix": "pk_test_",
        "is_active": true,
        "last_used_at": "2026-01-25T12:00:00Z",
        "created_at": "2026-01-20T14:00:00Z"
      }
    ]
  }
}
```

***

### Deactivate API Key

<ParamField path="PATCH" type="endpoint">
  `/merchants/api-keys/:merchant_id/:id/deactivate`
</ParamField>

Deactivate an API key without deleting it. Deactivated keys cannot be used but remain visible.

**Path Parameters**

<ParamField path="merchant_id" type="string" required>
  Merchant ID (UUID)
</ParamField>

<ParamField path="id" type="string" required>
  API Key ID (UUID)
</ParamField>

**Required Permission:** Owner

**Example Request**

```bash theme={null}
curl -X PATCH https://paymentgateway.redahaloubi.com/api/v1/merchants/api-keys/{merchant_id}/{api_key_id}/deactivate \
  -H "Authorization: Bearer {access_token}"
```

**Response (200 OK)**

```json theme={null}
{
  "success": true,
  "message": "API key deactivated successfully"
}
```

***

### Delete API Key

<ParamField path="DELETE" type="endpoint">
  `/merchants/api-keys/:merchant_id/:id`
</ParamField>

Permanently delete an API key. This action cannot be undone.

**Path Parameters**

<ParamField path="merchant_id" type="string" required>
  Merchant ID (UUID)
</ParamField>

<ParamField path="id" type="string" required>
  API Key ID (UUID)
</ParamField>

**Required Permission:** Owner

**Example Request**

```bash theme={null}
curl -X DELETE https://paymentgateway.redahaloubi.com/api/v1/merchants/api-keys/{merchant_id}/{api_key_id} \
  -H "Authorization: Bearer {access_token}"
```

**Response (200 OK)**

```json theme={null}
{
  "success": true,
  "message": "API key deleted successfully"
}
```

<Warning>
  **Permanent Action:**

  Deleted API keys cannot be recovered. Any services using this key will immediately stop working.
</Warning>

***

## Permission Requirements Summary

<AccordionGroup>
  <Accordion title="Read Operations (All Roles)" icon="eye">
    **Endpoints:**

    * GET /merchants/:id
    * GET /merchants/:id/details
    * GET /merchants/:id/team
    * GET /merchants/:id/invitations
    * GET /merchants/:id/settings

    **Who Can Access:** Owner, Admin, Manager, Staff
  </Accordion>

  <Accordion title="Create Operations (Owner, Admin, Manager)" icon="plus">
    **Endpoints:**

    * POST /merchants/:id/team/invite

    **Who Can Access:** Owner, Admin, Manager

    **Restrictions:** Staff cannot invite team members
  </Accordion>

  <Accordion title="Update Operations (Owner, Admin)" icon="pen">
    **Endpoints:**

    * PATCH /merchants/:id
    * PATCH /merchants/:id/settings
    * PATCH /merchants/:id/team/:user\_id

    **Who Can Access:** Owner, Admin

    **Restrictions:** Manager and Staff cannot modify merchant or settings
  </Accordion>

  <Accordion title="Delete Operations (Owner Only)" icon="trash">
    **Endpoints:**

    * DELETE /merchants/:id
    * DELETE /merchants/:id/team/:user\_id
    * POST /merchants/api-keys (Create requires Owner)
    * All API key operations

    **Who Can Access:** Owner only

    **Restrictions:** Even Admins cannot delete merchants or manage API keys
  </Accordion>
</AccordionGroup>

***

## Common Workflows

### Workflow 1: Setting Up a New Merchant

<Steps>
  <Step title="Create Merchant Account">
    ```bash theme={null}
    POST /merchants
    ```

    User becomes Owner with full permissions
  </Step>

  <Step title="Configure Settings">
    ```bash theme={null}
    PATCH /merchants/:id/settings
    ```

    Set currency, webhooks, and preferences
  </Step>

  <Step title="Generate API Key">
    ```bash theme={null}
    POST /merchants/api-keys
    ```

    Create key for payment processing
  </Step>

  <Step title="Invite Team Members">
    ```bash theme={null}
    POST /merchants/:id/team/invite
    ```

    Add team members with appropriate roles
  </Step>
</Steps>

### Workflow 2: Managing Team Members

<Steps>
  <Step title="Send Invitation">
    ```bash theme={null}
    POST /merchants/:id/team/invite
    ```

    Invitee receives email with token
  </Step>

  <Step title="User Accepts Invitation">
    ```bash theme={null}
    POST /invitations/:token/accept
    ```

    User joins merchant with assigned role
  </Step>

  <Step title="Update Role (if needed)">
    ```bash theme={null}
    PATCH /merchants/:id/team/:user_id
    ```

    Change team member's role
  </Step>

  <Step title="Remove Member (if needed)">
    ```bash theme={null}
    DELETE /merchants/:id/team/:user_id
    ```

    Remove team member from merchant
  </Step>
</Steps>

***

## Error Reference

<ResponseField name="400" type="Bad Request">
  Invalid request format or validation errors

  **Common causes:**

  * Invalid UUID format
  * Missing required fields
  * Invalid email format
  * Invalid business\_type value
</ResponseField>

<ResponseField name="401" type="Unauthorized">
  Missing or invalid authentication token

  **Solution:** Include valid JWT token in Authorization header
</ResponseField>

<ResponseField name="403" type="Forbidden">
  Authenticated but lacks required permissions

  **Common causes:**

  * Insufficient role permissions
  * Not a member of the merchant
  * Trying to perform owner-only actions
</ResponseField>

<ResponseField name="404" type="Not Found">
  Requested resource doesn't exist

  **Common causes:**

  * Invalid merchant ID
  * User not found
  * Invitation doesn't exist
</ResponseField>

<ResponseField name="409" type="Conflict">
  Request conflicts with current state

  **Common causes:**

  * User already has a merchant
  * Email already invited
  * User already in team
</ResponseField>

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Payment API" icon="credit-card" href="/api/payment-api">
    Process payments and manage transactions
  </Card>

  <Card title="Auth API" icon="key" href="/api/auth">
    User authentication and authorization
  </Card>

  <Card title="Quick Start" icon="rocket" href="/get-started/quick-start">
    Create your first payment intent
  </Card>

  <Card title="CLI Tool" icon="terminal" href="/tools/cli">
    Command-line interface for testing
  </Card>
</CardGroup>

***

**Questions?** Contact support at [redahaloubi8@gmail.com](mailto:redahaloubi8@gmail.com)
