openapi: 3.0.3
info:
  title: Player Account Management (PAM) API
  description: API for managing player accounts and authentication
  version: 1.0.0

servers:
  - url: /
    description: Base API path

paths:
  /v1/openapi.yaml:
    get:
      summary: Get OpenAPI specification
      description: Returns the OpenAPI specification in YAML format
      operationId: getOpenAPISpec
      tags:
        - API Documentation
      responses:
        '200':
          description: OpenAPI specification
          content:
            text/yaml:
              schema:
                type: string
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /v1/ws-schema:
    get:
      summary: Get WebSocket message schema
      description: Returns the JSON schema for WebSocket messages
      operationId: getWebSocketSchema
      tags:
        - API Documentation
      responses:
        '200':
          description: WebSocket JSON schema
          content:
            application/json:
              schema:
                type: object
                description: WebSocket message schema
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /v1/signup:
    post:
      summary: Sign up a new player
      description: Create a new player account with the provided credentials
      operationId: signupPlayer
      tags:
        - Player Account
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SignupRequest'
      responses:
        '201':
          description: Player account created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SignupResponse'
        '400':
          description: Invalid request payload
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '409':
          description: Username or email already exists
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /v1/signin:
    post:
      summary: Sign in a player
      description: Authenticate a player and receive an access token
      operationId: signinPlayer
      tags:
        - Player Account
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SigninRequest'
      responses:
        '200':
          description: Successfully authenticated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SigninResponse'
        '400':
          description: Invalid request payload
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Invalid credentials
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: Account is inactive or banned
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /v1/signinWithToken:
    post:
      summary: Sign in a player with external token
      description: Authenticate a player using an external authentication token (e.g. BankID, Trumo) and receive an access token
      operationId: signinPlayerWithToken
      tags:
        - Player Account
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SigninWithTokenRequest'
      responses:
        '200':
          description: Successfully authenticated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SigninResponse'
        '400':
          description: Invalid request payload
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Invalid token or authentication failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: Account is inactive or banned
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Player not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /v1/players/me:
    get:
      summary: Get current player info
      description: Retrieve detailed information about the currently authenticated player
      operationId: getCurrentPlayer
      tags:
        - Player Account
      security:
        - bearerAuth: []
      responses:
        '200':
          description: Player information retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PlayerResponse'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Player not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /v1/players/me/personal-info:
    post:
      summary: Update player personal information
      description: Update personal information for the currently authenticated player
      operationId: updatePlayerPersonalInfo
      tags:
        - Player Personal Information
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdatePersonalInfoRequest'
      responses:
        '200':
          description: Personal information updated successfully
          content:
            application/json:
              schema:
                type: object
                description: Empty response indicating successful update
        '400':
          description: Invalid request payload
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Player not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /v1/players/me/email:
    post:
      summary: Set primary email
      description: |
        Set or update the primary email address for the currently authenticated player.
        A verification email with a confirmation link will be sent to the provided email address.
        The email will only be set as primary after the user clicks the verification link.
      operationId: setPlayerEmail
      tags:
        - Player Account
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SetEmailRequest'
      responses:
        '200':
          description: Verification email sent successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SetEmailResponse'
        '400':
          description: Invalid request payload
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /v1/email/verify:
    post:
      summary: Verify email address
      description: |
        Verify an email address using the verification token sent to the user's email.
        This endpoint is called when a user clicks the verification link in their email.
        No authentication is required as the token itself serves as proof of email ownership.
      operationId: verifyEmail
      tags:
        - Player Account
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VerifyEmailRequest'
      responses:
        '200':
          description: Email verified successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VerifyEmailResponse'
        '400':
          description: Invalid or expired token
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /v1/deposit/request:
    post:
      summary: Create deposit request
      description: |
        Create a new deposit request for a player.

        This endpoint initiates a payment deposit flow through supported payment gateways.
        Authentication via Bearer token in the Authorization header is optional.
        If authenticated, the player ID is extracted from the token.
        If not authenticated, the player ID must be provided in the request body.

        The request can include encrypted card data for new payments or reference
        a previously saved payment account ID for quick deposits.

        Redirect URLs (successUrl, failureUrl, pendingUrl, cancelUrl) control
        where the user is redirected after payment completion based on the result.
      operationId: createDepositRequest
      tags:
        - "Cashier"
      security:
        - bearerAuth: []
        - {}
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PaymentDepositRequest'
      responses:
        '200':
          description: PaymentIQ deposit request created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaymentDepositResponse'
        '400':
          description: Invalid request payload
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /v1/settings:
    get:
      summary: Get brand payment settings
      description: Brand settings
      operationId: getBrandPaymentSettings
      tags:
        - Settings
      security: []
      responses:
        '200':
          description: Brand payment settings retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BrandSettingsResponse'
        '400':
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Brand not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /v1/deposit/status/{depositPublicId}:
    get:
      summary: Get deposit status by deposit public ID
      description: Retrieve the current status of a deposit using the deposit public ID
      operationId: getDepositStatus
      tags:
        - "Cashier"
      security:
        - bearerAuth: []
      parameters:
        - name: depositPublicId
          in: path
          description: Deposit public ID (e.g., dep_abc123xyz789)
          required: true
          schema:
            type: string
            pattern: '^dep_[a-zA-Z0-9]+$'
            example: "dep_abc123xyz789"
      responses:
        '200':
          description: Deposit status retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DepositStatusResponse'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Deposit not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /v1/deposit/schema:
    post:
      summary: Get deposit form schema
      description: Retrieve the dynamic form schema for deposit based on selected payment method (public endpoint)
      operationId: getDepositSchema
      tags:
        - "Cashier"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DepositSchemaRequest'
      responses:
        '200':
          description: Deposit form schema retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DepositSchemaResponse'
        '400':
          description: Invalid request payload
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /v1/withdrawal/schema:
    post:
      summary: Get withdrawal form schema
      description: Retrieve the dynamic form schema for withdrawal based on selected payment method (public endpoint)
      operationId: getWithdrawalSchema
      tags:
        - "Cashier"
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WithdrawalSchemaRequest'
      responses:
        '200':
          description: Withdrawal form schema retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WithdrawalSchemaResponse'
        '400':
          description: Invalid request payload
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /v1/withdrawal/init:
    post:
      summary: Initialize withdrawal with flat request structure
      description: |
        Initialize a new withdrawal request with a flat request structure.

        This endpoint uses a flat request structure where all payment method
        specific fields are at the top level and optional.

        **For bank transfer withdrawals (bankiban):**
        - New account: Provide beneficiaryName, accountNumber, and bic
        - Saved account: Provide paymentAccountId
      operationId: initWithdrawal
      tags:
        - "Cashier"
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WithdrawalInitRequest'
      responses:
        '200':
          description: Withdrawal initialized successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WithdrawalResponse'
        '400':
          description: Invalid request payload
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '402':
          description: Insufficient balance
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /v1/deposit/init:
    post:
      summary: Initialize deposit with flat request structure
      description: |
        Initialize a new deposit request with a flat request structure.

        This endpoint is similar to /v1/deposit/request but uses a flat request structure
        where all payment method specific fields are at the top level and optional.

        For credit card payments, provide the card details directly in the request body.
        For saved payment accounts, provide the paymentAccountId.
      operationId: initDeposit
      tags:
        - "Cashier"
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DepositInitRequest'
      responses:
        '200':
          description: Deposit initialized successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaymentDepositResponse'
        '400':
          description: Invalid request payload
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /v1/withdrawals:
    post:
      summary: Create withdrawal request
      description: Create a new withdrawal request for the authenticated player
      operationId: createWithdrawalRequest
      tags:
        - "Cashier"
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WithdrawalRequest'
      responses:
        '201':
          description: Withdrawal request created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WithdrawalResponse'
        '400':
          description: Invalid request payload or validation failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '402':
          description: Insufficient balance
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
    get:
      summary: Get player withdrawals
      description: Retrieve withdrawal history for the authenticated player
      operationId: getPlayerWithdrawals
      tags:
        - "Cashier"
      security:
        - bearerAuth: []
      parameters:
        - name: status
          in: query
          description: Filter by withdrawal status
          required: false
          schema:
            type: string
            enum: [requested, validated, accepted, approved, executed, failed]
        - name: limit
          in: query
          description: Maximum number of withdrawals to return
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 20
        - name: offset
          in: query
          description: Number of withdrawals to skip
          required: false
          schema:
            type: integer
            minimum: 0
            default: 0
      responses:
        '200':
          description: Withdrawal history retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WithdrawalListResponse'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /v1/withdrawals/{withdrawalId}:
    get:
      summary: Get withdrawal details
      description: Retrieve detailed information about a specific withdrawal
      operationId: getWithdrawalDetails
      tags:
        - "Cashier"
      security:
        - bearerAuth: []
      parameters:
        - name: withdrawalId
          in: path
          description: Withdrawal ID
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Withdrawal details retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WithdrawalResponse'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Withdrawal not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /v1/withdrawals/{withdrawalId}/cancel:
    post:
      summary: Cancel withdrawal
      description: Cancel a withdrawal request by ID
      operationId: cancelWithdrawal
      tags:
        - "Cashier"
      security:
        - bearerAuth: []
      parameters:
        - name: withdrawalId
          in: path
          description: Withdrawal ID to cancel
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Withdrawal cancelled successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WithdrawalResponse'
        '400':
          description: Invalid request or withdrawal cannot be cancelled
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: Forbidden - withdrawal does not belong to authenticated player
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Withdrawal not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /v1/kyc/init:
    post:
      summary: Initialize KYC verification
      description: |
        Initialize a KYC (Know Your Customer) verification session with Sumsub.
        Returns a verification URL that the player should open in their browser or webview
        to complete the identity verification process.
      operationId: initKYC
      tags:
        - "KYC"
      security:
        - bearerAuth: []
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/KYCInitRequest'
      responses:
        '200':
          description: KYC verification session initialized successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/KYCInitResponse'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /v1/kyc/status:
    get:
      summary: Get KYC verification status
      description: |
        Retrieve the current KYC verification status for the authenticated player.
        Returns an array of verification types (ID check, proof of address) with their status.
      operationId: getKYCStatus
      tags:
        - "KYC"
      security:
        - bearerAuth: []
      responses:
        '200':
          description: KYC status retrieved successfully
          content:
            application/json:
              schema:
                type: object
                required:
                  - verifications
                properties:
                  verifications:
                    type: array
                    items:
                      $ref: '#/components/schemas/KYCVerification'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /v1/kyc/pending:
    get:
      summary: Get pending KYC verification
      description: |
        Retrieve active KYC verification data from SumSub for the authenticated player.
        Returns verification object or null if no active verification found.
      operationId: getKYCPending
      tags:
        - "KYC"
      security:
        - bearerAuth: []
      responses:
        '200':
          description: Active KYC verification retrieved successfully (null if none found)
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/KYCPendingResponse'
                nullable: true
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '503':
          description: KYC service unavailable
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /v1/deposits:
    get:
      summary: Get player deposits
      description: Retrieve deposit history for the authenticated player
      operationId: getPlayerDeposits
      tags:
        - "Cashier"
      security:
        - bearerAuth: []
      parameters:
        - name: status
          in: query
          description: Filter by deposit status
          required: false
          schema:
            $ref: '#/components/schemas/DepositStatus'
        - name: limit
          in: query
          description: Maximum number of deposits to return
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 20
        - name: offset
          in: query
          description: Number of deposits to skip
          required: false
          schema:
            type: integer
            minimum: 0
            default: 0
      responses:
        '200':
          description: Deposit history retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DepositListResponse'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /v1/cashier/history:
    post:
      summary: Get cashier history
      description: Retrieve combined deposit and withdrawal history for the authenticated player with optional filters
      operationId: getCashierHistory
      tags:
        - "Cashier"
      security:
        - bearerAuth: []
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CashierHistoryRequest'
      responses:
        '200':
          description: Cashier history retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CashierHistoryResponse'
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /v1/games:
    get:
      x-internal: true
      summary: List all games
      description: Retrieve a list of all active games available in the platform
      operationId: listGames
      tags:
        - Games
      security: []
      parameters:
        - name: limit
          in: query
          description: Maximum number of games to return
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 2000
            default: 2000
        - name: offset
          in: query
          description: Number of games to skip for pagination
          required: false
          schema:
            type: integer
            minimum: 0
            default: 0
      responses:
        '200':
          description: List of games retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GamesListResponse'
        '400':
          description: Invalid request parameters
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /v1/games/launch:
    post:
      summary: Launch a game
      description: Request a game launch URL for a specific player and game via ST8
      operationId: launchGame
      tags:
        - Games
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GameLaunchRequest'
      responses:
        '200':
          description: Game launch successful
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GameLaunchResponse'
        '400':
          description: Invalid request parameters
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /v1/games/launchDemo:
    post:
      summary: Launch a demo game
      description: Request a demo game launch URL without authentication and traffic splitter registration
      operationId: launchDemoGame
      tags:
        - Games
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DemoGameLaunchRequest'
      responses:
        '200':
          description: Demo game launch successful
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GameLaunchResponse'
        '400':
          description: Invalid request parameters
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /v1/password-reset/request:
    post:
      summary: Request password reset
      description: Send a password reset email to the specified email address
      operationId: requestPasswordReset
      tags:
        - Password Reset
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PasswordResetRequest'
      responses:
        '200':
          description: Password reset email sent successfully (if email exists)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PasswordResetResponse'
        '400':
          description: Invalid request payload
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /v1/password-reset/confirm:
    post:
      summary: Confirm password reset
      description: Complete password reset with the provided token and new password
      operationId: confirmPasswordReset
      tags:
        - Password Reset
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PasswordResetConfirm'
      responses:
        '200':
          description: Password reset completed successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PasswordResetResponse'
        '400':
          description: Invalid request payload or token
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Invalid or expired token
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

  /v1/games/history:
    post:
      summary: Get player game history
      description: Retrieve casino action history for the authenticated player from casino actions
      operationId: getPlayerGameHistory
      tags:
        - Game History
      security:
        - bearerAuth: []
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GameHistoryRequest'
      responses:
        '200':
          description: Game history retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GameHistoryResponse'
        '400':
          description: Invalid request parameters
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'



