openapi: 3.1.0
info:
  title: Bitmessa API
  description: |
    # Bitmessa Partner API
    
    Convert BTC and USDT to Naira programmatically. This specification documents
    the public Partner API for external integrations — admin, referral, earn,
    and internal operations endpoints are intentionally excluded.
    
    ## Features
    
    - Real-time exchange rates
    - Payment lifecycle (create, track, finalize)
    - Bank account resolution and assignment
    - Transaction history
    - Webhook notifications
    - Public health and fee-rate endpoints
  version: '2.1.0'
  contact:
    name: Bitmessa Support
    url: https://bitmessa.com/support
    email: support@bitmessa.com
  license:
    name: MIT
    url: https://opensource.org/licenses/MIT
servers:
  - url: https://api.bitmessa.com
    description: Production server
  - url: http://localhost:3000
    description: Local development server
security:
  - ApiKeyAuth: []

tags:
  - name: Rates
    description: Exchange rate endpoints
  - name: Payments
    description: Payment processing endpoints
  - name: Transactions
    description: Transaction management endpoints
  - name: Accounts
    description: Bank account management endpoints
  - name: Webhooks
    description: Webhook configuration endpoints
  - name: Health
    description: Public health endpoints
  - name: Fees
    description: Public Bitcoin fee information

