openapi: 3.0.0
info:
  title: Airpero SaaS API Documentation
  version: 1.0.0
  description: API for Merchant Dashboards, SuperAdmin controls, and External Integrations.
  contact:
    name: Airpero Support
    email: support@airpero.com

servers:
  - url: http://localhost:8200/api/v1
    description: Development server
  - url: https://sandbox.v1.airpero.com/api/v1
    description: Sandbox server

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
    apiKeyPub:
      type: apiKey
      in: header
      name: x-public-key
    apiKeyPrv:
      type: apiKey
      in: header
      name: x-private-key

tags:
  - name: Admin
    description: SuperAdmin and Admin operations
  - name: Merchant
    description: Merchant dashboard and integration operations
  - name: Customer
    description: End-user account management
  - name: Tools
    description: Banking and utility tools

paths:
  /admin/login:
    post:
      summary: Admin Login
      tags: [Admin]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                email: { type: string }
                password: { type: string }
      responses:
        200: { description: Login successful }

  /admin/merchants:
    get:
      summary: List all merchants with pagination and search
      tags: [Admin]
      security: [{ bearerAuth: [] }]
      parameters:
        - in: query
          name: page
          schema: { type: integer, default: 1 }
        - in: query
          name: limit
          schema: { type: integer, default: 50 }
        - in: query
          name: status
          schema: { type: string, enum: [active, inactive, suspended] }
        - in: query
          name: search
          schema: { type: string }
          description: Search by business name or email
      responses:
        200: { description: Success }
    post:
      summary: Register a new Merchant (SuperAdmin Only)
      tags: [Admin]
      security: [{ bearerAuth: [] }]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                businessName: { type: string }
                email: { type: string }
                password: { type: string }
      responses:
        201: { description: Merchant created }

  /admin/merchants/{merchantId}:
    get:
      summary: Get full breakdown of a Merchant's profile, customers, and transactions
      tags: [Admin]
      security: [{ bearerAuth: [] }]
      parameters:
        - in: path
          name: merchantId
          required: true
          schema: { type: string }
      responses:
        200: { description: Success }

  /admin/merchants/{merchantId}/status:
    patch:
      summary: Update Merchant status (Activate, Deactivate, Suspend)
      tags: [Admin]
      security: [{ bearerAuth: [] }]
      parameters:
        - in: path
          name: merchantId
          required: true
          schema: { type: string }
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                status: { type: string, enum: [active, inactive, suspended] }
      responses:
        200: { description: Success }

  /admin/merchants/{merchantId}/stats:
    get:
      summary: Get detailed stats for a specific merchant (Admin View)
      tags: [Admin]
      security: [{ bearerAuth: [] }]
      parameters:
        - in: path
          name: merchantId
          required: true
          schema: { type: string }
      responses:
        200: { description: Merchant performance metrics }

  /admin/profits/stats:
    get:
      summary: Get platform-wide profit statistics
      tags: [Admin]
      security: [{ bearerAuth: [] }]
      responses:
        200: { description: Aggregated profit data }

  /admin/profits/history:
    get:
      summary: Get history of platform profit logs
      tags: [Admin]
      security: [{ bearerAuth: [] }]
      parameters:
        - in: query
          name: page
          schema: { type: integer, default: 1 }
        - in: query
          name: limit
          schema: { type: integer, default: 50 }
      responses:
        200: { description: Profit history list }

  /admin/report:
    get:
      summary: Get overall platform revenue report (Legacy aggregation)
      tags: [Admin]
      security: [{ bearerAuth: [] }]
      responses:
        200: { description: Report data }
  
  /admin/dashboard:
    get:
      summary: Comprehensive dashboard metrics and transaction trends
      tags: [Admin]
      security: [{ bearerAuth: [] }]
      parameters:
        - in: query
          name: startDate
          schema: { type: string, format: date }
          description: Filter data from this date
        - in: query
          name: endDate
          schema: { type: string, format: date }
          description: Filter data to this date
      responses:
        200:
          description: Success
          content:
            application/json:
              schema:
                type: object
                properties:
                  success: { type: boolean }
                  data:
                    type: object
                    properties:
                      merchants:
                        type: object
                        properties:
                          total: { type: integer }
                          active: { type: integer }
                          newInRange: { type: integer }
                          recent: { type: array, items: { type: object } }
                      transactions:
                        type: object
                        properties:
                          total: { type: integer }
                          success: { type: integer }
                          failed: { type: integer }
                          pending: { type: integer }
                          creditVolume: { type: number }
                          debitVolume: { type: number }
                      customers:
                        type: object
                        properties:
                          total: { type: integer }
                      funds:
                        type: object
                        properties:
                          totalSystemFunds: { type: number }
                          totalMerchantBalances: { type: number }
                          totalCustomerBalances: { type: number }
                      profit:
                        type: object
                        properties:
                          total: { type: number }
                      trends:
                        type: array
                        items: { type: object }
  
  /admin/transactions:
    get:
      summary: List all transactions system-wide with pagination and filters
      tags: [Admin]
      security: [{ bearerAuth: [] }]
      parameters:
        - in: query
          name: page
          schema: { type: integer, default: 1 }
        - in: query
          name: limit
          schema: { type: integer, default: 50 }
        - in: query
          name: status
          schema: { type: string, enum: [success, pending, failed] }
        - in: query
          name: type
          schema: { type: string, enum: [debit, credit] }
        - in: query
          name: class
          schema: { type: string, enum: [payout, deposit, transfer] }
        - in: query
          name: merchantId
          schema: { type: string }
        - in: query
          name: customerId
          schema: { type: string }
        - in: query
          name: startDate
          schema: { type: string, format: date }
        - in: query
          name: endDate
          schema: { type: string, format: date }
        - in: query
          name: search
          schema: { type: string }
          description: Search by transaction ID or info
      responses:
        200:
          description: Success
          content:
            application/json:
              schema:
                type: object
                properties:
                  success: { type: boolean }
                  total: { type: integer }
                  pages: { type: integer }
                  currentPage: { type: integer }
                  data: { type: array, items: { type: object } }

  /admin/customers:
    get:
      summary: List all customers system-wide with pagination and search
      tags: [Admin]
      security: [{ bearerAuth: [] }]
      parameters:
        - in: query
          name: page
          schema: { type: integer, default: 1 }
        - in: query
          name: limit
          schema: { type: integer, default: 50 }
        - in: query
          name: merchantId
          schema: { type: string }
        - in: query
          name: search
          schema: { type: string }
          description: Search by name, email, or account number
      responses:
        200: { description: Success }

  /admin/customers/{customerId}:
    get:
      summary: Get full details of a customer, including their merchant and recent activity
      tags: [Admin]
      security: [{ bearerAuth: [] }]
      parameters:
        - in: path
          name: customerId
          required: true
          schema: { type: string }
      responses:
        200: { description: Success }

  /admin/settings:
    get:
      summary: Get global fee settings
      tags: [Admin]
      security: [{ bearerAuth: [] }]
      responses:
        200: { description: Success }
    patch:
      summary: Update global fee settings
      tags: [Admin]
      security: [{ bearerAuth: [] }]
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                depositFeePercent: { type: number }
                depositFeeCap: { type: number }
                payoutFeeFlat: { type: number }
      responses:
        200: { description: Updated }

  /admin/merchants/{merchantId}/fees:
    patch:
      summary: Set custom fees for a specific merchant
      tags: [Admin]
      security: [{ bearerAuth: [] }]
      parameters:
        - in: path
          name: merchantId
          required: true
          schema: { type: string }
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                customDepositFeePercent: { type: number }
                customDepositFeeCap: { type: number }
                customPayoutFeeFlat: { type: number }
      responses:
        200: { description: Updated }

  /merchants/login:
    post:
      summary: Merchant Dashboard Login
      tags: [Merchant]
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                email: { type: string }
                password: { type: string }
      responses:
        200: { description: Success }

  /merchants/register:
    post:
      summary: Merchant Self-Registration
      tags: [Merchant]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                businessName: { type: string }
                preview: { type: string, description: "Custom prefix for customer virtual accounts" }
                email: { type: string }
                password: { type: string }
      responses:
        201: { description: Merchant created }

  /merchants/keys:
    get:
      summary: View API Public Key (JWT Required)
      tags: [Merchant]
      security: [{ bearerAuth: [] }]
      responses:
        200: { description: Success }

  /merchants/keys/regenerate:
    post:
      summary: Regenerate API Keys (JWT Required)
      tags: [Merchant]
      security: [{ bearerAuth: [] }]
      responses:
        200: { description: Success }

  /merchants/webhook:
    patch:
      summary: Update your notification Webhook URL
      tags: [Merchant]
      security: [{ bearerAuth: [] }]
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                webhookUrl: { type: string }
      responses:
        200: { description: Updated }
  /merchants/profile:
    patch:
      summary: Update Merchant Profile (Business Name, Preview Prefix)
      tags: [Merchant]
      security: [{ bearerAuth: [] }]
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                businessName: { type: string }
                preview: { type: string }
      responses:
        200: { description: Profile updated successfully }

  /merchants/me:
    get:
      summary: Get authenticated merchant details
      tags: [Merchant]
      security: [{ bearerAuth: [] }]
      responses:
        200: { description: Success }

  /merchants/stats:
    get:
      summary: Get aggregated financial stats for the merchant dashboard
      tags: [Merchant]
      security: [{ bearerAuth: [] }]
      responses:
        200:
          description: Financial metrics including total customer funds and inflows
          content:
            application/json:
              schema:
                type: object
                properties:
                  success: { type: boolean }
                  data:
                    type: object
                    properties:
                      merchantBalance: { type: string }
                      totalCustomerFunds: { type: number }
                      totalInflow: { type: number }
                      totalOutflow: { type: number }
                      customerCount: { type: number }

  /merchants/transactions:
    get:
      summary: List all transactions across all customers for this merchant
      tags: [Merchant]
      security: [{ bearerAuth: [] }]
      parameters:
        - in: query
          name: period
          schema: { type: string, enum: [daily, monthly, yearly] }
        - in: query
          name: status
          schema: { type: string, enum: [success, pending, failed] }
      responses:
        200: { description: Transaction list }

  /merchants/customers:
    get:
      summary: List all customers under this merchant
      tags: [Merchant]
      security: [{ bearerAuth: [] }]
      responses:
        200: { description: Success }

  /merchants/payout:
    post:
      summary: Initiate a Payout (API Keys or JWT)
      tags: [Merchant]
      security: [{ apiKeyPub: [], apiKeyPrv: [] }, { bearerAuth: [] }]
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                amount: { type: number }
                accountNumber: { type: string }
                bankCode: { type: string }
                accountName: { type: string }
                narration: { type: string }
      responses:
        200: { description: Success }

  /customers:
    post:
      summary: Create a new Customer + Virtual Account (API Keys ONLY)
      tags: [Customer]
      security: [{ apiKeyPub: [], apiKeyPrv: [] }]
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                fullName: { type: string }
                email: { type: string }
                phoneNumber: { type: string }
      responses:
        201: { description: Created }

  /customers/{customerId}:
    get:
      summary: Get full customer details
      tags: [Customer]
      security: [{ apiKeyPub: [], apiKeyPrv: [] }, { bearerAuth: [] }]
      parameters:
        - name: customerId
          in: path
          required: true
          schema: { type: string }
      responses:
        200: { description: Success }
        404: { description: Customer not found }

  /customers/{customerId}/report:
    get:
      summary: Get customer transaction summary & analytics
      tags: [Customers]
      security: [{ apiKeyPub: [], apiKeyPrv: [] }, { bearerAuth: [] }]
      parameters:
        - name: customerId
          in: path
          required: true
          schema: { type: string }
      responses:
        200: { description: Success }

  /customers/{customerId}/transactions:
    get:
      summary: Get granular transaction history for a customer
      tags: [Customers]
      security: [{ apiKeyPub: [], apiKeyPrv: [] }, { bearerAuth: [] }]
      parameters:
        - name: customerId
          in: path
          required: true
          schema: { type: string }
      responses:
        200: { description: List of transactions }

  /customers/{customerId}/payout:
    post:
      summary: Initiate a Payout for a Customer (Moves funds from Customer Balance)
      tags: [Customer]
      security: [{ apiKeyPub: [], apiKeyPrv: [] }, { bearerAuth: [] }]
      parameters:
        - in: path
          name: customerId
          required: true
          schema: { type: string }
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                amount: { type: number }
                accountNumber: { type: string }
                bankCode: { type: string }
                accountName: { type: string }
                narration: { type: string }
      responses:
        200: { description: Payout successful }
        400: { description: Insufficient funds or invalid details }

  /customers/{customerId}/debit:
    post:
      summary: Manually debit a customer's balance (Moves funds to Merchant Wallet)
      tags: [Customer]
      security: [{ apiKeyPub: [], apiKeyPrv: [] }, { bearerAuth: [] }]
      parameters:
        - in: path
          name: customerId
          required: true
          schema: { type: string }
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                amount: { type: number }
                reason: { type: string }
      responses:
        200: { description: Debit successful }
        400: { description: Insufficient funds or invalid amount }
  /customers/{customerId}/credit:
    post:
      summary: Directly credit a customer's balance from the Merchant Wallet
      tags: [Customer]
      security: [{ apiKeyPub: [], apiKeyPrv: [] }, { bearerAuth: [] }]
      parameters:
        - in: path
          name: customerId
          required: true
          schema: { type: string }
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                amount: { type: number }
                narration: { type: string }
      responses:
        200: { description: Credit successful }
        400: { description: Insufficient merchant funds or invalid details }

  /banks:
    get:
      summary: List all supported Nigerian Banks
      tags: [Tools]
      security: [{ apiKeyPub: [], apiKeyPrv: [] }, { bearerAuth: [] }]
      responses:
        200: { description: List of banks }

  /banks/enquiry:
    post:
      summary: Account Name Enquiry
      tags: [Tools]
      security: [{ apiKeyPub: [], apiKeyPrv: [] }, { bearerAuth: [] }]
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                accountNumber: { type: string }
                bankCode: { type: string }
      responses:
        200: { description: Resolved Name }

  /transactions/requery:
    post:
      summary: Re-query a transaction status
      tags: [Tools]
      security: [{ apiKeyPub: [], apiKeyPrv: [] }, { bearerAuth: [] }]
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                transactionId: { type: string }
                accountNo: { type: string, description: "Optional: Destination account number for better accuracy" }
      responses:
        200: { description: Transaction status }
