{
  "openapi": "3.0.0",
  "paths": {
    "/api/v1/bila/accounts": {
      "get": {
        "description": "Retrieve a paginated list of accounts/wallets for the authenticated merchant",
        "operationId": "BilaAccountsController_getAccounts",
        "parameters": [
          {
            "name": "page",
            "required": false,
            "in": "query",
            "description": "Page number (default: 1)",
            "schema": {
              "minimum": 1,
              "example": 1,
              "type": "number"
            }
          },
          {
            "name": "perPage",
            "required": false,
            "in": "query",
            "description": "Items per page (default: 50)",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "example": 50,
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Accounts retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/BilaResponseDto"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/PaginatedAccountsResponseDto"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key"
          }
        },
        "summary": "List all accounts",
        "tags": [
          "Accounts"
        ],
        "security": [
          {
            "x-api-key": []
          }
        ]
      }
    },
    "/api/v1/bila/accounts/{id}": {
      "get": {
        "description": "Retrieve a single account by its UUID",
        "operationId": "BilaAccountsController_getAccountById",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Account UUID",
            "schema": {
              "example": "68f11209-451f-4a15-bfcd-d916eb8b09f4",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Account retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/BilaResponseDto"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/AccountResponseDto"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key"
          },
          "404": {
            "description": "Account not found"
          }
        },
        "summary": "Get account by ID",
        "tags": [
          "Accounts"
        ],
        "security": [
          {
            "x-api-key": []
          }
        ]
      }
    },
    "/api/v1/bila/accounts/{id}/balance": {
      "get": {
        "description": "Retrieve the balance of a specific account",
        "operationId": "BilaAccountsController_getAccountBalance",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Account UUID",
            "schema": {
              "example": "68f11209-451f-4a15-bfcd-d916eb8b09f4",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Account balance retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/BilaResponseDto"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/AccountBalanceResponseDto"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key"
          },
          "404": {
            "description": "Account not found"
          }
        },
        "summary": "Get account balance",
        "tags": [
          "Accounts"
        ],
        "security": [
          {
            "x-api-key": []
          }
        ]
      }
    },
    "/api/v1/bila/banks": {
      "get": {
        "description": "Retrieve a list of all supported banks and financial institutions",
        "operationId": "BilaBanksController_getBanks",
        "parameters": [
          {
            "name": "country",
            "required": false,
            "in": "query",
            "description": "Filter banks by country code",
            "schema": {
              "example": "zm",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Banks retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/BilaResponseDto"
                    },
                    {
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/BankResponseDto"
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Bad request"
          }
        },
        "summary": "List all banks",
        "tags": [
          "Banks"
        ],
        "security": [
          {
            "x-api-key": []
          }
        ]
      }
    },
    "/api/v1/bila/resolve/bank-account": {
      "post": {
        "description": "Verify and retrieve bank account holder details",
        "operationId": "BilaResolveController_resolveBankAccount",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ResolveBankAccountDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Bank account resolved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/BilaResponseDto"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/ResolvedAccountResponseDto"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid account details or unable to resolve"
          }
        },
        "summary": "Resolve bank account",
        "tags": [
          "Resolve"
        ],
        "security": [
          {
            "x-api-key": []
          }
        ]
      }
    },
    "/api/v1/bila/resolve/mobile-money": {
      "post": {
        "description": "Verify and retrieve mobile money account holder details",
        "operationId": "BilaResolveController_resolveMobileMoneyAccount",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ResolveMobileMoneyDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Mobile money account resolved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/BilaResponseDto"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/ResolvedAccountResponseDto"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid phone number or unable to resolve"
          }
        },
        "summary": "Resolve mobile money account",
        "tags": [
          "Resolve"
        ],
        "security": [
          {
            "x-api-key": []
          }
        ]
      }
    },
    "/api/v1/bila/transfer-recipients": {
      "get": {
        "description": "Retrieve a paginated list of saved transfer recipients",
        "operationId": "BilaRecipientsController_getRecipients",
        "parameters": [
          {
            "name": "page",
            "required": false,
            "in": "query",
            "description": "Page number (default: 1)",
            "schema": {
              "minimum": 1,
              "example": 1,
              "type": "number"
            }
          },
          {
            "name": "perPage",
            "required": false,
            "in": "query",
            "description": "Items per page (default: 50)",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "example": 50,
              "type": "number"
            }
          },
          {
            "name": "type",
            "required": false,
            "in": "query",
            "description": "Filter by recipient type",
            "schema": {
              "type": "string",
              "enum": [
                "bank-account",
                "mobile-money"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Recipients retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/BilaResponseDto"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/PaginatedRecipientsResponseDto"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Bad request"
          }
        },
        "summary": "List transfer recipients",
        "tags": [
          "Transfer Recipients"
        ],
        "security": [
          {
            "x-api-key": []
          }
        ]
      }
    },
    "/api/v1/bila/transfer-recipients/{id}": {
      "get": {
        "description": "Retrieve a single transfer recipient by its UUID",
        "operationId": "BilaRecipientsController_getRecipientById",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Recipient UUID",
            "schema": {
              "example": "68f11209-451f-4a15-bfcd-d916eb8b09f4",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Recipient retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/BilaResponseDto"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/RecipientResponseDto"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Recipient not found"
          }
        },
        "summary": "Get recipient by ID",
        "tags": [
          "Transfer Recipients"
        ],
        "security": [
          {
            "x-api-key": []
          }
        ]
      }
    },
    "/api/v1/bila/transfer-recipients/bank-account": {
      "post": {
        "description": "Create a new bank account transfer recipient",
        "operationId": "BilaRecipientsController_createBankRecipient",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateBankRecipientDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Recipient created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/BilaResponseDto"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/RecipientResponseDto"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid recipient details"
          }
        },
        "summary": "Create bank account recipient",
        "tags": [
          "Transfer Recipients"
        ],
        "security": [
          {
            "x-api-key": []
          }
        ]
      }
    },
    "/api/v1/bila/transfer-recipients/mobile-money": {
      "post": {
        "description": "Create a new mobile money transfer recipient",
        "operationId": "BilaRecipientsController_createMobileMoneyRecipient",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateMobileMoneyRecipientDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Recipient created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/BilaResponseDto"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/RecipientResponseDto"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid recipient details"
          }
        },
        "summary": "Create mobile money recipient",
        "tags": [
          "Transfer Recipients"
        ],
        "security": [
          {
            "x-api-key": []
          }
        ]
      }
    },
    "/api/v1/bila/transfers": {
      "get": {
        "description": "Retrieve a paginated list of transfers/payouts for the authenticated merchant",
        "operationId": "BilaTransfersController_getTransfers",
        "parameters": [
          {
            "name": "page",
            "required": false,
            "in": "query",
            "description": "Page number (default: 1)",
            "schema": {
              "minimum": 1,
              "example": 1,
              "type": "number"
            }
          },
          {
            "name": "perPage",
            "required": false,
            "in": "query",
            "description": "Items per page (default: 50)",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "example": 50,
              "type": "number"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "description": "Filter by transfer status",
            "schema": {
              "type": "string",
              "enum": [
                "pending",
                "successful",
                "failed"
              ]
            }
          },
          {
            "name": "type",
            "required": false,
            "in": "query",
            "description": "Filter by transfer type",
            "schema": {
              "type": "string",
              "enum": [
                "bank-account",
                "mobile-money"
              ]
            }
          },
          {
            "name": "accountId",
            "required": false,
            "in": "query",
            "description": "Filter by account ID",
            "schema": {
              "example": "68f11209-451f-4a15-bfcd-d916eb8b09f4",
              "type": "string"
            }
          },
          {
            "name": "startDate",
            "required": false,
            "in": "query",
            "description": "Filter by start date (ISO 8601)",
            "schema": {
              "example": "2024-01-01T00:00:00Z",
              "type": "string"
            }
          },
          {
            "name": "endDate",
            "required": false,
            "in": "query",
            "description": "Filter by end date (ISO 8601)",
            "schema": {
              "example": "2024-12-31T23:59:59Z",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Transfers retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/BilaResponseDto"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/PaginatedTransfersResponseDto"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Bad request"
          }
        },
        "summary": "List transfers",
        "tags": [
          "Transfers"
        ],
        "security": [
          {
            "x-api-key": []
          }
        ]
      }
    },
    "/api/v1/bila/transfers/{id}": {
      "get": {
        "description": "Retrieve a single transfer by its UUID",
        "operationId": "BilaTransfersController_getTransferById",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Transfer UUID",
            "schema": {
              "example": "68f11209-451f-4a15-bfcd-d916eb8b09f4",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Transfer retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/BilaResponseDto"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/TransferResponseDto"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Transfer not found"
          }
        },
        "summary": "Get transfer by ID",
        "tags": [
          "Transfers"
        ],
        "security": [
          {
            "x-api-key": []
          }
        ]
      }
    },
    "/api/v1/bila/transfers/status/{reference}": {
      "get": {
        "description": "Retrieve transfer status by client reference",
        "operationId": "BilaTransfersController_getTransferByReference",
        "parameters": [
          {
            "name": "reference",
            "required": true,
            "in": "path",
            "description": "Client reference",
            "schema": {
              "example": "transfer-001",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Transfer retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/BilaResponseDto"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/TransferResponseDto"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Transfer not found"
          }
        },
        "summary": "Get transfer by reference",
        "tags": [
          "Transfers"
        ],
        "security": [
          {
            "x-api-key": []
          }
        ]
      }
    },
    "/api/v1/bila/transfers/bank-account": {
      "post": {
        "description": "Initiate a transfer to a bank account. Creates a transaction record in your dashboard.",
        "operationId": "BilaTransfersController_initiateBankTransfer",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BankTransferDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Transfer initiated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/BilaResponseDto"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/TransferResponseDto"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid transfer details"
          }
        },
        "summary": "Initiate bank transfer",
        "tags": [
          "Transfers"
        ],
        "security": [
          {
            "x-api-key": []
          }
        ]
      }
    },
    "/api/v1/bila/transfers/mobile-money": {
      "post": {
        "description": "Initiate a transfer to a mobile money account. Creates a transaction record in your dashboard.",
        "operationId": "BilaTransfersController_initiateMobileMoneyTransfer",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MobileMoneyTransferDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Transfer initiated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/BilaResponseDto"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/TransferResponseDto"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid transfer details"
          }
        },
        "summary": "Initiate mobile money transfer",
        "tags": [
          "Transfers"
        ],
        "security": [
          {
            "x-api-key": []
          }
        ]
      }
    },
    "/api/v1/bila/collections": {
      "get": {
        "description": "Retrieve a paginated list of payment collections for the authenticated merchant",
        "operationId": "BilaCollectionsController_getCollections",
        "parameters": [
          {
            "name": "page",
            "required": false,
            "in": "query",
            "description": "Page number (default: 1)",
            "schema": {
              "minimum": 1,
              "example": 1,
              "type": "number"
            }
          },
          {
            "name": "perPage",
            "required": false,
            "in": "query",
            "description": "Items per page (default: 50)",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "example": 50,
              "type": "number"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "description": "Filter by collection status",
            "schema": {
              "type": "string",
              "enum": [
                "pending",
                "successful",
                "failed",
                "otp-required",
                "pay-offline"
              ]
            }
          },
          {
            "name": "accountId",
            "required": false,
            "in": "query",
            "description": "Filter by account ID",
            "schema": {
              "example": "68f11209-451f-4a15-bfcd-d916eb8b09f4",
              "type": "string"
            }
          },
          {
            "name": "startDate",
            "required": false,
            "in": "query",
            "description": "Filter by start date (ISO 8601)",
            "schema": {
              "example": "2024-01-01T00:00:00Z",
              "type": "string"
            }
          },
          {
            "name": "endDate",
            "required": false,
            "in": "query",
            "description": "Filter by end date (ISO 8601)",
            "schema": {
              "example": "2024-12-31T23:59:59Z",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Collections retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/BilaResponseDto"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/PaginatedCollectionsResponseDto"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Bad request"
          }
        },
        "summary": "List collections",
        "tags": [
          "Collections"
        ],
        "security": [
          {
            "x-api-key": []
          }
        ]
      }
    },
    "/api/v1/bila/collections/{id}": {
      "get": {
        "description": "Retrieve a single collection by its UUID",
        "operationId": "BilaCollectionsController_getCollectionById",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Collection UUID",
            "schema": {
              "example": "68f11209-451f-4a15-bfcd-d916eb8b09f4",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Collection retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/BilaResponseDto"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/BilaCollectionResponseDto"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Collection not found"
          }
        },
        "summary": "Get collection by ID",
        "tags": [
          "Collections"
        ],
        "security": [
          {
            "x-api-key": []
          }
        ]
      }
    },
    "/api/v1/bila/collections/status/{reference}": {
      "get": {
        "description": "Retrieve collection status by client reference",
        "operationId": "BilaCollectionsController_getCollectionByReference",
        "parameters": [
          {
            "name": "reference",
            "required": true,
            "in": "path",
            "description": "Client reference",
            "schema": {
              "example": "collection-001",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Collection retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/BilaResponseDto"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/BilaCollectionResponseDto"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Collection not found"
          }
        },
        "summary": "Get collection by reference",
        "tags": [
          "Collections"
        ],
        "security": [
          {
            "x-api-key": []
          }
        ]
      }
    },
    "/api/v1/bila/collections/mobile-money": {
      "post": {
        "description": "Initiate a payment collection from a mobile money account. Creates a transaction record in your dashboard.",
        "operationId": "BilaCollectionsController_initiateMobileMoneyCollection",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MobileMoneyCollectionDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Collection initiated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/BilaResponseDto"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/BilaCollectionResponseDto"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid collection details"
          }
        },
        "summary": "Initiate mobile money collection",
        "tags": [
          "Collections"
        ],
        "security": [
          {
            "x-api-key": []
          }
        ]
      }
    },
    "/api/v1/bila/transactions": {
      "get": {
        "description": "Retrieve a paginated list of transactions",
        "operationId": "BilaTransactionsController_getTransactions",
        "parameters": [
          {
            "name": "page",
            "required": false,
            "in": "query",
            "description": "Page number (default: 1)",
            "schema": {
              "minimum": 1,
              "example": 1,
              "type": "number"
            }
          },
          {
            "name": "perPage",
            "required": false,
            "in": "query",
            "description": "Items per page (default: 50)",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "example": 50,
              "type": "number"
            }
          },
          {
            "name": "type",
            "required": false,
            "in": "query",
            "description": "Filter by transaction type",
            "schema": {
              "type": "string",
              "enum": [
                "credit",
                "debit"
              ]
            }
          },
          {
            "name": "accountId",
            "required": false,
            "in": "query",
            "description": "Filter by account ID",
            "schema": {
              "example": "68f11209-451f-4a15-bfcd-d916eb8b09f4",
              "type": "string"
            }
          },
          {
            "name": "startDate",
            "required": false,
            "in": "query",
            "description": "Filter by start date (ISO 8601)",
            "schema": {
              "example": "2024-01-01T00:00:00Z",
              "type": "string"
            }
          },
          {
            "name": "endDate",
            "required": false,
            "in": "query",
            "description": "Filter by end date (ISO 8601)",
            "schema": {
              "example": "2024-12-31T23:59:59Z",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Transactions retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/BilaResponseDto"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/PaginatedTransactionsResponseDto"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Bad request"
          }
        },
        "summary": "List transactions",
        "tags": [
          "Transactions"
        ],
        "security": [
          {
            "x-api-key": []
          }
        ]
      }
    },
    "/api/v1/bila/transactions/{id}": {
      "get": {
        "description": "Retrieve a single transaction by its UUID",
        "operationId": "BilaTransactionsController_getTransactionById",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Transaction UUID",
            "schema": {
              "example": "68f11209-451f-4a15-bfcd-d916eb8b09f4",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Transaction retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/BilaResponseDto"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/TransactionResponseDto"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Transaction not found"
          }
        },
        "summary": "Get transaction by ID",
        "tags": [
          "Transactions"
        ],
        "security": [
          {
            "x-api-key": []
          }
        ]
      }
    },
    "/api/v1/bila/webhooks": {
      "get": {
        "operationId": "BilaWebhooksController_list",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Webhook configs retrieved",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/BilaResponseDto"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/WebhookConfigResponseDtoList"
                        }
                      }
                    }
                  ]
                }
              }
            }
          }
        },
        "security": [
          {
            "x-api-key": []
          }
        ],
        "summary": "List webhook configs",
        "tags": [
          "Webhooks"
        ]
      },
      "post": {
        "operationId": "BilaWebhooksController_create",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateWebhookConfigDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Webhook config created (secret returned once)",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/BilaResponseDto"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/WebhookConfigResponseDto"
                        }
                      }
                    }
                  ]
                }
              }
            }
          }
        },
        "security": [
          {
            "x-api-key": []
          }
        ],
        "summary": "Create a webhook config",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "/api/v1/bila/webhooks/events": {
      "get": {
        "operationId": "BilaWebhooksController_listEventTypes",
        "parameters": [],
        "responses": {
          "200": {
            "description": "Webhook events retrieved",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/BilaResponseDto"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/WebhookEventTypesList"
                        }
                      }
                    }
                  ]
                }
              }
            }
          }
        },
        "security": [
          {
            "x-api-key": []
          }
        ],
        "summary": "List webhook event types",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "/api/v1/bila/webhooks/{id}": {
      "patch": {
        "operationId": "BilaWebhooksController_update",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Webhook config UUID",
            "schema": {
              "example": "68f11209-451f-4a15-bfcd-d916eb8b09f4",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateWebhookConfigDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Webhook config updated",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/BilaResponseDto"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/WebhookConfigResponseDto"
                        }
                      }
                    }
                  ]
                }
              }
            }
          }
        },
        "security": [
          {
            "x-api-key": []
          }
        ],
        "summary": "Update a webhook config",
        "tags": [
          "Webhooks"
        ]
      },
      "delete": {
        "operationId": "BilaWebhooksController_deactivate",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Webhook config UUID",
            "schema": {
              "example": "68f11209-451f-4a15-bfcd-d916eb8b09f4",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Webhook config deactivated",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/BilaResponseDto"
                    },
                    {}
                  ]
                }
              }
            }
          }
        },
        "security": [
          {
            "x-api-key": []
          }
        ],
        "summary": "Deactivate a webhook",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "/api/v1/bila/webhooks/{id}/rotate-secret": {
      "post": {
        "operationId": "BilaWebhooksController_rotateSecret",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Webhook config UUID",
            "schema": {
              "example": "68f11209-451f-4a15-bfcd-d916eb8b09f4",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Secret rotated",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/BilaResponseDto"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/RotateWebhookSecretResultDto"
                        }
                      }
                    }
                  ]
                }
              }
            }
          }
        },
        "security": [
          {
            "x-api-key": []
          }
        ],
        "summary": "Rotate webhook signing secret",
        "tags": [
          "Webhooks"
        ]
      }
    },
    "/api/v1/bila/webhooks/{id}/deliveries": {
      "get": {
        "operationId": "BilaWebhooksController_deliveries",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Webhook config UUID",
            "schema": {
              "example": "68f11209-451f-4a15-bfcd-d916eb8b09f4",
              "type": "string"
            }
          },
          {
            "name": "eventType",
            "required": false,
            "in": "query",
            "description": "Filter by event type",
            "schema": {
              "example": "payment.completed",
              "type": "string"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "description": "Filter by status (QUEUED, DELIVERED, FAILED, RETRYING)",
            "schema": {
              "example": "DELIVERED",
              "type": "string"
            }
          },
          {
            "name": "startDate",
            "required": false,
            "in": "query",
            "description": "ISO 8601 start of createdAt range (inclusive)",
            "schema": {
              "example": "2026-04-01T00:00:00.000Z",
              "type": "string"
            }
          },
          {
            "name": "endDate",
            "required": false,
            "in": "query",
            "description": "ISO 8601 end of createdAt range (inclusive)",
            "schema": {
              "example": "2026-04-30T23:59:59.999Z",
              "type": "string"
            }
          },
          {
            "name": "page",
            "required": false,
            "in": "query",
            "description": "Page number",
            "schema": {
              "minimum": 1,
              "default": 1,
              "example": 1,
              "type": "number"
            }
          },
          {
            "name": "perPage",
            "required": false,
            "in": "query",
            "description": "Items per page",
            "schema": {
              "minimum": 1,
              "maximum": 100,
              "default": 20,
              "example": 20,
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deliveries retrieved",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/BilaResponseDto"
                    },
                    {
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/PaginatedWebhookDeliveriesResponseDto"
                        }
                      }
                    }
                  ]
                }
              }
            }
          }
        },
        "security": [
          {
            "x-api-key": []
          }
        ],
        "summary": "Get delivery history",
        "tags": [
          "Webhooks"
        ]
      }
    }
  },
  "info": {
    "title": "Bila Payment Gateway API",
    "description": "\nBila Payment Gateway API - A payment processing API for Africa.\n\n## Overview\n\nThis API provides payment gateway functionality for:\n- **Account Management**: Manage payment accounts/wallets\n- **Bank Operations**: Access bank reference data\n- **Account Resolution**: Verify bank and mobile money accounts\n- **Transfer Recipients**: Manage saved transfer recipients\n- **Transfers (Payouts)**: Send money to bank accounts and mobile money\n- **Collections (Receive Payments)**: Collect payments via mobile money\n- **Transaction History**: View all transactions\n\n## Mobile Money Providers\n\n- Airtel Money\n- MTN Mobile Money (MoMo)\n- Zamtel Kwacha\n\n## Countries Supported\n\n- Zambia (zm)\n- Nigeria (ng)\n\n## Authentication\n\nUse your merchant API key in the `x-api-key` header.\nYou can generate API keys from your merchant dashboard.\n\n## Base URL\n\n```\nhttps://api.usebila.com/api/v1\n```\n\nFor sandbox/testing:\n```\nhttps://sandbox.usebila.com/api/v1\n```\n    ",
    "version": "2.0",
    "contact": {}
  },
  "tags": [
    {
      "name": "Accounts",
      "description": "Account/wallet management endpoints"
    },
    {
      "name": "Banks",
      "description": "Bank reference data endpoints"
    },
    {
      "name": "Resolve",
      "description": "Account resolution/verification endpoints"
    },
    {
      "name": "Transfer Recipients",
      "description": "Transfer recipient management endpoints"
    },
    {
      "name": "Transfers",
      "description": "Payout/transfer operation endpoints"
    },
    {
      "name": "Collections",
      "description": "Payment collection operation endpoints"
    },
    {
      "name": "Transactions",
      "description": "Transaction history endpoints"
    },
    {
      "name": "Webhooks",
      "description": "Webhook configuration and delivery history"
    }
  ],
  "servers": [
    {
      "url": "https://api.usebila.com",
      "description": "Production"
    },
    {
      "url": "https://sandbox.usebila.com",
      "description": "Sandbox"
    }
  ],
  "components": {
    "securitySchemes": {
      "x-api-key": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "Merchant API key (e.g., sk_live_xxx or sk_test_xxx)"
      }
    },
    "schemas": {
      "BilaResponseDto": {
        "type": "object",
        "properties": {
          "status": {
            "type": "boolean",
            "description": "Request success status",
            "example": true
          },
          "message": {
            "type": "string",
            "description": "Response message",
            "example": "Operation completed successfully"
          }
        },
        "required": [
          "status",
          "message"
        ]
      },
      "AccountDetailsDto": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "description": "Account detail type",
            "example": "bank-account"
          },
          "accountName": {
            "type": "string",
            "description": "Account holder name",
            "example": "John Doe"
          },
          "tillNumber": {
            "type": "string",
            "description": "Till number (for mobile money)",
            "example": "123456"
          }
        },
        "required": [
          "type",
          "accountName"
        ]
      },
      "AccountResponseDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Account UUID",
            "example": "68f11209-451f-4a15-bfcd-d916eb8b09f4",
            "format": "uuid"
          },
          "type": {
            "type": "string",
            "description": "Account type",
            "enum": [
              "main",
              "sub",
              "virtual"
            ],
            "example": "main"
          },
          "status": {
            "type": "string",
            "description": "Account status",
            "enum": [
              "active",
              "inactive",
              "suspended"
            ],
            "example": "active"
          },
          "currency": {
            "type": "string",
            "description": "Currency code",
            "example": "ZMW"
          },
          "createdAt": {
            "type": "string",
            "description": "Account creation timestamp",
            "example": "2024-01-15T10:30:00Z",
            "format": "date-time"
          },
          "details": {
            "description": "Account details",
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountDetailsDto"
              }
            ]
          },
          "availableBalance": {
            "type": "string",
            "description": "Available balance",
            "example": "1500.00"
          },
          "ledgerBalance": {
            "type": "string",
            "description": "Ledger balance",
            "example": "1500.00"
          }
        },
        "required": [
          "id",
          "type",
          "status",
          "currency",
          "createdAt",
          "details"
        ]
      },
      "PaginationMetaDto": {
        "type": "object",
        "properties": {
          "total": {
            "type": "number",
            "description": "Total number of records",
            "example": 150
          },
          "perPage": {
            "type": "number",
            "description": "Items per page",
            "example": 50
          },
          "currentPage": {
            "type": "number",
            "description": "Current page number",
            "example": 1
          },
          "pageCount": {
            "type": "number",
            "description": "Total number of pages",
            "example": 3
          }
        },
        "required": [
          "total",
          "perPage",
          "currentPage",
          "pageCount"
        ]
      },
      "PaginatedAccountsResponseDto": {
        "type": "object",
        "properties": {
          "data": {
            "description": "List of accounts",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AccountResponseDto"
            }
          },
          "meta": {
            "description": "Pagination metadata",
            "allOf": [
              {
                "$ref": "#/components/schemas/PaginationMetaDto"
              }
            ]
          }
        },
        "required": [
          "data",
          "meta"
        ]
      },
      "AccountBalanceResponseDto": {
        "type": "object",
        "properties": {
          "availableBalance": {
            "type": "string",
            "description": "Available balance",
            "example": "1500.00"
          },
          "ledgerBalance": {
            "type": "string",
            "description": "Ledger balance",
            "example": "1500.00"
          },
          "currency": {
            "type": "string",
            "description": "Currency code",
            "example": "ZMW"
          }
        },
        "required": [
          "availableBalance",
          "ledgerBalance",
          "currency"
        ]
      },
      "BankResponseDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Bank ID",
            "example": "bank-001"
          },
          "name": {
            "type": "string",
            "description": "Bank name",
            "example": "First National Bank"
          },
          "code": {
            "type": "string",
            "description": "Bank code",
            "example": "FNB"
          },
          "country": {
            "type": "string",
            "description": "Country code",
            "example": "zm"
          },
          "type": {
            "type": "string",
            "description": "Bank type",
            "example": "commercial"
          }
        },
        "required": [
          "id",
          "name",
          "code",
          "country"
        ]
      },
      "ResolvedAccountResponseDto": {
        "type": "object",
        "properties": {
          "accountName": {
            "type": "string",
            "description": "Account holder name",
            "example": "John Doe"
          },
          "accountNumber": {
            "type": "string",
            "description": "Bank account number",
            "example": "1234567890"
          },
          "phone": {
            "type": "string",
            "description": "Phone number",
            "example": "0977433571"
          },
          "operator": {
            "type": "string",
            "description": "Mobile money operator",
            "example": "airtel"
          },
          "bankId": {
            "type": "string",
            "description": "Bank ID",
            "example": "bank-001"
          },
          "bankName": {
            "type": "string",
            "description": "Bank name",
            "example": "First National Bank"
          },
          "country": {
            "type": "string",
            "description": "Country code",
            "example": "zm"
          }
        },
        "required": [
          "accountName",
          "country"
        ]
      },
      "ResolveBankAccountDto": {
        "type": "object",
        "properties": {
          "accountNumber": {
            "type": "string",
            "description": "Bank account number",
            "example": "1234567890"
          },
          "bankId": {
            "type": "string",
            "description": "Bank ID",
            "example": "bank-001"
          },
          "country": {
            "type": "string",
            "description": "Country code",
            "enum": [
              "zm",
              "ng"
            ],
            "example": "zm"
          }
        },
        "required": [
          "accountNumber",
          "bankId"
        ]
      },
      "ResolveMobileMoneyDto": {
        "type": "object",
        "properties": {
          "phone": {
            "type": "string",
            "description": "Mobile phone number",
            "example": "0977433571"
          },
          "operator": {
            "type": "string",
            "description": "Mobile money operator",
            "enum": [
              "airtel",
              "mtn",
              "zamtel",
              "vodacom"
            ],
            "example": "airtel"
          },
          "country": {
            "type": "string",
            "description": "Country code",
            "enum": [
              "zm",
              "ng"
            ],
            "example": "zm"
          }
        },
        "required": [
          "phone",
          "operator",
          "country"
        ]
      },
      "RecipientResponseDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Recipient UUID",
            "example": "68f11209-451f-4a15-bfcd-d916eb8b09f4",
            "format": "uuid"
          },
          "type": {
            "type": "string",
            "description": "Recipient type",
            "enum": [
              "bank-account",
              "mobile-money"
            ],
            "example": "bank-account"
          },
          "accountNumber": {
            "type": "string",
            "description": "Bank account number (bank-account only)",
            "example": "1234567890"
          },
          "accountName": {
            "type": "string",
            "description": "Account holder name",
            "example": "John Doe"
          },
          "bankId": {
            "type": "string",
            "description": "Bank ID (bank-account only)",
            "example": "bank-001"
          },
          "bankName": {
            "type": "string",
            "description": "Bank name (bank-account only)",
            "example": "Zambia National Commercial Bank"
          },
          "phone": {
            "type": "string",
            "description": "Phone number (mobile-money only)",
            "example": "0977123456"
          },
          "operator": {
            "type": "string",
            "description": "Mobile money operator (mobile-money only)",
            "example": "airtel"
          },
          "country": {
            "type": "string",
            "description": "Country code",
            "example": "zm"
          },
          "createdAt": {
            "type": "string",
            "description": "Creation timestamp",
            "example": "2024-01-15T10:30:00Z",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "type",
          "accountName",
          "country",
          "createdAt"
        ]
      },
      "PaginatedRecipientsResponseDto": {
        "type": "object",
        "properties": {
          "data": {
            "description": "List of recipients",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RecipientResponseDto"
            }
          },
          "meta": {
            "description": "Pagination metadata",
            "allOf": [
              {
                "$ref": "#/components/schemas/PaginationMetaDto"
              }
            ]
          }
        },
        "required": [
          "data",
          "meta"
        ]
      },
      "CreateBankRecipientDto": {
        "type": "object",
        "properties": {
          "accountNumber": {
            "type": "string",
            "description": "Bank account number",
            "example": "1234567890"
          },
          "bankId": {
            "type": "string",
            "description": "Bank ID",
            "example": "bank-001"
          },
          "accountName": {
            "type": "string",
            "description": "Account holder name (optional, will be resolved)",
            "example": "John Doe"
          },
          "country": {
            "type": "string",
            "description": "Country code",
            "enum": [
              "zm",
              "ng"
            ],
            "example": "zm"
          }
        },
        "required": [
          "accountNumber",
          "bankId"
        ]
      },
      "CreateMobileMoneyRecipientDto": {
        "type": "object",
        "properties": {
          "phone": {
            "type": "string",
            "description": "Mobile phone number",
            "example": "0977433571"
          },
          "operator": {
            "type": "string",
            "description": "Mobile money operator",
            "enum": [
              "airtel",
              "mtn",
              "zamtel",
              "vodacom"
            ],
            "example": "airtel"
          },
          "accountName": {
            "type": "string",
            "description": "Account holder name (optional, will be resolved)",
            "example": "John Doe"
          },
          "country": {
            "type": "string",
            "description": "Country code",
            "enum": [
              "zm",
              "ng"
            ],
            "example": "zm"
          }
        },
        "required": [
          "phone",
          "operator",
          "country"
        ]
      },
      "TransferRecipientDto": {
        "type": "object",
        "properties": {
          "accountNumber": {
            "type": "string",
            "description": "Bank account number (bank-account only)",
            "example": "1234567890"
          },
          "accountName": {
            "type": "string",
            "description": "Account holder / recipient name",
            "example": "JOHN DOE"
          },
          "bankName": {
            "type": "string",
            "description": "Bank name (bank-account only)",
            "example": "Zambia National Commercial Bank"
          },
          "phone": {
            "type": "string",
            "description": "Phone number (mobile-money only)",
            "example": "0977123456"
          },
          "operator": {
            "type": "string",
            "description": "Mobile money operator (mobile-money only)",
            "example": "airtel"
          }
        },
        "required": [
          "accountName"
        ]
      },
      "TransferResponseDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Transfer ID",
            "example": "txn-001"
          },
          "reference": {
            "type": "string",
            "description": "Client reference",
            "example": "payout-12345"
          },
          "type": {
            "type": "string",
            "description": "Transfer type",
            "enum": [
              "bank-account",
              "mobile-money"
            ],
            "example": "bank-account"
          },
          "status": {
            "type": "string",
            "description": "Transfer status",
            "enum": [
              "pending",
              "successful",
              "failed"
            ],
            "example": "successful"
          },
          "amount": {
            "type": "number",
            "description": "Transfer amount",
            "example": 1000
          },
          "currency": {
            "type": "string",
            "description": "Currency code",
            "example": "ZMW"
          },
          "narration": {
            "type": "string",
            "description": "Transfer narration",
            "example": "Salary payment"
          },
          "recipient": {
            "description": "Recipient details",
            "allOf": [
              {
                "$ref": "#/components/schemas/TransferRecipientDto"
              }
            ]
          },
          "createdAt": {
            "type": "string",
            "description": "Creation timestamp (from Payment)",
            "example": "2024-01-15T10:30:00Z",
            "format": "date-time"
          },
          "completedAt": {
            "type": "string",
            "description": "Completion timestamp (from Payment.processedAt)",
            "example": "2024-01-15T10:31:00Z",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "reference",
          "type",
          "status",
          "amount",
          "currency",
          "recipient",
          "createdAt"
        ]
      },
      "PaginatedTransfersResponseDto": {
        "type": "object",
        "properties": {
          "data": {
            "description": "List of transfers",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TransferResponseDto"
            }
          },
          "meta": {
            "description": "Pagination metadata",
            "allOf": [
              {
                "$ref": "#/components/schemas/PaginationMetaDto"
              }
            ]
          }
        },
        "required": [
          "data",
          "meta"
        ]
      },
      "BankTransferDto": {
        "type": "object",
        "properties": {
          "accountId": {
            "type": "string",
            "description": "Source account UUID",
            "example": "68f11209-451f-4a15-bfcd-d916eb8b09f4",
            "format": "uuid"
          },
          "amount": {
            "type": "number",
            "description": "Transfer amount",
            "example": 1000,
            "minimum": 0.01
          },
          "reference": {
            "type": "string",
            "description": "Unique client reference (alphanumeric, dots, underscores, hyphens)",
            "example": "transfer-001",
            "pattern": "^[a-zA-Z0-9._-]+$"
          },
          "narration": {
            "type": "string",
            "description": "Transfer narration",
            "example": "Payment for services",
            "maxLength": 100
          },
          "transferRecipientId": {
            "type": "string",
            "description": "Transfer recipient UUID (use this OR accountNumber+bankId)",
            "example": "68f11209-451f-4a15-bfcd-d916eb8b09f4",
            "format": "uuid"
          },
          "accountNumber": {
            "type": "string",
            "description": "Bank account number (required if no transferRecipientId)",
            "example": "1234567890"
          },
          "bankId": {
            "type": "string",
            "description": "Bank ID (required if no transferRecipientId)",
            "example": "bank-001"
          },
          "country": {
            "type": "string",
            "description": "Country code",
            "enum": [
              "zm",
              "ng"
            ],
            "example": "zm"
          },
          "walletId": {
            "type": "string",
            "description": "Source wallet ID to debit (optional, uses main wallet if not specified)",
            "example": "68f11209-451f-4a15-bfcd-d916eb8b09f4"
          },
          "recipientName": {
            "type": "string",
            "description": "Recipient name for the transaction record",
            "example": "Jane Doe",
            "maxLength": 100
          }
        },
        "required": [
          "accountId",
          "amount",
          "reference"
        ]
      },
      "MobileMoneyTransferDto": {
        "type": "object",
        "properties": {
          "amount": {
            "type": "number",
            "description": "Transfer amount",
            "example": 250,
            "minimum": 0.01
          },
          "reference": {
            "type": "string",
            "description": "Unique client reference",
            "example": "mobile-transfer-001",
            "pattern": "^[a-zA-Z0-9._-]+$"
          },
          "phone": {
            "type": "string",
            "description": "Recipient phone number",
            "example": "0977433571"
          },
          "operator": {
            "type": "string",
            "description": "Mobile money operator",
            "enum": [
              "airtel",
              "mtn",
              "zamtel",
              "vodacom"
            ],
            "example": "airtel"
          },
          "country": {
            "type": "string",
            "description": "Country code",
            "enum": [
              "zm",
              "ng"
            ],
            "example": "zm"
          },
          "narration": {
            "type": "string",
            "description": "Transfer narration",
            "example": "Mobile money payout",
            "maxLength": 100
          },
          "walletId": {
            "type": "string",
            "description": "Source wallet ID to debit (defaults to main wallet if omitted)",
            "example": "68f11209-451f-4a15-bfcd-d916eb8b09f4",
            "format": "uuid"
          },
          "recipientName": {
            "type": "string",
            "description": "Recipient name for the transaction record",
            "example": "Jane Doe",
            "maxLength": 100
          }
        },
        "required": [
          "amount",
          "reference",
          "phone",
          "operator",
          "country"
        ]
      },
      "BilaCollectionCustomerDto": {
        "type": "object",
        "properties": {
          "phone": {
            "type": "string",
            "description": "Customer phone number",
            "example": "0977123456"
          },
          "name": {
            "type": "string",
            "description": "Customer name",
            "example": "JOHN DOE"
          },
          "operator": {
            "type": "string",
            "description": "Mobile money operator",
            "example": "airtel"
          }
        },
        "required": [
          "phone",
          "name",
          "operator"
        ]
      },
      "BilaCollectionResponseDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Collection ID",
            "example": "col-001"
          },
          "reference": {
            "type": "string",
            "description": "Client reference",
            "example": "order-12345"
          },
          "status": {
            "type": "string",
            "description": "Collection status",
            "enum": [
              "pending",
              "successful",
              "failed",
              "otp-required",
              "pay-offline"
            ],
            "example": "successful"
          },
          "amount": {
            "type": "number",
            "description": "Collection amount",
            "example": 100
          },
          "currency": {
            "type": "string",
            "description": "Currency code",
            "example": "ZMW"
          },
          "feeBearer": {
            "type": "string",
            "description": "Who bears the collection platform fee",
            "enum": [
              "merchant",
              "customer"
            ]
          },
          "narration": {
            "type": "string",
            "description": "Collection narration",
            "example": "Payment for Order #12345"
          },
          "customer": {
            "description": "Customer details",
            "allOf": [
              {
                "$ref": "#/components/schemas/BilaCollectionCustomerDto"
              }
            ]
          },
          "createdAt": {
            "type": "string",
            "description": "Collection creation timestamp",
            "example": "2024-01-15T10:30:00Z",
            "format": "date-time"
          },
          "completedAt": {
            "type": "string",
            "description": "Collection completion timestamp",
            "example": "2024-01-15T10:31:00Z",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "reference",
          "status",
          "amount",
          "currency",
          "customer",
          "createdAt"
        ]
      },
      "PaginatedCollectionsResponseDto": {
        "type": "object",
        "properties": {
          "data": {
            "description": "List of collections",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BilaCollectionResponseDto"
            }
          },
          "meta": {
            "description": "Pagination metadata",
            "allOf": [
              {
                "$ref": "#/components/schemas/PaginationMetaDto"
              }
            ]
          }
        },
        "required": [
          "data",
          "meta"
        ]
      },
      "MobileMoneyCollectionDto": {
        "type": "object",
        "properties": {
          "amount": {
            "type": "number",
            "description": "Collection amount",
            "example": 100.5,
            "minimum": 0.01
          },
          "reference": {
            "type": "string",
            "description": "Unique client reference",
            "example": "collection-001",
            "pattern": "^[a-zA-Z0-9._-]+$"
          },
          "phone": {
            "type": "string",
            "description": "Customer phone number",
            "example": "0977433571"
          },
          "operator": {
            "type": "string",
            "description": "Mobile money operator",
            "enum": [
              "airtel",
              "mtn",
              "zamtel",
              "vodacom"
            ],
            "example": "airtel"
          },
          "country": {
            "type": "string",
            "description": "Country code",
            "enum": [
              "zm",
              "ng"
            ],
            "example": "zm"
          },
          "bearer": {
            "type": "string",
            "description": "Who bears the transaction fee",
            "enum": [
              "merchant",
              "customer"
            ],
            "example": "customer",
            "default": "merchant"
          },
          "narration": {
            "type": "string",
            "description": "Collection narration",
            "example": "Payment for subscription",
            "maxLength": 100
          },
          "walletId": {
            "type": "string",
            "description": "Target wallet ID to credit",
            "example": "68f11209-451f-4a15-bfcd-d916eb8b09f4",
            "format": "uuid"
          },
          "customerName": {
            "type": "string",
            "description": "Customer name for the transaction record",
            "example": "John Doe",
            "maxLength": 100
          }
        },
        "required": [
          "amount",
          "reference",
          "phone",
          "operator",
          "country",
          "walletId"
        ]
      },
      "TransactionResponseDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Transaction UUID",
            "example": "txn-001"
          },
          "type": {
            "type": "string",
            "description": "Transaction type",
            "enum": [
              "credit",
              "debit"
            ],
            "example": "credit"
          },
          "amount": {
            "type": "number",
            "description": "Transaction amount",
            "example": 1000
          },
          "currency": {
            "type": "string",
            "description": "Currency code",
            "example": "ZMW"
          },
          "status": {
            "type": "string",
            "description": "Transaction status",
            "enum": [
              "pending",
              "successful",
              "failed",
              "cancelled"
            ],
            "example": "successful"
          },
          "description": {
            "type": "string",
            "description": "Transaction description",
            "example": "Mobile money collection"
          },
          "reference": {
            "type": "string",
            "description": "Client reference",
            "example": "order-12345"
          },
          "accountId": {
            "type": "string",
            "description": "Account / wallet ID",
            "example": "acc-001"
          },
          "balanceBefore": {
            "type": "number",
            "description": "Balance before transaction",
            "example": 5000
          },
          "balanceAfter": {
            "type": "number",
            "description": "Balance after transaction",
            "example": 6000
          },
          "createdAt": {
            "type": "string",
            "description": "Transaction timestamp",
            "example": "2024-01-15T10:30:00Z",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "type",
          "amount",
          "currency",
          "status",
          "accountId",
          "balanceBefore",
          "balanceAfter",
          "createdAt"
        ]
      },
      "PaginatedTransactionsResponseDto": {
        "type": "object",
        "properties": {
          "data": {
            "description": "List of transactions",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TransactionResponseDto"
            }
          },
          "meta": {
            "description": "Pagination metadata",
            "allOf": [
              {
                "$ref": "#/components/schemas/PaginationMetaDto"
              }
            ]
          }
        },
        "required": [
          "data",
          "meta"
        ]
      },
      "WebhookConfigResponseDtoList": {
        "type": "array",
        "items": {
          "$ref": "#/components/schemas/WebhookConfigResponseDto"
        },
        "example": [
          {
            "id": "68f11209-451f-4a15-bfcd-d916eb8b09f4",
            "merchantId": "68f11209-451f-4a15-bfcd-d916eb8b09f5",
            "url": "https://example.com/webhooks/bila",
            "secret": "a1b2****c3d4",
            "events": [
              "payment.completed",
              "collection.completed"
            ],
            "isActive": true,
            "createdAt": "2026-04-01T10:00:00.000Z",
            "updatedAt": "2026-04-15T14:30:00.000Z"
          }
        ]
      },
      "WebhookEventTypesList": {
        "type": "array",
        "items": {
          "type": "string"
        },
        "example": [
          "order.created",
          "order.paid",
          "order.cancelled",
          "stock.low",
          "payment.created",
          "payment.completed",
          "payment.failed",
          "collection.pending",
          "collection.completed",
          "collection.failed",
          "withdrawal.created",
          "withdrawal.completed",
          "withdrawal.failed",
          "transaction.updated",
          "transfer.pending",
          "transfer.completed",
          "transfer.failed",
          "settlement.completed"
        ]
      },
      "WebhookConfigResponseDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Webhook config UUID",
            "example": "68f11209-451f-4a15-bfcd-d916eb8b09f4",
            "format": "uuid"
          },
          "merchantId": {
            "type": "string",
            "description": "Merchant UUID",
            "example": "68f11209-451f-4a15-bfcd-d916eb8b09f5",
            "format": "uuid"
          },
          "url": {
            "type": "string",
            "description": "Webhook endpoint URL",
            "example": "https://example.com/webhooks/bila"
          },
          "secret": {
            "type": "string",
            "description": "Signing secret; plaintext only on create/rotate-secret, otherwise masked",
            "example": "a1b2****c3d4"
          },
          "events": {
            "description": "Subscribed event types",
            "example": [
              "payment.completed",
              "collection.completed"
            ],
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "isActive": {
            "type": "boolean",
            "description": "Whether the webhook is active",
            "example": true
          },
          "createdAt": {
            "format": "date-time",
            "type": "string",
            "example": "2026-04-01T10:00:00.000Z"
          },
          "updatedAt": {
            "format": "date-time",
            "type": "string",
            "example": "2026-04-15T14:30:00.000Z"
          }
        },
        "required": [
          "id",
          "merchantId",
          "url",
          "secret",
          "events",
          "isActive",
          "createdAt",
          "updatedAt"
        ]
      },
      "CreateWebhookConfigDto": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "description": "Webhook endpoint URL",
            "example": "https://example.com/webhooks"
          },
          "events": {
            "type": "array",
            "description": "Event types to subscribe to",
            "example": [
              "payment.completed",
              "withdrawal.completed"
            ],
            "items": {
              "type": "string",
              "enum": [
                "order.created",
                "order.paid",
                "order.cancelled",
                "stock.low",
                "payment.created",
                "payment.completed",
                "payment.failed",
                "collection.pending",
                "collection.completed",
                "collection.failed",
                "withdrawal.created",
                "withdrawal.completed",
                "withdrawal.failed",
                "transaction.updated",
                "transfer.pending",
                "transfer.completed",
                "transfer.failed",
                "settlement.completed"
              ]
            }
          }
        },
        "required": [
          "url",
          "events"
        ]
      },
      "UpdateWebhookConfigDto": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "description": "Webhook endpoint URL",
            "example": "https://example.com/webhooks"
          },
          "events": {
            "type": "array",
            "description": "Event types to subscribe to",
            "example": [
              "payment.completed",
              "collection.completed"
            ],
            "items": {
              "type": "string",
              "enum": [
                "order.created",
                "order.paid",
                "order.cancelled",
                "stock.low",
                "payment.created",
                "payment.completed",
                "payment.failed",
                "collection.pending",
                "collection.completed",
                "collection.failed",
                "withdrawal.created",
                "withdrawal.completed",
                "withdrawal.failed",
                "transaction.updated",
                "transfer.pending",
                "transfer.completed",
                "transfer.failed",
                "settlement.completed"
              ]
            }
          },
          "isActive": {
            "type": "boolean",
            "description": "Whether the webhook is active",
            "example": true
          }
        }
      },
      "RotateWebhookSecretResultDto": {
        "type": "object",
        "properties": {
          "secret": {
            "type": "string",
            "description": "New signing secret (64-character hex, shown once)",
            "example": "7f3a9c2e8b1d4f6a0e5c8b2d9f1a4e6c0b3d8f2a1e5c9b6d0f4a8e2c7b1d5f9a3"
          }
        },
        "required": [
          "secret"
        ]
      },
      "WebhookDeliveryResponseDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Delivery UUID",
            "example": "68f11209-451f-4a15-bfcd-d916eb8b09f6",
            "format": "uuid"
          },
          "webhookConfigId": {
            "type": "string",
            "description": "Webhook config UUID",
            "example": "68f11209-451f-4a15-bfcd-d916eb8b09f4",
            "format": "uuid"
          },
          "eventType": {
            "type": "string",
            "description": "Webhook event type",
            "example": "payment.completed"
          },
          "payload": {
            "type": "object",
            "description": "Event payload JSON as stored for delivery",
            "example": {
              "id": "68f11209-451f-4a15-bfcd-d916eb8b09f7",
              "transactionId": "68f11209-451f-4a15-bfcd-d916eb8b09f8",
              "amount": "100.50",
              "status": "COMPLETED"
            }
          },
          "status": {
            "type": "string",
            "description": "Delivery status",
            "enum": [
              "QUEUED",
              "DELIVERED",
              "FAILED",
              "RETRYING"
            ],
            "example": "DELIVERED"
          },
          "responseStatus": {
            "type": "number",
            "description": "HTTP status code from the merchant endpoint",
            "nullable": true,
            "example": 200
          },
          "responseBody": {
            "type": "string",
            "description": "Response body from the merchant endpoint (truncated)",
            "nullable": true,
            "example": "{\"received\":true}"
          },
          "attempts": {
            "type": "number",
            "description": "Number of delivery attempts",
            "example": 1
          },
          "maxAttempts": {
            "type": "number",
            "description": "Maximum delivery attempts",
            "example": 5
          },
          "deliveredAt": {
            "type": "object",
            "description": "When the delivery succeeded",
            "nullable": true,
            "format": "date-time",
            "example": "2026-04-15T14:30:05.000Z"
          },
          "failedAt": {
            "type": "object",
            "description": "When the delivery permanently failed",
            "nullable": true,
            "format": "date-time",
            "example": null
          },
          "nextRetryAt": {
            "type": "object",
            "description": "When the next retry is scheduled",
            "nullable": true,
            "format": "date-time",
            "example": null
          },
          "createdAt": {
            "format": "date-time",
            "type": "string",
            "example": "2026-04-15T14:30:00.000Z"
          }
        },
        "required": [
          "id",
          "webhookConfigId",
          "eventType",
          "payload",
          "status",
          "responseStatus",
          "responseBody",
          "attempts",
          "maxAttempts",
          "deliveredAt",
          "failedAt",
          "nextRetryAt",
          "createdAt"
        ]
      },
      "PaginatedWebhookDeliveriesResponseDto": {
        "type": "object",
        "properties": {
          "data": {
            "description": "List of webhook deliveries",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WebhookDeliveryResponseDto"
            }
          },
          "meta": {
            "description": "Pagination metadata",
            "allOf": [
              {
                "$ref": "#/components/schemas/PaginationMetaDto"
              }
            ]
          }
        },
        "required": [
          "data",
          "meta"
        ]
      }
    }
  },
  "security": [
    {
      "x-api-key": []
    }
  ]
}