paths:
  # ========================================
  # HEALTH & MONITORING ENDPOINTS
  # ========================================
  /health:
    get:
      tags:
        - Health
      summary: System health check
      description: Returns basic system health status
      operationId: getHealth
      security: []
      responses:
        '200':
          description: System is healthy
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: "healthy"
                  timestamp:
                    type: string
                    format: date-time
                  uptime:
                    type: number
                    description: System uptime in seconds
        '503':
          description: System is unhealthy

  # ========================================
  # RATES ENDPOINTS
  # ========================================
  /get/rate:
    get:
      tags:
        - Rates
      summary: Get current exchange rates
      description: |
        Returns the current exchange rates for BTC and USDT to Naira.
        This is the main rate endpoint used by the platform.
      operationId: getCurrentRates
      security: []
      responses:
        '200':
          description: Successful operation
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    type: object
                    properties:
                      btc_rate:
                        type: number
                        description: BTC to Naira rate
                      usdt_rate:
                        type: number
                        description: USDT to Naira rate
                      timestamp:
                        type: string
                        format: date-time
                  message:
                    type: string

  /rates/current:
    get:
      tags:
        - Rates
      summary: Get current exchange rates (commercial API)
      description: |
        Returns the current exchange rates for BTC and USDT to Naira.
        Rates are updated every minute.
      operationId: getCurrentRatesCommercial
      parameters:
        - name: currency
          in: query
          description: Filter by specific currency (BTC or USDT)
          required: false
          schema:
            type: string
            enum: [BTC, USDT]
      responses:
        '200':
          description: Successful operation
          content:
            application/json:
              schema:
                type: object
                properties:
                  timestamp:
                    type: string
                    format: date-time
                    description: Timestamp of the rates
                  rates:
                    type: object
                    properties:
                      BTC:
                        type: object
                        properties:
                          buy:
                            type: number
                            format: float
                            description: Buy rate in Naira
                          sell:
                            type: number
                            format: float
                            description: Sell rate in Naira
                      USDT:
                        type: object
                        properties:
                          buy:
                            type: number
                            format: float
                            description: Buy rate in Naira
                          sell:
                            type: number
                            format: float
                            description: Sell rate in Naira
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '429':
          $ref: '#/components/responses/TooManyRequests'

  # ========================================
  # PAYMENT ENDPOINTS
  # ========================================
  /payment:
    post:
      tags:
        - Payments
      summary: Create a new payment
      description: |
        Creates a new payment request to convert BTC or USDT to Naira.
      operationId: createPayment
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - amount
                - currency
              properties:
                amount:
                  type: number
                  description: Amount to convert
                currency:
                  type: string
                  enum: [BTC, USDT]
                  description: Source currency
                bank_account:
                  type: string
                  description: Bank account number
                bank_name:
                  type: string
                  description: Bank name
      responses:
        '201':
          description: Payment created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Payment'
        '400':
          $ref: '#/components/responses/BadRequestError'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '429':
          $ref: '#/components/responses/TooManyRequests'

  /payment/{id}:
    get:
      tags:
        - Payments
      summary: Get payment details
      description: |
        Returns details of a specific payment (authenticated access).
      operationId: getPayment
      parameters:
        - name: id
          in: path
          description: Payment ID
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Successful operation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Payment'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '404':
          $ref: '#/components/responses/NotFoundError'
        '429':
          $ref: '#/components/responses/TooManyRequests'

  /payment/search/{id}:
    get:
      tags:
        - Payments
      summary: Search payment (public)
      description: |
        Returns details of a specific payment (public access).
      operationId: searchPayment
      security: []
      parameters:
        - name: id
          in: path
          description: Payment ID
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Successful operation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Payment'
        '404':
          $ref: '#/components/responses/NotFoundError'

  /payments:
    get:
      tags:
        - Payments
      summary: List user payments
      description: |
        Returns a list of payments for the authenticated user.
      operationId: listPayments
      parameters:
        - name: page
          in: query
          description: Page number
          required: false
          schema:
            type: integer
            default: 1
        - name: limit
          in: query
          description: Number of items per page
          required: false
          schema:
            type: integer
            default: 20
            maximum: 100
        - name: status
          in: query
          description: Filter by payment status
          required: false
          schema:
            type: string
            enum: [pending, completed, failed]
      responses:
        '200':
          description: Successful operation
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Payment'
                  pagination:
                    $ref: '#/components/schemas/Pagination'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '429':
          $ref: '#/components/responses/TooManyRequests'

  /payment/finalize/{id}:
    post:
      tags:
        - Payments
      summary: Finalize payment
      description: |
        Finalizes a payment with bank account details.
      operationId: finalizePayment
      parameters:
        - name: id
          in: path
          description: Payment ID
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - bank_account
                - bank_name
                - account_name
              properties:
                bank_account:
                  type: string
                  description: Bank account number
                bank_name:
                  type: string
                  description: Bank name
                account_name:
                  type: string
                  description: Account holder name
      responses:
        '200':
          description: Payment finalized successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Payment'
        '400':
          $ref: '#/components/responses/BadRequestError'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '404':
          $ref: '#/components/responses/NotFoundError'
        '429':
          $ref: '#/components/responses/TooManyRequests'

  # ========================================
  # ACCOUNT ENDPOINTS
  # ========================================
  /accounts:
    get:
      tags:
        - Accounts
      summary: List user bank accounts
      description: |
        Returns a list of bank accounts for the authenticated user.
      operationId: listAccounts
      responses:
        '200':
          description: Successful operation
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/BankAccount'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '429':
          $ref: '#/components/responses/TooManyRequests'

  /account/{id}:
    get:
      tags:
        - Accounts
      summary: Get account details
      description: |
        Returns details of a specific bank account.
      operationId: getAccount
      parameters:
        - name: id
          in: path
          description: Account ID
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Successful operation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BankAccount'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '404':
          $ref: '#/components/responses/NotFoundError'
        '429':
          $ref: '#/components/responses/TooManyRequests'

  /account/assign/{payment_id}:
    post:
      tags:
        - Accounts
      summary: Assign account to payment
      description: |
        Assigns a bank account to a specific payment.
      operationId: assignAccountToPayment
      parameters:
        - name: payment_id
          in: path
          description: Payment ID
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - account_id
              properties:
                account_id:
                  type: string
                  description: Account ID to assign
      responses:
        '200':
          description: Account assigned successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  message:
                    type: string
        '400':
          $ref: '#/components/responses/BadRequestError'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '404':
          $ref: '#/components/responses/NotFoundError'
        '429':
          $ref: '#/components/responses/TooManyRequests'

  /banks/get:
    get:
      tags:
        - Accounts
      summary: Get bank list
      description: |
        Returns a list of supported Nigerian banks.
      operationId: getBankList
      responses:
        '200':
          description: Successful operation
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Bank'

  /account-resolve:
    post:
      tags:
        - Accounts
      summary: Resolve bank account
      description: |
        Resolves bank account details using account number and bank code.
      operationId: resolveAccount
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - account_number
                - bank_code
              properties:
                account_number:
                  type: string
                  description: Bank account number
                bank_code:
                  type: string
                  description: Bank code
      responses:
        '200':
          description: Account resolved successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    type: object
                    properties:
                      account_name:
                        type: string
                      account_number:
                        type: string
                      bank_name:
                        type: string
        '400':
          $ref: '#/components/responses/BadRequestError'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '429':
          $ref: '#/components/responses/TooManyRequests'

  # ========================================
  # TRANSACTION ENDPOINTS
  # ========================================
  /transactions:
    get:
      tags:
        - Transactions
      summary: List user transactions
      description: |
        Returns a list of transactions for the authenticated user.
      operationId: listTransactions
      parameters:
        - name: page
          in: query
          description: Page number
          required: false
          schema:
            type: integer
            default: 1
        - name: limit
          in: query
          description: Number of items per page
          required: false
          schema:
            type: integer
            default: 20
            maximum: 100
        - name: status
          in: query
          description: Filter by transaction status
          required: false
          schema:
            type: string
            enum: [pending, completed, failed]
        - name: currency
          in: query
          description: Filter by currency
          required: false
          schema:
            type: string
            enum: [BTC, USDT]
      responses:
        '200':
          description: Successful operation
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Transaction'
                  pagination:
                    $ref: '#/components/schemas/Pagination'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '429':
          $ref: '#/components/responses/TooManyRequests'

  /transaction/{id}:
    get:
      tags:
        - Transactions
      summary: Get transaction details
      description: |
        Returns details of a specific transaction.
      operationId: getTransaction
      parameters:
        - name: id
          in: path
          description: Transaction ID
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Successful operation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Transaction'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '404':
          $ref: '#/components/responses/NotFoundError'
        '429':
          $ref: '#/components/responses/TooManyRequests'

  # ========================================
  # PUBLIC FEE ENDPOINTS
  # ========================================
  /bitcoin/public/currentfeerates:
    get:
      tags:
        - Fees
      summary: Get Bitcoin fee rates
      description: |
        Returns current Bitcoin network fee rates. Public endpoint — no authentication required.
        Useful for estimating confirmation times when building payment integrations.
      operationId: getBitcoinFeeRates
      security: []
      responses:
        '200':
          description: Fee rates returned successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  data:
                    type: object
                    additionalProperties: true
        '503':
          description: Fee service temporarily unavailable

  # ========================================
  # WEBHOOK ENDPOINTS
  # ========================================
  /webhooks:
    post:
      tags:
        - Webhooks
      summary: Register a webhook
      description: |
        Registers a new webhook to receive notifications for specific events.
      operationId: registerWebhook
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WebhookRequest'
      responses:
        '201':
          description: Webhook registered successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Webhook'
        '400':
          $ref: '#/components/responses/BadRequestError'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '429':
          $ref: '#/components/responses/TooManyRequests'