components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

  schemas:
    SetEmailRequest:
      type: object
      required:
        - email
      properties:
        email:
          type: string
          format: email
          description: The email address to set as primary
          example: "user@example.com"

    SetEmailResponse:
      type: object
      required:
        - message
        - verificationSent
      properties:
        message:
          type: string
          description: Status message
          example: "Verification email sent successfully"
        verificationSent:
          type: boolean
          description: Whether the verification email was sent
          example: true
        email:
          type: string
          description: The email address to be verified
          example: "user@example.com"

    VerifyEmailRequest:
      type: object
      required:
        - token
      properties:
        token:
          type: string
          description: The verification token from the email link
          example: "abc123def456..."

    VerifyEmailResponse:
      type: object
      required:
        - message
        - verified
      properties:
        message:
          type: string
          description: Status message
          example: "Email verified successfully"
        verified:
          type: boolean
          description: Whether the email was successfully verified
          example: true
        email:
          type: string
          description: The verified email address
          example: "user@example.com"
        errorCode:
          type: string
          description: Error code when verification fails (token_already_used, token_expired, invalid_token)
          example: "token_expired"

    SignupRequest:
      type: object
      required:
        - email
        - password
      properties:
        email:
          type: string
          format: email
        password:
          type: string
        username:
          type: string
          description: Optional username for the player
        currency:
          type: string
          description: Base currency for the player account
          default: EUR
          example: EUR
        originIp:
          type: string
          description: IP address at signup
        seonSessionToken:
          type: string
          description: Optional SEON session token for fraud detection

    SigninRequest:
      type: object
      required:
        - email
        - password
        - originIp
      properties:
        email:
          type: string
          format: email
          description: Player's email address
          example: "player@example.com"
        password:
          type: string
          format: password
          description: Player's password
          example: "securePassword123"
        originIp:
          type: string
          description: IP address at signin
        seonSessionToken:
          type: string
          description: Optional SEON session token for fraud detection

    SigninWithTokenRequest:
      type: object
      required:
        - token
      properties:
        token:
          type: string
          description: External authentication token (e.g. from BankID, Trumo, etc.)
          example: "eyJhbGciOiJIUzI1NiIs..."
        seonSessionToken:
          type: string
          description: Optional SEON session token for fraud detection

    SigninResponse:
      type: object
      required:
        - accessToken
        - tokenType
        - expiresIn
        - player
      properties:
        accessToken:
          type: string
          description: JWT access token
          example: "eyJhbGciOiJIUzI1NiIs..."
        tokenType:
          type: string
          description: Type of the token
          example: "Bearer"
        expiresIn:
          type: integer
          description: Token expiration time in seconds
          example: 3600
        player:
          $ref: '#/components/schemas/PlayerResponse'

    SignupResponse:
      type: object
      required:
        - accessToken
        - tokenType
        - expiresIn
        - player
      description: Response for successful signup containing token and player
      properties:
        accessToken:
          type: string
          description: JWT access token
        tokenType:
          type: string
          description: Type of the token
          example: Bearer
        expiresIn:
          type: integer
          description: Token expiration time in seconds
          example: 86400
        player:
          $ref: '#/components/schemas/PlayerResponse'

    Balance:
      type: object
      required:
        - amount
        - type
        - lastUpdatedAt
        - currency
      properties:
        amount:
          type: string
          description: Balance amount as fixed-point decimal string
          pattern: ^\d+\.\d{2}$
          example: "150.50"
        type:
          type: string
          enum: [real, bonus]
          description: Type of balance
          example: "real"
        lastUpdatedAt:
          type: string
          format: date-time
          description: ISO 8601 timestamp when the balance was last updated
          example: "2024-01-15T10:30:00Z"
        currency:
          type: string
          description: Currency code for the balance
          pattern: ^[A-Z]{3}$
          example: "USD"

    PlayerResponse:
      type: object
      required:
        - id
        - username
        - email
        - status
        - balances
        - personalInfo
        - kycStatus
      properties:
        id:
          type: string
          description: Player's public ID
          example: "pub_123456789"
        username:
          type: string
          description: Player's username
          example: "player123"
        email:
          type: string
          description: Player's email address
          example: "player@example.com"
        emailVerified:
          type: boolean
          description: Whether the player's email address has been verified
          example: true
        passwordAuthEnabled:
          type: boolean
          description: Whether password authentication is enabled for this player
          example: true
        status:
          type: string
          enum: [active, banned]
          description: Current status of the player account
          example: "active"
        balances:
          type: array
          description: Array of player balances
          items:
            $ref: '#/components/schemas/Balance'
          example:
            - amount: "150.50"
              type: "real"
              lastUpdatedAt: "2024-01-15T10:30:00Z"
              currency: "USD"
            - amount: "25.00"
              type: "bonus"
              lastUpdatedAt: "2024-01-15T10:30:00Z"
              currency: "USD"
        personalInfo:
          $ref: '#/components/schemas/PersonalInfo'
        kycStatus:
          type: array
          description: Array of KYC verification statuses
          items:
            $ref: '#/components/schemas/KYCVerification'
        paymentMethods:
          type: array
          description: List of available payment methods for the player's brand
          items:
            $ref: '#/components/schemas/AvailablePaymentMethods'

    PersonalInfo:
      type: object
      properties:
        firstName:
          type: string
          description: Player's first name
          example: "John"
        lastName:
          type: string
          description: Player's last name
          example: "Doe"
        country:
          type: string
          description: ISO 3166-1 alpha-2 country code
          example: "US"
        dateOfBirth:
          type: string
          format: date
          description: Player's date of birth (YYYY-MM-DD)
          example: "1990-01-15"
        isComplete:
          type: boolean
          description: Whether the personal information is complete
          example: false

    Error:
      type: object
      required:
        - code
        - message
      properties:
        code:
          type: string
          description: Error code
          example: "invalid_request"
        message:
          type: string
          description: Human-readable error message
          example: "Invalid request payload"
        details:
          type: object
          description: Additional error details
          additionalProperties: true

    KYCInitRequest:
      type: object
      required:
        - verificationType
      properties:
        verificationType:
          type: string
          description: Type of KYC verification to perform
          enum:
            - idcheck
            - poa
          example: "idcheck"
        successUrl:
          type: string
          description: URL to redirect to after successful KYC verification
          example: "https://yourapp.com/kyc/success"
        failureUrl:
          type: string
          description: URL to redirect to after failed KYC verification
          example: "https://yourapp.com/kyc/failure"

    KYCInitResponse:
      type: object
      required:
        - verificationUrl
      properties:
        verificationUrl:
          type: string
          description: URL to open in browser or webview for the player to complete identity verification at Sumsub
          example: "https://sumsub.com/idensic/l/#/uni_abc123xyz789"
        accessToken:
          type: string
          description: Access token for initializing SumSub SDK (if using SDK integration)
          example: "sbx:abc123xyz789..."

    KYCVerification:
      type: object
      required:
        - type
        - status
        - allowed
      properties:
        type:
          type: string
          enum:
            - idcheck
            - poa
          description: Type of KYC verification
          example: "idcheck"
        status:
          type: string
          enum:
            - not-started
            - pending
            - approved
            - rejected
            - expired
          description: Current status of the verification
          example: "approved"
        validUntil:
          type: string
          format: date-time
          nullable: true
          description: Date and time when the verification expires (ISO 8601 format)
          example: "2025-12-31T23:59:59Z"
        allowed:
          type: boolean
          description: Whether the verification is approved and not expired
          example: true

    KYCPendingResponse:
      type: object
      description: Active KYC verification data from SumSub
      required:
        - id
        - externalUserId
        - createdAt
        - reviewStatus
        - stage
      properties:
        id:
          type: string
          description: SumSub applicant ID
          example: "68f8cfe217687b136a9ea582"
        externalUserId:
          type: string
          description: External user ID (player public ID)
          example: "5726346"
        createdAt:
          type: string
          format: date-time
          description: When verification was created
          example: "2024-01-15T10:30:00Z"
        reviewStatus:
          type: string
          description: Current review status
          enum: [init, pending, prechecked, queued, completed, onHold]
          example: "onHold"
        stage:
          type: string
          description: Simplified verification stage
          enum: [not_started, in_progress, under_review, approved, rejected]
          example: "in_progress"
        reviewAnswer:
          type: string
          description: Final review decision (only when completed)
          enum: [GREEN, RED, YELLOW]
          example: "GREEN"
          nullable: true
        reviewDate:
          type: string
          format: date-time
          description: When review was completed
          nullable: true
        levelName:
          type: string
          description: Verification level
          example: "nvp-stage-basic"
          nullable: true
        attemptCount:
          type: integer
          description: Number of verification attempts
          nullable: true
        info:
          type: object
          description: Applicant personal info (present after form submission)
          nullable: true
          properties:
            firstName:
              type: string
            lastName:
              type: string
            dob:
              type: string
              format: date
            country:
              type: string
            addresses:
              type: array
              description: Address information (for POA verifications)
              nullable: true
              items:
                type: object
                properties:
                  country:
                    type: string
                  formattedAddress:
                    type: string
                  postCode:
                    type: string
                  town:
                    type: string
                  street:
                    type: string
                  source:
                    type: string
                    description: Source of address data
                    example: "proofOfAddress"
            idDocs:
              type: array
              description: Submitted identity documents
              nullable: true
              items:
                type: object
                properties:
                  idDocType:
                    type: string
                    example: "ID_CARD"
                  number:
                    type: string
                    description: Document number (for ID cards)
                  issuedDate:
                    type: string
                    format: date
                    description: Issue date (for utility bills)
                  validUntil:
                    type: string
                    format: date
                    description: Document validity date
                  address:
                    type: object
                    description: Address from document (for utility bills)
                    nullable: true
                    properties:
                      formattedAddress:
                        type: string
                      street:
                        type: string
                      town:
                        type: string
                      country:
                        type: string
                      source:
                        type: string

    UpdatePersonalInfoRequest:
      type: object
      required:
        - firstName
        - lastName
        - country
        - dateOfBirth
      properties:
        firstName:
          type: string
          description: Player's first name
          minLength: 1
          maxLength: 50
          example: "John"
        lastName:
          type: string
          description: Player's last name
          minLength: 1
          maxLength: 50
          example: "Doe"
        country:
          type: string
          description: ISO 3166-1 alpha-2 country code
          pattern: ^[A-Z]{2}$
          example: "US"
        dateOfBirth:
          type: string
          format: date
          description: Player's date of birth (YYYY-MM-DD)
          example: "1990-01-15"

    PaymentDepositRequest:
      type: object
      description: |
        Request for creating a payment deposit.

        **Required Fields:**
        - `amount`: Payment amount as decimal string
        - `currency`: Currency code (e.g., EUR, USD)
        - `paymentMethod`: Payment method (e.g., bankid, visamc)
        - `paymentGateway`: Payment gateway (piq, fpiq, or trumo)

        **Payment Method Requirements (PIQ/FPIQ):**

        For `visamc` (Visa/Mastercard) payments:
        - **Saved card payment**: Provide `paymentAccountId` (references a previously saved card) and optionally `encryptedCardCCV` for additional security
        - **New card payment**: Leave `paymentAccountId` empty and provide `encryptedCardData` (required for new card transactions)

        For `bankiban` payments:
        - No additional encrypted data required, bank details are collected separately
      required:
        - amount
        - currency
        - paymentMethod
        - paymentGateway
      properties:
        amount:
          type: string
          description: Payment amount as decimal string
          pattern: ^\d+(\.\d{1,2})?$
          example: "100.00"
        currency:
          type: string
          description: Currency code for the payment
          pattern: ^[A-Z]{3}$
          example: "EUR"
        paymentAccountId:
          type: string
          description: Payment account ID for previously saved deposit
          example: "799"
        bonusPublicId:
          type: string
          description: Optional bonus public ID to apply to the deposit
          example: "bonus_67890"
        encryptedCardData:
          $ref: '#/components/schemas/EncryptedCardData'
          description: Encrypted credit card data (required for card payments)
        encryptedCardCCV:
          $ref: '#/components/schemas/EncryptedCardCCV'
          description: Encrypted CVV data (optional, used for saved payment methods)
        paymentMethod:
          $ref: '#/components/schemas/PaymentMethod'
          description: Payment method
        paymentGateway:
          type: string
          description: Payment gateway identifier (currently supports PaymentIQ, Fake PaymentIQ, and Trumo)
          enum:
            - "piq"
            - "fpiq"
            - "trumo"
          example: "piq"
        successUrl:
          type: string
          format: uri
          description: URL to redirect to after successful payment
          example: "https://example.com/payment/success"
        failureUrl:
          type: string
          format: uri
          description: URL to redirect to after failed payment
          example: "https://example.com/payment/failure"
        pendingUrl:
          type: string
          format: uri
          description: URL to redirect to when payment is pending (overrides PIQ merchant config if provided)
          example: "https://example.com/payment/pending"
        cancelUrl:
          type: string
          format: uri
          description: URL to redirect to when payment is cancelled (overrides PIQ merchant config if provided)
          example: "https://example.com/payment/cancel"

    PaymentDepositResponse:
      type: object
      description: |
        Minimal deposit response with only essential client-facing fields.

        For simple redirects (GET), only `redirectUrl` is provided.
        For complex flows (iframe, POST, 3DS), the `redirect` object contains advanced configuration.
      required:
        - success
      properties:
        success:
          type: boolean
          description: Whether the deposit request was successful
          example: true
        redirectUrl:
          type: string
          format: uri
          description: Simple redirect URL for payment flows (GET redirect)
          example: "https://payment-provider.com/checkout?id=abc123"
        redirect:
          $ref: '#/components/schemas/PaymentRedirect'
          description: Advanced redirect configuration for complex payment flows (iframe, POST forms, 3DS)

    PaymentRedirect:
      type: object
      description: Advanced redirect configuration for complex payment flows (iframe, POST forms, 3DS)
      required:
        - url
        - method
      properties:
        url:
          type: string
          format: uri
          description: URL to redirect user for payment
          example: "https://payment-provider.com/3ds"
        method:
          type: string
          description: HTTP method or display method
          enum: ["GET", "POST", "iframe"]
          example: "POST"
        html:
          type: string
          description: HTML content for payment form (optional, for POST forms)
          example: "<form action='https://payment-provider.com' method='POST'>...</form>"
        parameters:
          type: object
          description: Additional parameters for the payment request
          additionalProperties: true
          example:
            merchantId: "12345"
            signature: "xyz789"

    PaymentMethodSettings:
      type: object
      description: Configuration settings for a payment method
      properties:
        version:
          type: string
          description: Version of the payment method configuration
          pattern: ^\d+\.\d+\.\d+$
          example: "1.0.0"
        displayName:
          type: string
          description: Human-readable display name for the payment method
          example: "Visa/Mastercard"
        isPnP:
          type: boolean
          description: Indicates if this is a Pay and Play (PnP) payment method
          example: false
        # Country configuration
        countriesAllowed:
          type: array
          description: List of allowed country codes for this payment method
          items:
            type: string
            pattern: ^[A-Z]{2}$
          example: ["MT", "IT", "DE", "FR", "ES"]
        countriesExcluded:
          type: array
          description: List of excluded country codes for this payment method
          items:
            type: string
            pattern: ^[A-Z]{2}$
          example: ["US", "CA"]
        # Deposit configuration
        depositMinAmount:
          type: string
          description: Minimum deposit amount as decimal string
          example: "10"
        depositMaxAmount:
          type: string
          description: Maximum deposit amount as decimal string
          example: "5000"
        depositFeeFixed:
          type: string
          description: Fixed deposit fee amount as decimal string
          example: "0.50"
        depositFeePercent:
          type: string
          description: Deposit fee as percentage as decimal string
          example: "2.5"
        quickDepositOptions:
          type: array
          description: Quick deposit amount options in cents/minor units
          items:
            type: integer
            minimum: 1
          example: [1000, 2500, 5000, 10000, 25000]
        # Withdrawal configuration
        withdrawalMinAmount:
          type: string
          description: Minimum withdrawal amount as decimal string
          example: "20"
        withdrawalMaxAmount:
          type: string
          description: Maximum withdrawal amount as decimal string
          example: "2000"
        withdrawalFeeFixed:
          type: string
          description: Fixed withdrawal fee amount as decimal string
          example: "1.00"
        withdrawalFeePercent:
          type: string
          description: Withdrawal fee as percentage as decimal string
          example: "1.0"
        # Attributes section for provider-specific configuration
        attributes:
          type: object
          description: Provider-specific attributes and configuration
          properties:
            encryptor:
              type: object
              description: Encryptor configuration for PIQ payment provider with visamc payment method
              properties:
                src:
                  type: string
                  description: Encryptor script source URL
                  example: "https://api.paymentiq.io/paymentiq/api/viq/jscardencrypter/merchant123"
                fn:
                  type: string
                  description: Encryptor function name to call
                  example: "encryptData"
          additionalProperties: true

    PlayerPaymentMethodSettings:
      type: object
      description: Player-facing configuration settings for a payment method (excludes country restrictions)
      properties:
        version:
          type: string
          description: Version of the payment method configuration
          pattern: ^\d+\.\d+\.\d+$
          example: "1.0.0"
        displayName:
          type: string
          description: Human-readable display name for the payment method
          example: "Visa/Mastercard"
        isPnP:
          type: boolean
          description: Indicates if this is a Pay and Play (PnP) payment method
          example: false
        # Deposit configuration
        depositMinAmount:
          type: string
          description: Minimum deposit amount as decimal string
          example: "10"
        depositMaxAmount:
          type: string
          description: Maximum deposit amount as decimal string
          example: "5000"
        depositFeeFixed:
          type: string
          description: Fixed deposit fee amount as decimal string
          example: "0.50"
        depositFeePercent:
          type: string
          description: Deposit fee as percentage as decimal string
          example: "2.5"
        quickDepositOptions:
          type: array
          description: Quick deposit amount options in cents/minor units
          items:
            type: integer
            minimum: 1
          example: [1000, 2500, 5000, 10000, 25000]
        # Withdrawal configuration
        withdrawalMinAmount:
          type: string
          description: Minimum withdrawal amount as decimal string
          example: "20"
        withdrawalMaxAmount:
          type: string
          description: Maximum withdrawal amount as decimal string
          example: "2000"
        withdrawalFeeFixed:
          type: string
          description: Fixed withdrawal fee amount as decimal string
          example: "1.00"
        withdrawalFeePercent:
          type: string
          description: Withdrawal fee as percentage as decimal string
          example: "1.0"
        # Attributes section for provider-specific configuration
        attributes:
          type: object
          description: Provider-specific attributes and configuration
          properties:
            encryptor:
              type: object
              description: Encryptor configuration for PIQ payment provider with visamc payment method
              properties:
                src:
                  type: string
                  description: Encryptor script source URL
                  example: "https://api.paymentiq.io/paymentiq/api/viq/jscardencrypter/merchant123"
                fn:
                  type: string
                  description: Encryptor function name to call
                  example: "encryptData"
          additionalProperties: true

    AvailablePaymentMethod:
      type: object
      description: Payment method available to the player (excludes country restrictions)
      required:
        - gateway
        - method
        - depositEnabled
        - withdrawalEnabled
        - settings
      properties:
        gateway:
          $ref: '#/components/schemas/Gateway'
        method:
          $ref: '#/components/schemas/PaymentMethod'
        depositEnabled:
          type: boolean
          description: Whether deposit is enabled for this payment method
          example: true
        withdrawalEnabled:
          type: boolean
          description: Whether withdrawal is enabled for this payment method
          example: true
        settings:
          $ref: '#/components/schemas/PlayerPaymentMethodSettings'

    BrandPaymentMethod:
      type: object
      description: Payment method configuration for a brand
      required:
        - gateway
        - method
        - depositEnabled
        - withdrawalEnabled
        - settings
      properties:
        gateway:
          $ref: '#/components/schemas/Gateway'
        method:
          $ref: '#/components/schemas/PaymentMethod'
        depositEnabled:
          type: boolean
          description: Whether deposit is enabled for this payment method
          example: true
        withdrawalEnabled:
          type: boolean
          description: Whether withdrawal is enabled for this payment method
          example: true
        settings:
          $ref: '#/components/schemas/PaymentMethodSettings'

    BrandSettingsResponse:
      type: object
      description: Response containing brand payment settings
      required:
        - paymentMethods
      properties:
        paymentMethods:
          type: array
          description: List of available payment methods for the brand
          items:
            $ref: '#/components/schemas/BrandPaymentMethod'

    AvailablePaymentMethods:
      type: object
      description: Available payment method for the player (wraps payment method config with accounts)
      required:
        - paymentMethod
      properties:
        paymentMethod:
          $ref: '#/components/schemas/AvailablePaymentMethod'
        paymentAccounts:
          type: array
          description: Player's saved payment accounts applicable for this method
          items:
            $ref: '#/components/schemas/PaymentAccount'

    PaymentAccount:
      type: object
      description: Player's saved payment account details
      required:
        - paymentAccountId
        - maskedAccount
        - accountHolder
      properties:
        paymentAccountId:
          type: string
          description: Unique identifier of the payment account
          example: "123"
        maskedAccount:
          type: string
          description: Masked representation of the account (e.g., **** **** **** 1234)
          example: "**** **** **** 1234"
        accountHolder:
          type: string
          description: Name of the account holder
          example: "John Doe"
        expiryMonth:
          type: string
          nullable: true
          description: Card expiry month if applicable
          example: "12"
        expiryYear:
          type: string
          nullable: true
          description: Card expiry year if applicable
          example: "2030"

    BankIbanData:
      type: object
      description: Bank IBAN data for withdrawals
      required:
        - beneficiaryName
        - iban
        - bic
      properties:
        beneficiaryName:
          type: string
          description: Name of the beneficiary
          example: "John Doe"
        iban:
          type: string
          description: International Bank Account Number
          example: "DE89370400440532013000"
        bic:
          type: string
          description: SWIFT/BIC code
          example: "DEUTDEFF"

    WithdrawalRequest:
      type: object
      required:
        - amount
        - paymentMethod
      properties:
        amount:
          type: string
          description: Withdrawal amount as decimal string (e.g., "100.00")
          pattern: ^\d+\.\d{2}$
          example: "100.00"
        paymentMethod:
          $ref: '#/components/schemas/PaymentMethod'
        paymentAccountId:
          type: string
          description: Payment account ID to use for withdrawal (optional)
          example: "123"
        bankIbanData:
          $ref: '#/components/schemas/BankIbanData'
          description: Bank IBAN data (required for bank IBAN withdrawals)

    WithdrawalDataBankIBAN:
      type: object
      description: Bank IBAN data for withdrawals
      required:
        - beneficiaryName
        - iban
        - bic
      properties:
        beneficiaryName:
          type: string
          description: Name of the beneficiary
          example: "John Doe"
        iban:
          type: string
          description: International Bank Account Number
          example: "DE89370400440532013000"
        bic:
          type: string
          description: SWIFT/BIC code
          example: "DEUTDEFF"

    WithdrawalData:
      type: object
      description: Additional data for withdrawal requests
      properties:
        bankIban:
          $ref: '#/components/schemas/WithdrawalDataBankIBAN'
        balanceChange:
          type: object
          description: Balance change information for completed withdrawals
          properties:
            from:
              type: string
              description: Balance before withdrawal
              example: "340.50"
            to:
              type: string
              description: Balance after withdrawal
              example: "100.00"
        withdrawalNumber:
          type: integer
          description: Chronological number of successful withdrawals for the player
          example: 3

    ChangedBalance:
      type: object
      description: Balance change information for completed deposits
      properties:
        from:
          type: string
          description: Balance before deposit
          example: "100.00"
        to:
          type: string
          description: Balance after deposit
          example: "200.00"

    WithdrawalProcessedData:
      type: object
      description: Processed data for completed withdrawals
      properties:
        psp:
          type: string
          description: Payment service provider
          example: "piq"
        referenceNumber:
          type: string
          description: Reference number for the withdrawal
          example: "w1705312200000000000"
        pspStatusMessage:
          type: string
          description: Status message from the payment service provider
          example: "Transaction completed successfully"
        pspRefId:
          type: string
          description: Reference ID from the payment service provider
          example: "piq_ref_12345"
        pspName:
          type: string
          description: Name of the payment service provider
          example: "PaymentIQ"
        withdrawalNumber:
          type: integer
          description: Chronological number of successful withdrawals for the player
          example: 3
        changedBalance:
          $ref: '#/components/schemas/ChangedBalance'

    WithdrawalResponse:
      type: object
      description: Response for a withdrawal request
      required:
        - withdrawalPublicId
        - playerPublicId
        - status
        - amount
        - createdAt
      properties:
        withdrawalPublicId:
          type: string
          description: Public withdrawal ID
          example: "w1705312200000000000"
        playerPublicId:
          type: string
          description: Player public ID
          example: "player_456"
        status:
          type: string
          enum: [requested, validated, accepted, approved, executed, failed, cancelled]
          description: Current status of the withdrawal
          example: "requested"
        amount:
          type: string
          description: Withdrawal amount as decimal string
          example: "100.00"

        createdAt:
          type: string
          format: date-time
          description: ISO 8601 timestamp when the withdrawal was created
          example: "2024-01-15T10:30:00Z"

    WithdrawalListResponse:
      type: object
      description: Response containing a list of withdrawals
      required:
        - withdrawals
        - total
        - limit
        - offset
      properties:
        withdrawals:
          type: array
          description: List of withdrawals
          items:
            $ref: '#/components/schemas/WithdrawalResponse'
        total:
          type: integer
          description: Total number of withdrawals available
          example: 100
        limit:
          type: integer
          description: Maximum number of withdrawals returned
          example: 20
        offset:
          type: integer
          description: Number of withdrawals skipped
          example: 0

    Deposit:
      type: object
      description: Response for a deposit
      required:
        - externalId
        - amount
        - paymentMethod
        - status
        - createdAt
      properties:
        externalId:
          type: string
          description: External deposit ID
          example: "dep_1705312200000000000"

        amount:
          type: string
          description: Deposit amount as decimal string
          example: "100.00"

        paymentMethod:
          type: string
          description: Payment method used
          example: "visamc"
          
        status:
          $ref: '#/components/schemas/DepositStatus'
          
        createdAt:
          type: string
          format: date-time
          description: ISO 8601 timestamp when the deposit was created
          example: "2024-01-15T10:30:00Z"

    DepositListResponse:
      type: object
      description: Response containing a list of deposits
      required:
        - deposits
        - total
        - limit
        - offset
      properties:
        deposits:
          type: array
          description: List of deposits
          items:
            $ref: '#/components/schemas/Deposit'
        total:
          type: integer
          description: Total number of deposits available
          example: 100
        limit:
          type: integer
          description: Maximum number of deposits returned
          example: 20
        offset:
          type: integer
          description: Number of deposits skipped
          example: 0

    CashierHistoryRequest:
      type: object
      description: Request parameters for filtering cashier history
      properties:
        from:
          type: string
          format: date-time
          description: Start date for filtering transactions (inclusive)
          example: "2024-01-01T00:00:00Z"
        to:
          type: string
          format: date-time
          description: End date for filtering transactions (inclusive)
          example: "2024-12-31T23:59:59Z"
        transactionType:
          type: string
          description: Filter by transaction type
          enum: ["deposit", "withdrawal"]
          example: "deposit"
        limit:
          type: integer
          description: Maximum number of transactions to return
          minimum: 1
          maximum: 100
          default: 20
          example: 20
        offset:
          type: integer
          description: Number of transactions to skip
          minimum: 0
          default: 0
          example: 0

    CashierHistoryResponse:
      type: object
      description: Response containing combined deposit and withdrawal history
      required:
        - transactions
        - total
        - limit
        - offset
      properties:
        transactions:
          type: array
          description: List of transactions (deposits and withdrawals)
          items:
            $ref: '#/components/schemas/CashierHistoryItem'
        total:
          type: integer
          description: Total number of transactions available
          example: 150
        limit:
          type: integer
          description: Maximum number of transactions returned
          example: 20
        offset:
          type: integer
          description: Number of transactions skipped
          example: 0

    CashierHistoryItem:
      type: object
      description: A single cashier transaction (deposit or withdrawal)
      required:
        - date
        - publicId
        - amount
        - currency
        - status
        - transactionType
      properties:
        date:
          type: string
          format: date-time
          description: Transaction creation date
          example: "2024-01-15T14:30:00Z"
        publicId:
          type: string
          description: Transaction public identifier (deposit or withdrawal ID)
          example: "dep_xyz789abc123"
        amount:
          type: string
          description: Transaction amount as decimal string
          example: "100.00"
        currency:
          type: string
          description: Currency code
          pattern: ^[A-Z]{3}$
          example: "EUR"
        status:
          type: string
          description: Transaction status
          example: "completed"
        transactionType:
          type: string
          description: Type of transaction
          enum: ["deposit", "withdrawal"]
          example: "deposit"

    Gateway:
      type: string
      description: Payment gateway identifier
      enum: ["piq", "fpiq", "trumo"]
      example: "piq"

    PaymentMethod:
      type: string
      description: Payment method identifier
      enum: ["visamc", "bankiban", "bankid"]
      example: "visamc"

    EncryptedCardData:
      type: object
      description: Encrypted credit card data for secure payment processing
      required:
        - cardHolder
        - encCreditcardNumber
        - expiryMonth
        - expiryYear
        - encCvv
      properties:
        cardHolder:
          type: string
          description: Name of the card holder
          example: "John Doe"
        encCreditcardNumber:
          type: string
          description: Encrypted credit card number
          example: "encrypted_card_data"
        expiryMonth:
          type: string
          description: Card expiry month (MM format)
          minLength: 2
          maxLength: 2
          example: "12"
        expiryYear:
          type: string
          description: Card expiry year (YYYY format)
          minLength: 4
          maxLength: 4
          example: "2025"
        encCvv:
          type: string
          description: Encrypted CVV code
          example: "encrypted_cvv"

    EncryptedCardCCV:
      type: object
      description: Encrypted CVV data for secure payment processing
      required:
        - encCvv
      properties:
        encCvv:
          type: string
          description: Encrypted CVV code
          example: "encrypted_cvv"

    DepositStatusResponse:
      type: object
      description: Response containing deposit status information
      required:
        - publicId
        - status
        - amount
        - currency
        - paymentGateway
        - paymentMethod
        - createdAt
        - updatedAt
      properties:
        publicId:
          type: string
          description: Deposit public ID
          pattern: '^dep_[a-zA-Z0-9]+$'
          example: "dep_abc123xyz789"
        status:
          $ref: '#/components/schemas/DepositStatus'
        amount:
          type: string
          description: Deposit amount as decimal string
          example: "100.00"
        currency:
          type: string
          description: Currency code for the deposit
          pattern: ^[A-Z]{3}$
          example: "EUR"
        paymentGateway:
          type: string
          description: Payment gateway used for the deposit
          enum: ["piq", "fpiq", "trumo"]
          example: "piq"
        paymentMethod:
          type: string
          description: Payment method used for the deposit
          example: "visamc"
        createdAt:
          type: string
          format: date-time
          description: ISO 8601 timestamp when the deposit was created
          example: "2024-01-15T10:30:00Z"
        updatedAt:
          type: string
          format: date-time
          description: ISO 8601 timestamp when the deposit was last updated
          example: "2024-01-15T10:35:00Z"
        providerTransactionId:
          type: string
          nullable: true
          description: Provider-specific transaction ID (for debugging)
          example: "2883208724"
        providerStatus:
          type: string
          nullable: true
          description: Provider-specific status (for debugging)
          example: "TRANSFERRED"

    DepositStatus:
      type: string
      description: Status of a deposit
      enum: ["requested", "waiting_user_input", "funded", "failed", "refund_requested", "refunded"]
      example: "requested"

    PasswordResetRequest:
      type: object
      description: Request to initiate a password reset
      required:
        - email
      properties:
        email:
          type: string
          format: email
          description: Email address to send password reset to
          example: "player@example.com"

    PasswordResetConfirm:
      type: object
      description: Request to confirm password reset with token
      required:
        - token
        - newPassword
        - confirmPassword
      properties:
        token:
          type: string
          description: Password reset token received via email
          example: "abc123def456..."
        newPassword:
          type: string
          format: password
          description: New password for the account
          minLength: 8
          example: "newSecurePassword123"
        confirmPassword:
          type: string
          format: password
          description: Confirmation of the new password
          example: "newSecurePassword123"

    PasswordResetResponse:
      type: object
      description: Response for password reset operations
      required:
        - message
        - success
      properties:
        message:
          type: string
          description: Human-readable message about the operation result
          example: "Password reset email sent successfully"
        success:
          type: boolean
          description: Whether the operation was successful
          example: true

    Game:
      type: object
      description: Game information including data fields from pam.games.data
      required:
        - gameId
        - gateway
        - publicId
        - name
        - isWagerBonusAllowed
        - wageringContribution
        - isActive
        - createdAt
        - updatedAt
        - funMode
      properties:
        gameId:
          type: string
          description: External game identifier (without gateway prefix)
          example: "holmes_and_the_stolen_stones_megaways"
        gateway:
          type: string
          description: Game gateway/provider identifier
          example: "st8"
        publicId:
          type: string
          description: Public game identifier in format "gateway:external_id"
          example: "st8:holmes_and_the_stolen_stones_megaways"
        name:
          type: string
          description: Display name of the game
          example: "Holmes and the Stolen Stones Megaways"
        provider:
          type: string
          nullable: true
          description: Game provider name
          example: "Yggdrasil Gaming"
        isWagerBonusAllowed:
          type: boolean
          description: Whether the game allows wagering with bonus money
          example: true
        wageringContribution:
          type: string
          description: Wagering contribution percentage as decimal string
          example: "100.00"
        isActive:
          type: boolean
          description: Whether the game is currently active
          example: true
        createdAt:
          type: string
          format: date-time
          description: Timestamp when the game was created
          example: "2023-01-01T00:00:00Z"
        updatedAt:
          type: string
          format: date-time
          description: Timestamp when the game was last updated
          example: "2023-01-01T00:00:00Z"
        # Extended fields from pam.games.data JSONB column
        allowBonusPlay:
          type: boolean
          description: Whether the game allows bonus play (from data.allowBonusPlay)
          example: true
        categories:
          type: array
          items:
            type: string
          description: Game categories (from data.categories)
          example: ["slots", "video-slots", "megaways"]
        rtp:
          type: number
          format: float
          description: Return to Player percentage (from data.rtp)
          example: 96.8
          nullable: true
        volatility:
          type: string
          description: Game volatility level (from data.volatility)
          example: "high"
          nullable: true
          enum: ["low", "medium", "high"]
        minBet:
          type: string
          description: Minimum bet amount as decimal string (from data.minBet)
          pattern: ^\d+\.\d{2}$
          example: "0.10"
          nullable: true
        maxBet:
          type: string
          description: Maximum bet amount as decimal string (from data.maxBet)
          pattern: ^\d+\.\d{2}$
          example: "100.00"
          nullable: true
        funMode:
          type: boolean
          description: Whether the game supports fun/demo mode (from data.fun_mode)
          example: true
        bonusTypes:
          type: array
          items:
            type: string
          description: Available bonus types for this game (from data.bonus_types)
          example: ["free_spins", "multipliers"]
          nullable: true
        features:
          type: array
          items:
            type: string
          description: Game features available (from data.features)
          example: ["autoplay", "freeSpins", "multipliers"]
          nullable: true
        themes:
          type: array
          items:
            type: string
          description: Game themes (from data.themes)
          example: ["adventure", "egypt", "ancient"]
          nullable: true
        developer:
          type: string
          description: Game developer/studio (from data.developer)
          example: "Yggdrasil Gaming"
          nullable: true
        releaseDate:
          type: string
          format: date
          description: Game release date (from data.release_date)
          example: "2023-01-15"
          nullable: true
        deprecationDate:
          type: string
          format: date
          description: Game deprecation date (from data.deprecation_date)
          example: "2025-12-31"
          nullable: true
        maxPayoutCoeff:
          type: string
          description: Maximum payout coefficient as decimal string (from data.max_payout_coeff)
          pattern: ^\d+\.\d{2}$
          example: "5000.00"
          nullable: true
        extraSettings:
          type: object
          description: Additional game-specific settings (from data.extraSettings)
          additionalProperties: true
          example:
            paylines: "117649"
            maxWin: "20000x"
            freeSpins: true
            multipliers: true
            autoplay: true
            cascadingReels: true

    GamesListResponse:
      type: object
      description: Response containing a list of games
      required:
        - games
        - total
        - limit
        - offset
      properties:
        games:
          type: array
          items:
            $ref: '#/components/schemas/Game'
          description: Array of games
        total:
          type: integer
          description: Total number of games available (for pagination)
          example: 150
        limit:
          type: integer
          description: Number of games requested
          example: 100
        offset:
          type: integer
          description: Number of games skipped
          example: 0

    GameLaunchRequest:
      type: object
      required:
        - gameId
        - currency
      properties:
        gameId:
          type: string
          description: Game public identifier in format "gateway:external_id" (e.g., "st8:holmes_and_the_stolen_stones_megaways")
          example: "st8:holmes_and_the_stolen_stones_megaways"
        currency:
          type: string
          description: Currency code (ISO 4217)
          example: "EUR"
        language:
          type: string
          description: Language code (ISO 639-3). ISO 639-1 and common language names are also accepted and will be converted automatically.
          example: "eng"
        device:
          type: string
          enum: ["DESKTOP", "MOBILE", "TABLET"]
          description: Device type
          example: "DESKTOP"
        returnUrl:
          type: string
          description: URL to return to after game session
          example: "https://casino.example.com/lobby"
        depositUrl:
          type: string
          description: URL for cashier/deposit functionality
          example: "https://casino.example.com/cashier"

    DemoGameLaunchRequest:
      type: object
      required:
        - gameId
      properties:
        gameId:
          type: string
          description: Game public identifier in format "gateway:external_id" (e.g., "st8:holmes_and_the_stolen_stones_megaways")
          example: "st8:holmes_and_the_stolen_stones_megaways"
        language:
          type: string
          description: Language code (ISO 639-3). ISO 639-1 and common language names are also accepted and will be converted automatically.
          example: "eng"
        returnUrl:
          type: string
          description: URL to return to after game session
          example: "https://casino.example.com/lobby"
        depositUrl:
          type: string
          description: URL for cashier/deposit functionality
          example: "https://casino.example.com/cashier"

    GameLaunchResponse:
      type: object
      required:
        - success
      properties:
        success:
          type: boolean
          description: Whether the game launch was successful
        gameUrl:
          type: string
          description: Game launch URL (present when success is true)
          example: "https://launcher.p8d.com/game/abc123"
        errorMessage:
          type: string
          description: Error message (present when success is false)


    GameHistoryAction:
      type: object
      description: Casino action from game history
      required:
        - gateway
        - externalId
        - actionType
        - amount
        - currency
        - createdAt
      properties:
        gateway:
          type: string
          description: Game gateway identifier
          enum: [st8, yggdrasil]
          example: "st8"
        externalId:
          type: string
          description: External transaction ID from game provider
          example: "tx_abc123def456"
        actionType:
          type: string
          description: Type of casino action
          enum: [credit, debit, cancel]
          example: "credit"
        gameCode:
          type: string
          description: Game code from provider
          example: "slot_adventure"
          nullable: true
        gameName:
          type: string
          description: Human-readable game name
          example: "Adventure Slots"
          nullable: true
        roundId:
          type: string
          description: Game round identifier
          example: "round_789xyz"
          nullable: true
        roundClosed:
          type: boolean
          description: Whether the game round is closed/completed
          example: true
          nullable: true
        transactionId:
          type: string
          description: Transaction identifier
          example: "tx_unique_123"
        amount:
          type: string
          description: Transaction amount in base currency
          pattern: ^\d+\.\d{2}$
          example: "25.50"
        currency:
          type: string
          description: Transaction currency code
          pattern: ^[A-Z]{3}$
          example: "EUR"
        realPreviousBalance:
          type: string
          description: Real balance before transaction
          pattern: ^\d+\.\d{2}$
          example: "100.00"
          nullable: true
        realNewBalance:
          type: string
          description: Real balance after transaction
          pattern: ^\d+\.\d{2}$
          example: "125.50"
          nullable: true
        bonusPreviousBalance:
          type: string
          description: Bonus balance before transaction
          pattern: ^\d+\.\d{2}$
          example: "0.00"
          nullable: true
        bonusNewBalance:
          type: string
          description: Bonus balance after transaction
          pattern: ^\d+\.\d{2}$
          example: "0.00"
          nullable: true
        sessionId:
          type: string
          description: Game launch token from the session
          example: "glt_OJxNA042JNxFhQiY"
          nullable: true
        gameLaunchId:
          type: integer
          format: int64
          description: PAM gamelaunch ID
          example: 555444333
          nullable: true
        createdAt:
          type: string
          format: date-time
          description: Timestamp when action was created
          example: "2025-01-15T14:30:00Z"

    GameHistoryRequest:
      type: object
      description: Request to get game history with optional filters
      properties:
        gameCode:
          type: string
          description: Filter by specific game code
          example: "slot_adventure"
        actionType:
          type: string
          description: Filter by casino action type
          enum: [credit, debit, cancel]
          example: "credit"
        from:
          type: string
          format: date-time
          description: Filter actions from this date (ISO 8601 format)
          example: "2025-01-01T00:00:00Z"
        to:
          type: string
          format: date-time
          description: Filter actions to this date (ISO 8601 format)
          example: "2025-01-31T23:59:59Z"
        limit:
          type: integer
          description: Maximum number of actions to return
          minimum: 1
          maximum: 1000
          default: 100
          example: 100
        offset:
          type: integer
          description: Number of actions to skip for pagination
          minimum: 0
          default: 0
          example: 0

    GameHistoryResponse:
      type: object
      description: Response containing game history actions
      required:
        - actions
        - total
        - limit
        - offset
      properties:
        actions:
          type: array
          items:
            $ref: '#/components/schemas/GameHistoryAction'
          description: Array of casino actions
        total:
          type: integer
          description: Total number of actions available (for pagination)
          example: 250
        limit:
          type: integer
          description: Number of actions requested
          example: 100
        offset:
          type: integer
          description: Number of actions skipped
          example: 0

    DepositSchemaRequest:
      type: object
      description: Request to get deposit form schema for a specific payment method. Brand ID is extracted from hostname and payment gateway is determined from brand configuration.
      required:
        - paymentMethod
      properties:
        paymentMethod:
          type: string
          description: Payment method code
          example: "visamc"
        isSavedAccount:
          type: boolean
          description: Whether this is for a saved payment account
          example: false

    DepositInitRequest:
      type: object
      description: |
        Flat request structure for initializing a deposit.

        This schema contains all possible payment fields at the top level.
        Payment method specific fields are optional and should only be provided
        when relevant to the selected payment method.

        **For credit card payments (visamc):**
        - New card: Provide cardHolder, encCreditcardNumber, expiryMonth, expiryYear, encCvv
        - Saved card: Provide paymentAccountId and optionally encCvv

        **For bank transfer payments (bankiban):**
        - Provide accountHolder and accountNumber
      required:
        - currency
        - paymentGateway
        - paymentMethod
      properties:
        amount:
          type: string
          description: Payment amount as decimal string
          example: "100.00"
        currency:
          type: string
          description: Currency code for the payment
          pattern: ^[A-Z]{3}$
          example: "EUR"
        paymentAccountId:
          type: string
          description: Payment account ID for previously saved payment account
          example: "799"
        bonusPublicId:
          type: string
          description: Optional bonus public ID to apply to the deposit
          example: "bonus_67890"
        paymentMethod:
          type: string
          description: Payment method code
          example: "visamc"
        paymentGateway:
          type: string
          description: Payment gateway identifier
          enum:
            - "piq"
            - "fpiq"
            - "trumo"
          example: "piq"
        successUrl:
          type: string
          format: uri
          description: URL to redirect to after successful payment
          example: "https://example.com/payment/success"
        failureUrl:
          type: string
          format: uri
          description: URL to redirect to after failed payment
          example: "https://example.com/payment/failure"
        pendingUrl:
          type: string
          format: uri
          description: URL to redirect to when payment is pending
          example: "https://example.com/payment/pending"
        cancelUrl:
          type: string
          format: uri
          description: URL to redirect to when payment is cancelled
          example: "https://example.com/payment/cancel"
        # Credit card fields (optional, for card payments)
        cardHolder:
          type: string
          description: Name of the card holder (for credit card payments)
          example: "John Doe"
        encCreditcardNumber:
          type: string
          description: Encrypted credit card number (for new credit card payments)
          example: "encrypted_card_data"
        expiryMonth:
          type: string
          description: Card expiry month in MM format (for credit card payments)
          minLength: 2
          maxLength: 2
          example: "12"
        expiryYear:
          type: string
          description: Card expiry year in YY format (for credit card payments)
          minLength: 2
          maxLength: 2
          pattern: '^\d{2}$'
          example: "25"
        encCvv:
          type: string
          description: Encrypted CVV code (for credit card payments)
          example: "encrypted_cvv_data"
        # Bank account fields (optional, for bank transfer payments)
        accountHolder:
          type: string
          description: Account holder name (for bank transfer payments)
          example: "John Doe"
        accountNumber:
          type: string
          description: Bank account number or IBAN (for bank transfer payments)
          example: "DE89370400440532013000"

    DepositSchemaResponse:
      type: object
      description: Dynamic form schema for deposit
      required:
        - fields
      properties:
        fields:
          type: array
          items:
            $ref: '#/components/schemas/FormField'
          description: Array of form fields with validation rules
        encryptor:
          $ref: '#/components/schemas/Encryptor'
          description: Encryption script configuration for secure field handling

    WithdrawalSchemaRequest:
      type: object
      description: Request to get withdrawal form schema for a specific payment method. Brand ID is extracted from hostname and payment gateway is determined from brand configuration.
      required:
        - paymentMethod
      properties:
        paymentMethod:
          type: string
          description: Payment method code
          example: "visamc"
        isSavedAccount:
          type: boolean
          description: Whether this is for a saved payment account
          example: false

    WithdrawalSchemaResponse:
      type: object
      description: Dynamic form schema for withdrawal
      required:
        - fields
      properties:
        fields:
          type: array
          items:
            $ref: '#/components/schemas/FormField'
          description: Array of form fields with validation rules
        encryptor:
          $ref: '#/components/schemas/Encryptor'
          description: Encryption script configuration for secure field handling

    WithdrawalInitRequest:
      type: object
      description: |
        Flat request structure for initializing a withdrawal.

        This schema contains all possible payment fields at the top level.
        Payment method specific fields are optional and should only be provided
        when relevant to the selected payment method.

        **For bank transfer withdrawals (bankiban):**
        - New account: Provide beneficiaryName, accountNumber, and bic
        - Saved account: Provide paymentAccountId
      required:
        - currency
        - paymentGateway
        - paymentMethod
      properties:
        amount:
          type: string
          description: Withdrawal amount as decimal string
          example: "100.00"
        currency:
          type: string
          description: Currency code for the withdrawal
          pattern: ^[A-Z]{3}$
          example: "EUR"
        paymentAccountId:
          type: string
          description: Payment account ID for previously saved payment account
          example: "799"
        paymentMethod:
          type: string
          description: Payment method code
          example: "bankiban"
        paymentGateway:
          type: string
          description: Payment gateway identifier
          enum:
            - "piq"
            - "fpiq"
            - "trumo"
          example: "piq"
        successUrl:
          type: string
          format: uri
          description: URL to redirect to after successful withdrawal
          example: "https://example.com/withdrawal/success"
        failureUrl:
          type: string
          format: uri
          description: URL to redirect to after failed withdrawal
          example: "https://example.com/withdrawal/failure"
        pendingUrl:
          type: string
          format: uri
          description: URL to redirect to when withdrawal is pending
          example: "https://example.com/withdrawal/pending"
        cancelUrl:
          type: string
          format: uri
          description: URL to redirect to when withdrawal is cancelled
          example: "https://example.com/withdrawal/cancel"
        # Bank account fields (optional, for bank transfer withdrawals)
        beneficiaryName:
          type: string
          description: Beneficiary name (for bank transfer withdrawals)
          example: "John Doe"
        accountNumber:
          type: string
          description: Bank account number or IBAN (for bank transfer withdrawals)
          example: "DE89370400440532013000"
        bic:
          type: string
          description: BIC/SWIFT code (for bank transfer withdrawals)
          example: "DEUTDEFF"

    FormField:
      type: object
      description: Form field definition with validators
      required:
        - code
        - name
        - fieldType
        - required
      properties:
        code:
          type: string
          description: Field identifier/code
          example: "cardHolder"
        name:
          type: string
          description: Display name for the field
          example: "Card Holder"
        fieldType:
          type: string
          description: Type of the field (string, number, date, etc.)
          example: "string"
        dataType:
          type: string
          description: Data type for the field
          example: "string"
        required:
          type: boolean
          description: Whether the field is required
          example: false
        width:
          type: integer
          description: Field width percentage (0-100)
          example: 100
        encryptionRequired:
          type: boolean
          description: Whether this field requires encryption (true for fields with codes starting with 'enc')
          example: true
        hidden:
          type: boolean
          description: Whether this field should be hidden in the UI
          example: false
        validators:
          type: array
          items:
            $ref: '#/components/schemas/FieldValidator'
          description: Array of validators to apply to this field

    FieldValidator:
      type: object
      description: Validator configuration for a form field
      required:
        - key
        - name
        - invalid_message
        - description
      properties:
        key:
          type: string
          description: Validator type identifier
          example: "minLength"
        name:
          type: string
          description: Validator name
          example: "minLength"
        invalid_message:
          type: string
          description: Error message key when validation fails
          example: "min_length_not_met"
        description:
          type: string
          description: Human-readable description of the validator
          example: "Checks if input value length is greater than targetLength. In case it is less, method will return an error"
        parameters:
          type: object
          description: Validator-specific parameters
          additionalProperties: true
          example:
            targetLength: 4

    Encryptor:
      type: object
      description: Encryption script configuration for secure field handling
      required:
        - scriptAddress
        - functionName
      properties:
        scriptAddress:
          type: string
          description: URL or path to the encryption script
          format: uri
          example: "https://cdn.example.com/encryption/piq-encryptor.js"
        functionName:
          type: string
          description: Name of the encryption function to call
          example: "encryptField"

security:
  - bearerAuth: [] 