components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: secretkey
      description: Partner API key issued by Bitmessa

  schemas:
    Payment:
      type: object
      properties:
        id:
          type: string
          description: Payment ID
        amount:
          type: number
          description: Payment amount
        currency:
          type: string
          enum: [BTC, USDT]
          description: Source currency
        status:
          type: string
          enum: [pending, completed, failed]
          description: Payment status
        bank_account:
          type: string
          description: Bank account number
        bank_name:
          type: string
          description: Bank name
        account_name:
          type: string
          description: Account holder name
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time

    Transaction:
      type: object
      properties:
        id:
          type: string
          description: Transaction ID
        payment_id:
          type: string
          description: Associated payment ID
        type:
          type: string
          enum: [deposit, withdrawal]
          description: Transaction type
        amount:
          type: number
          description: Transaction amount
        currency:
          type: string
          enum: [BTC, USDT, NGN]
          description: Transaction currency
        status:
          type: string
          enum: [pending, completed, failed]
          description: Transaction status
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time

    BankAccount:
      type: object
      properties:
        id:
          type: string
          description: Account ID
        account_number:
          type: string
          description: Bank account number
        account_name:
          type: string
          description: Account holder name
        bank_name:
          type: string
          description: Bank name
        bank_code:
          type: string
          description: Bank code
        is_active:
          type: boolean
          description: Account status
        created_at:
          type: string
          format: date-time

    Bank:
      type: object
      properties:
        code:
          type: string
          description: Bank code
        name:
          type: string
          description: Bank name
        longcode:
          type: string
          description: Long bank code
        active:
          type: boolean
          description: Bank status
        country:
          type: string
          description: Country code
        currency:
          type: string
          description: Currency code

    WebhookRequest:
      type: object
      required:
        - url
        - events
      properties:
        url:
          type: string
          format: uri
          description: Webhook URL
        events:
          type: array
          items:
            type: string
            enum: [payment.completed, payment.failed, transaction.completed]
          description: Events to subscribe to
        secret:
          type: string
          description: Webhook secret for signature verification

    Webhook:
      type: object
      properties:
        id:
          type: string
          description: Webhook ID
        url:
          type: string
          format: uri
          description: Webhook URL
        events:
          type: array
          items:
            type: string
          description: Subscribed events
        is_active:
          type: boolean
          description: Webhook status
        created_at:
          type: string
          format: date-time

    Pagination:
      type: object
      properties:
        page:
          type: integer
          description: Current page number
        limit:
          type: integer
          description: Items per page
        total:
          type: integer
          description: Total number of items
        pages:
          type: integer
          description: Total number of pages

  responses:
    BadRequestError:
      description: Bad request
      content:
        application/json:
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              error:
                type: object
                properties:
                  code:
                    type: string
                    example: "BAD_REQUEST"
                  message:
                    type: string
                    example: "Invalid request parameters"
                  details:
                    type: object

    UnauthorizedError:
      description: Unauthorized
      content:
        application/json:
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              error:
                type: object
                properties:
                  code:
                    type: string
                    example: "UNAUTHORIZED"
                  message:
                    type: string
                    example: "Authentication required"

    ForbiddenError:
      description: Forbidden
      content:
        application/json:
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              error:
                type: object
                properties:
                  code:
                    type: string
                    example: "FORBIDDEN"
                  message:
                    type: string
                    example: "Insufficient permissions"

    NotFoundError:
      description: Not found
      content:
        application/json:
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              error:
                type: object
                properties:
                  code:
                    type: string
                    example: "NOT_FOUND"
                  message:
                    type: string
                    example: "Resource not found"

    TooManyRequests:
      description: Too many requests
      content:
        application/json:
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              error:
                type: object
                properties:
                  code:
                    type: string
                    example: "RATE_LIMIT_EXCEEDED"
                  message:
                    type: string
                    example: "Rate limit exceeded"
                  retry_after:
                    type: integer
                    description: Seconds to wait before retrying
