{
  "info": {
    "_postman_id": "airpero-saas-api-v1-collection",
    "name": "Airpero SaaS Backend API Collection",
    "description": "Complete Postman API Collection for Airpero SaaS Backend (Multi-tenant SaaS for 9PSB Naira integration, Virtual Cards, Merchant Dashboards, and SuperAdmin controls).\n\nIncludes all 125 system endpoints across Admin, Merchant, Customer, and Provider Webhook domains.",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "item": [
    {
      "name": "01. System & Operational Health",
      "description": "System health check and root operational endpoints",
      "item": [
        {
          "name": "GET /",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/",
              "host": [
                "{{baseUrl}}"
              ],
              "path": []
            },
            "description": "GET /"
          },
          "response": []
        }
      ]
    },
    {
      "name": "02. Admin - Auth & Security",
      "description": "SuperAdmin and Admin login, OTP verification, password reset, and 2FA management",
      "item": [
        {
          "name": "Admin Login",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/login",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "login"
              ]
            },
            "description": "Authenticate an Admin user with email and password.\n\n**2FA Flow:**\n- If 2FA is **disabled** → Returns a full `token` immediately.\n- If 2FA is **enabled** → Returns `requiresOtp: true` and an `otpId`. \n  A 6-digit code is sent to the Admin's registered email. \n  The client must then call `POST /admin/verify-otp` with the `otpId` and code to receive the JWT.\n",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"email\": \"superadmin@airpero.com\",\n  \"password\": \"SuperAdmin@123\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Complete Admin login with OTP (2FA Step 2)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/verify-otp",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "verify-otp"
              ]
            },
            "description": "Submit the 6-digit OTP received by email to complete a 2FA login.\n\n**OTP Rules:**\n- Expires after the configured `OTP_EXPIRES_MINUTES` (default: 10 minutes).\n- Single-use only — cannot be reused after successful verification.\n- Locked after **5 failed attempts** — must request a new OTP.\n- Rate-limited to **3 requests per minute** per IP.\n",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"otpId\": \"b5c6d7e8-f9a0-1b2c-3d4e-5f6a7b8c9d0e\",\n  \"code\": \"483920\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Request Admin password reset",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/forgot-password",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "forgot-password"
              ]
            },
            "description": "Triggers a password reset email to the admin's registered address.\nThe email contains a secure link that expires in **30 minutes**.\n\n**Security:** This endpoint always returns `200 OK` regardless of whether the email exists, \nto prevent email enumeration attacks.\n\nRate-limited to **3 requests per minute** per IP.\n",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"email\": \"superadmin@airpero.com\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Complete Admin password reset",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/reset-password",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "reset-password"
              ]
            },
            "description": "Submits the reset token (from the email link) along with a new password.\nThe token is valid for **30 minutes** from when it was issued.\nAfter use, the token is invalidated and cannot be reused.\n",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"token\": \"a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2\",\n  \"newPassword\": \"NewStrongPassword@2026\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Enable or disable 2FA for Admin",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/2fa/toggle",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "2fa",
                "toggle"
              ]
            },
            "description": "Toggles 2FA on or off for the currently authenticated Admin.\n- If 2FA is currently **OFF** → it will be turned **ON**. Future logins will require an email OTP.\n- If 2FA is currently **ON** → it will be turned **OFF**. Future logins will return a token immediately.\n\nRequires a valid Bearer token.\n",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"enable\": true\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        }
      ]
    },
    {
      "name": "03. Admin - Merchant Management",
      "description": "SuperAdmin onboarding of merchants, merchant status management, fee structures, and merchant stats",
      "item": [
        {
          "name": "Register a new Merchant (SuperAdmin Only)",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/merchants",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "merchants"
              ]
            },
            "description": "Register a new Merchant (SuperAdmin Only)",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"businessName\": \"sample_businessName\",\n  \"email\": \"sample_email\",\n  \"password\": \"sample_password\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "List all merchants with pagination and search",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/merchants",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "merchants"
              ]
            },
            "description": "List all merchants with pagination and search"
          },
          "response": []
        },
        {
          "name": "Get full breakdown of a Merchant's profile, customers, and transactions",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/merchants/:merchantId",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "merchants",
                ":merchantId"
              ],
              "variable": [
                {
                  "key": "merchantId",
                  "value": "{{merchantId}}",
                  "description": "Path variable merchantId"
                }
              ]
            },
            "description": "Get full breakdown of a Merchant's profile, customers, and transactions"
          },
          "response": []
        },
        {
          "name": "Update Merchant status (Activate, Deactivate, Suspend)",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "PATCH",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/merchants/:merchantId/status",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "merchants",
                ":merchantId",
                "status"
              ],
              "variable": [
                {
                  "key": "merchantId",
                  "value": "{{merchantId}}",
                  "description": "Path variable merchantId"
                }
              ]
            },
            "description": "Update Merchant status (Activate, Deactivate, Suspend)",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"status\": \"suspended\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Get detailed stats for a specific merchant (Admin View)",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/merchants/:merchantId/stats",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "merchants",
                ":merchantId",
                "stats"
              ],
              "variable": [
                {
                  "key": "merchantId",
                  "value": "{{merchantId}}",
                  "description": "Path variable merchantId"
                }
              ]
            },
            "description": "Get detailed stats for a specific merchant (Admin View)"
          },
          "response": []
        },
        {
          "name": "Set custom fees for a specific merchant",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "PATCH",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/merchants/:merchantId/fees",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "merchants",
                ":merchantId",
                "fees"
              ],
              "variable": [
                {
                  "key": "merchantId",
                  "value": "{{merchantId}}",
                  "description": "Path variable merchantId"
                }
              ]
            },
            "description": "Dual-purpose based on the request body. Omit `serviceName`/`currency` to set the legacy flat NGN deposit/payout override on the merchant record directly. Include `serviceName` and `currency` to instead set a per-service/per-currency pricing override (upserted into a dedicated MerchantServicePricing record) — see `/admin/merchants/{merchantId}/service-pricing` to list or remove these. This override takes priority over any subscription-plan override and the platform default for that merchant/service/currency combination.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"customDepositFeePercent\": 100,\n  \"customDepositFeeCap\": 100,\n  \"customPayoutFeeFlat\": 100\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "List a merchant's per-service/per-currency pricing overrides",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/merchants/:merchantId/service-pricing",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "merchants",
                ":merchantId",
                "service-pricing"
              ],
              "variable": [
                {
                  "key": "merchantId",
                  "value": "{{merchantId}}",
                  "description": "Path variable merchantId"
                }
              ]
            },
            "description": "List a merchant's per-service/per-currency pricing overrides"
          },
          "response": []
        },
        {
          "name": "Remove a merchant's per-service/per-currency pricing override",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "DELETE",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/merchants/:merchantId/service-pricing/:id",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "merchants",
                ":merchantId",
                "service-pricing",
                ":id"
              ],
              "variable": [
                {
                  "key": "merchantId",
                  "value": "{{merchantId}}",
                  "description": "Path variable merchantId"
                },
                {
                  "key": "id",
                  "value": "{{id}}",
                  "description": "Path variable id"
                }
              ]
            },
            "description": "Reverts that service+currency back to any subscription-plan override, or the platform default, for this merchant."
          },
          "response": []
        }
      ]
    },
    {
      "name": "04. Admin - Dashboard & Analytics",
      "description": "Platform-wide dashboard statistics, financial report generation, system profit analytics, transactions, and customer management",
      "item": [
        {
          "name": "Get platform-wide profit statistics",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/profits/stats",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "profits",
                "stats"
              ]
            },
            "description": "Get platform-wide profit statistics"
          },
          "response": []
        },
        {
          "name": "Get history of platform profit logs",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/profits/history",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "profits",
                "history"
              ]
            },
            "description": "Get history of platform profit logs"
          },
          "response": []
        },
        {
          "name": "Get overall platform revenue report (Legacy aggregation)",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/report",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "report"
              ]
            },
            "description": "Get overall platform revenue report (Legacy aggregation)"
          },
          "response": []
        },
        {
          "name": "Comprehensive dashboard metrics and transaction trends",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/dashboard",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "dashboard"
              ]
            },
            "description": "Comprehensive dashboard metrics and transaction trends"
          },
          "response": []
        },
        {
          "name": "List all transactions system-wide with pagination and filters",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/transactions",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "transactions"
              ]
            },
            "description": "List all transactions system-wide with pagination and filters"
          },
          "response": []
        },
        {
          "name": "List all customers system-wide with pagination and search",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/customers",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "customers"
              ]
            },
            "description": "List all customers system-wide with pagination and search"
          },
          "response": []
        },
        {
          "name": "Get full details of a customer, including their merchant and recent activity",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/customers/:customerId",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "customers",
                ":customerId"
              ],
              "variable": [
                {
                  "key": "customerId",
                  "value": "{{customerId}}",
                  "description": "Path variable customerId"
                }
              ]
            },
            "description": "Get full details of a customer, including their merchant and recent activity"
          },
          "response": []
        },
        {
          "name": "Update customer status",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "PATCH",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/customers/:customerId/status",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "customers",
                ":customerId",
                "status"
              ],
              "variable": [
                {
                  "key": "customerId",
                  "value": "{{customerId}}",
                  "description": "Path variable customerId"
                }
              ]
            },
            "description": "Update customer status",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"status\": \"active\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        }
      ]
    },
    {
      "name": "05. Admin - IP Whitelist Management",
      "description": "SuperAdmin control for IP whitelisting across administrative users",
      "item": [
        {
          "name": "List all Admin IP Whitelists",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/ip-whitelist",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "ip-whitelist"
              ]
            },
            "description": "Retrieve all IP addresses approved for SuperAdmin access. SuperAdmin only."
          },
          "response": []
        },
        {
          "name": "Add a new IP Address to the Admin Whitelist",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/ip-whitelist",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "ip-whitelist"
              ]
            },
            "description": "Registers an IP address as an approved access point for SuperAdmin operations.\nOnce at least one IP is in the database, ALL SuperAdmin routes will be restricted to only those IPs.\n**SuperAdmin only.**\n",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"ipAddress\": \"102.89.83.63\",\n  \"description\": \"Super Admin - Primary Office IP\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Update an Admin IP Whitelist entry",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "PATCH",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/ip-whitelist/:id",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "ip-whitelist",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{id}}",
                  "description": "Path variable id"
                }
              ]
            },
            "description": "Update the status (active/inactive) or description of a whitelisted IP. SuperAdmin only.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"status\": \"inactive\",\n  \"description\": \"Temporary office IP — deactivated\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Remove an IP from the Admin Whitelist",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "DELETE",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/ip-whitelist/:id",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "ip-whitelist",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{id}}",
                  "description": "Path variable id"
                }
              ]
            },
            "description": "Deletes an IP address from the SuperAdmin whitelist. SuperAdmin only."
          },
          "response": []
        }
      ]
    },
    {
      "name": "06. Admin - Card Management",
      "description": "SuperAdmin and Admin virtual card controls: freeze, unfreeze, terminate, balance updates, and card lookup",
      "item": [
        {
          "name": "List all cards for a specific customer (Admin view)",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/customers/:customerId/cards",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "customers",
                ":customerId",
                "cards"
              ],
              "variable": [
                {
                  "key": "customerId",
                  "value": "{{customerId}}",
                  "description": "Path variable customerId"
                }
              ]
            },
            "description": "Returns all virtual cards belonging to a specific customer.\nNo merchant restriction — admin can view any customer's cards.\nA customer can have multiple cards.\n\n**Any authenticated Admin.**\n"
          },
          "response": []
        },
        {
          "name": "List all cards under a merchant",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/merchants/:merchantId/cards",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "merchants",
                ":merchantId",
                "cards"
              ],
              "variable": [
                {
                  "key": "merchantId",
                  "value": "{{merchantId}}",
                  "description": "Path variable merchantId"
                }
              ]
            },
            "description": "Returns all virtual cards belonging to all customers of a specific merchant.\nA customer can have multiple cards — all are returned and grouped with customer info.\nSupports pagination and status filtering.\n\n**Any authenticated Admin.**\n"
          },
          "response": []
        },
        {
          "name": "Get full details of a single card",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/cards/:cardId",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "cards",
                ":cardId"
              ],
              "variable": [
                {
                  "key": "cardId",
                  "value": "{{cardId}}",
                  "description": "Path variable cardId"
                }
              ]
            },
            "description": "Returns complete card information including card number, expiry, balance, status,\nand associated customer + merchant details.\n\n> **Note**: CVV is excluded from all admin reads for PCI compliance.\n\n**Any authenticated Admin.**\n"
          },
          "response": []
        },
        {
          "name": "Freeze a card (Admin)",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/cards/:cardId/freeze",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "cards",
                ":cardId",
                "freeze"
              ],
              "variable": [
                {
                  "key": "cardId",
                  "value": "{{cardId}}",
                  "description": "Path variable cardId"
                }
              ]
            },
            "description": "Freezes a virtual card. The card must be in `active` status.\nThe freeze is sent to PayScribe and the status is updated in the database.\n\nAction is logged to the audit trail.\n\n**Any authenticated Admin.**\n",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"status\": \"active\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Unfreeze a card (Admin)",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/cards/:cardId/unfreeze",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "cards",
                ":cardId",
                "unfreeze"
              ],
              "variable": [
                {
                  "key": "cardId",
                  "value": "{{cardId}}",
                  "description": "Path variable cardId"
                }
              ]
            },
            "description": "Unfreezes a virtual card. The card must be in `frozen` status.\nThe unfreeze is sent to PayScribe and the status is updated.\n\nAction is logged to the audit trail.\n\n**Any authenticated Admin.**\n",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"status\": \"active\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Terminate a card (SuperAdmin only)",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/cards/:cardId/terminate",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "cards",
                ":cardId",
                "terminate"
              ],
              "variable": [
                {
                  "key": "cardId",
                  "value": "{{cardId}}",
                  "description": "Path variable cardId"
                }
              ]
            },
            "description": "Permanently terminates a virtual card. This action is **irreversible**.\n\nOn termination:\n- The card is terminated on PayScribe\n- Any remaining card balance is automatically refunded to the customer's USD service balance\n- Card status is set to `terminated` and balance is set to `0`\n\nAction is logged to the audit trail.\n\n**SuperAdmin only.**\n",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"status\": \"active\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Update card balance — Admin manual adjustment (SuperAdmin only)",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "PATCH",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/cards/:cardId/balance",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "cards",
                ":cardId",
                "balance"
              ],
              "variable": [
                {
                  "key": "cardId",
                  "value": "{{cardId}}",
                  "description": "Path variable cardId"
                }
              ]
            },
            "description": "Performs a manual balance credit (add funds) or debit (remove funds) on a virtual card.\n\nThis is an **administrative override** — it directly adjusts the local card balance\nin the database. Use this for balance corrections (e.g. when there is a discrepancy\nbetween PayScribe and the local record).\n\n**Required fields:**\n- `operation` — `\"credit\"` to add funds, `\"debit\"` to remove funds\n- `amount` — Positive number specifying how much to add/remove\n- `title` — Short heading describing this adjustment (e.g. `\"Balance Correction\"`)\n- `description` — Full explanation of the reason for the adjustment\n\nAll adjustments are fully logged to the audit trail with the title, description, old balance, and new balance.\n\n**SuperAdmin only.**\n",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"operation\": \"credit\",\n  \"amount\": 50,\n  \"title\": \"Balance Correction\",\n  \"description\": \"PayScribe reported an extra $50 on this card that was not reflected locally. Crediting to reconcile.\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        }
      ]
    },
    {
      "name": "07. Admin - KYB Review",
      "description": "SuperAdmin review and status updates for Merchant Know Your Business (KYB) applications",
      "item": [
        {
          "name": "Get all KYB applications",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/kyb",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "kyb"
              ]
            },
            "description": "Returns all merchant KYB applications. SuperAdmin can filter by status."
          },
          "response": []
        },
        {
          "name": "Get a single KYB application",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/kyb/:id",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "kyb",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{id}}",
                  "description": "Path variable id"
                }
              ]
            },
            "description": "Returns the full details of a single KYB application including documents, directors, and history logs."
          },
          "response": []
        },
        {
          "name": "Update KYB application status",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "PATCH",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/kyb/:id/status",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "kyb",
                ":id",
                "status"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{id}}",
                  "description": "Path variable id"
                }
              ]
            },
            "description": "SuperAdmin can update the status of the application. \n- If 'Rejected' or 'Additional Documents Required', a reason MUST be provided.\n- Triggers automatic email notification to the Merchant.\n",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"status\": \"sample_status\",\n  \"reason\": \"sample_reason\",\n  \"documentIdToReject\": \"sample_documentIdToReject\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        }
      ]
    },
    {
      "name": "08. Admin - Settings & Services & KYC Stages",
      "description": "Global system settings, dynamic fee config, system service toggles, and KYC stage mappings",
      "item": [
        {
          "name": "Get global fee settings",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/settings",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "settings"
              ]
            },
            "description": "Get global fee settings"
          },
          "response": []
        },
        {
          "name": "Update global fee settings",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "PATCH",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/settings",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "settings"
              ]
            },
            "description": "Update global fee settings",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"depositFeePercent\": 100,\n  \"depositFeeCap\": 100,\n  \"payoutFeeFlat\": 100\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "List all KYC stages",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/kyc/stages",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "kyc",
                "stages"
              ]
            },
            "description": "List all KYC stages"
          },
          "response": []
        },
        {
          "name": "List all system services",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/services",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "services"
              ]
            },
            "description": "List all system services"
          },
          "response": []
        },
        {
          "name": "Toggle global service status",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "PATCH",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/services/:serviceId/status",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "services",
                ":serviceId",
                "status"
              ],
              "variable": [
                {
                  "key": "serviceId",
                  "value": "{{serviceId}}",
                  "description": "Path variable serviceId"
                }
              ]
            },
            "description": "Toggle global service status",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"isActive\": false\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Map a system service to a KYC stage",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/kyc/stages/:stageId/services",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "kyc",
                "stages",
                ":stageId",
                "services"
              ],
              "variable": [
                {
                  "key": "stageId",
                  "value": "{{stageId}}",
                  "description": "Path variable stageId"
                }
              ]
            },
            "description": "Map a system service to a KYC stage",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"serviceId\": \"s1s2s3s4-s5s6-s7s8-s9s0-s1s2s3s4s5s6\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Toggle active status of a service inside a KYC stage",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "PATCH",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/kyc/stages/:stageId/services/:serviceId",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "kyc",
                "stages",
                ":stageId",
                "services",
                ":serviceId"
              ],
              "variable": [
                {
                  "key": "stageId",
                  "value": "{{stageId}}",
                  "description": "Path variable stageId"
                },
                {
                  "key": "serviceId",
                  "value": "{{serviceId}}",
                  "description": "Path variable serviceId"
                }
              ]
            },
            "description": "Toggle active status of a service inside a KYC stage",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"isActive\": true\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        }
      ]
    },
    {
      "name": "09. Admin - Currency Management",
      "description": "Global multi-currency configuration and virtual account capabilities",
      "item": [
        {
          "name": "Create a new global currency",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/currencies",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "currencies"
              ]
            },
            "description": "Allows a SuperAdmin to add a new currency (e.g. KES, GHS) to the platform.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"code\": \"KES\",\n  \"name\": \"Kenyan Shilling\",\n  \"symbol\": \"KSh\",\n  \"status\": \"active\",\n  \"virtualAccountStatus\": \"active\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Get all platform currencies",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/currencies",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "currencies"
              ]
            },
            "description": "Returns a list of all active and inactive currencies managed by the platform."
          },
          "response": []
        },
        {
          "name": "Toggle currency status",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "PATCH",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/currencies/:code/status",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "currencies",
                ":code",
                "status"
              ],
              "variable": [
                {
                  "key": "code",
                  "value": "USD",
                  "description": "Path variable code"
                }
              ]
            },
            "description": "Allows a SuperAdmin to activate or deactivate a currency platform-wide.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"status\": \"inactive\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Toggle whether a currency is enabled for merchant wallets",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "PATCH",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/currencies/:code/virtual-account-status",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "currencies",
                ":code",
                "virtual-account-status"
              ],
              "variable": [
                {
                  "key": "code",
                  "value": "USD",
                  "description": "Path variable code"
                }
              ]
            },
            "description": "Controls whether merchants get a wallet in this currency. Not instant — a background job (runs at server startup, then every 24 hours) creates/activates or deactivates merchant wallets to match. Existing wallet balances are never deleted when deactivated, only marked inactive. NGN cannot be toggled — it's the merchant's native balance, not part of this system, and this endpoint returns 400 if attempted.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"virtualAccountStatus\": \"active\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        }
      ]
    },
    {
      "name": "10. Admin - Service Pricing",
      "description": "Service pricing tiers and tier rates configuration",
      "item": [
        {
          "name": "Create new service pricing rule",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/service-pricing",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "service-pricing"
              ]
            },
            "description": "Allows a SuperAdmin to define a new pricing rule for a specific service and currency.\n\n**`serviceName` is a free-text slug** — not a dropdown. The following are standard names used in this system:\n\n| serviceName | Description |\n|---|---|\n| `wallet_deposit` | Fee charged when a customer deposits into their wallet |\n| `payout` | Fee charged on payout/withdrawal transactions |\n| `card_decline_fee` | Flat fee charged when a virtual card transaction is declined |\n| `card_fx_charge` | Foreign exchange (FX) markup on international card spend |\n\n**Pricing Fields:**\n- `providerPercentage` — % the provider charges Airpero (decimal: `0.015` = 1.5%)\n- `providerFixedFee` — Flat fee the provider charges Airpero\n- `customerPercentage` — % Airpero charges the merchant/customer\n- `customerFixedFee` — Flat fee Airpero charges the merchant/customer\n- `customerMinCap` — Minimum fee charged to the customer\n- `customerMaxCap` — Maximum fee charged (`999999999.99` = uncapped)\n\n**SuperAdmin only.**\n",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"serviceName\": \"wallet_deposit\",\n  \"currency\": \"NGN\",\n  \"providerPercentage\": 0.015,\n  \"providerFixedFee\": 0,\n  \"customerPercentage\": 0.02,\n  \"customerFixedFee\": 0,\n  \"isActive\": true\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Get all service pricing rules",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/service-pricing",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "service-pricing"
              ]
            },
            "description": "Returns all service pricing rules (active and inactive)."
          },
          "response": []
        },
        {
          "name": "Update a service pricing rule",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "PATCH",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/service-pricing/:id",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "service-pricing",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{id}}",
                  "description": "Path variable id"
                }
              ]
            },
            "description": "Update any pricing field of an existing rule. Send only what you want to change. SuperAdmin only.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"providerPercentage\": 0.018,\n  \"providerFixedFee\": 0,\n  \"customerPercentage\": 0.025,\n  \"customerFixedFee\": 0,\n  \"customerMinCap\": 50,\n  \"customerMaxCap\": 2000,\n  \"isActive\": false\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Delete a service pricing rule",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "DELETE",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/service-pricing/:id",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "service-pricing",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{id}}",
                  "description": "Path variable id"
                }
              ]
            },
            "description": "Permanently removes a pricing rule. SuperAdmin only."
          },
          "response": []
        }
      ]
    },
    {
      "name": "11. Admin - Email Templates",
      "description": "Email template management for automated system notifications",
      "item": [
        {
          "name": "Get all email templates",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/email-templates",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "email-templates"
              ]
            },
            "description": "Retrieve a list of all email templates available in the system for SuperAdmins to manage."
          },
          "response": []
        },
        {
          "name": "Get email template by slug",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/email-templates/:slug",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "email-templates",
                ":slug"
              ],
              "variable": [
                {
                  "key": "slug",
                  "value": "welcome-email",
                  "description": "Path variable slug"
                }
              ]
            },
            "description": "Retrieve the full HTML content and details of a specific email template."
          },
          "response": []
        },
        {
          "name": "Update email template",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "PATCH",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/email-templates/:slug",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "email-templates",
                ":slug"
              ],
              "variable": [
                {
                  "key": "slug",
                  "value": "welcome-email",
                  "description": "Path variable slug"
                }
              ]
            },
            "description": "Update the subject or HTML body of an email template. The `bodyHtml` will be injected into the standard Airpero branded wrapper.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"subject\": \"Welcome aboard, {{businessName}}!\",\n  \"bodyHtml\": \"<p>Hello {{businessName}}, welcome to Airpero!</p>\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        }
      ]
    },
    {
      "name": "12. Admin - Exchange Rates",
      "description": "Foreign exchange rate definitions, live rate previews, and FX markup controls",
      "item": [
        {
          "name": "List all Exchange Rate Rules",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/exchange-rates",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "exchange-rates"
              ]
            },
            "description": "Returns all configured exchange rate rules. For each rule, the response includes:\n- `storedRate` — The rate saved in the database\n- `liveRate` — The real-time rate fetched from the configured provider (WeWire, Graph, etc.)\n- `effectiveRate` — The final rate merchants see after the admin's margin is applied\n\n**SuperAdmin only.**\n"
          },
          "response": []
        },
        {
          "name": "Preview Live Rate from a Provider",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/exchange-rates/preview",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "exchange-rates",
                "preview"
              ]
            },
            "description": "Fetches and shows the current live exchange rate from a third-party provider\n**without saving anything**. Useful for the admin to check what the live market\nrate is before creating or updating a rule.\n\n**SuperAdmin only.**\n"
          },
          "response": []
        },
        {
          "name": "Create an Exchange Rate Rule",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/exchange-rates",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "exchange-rates"
              ]
            },
            "description": "Creates a new exchange rate rule for a currency pair.\n\n**Rate Sources:**\n- `manual` — Admin sets a fixed rate directly. The `rate` field is required.\n- `wewire` — System fetches the live rate from the WeWire API and applies the margin.\n- `graph` — System fetches the live rate from the Graph API and applies the margin.\n- `nine_psb` — Uses 9PSB as source (falls back to `rate` value as 9PSB has no public FX API).\n\n**Margin Operation:**\n- `add` — `effectiveRate = liveRate + margin` (e.g. rate=1650, margin=10 → 1660)\n- `subtract` — `effectiveRate = liveRate - margin` (e.g. rate=1650, margin=10 → 1640)\n\n**SuperAdmin only.**\n",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"baseCurrency\": \"NGN\",\n  \"targetCurrency\": \"USD\",\n  \"rateSource\": \"manual\",\n  \"rate\": 1650,\n  \"margin\": 20,\n  \"marginOperation\": \"add\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Update an Exchange Rate Rule",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "PATCH",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/exchange-rates/:id",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "exchange-rates",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{id}}",
                  "description": "Path variable id"
                }
              ]
            },
            "description": "Update any field of an existing exchange rate rule. All fields are optional — only send what you want to change.\n\nIf you switch to a live rateSource (wewire, graph), the system will immediately fetch\nand store the current live rate.\n\n**SuperAdmin only.**\n",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"margin\": 30,\n  \"marginOperation\": \"add\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Delete an Exchange Rate Rule",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "DELETE",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/exchange-rates/:id",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "exchange-rates",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{id}}",
                  "description": "Path variable id"
                }
              ]
            },
            "description": "Permanently removes an exchange rate rule. SuperAdmin only."
          },
          "response": []
        }
      ]
    },
    {
      "name": "13. Admin - Subscription Plans",
      "description": "SaaS subscription tier management and global subscription metrics",
      "item": [
        {
          "name": "Create a subscription plan",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/subscription-plans",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "subscription-plans"
              ]
            },
            "description": "SuperAdmin creates a new subscription plan available for merchants to subscribe to.\n\n**Key fields:**\n- `monthlyPrice` — the base price for one month's billing. The system calculates the annual price automatically using the discount.\n- `annualDiscountPercentage` — e.g. `20` means a 20% discount when billing yearly. Annual price = `monthlyPrice × 12 × (1 - discount/100)`.\n- `currency` — the currency merchants will be charged in (e.g. `NGN`, `USD`). Merchants must have sufficient wallet balance in this currency.\n- `benefits` — free-text bullet points displayed on the pricing page.\n- `includedServices` — array of SystemService codes that this plan unlocks for the merchant.\n- `transactionLimit` — max monthly transactions allowed. `null` = unlimited.\n",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"name\": \"Growth\",\n  \"description\": \"Best for growing businesses with moderate transaction volumes.\",\n  \"monthlyPrice\": 25000,\n  \"currency\": \"NGN\",\n  \"annualDiscountPercentage\": 20,\n  \"transactionLimit\": 5000,\n  \"benefits\": [\n    \"20% fee discount\",\n    \"Up to 5,000 transactions/month\",\n    \"Priority support\"\n  ],\n  \"includedServices\": [\n    \"virtual_cards\",\n    \"international_payout\"\n  ],\n  \"servicePricingOverrides\": \"sample_servicePricingOverrides\",\n  \"sortOrder\": 2\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Get all subscription plans (admin view)",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/subscription-plans",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "subscription-plans"
              ]
            },
            "description": "Returns **all** subscription plans including inactive ones, ordered by sortOrder then createdAt.\n\n> To get only active plans (merchant-facing), use `GET /merchants/subscriptions/plans`.\n"
          },
          "response": []
        },
        {
          "name": "Update a subscription plan",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "PATCH",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/subscription-plans/:id",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "subscription-plans",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{id}}",
                  "description": "Path variable id"
                }
              ]
            },
            "description": "Updates any fields on a subscription plan. Only send the fields you want to change.\n\n**Updatable fields:** `name`, `description`, `monthlyPrice`, `annualDiscountPercentage`,\n`currency`, `servicePricingOverrides`, `transactionLimit`, `benefits`, `includedServices`,\n`sortOrder`, `status`\n\n> Setting `status` to `inactive` will hide the plan from new merchants but will NOT affect existing active subscriptions.\n",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"name\": \"Growth Plus\",\n  \"description\": \"sample_description\",\n  \"monthlyPrice\": 30000,\n  \"annualDiscountPercentage\": 25,\n  \"currency\": \"NGN\",\n  \"transactionLimit\": 10000,\n  \"benefits\": [\n    \"25% fee discount\",\n    \"Up to 10,000 transactions/month\"\n  ],\n  \"includedServices\": \"sample_includedServices\",\n  \"status\": \"inactive\",\n  \"sortOrder\": 2\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Deactivate a subscription plan",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "DELETE",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/subscription-plans/:id",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "subscription-plans",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{id}}",
                  "description": "Path variable id"
                }
              ]
            },
            "description": "**Soft-deactivates** the plan by setting its `status` to `inactive`.\n\n- The plan will no longer appear on the merchant-facing pricing page.\n- **Existing active subscribers are NOT affected** — their subscription continues until the billing period ends.\n- Plans can be re-activated via PATCH with `{ \"status\": \"active\" }`.\n"
          },
          "response": []
        },
        {
          "name": "Get subscription dashboard stats",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{adminToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/admin/subscriptions/stats",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "admin",
                "subscriptions",
                "stats"
              ]
            },
            "description": "Returns aggregated subscription statistics for the admin dashboard:\n- Plan counts (total + active)\n- Subscription counts by status\n- Total subscription revenue (paid invoices)\n- Top 5 plans by active subscriber count\n"
          },
          "response": []
        }
      ]
    },
    {
      "name": "14. Merchant - Auth & Key Management",
      "description": "Merchant self-registration, dashboard auth, API key generation, webhook URL setup, and profile settings",
      "item": [
        {
          "name": "Merchant Self-Registration",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/merchants/register",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "merchants",
                "register"
              ]
            },
            "description": "Merchant Self-Registration",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"businessName\": \"sample_businessName\",\n  \"preview\": \"sample_preview\",\n  \"email\": \"sample_email\",\n  \"password\": \"sample_password\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Merchant Dashboard Login",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/merchants/login",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "merchants",
                "login"
              ]
            },
            "description": "Authenticate a Merchant user with email and password to receive a dashboard JWT token.\n\n**2FA Flow:**\n- If 2FA is **disabled** → Returns a full `token` immediately.\n- If 2FA is **enabled** → Returns `requiresOtp: true` and an `otpId`.\n  A 6-digit code is emailed to the merchant. Call `POST /merchants/verify-otp` next.\n\nRate-limited to **5 attempts per minute** per IP.\n",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"email\": \"merchant@business.com\",\n  \"password\": \"MerchantPassword@2026\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Complete Merchant login with OTP (2FA Step 2)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/merchants/verify-otp",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "merchants",
                "verify-otp"
              ]
            },
            "description": "Submit the 6-digit OTP received by email after a 2FA login challenge.\n\n**OTP Rules:**\n- Expires in `OTP_EXPIRES_MINUTES` (default: 10 minutes).\n- Single-use — invalidated immediately after successful verification.\n- Locked after **5 failed attempts**.\n- Rate-limited to **3 requests per minute** per IP.\n",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"otpId\": \"c5d6e7f8-a9b0-c1d2-e3f4-a5b6c7d8e9f0\",\n  \"code\": \"748231\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Request Merchant password reset",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/merchants/forgot-password",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "merchants",
                "forgot-password"
              ]
            },
            "description": "Sends a secure password reset link to the merchant's registered email address.\nThe link expires after **30 minutes**.\n\nAlways returns `200` — does NOT confirm whether the email exists (anti-enumeration).\n",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"email\": \"merchant@business.com\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Complete Merchant password reset",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/merchants/reset-password",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "merchants",
                "reset-password"
              ]
            },
            "description": "Accepts the reset token (from the link in the email) and the new password.\nThe token is single-use and expires after **30 minutes**.\n",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"token\": \"d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2\",\n  \"newPassword\": \"NewSecurePassword@2026\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Enable or disable 2FA for Merchant",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/merchants/2fa/toggle",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "merchants",
                "2fa",
                "toggle"
              ]
            },
            "description": "Toggles 2FA on or off for the currently authenticated merchant account.\n- **ON** → Future logins require an email OTP before a token is issued.\n- **OFF** → Future logins return the token immediately after password check.\n\nRequires a valid Dashboard Bearer token (JWT).\n",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"enable\": true\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "View API Public Key (JWT Required)",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/merchants/keys",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "merchants",
                "keys"
              ]
            },
            "description": "View API Public Key (JWT Required)"
          },
          "response": []
        },
        {
          "name": "Regenerate API Keys (JWT Required)",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/merchants/keys/regenerate",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "merchants",
                "keys",
                "regenerate"
              ]
            },
            "description": "Regenerate API Keys (JWT Required)",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"status\": \"active\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Update your notification Webhook URL",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "PATCH",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/merchants/webhook",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "merchants",
                "webhook"
              ]
            },
            "description": "Update your notification Webhook URL",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"webhookUrl\": \"sample_webhookUrl\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Update Merchant Profile (Business Name, Preview Prefix)",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "PATCH",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/merchants/profile",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "merchants",
                "profile"
              ]
            },
            "description": "Update Merchant Profile (Business Name, Preview Prefix)",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"businessName\": \"sample_businessName\",\n  \"preview\": \"sample_preview\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Request a payout authorization OTP",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "x-public-key",
                "value": "{{apiKey}}",
                "description": "Optional API Public Key for S2S"
              },
              {
                "key": "x-private-key",
                "value": "{{secretKey}}",
                "description": "Optional API Private Key for S2S"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/merchants/payout/request-otp",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "merchants",
                "payout",
                "request-otp"
              ]
            },
            "description": "**Step 1 of a protected payout.** Generates and emails a 6-digit OTP to the merchant's registered email address.\n\nThe returned `otpId` must be submitted alongside your payout request payload so the system can verify \nthe transaction was explicitly authorized by the merchant.\n\n**Workflow:**\n1. Call `POST /merchants/payout/request-otp` → Receive `otpId` + email with 6-digit code.\n2. Call `POST /merchants/payout` with `{ otpId, otpCode, ...payoutFields }`.\n3. The payout is executed only if the OTP is valid and unexpired.\n\n**OTP Rules:**\n- Expires in `OTP_EXPIRES_MINUTES` (default: 10 minutes).\n- Single-use — cannot be reused.\n- Locked after **5 failed verification attempts**.\n",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"amount\": 5000,\n  \"accountNumber\": \"0123456789\",\n  \"bankCode\": \"033\",\n  \"accountName\": \"John Doe\",\n  \"narration\": \"Payout settlement\",\n  \"otp\": \"123456\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        }
      ]
    },
    {
      "name": "15. Merchant - KYB Application",
      "description": "Merchant business verification form submission and status checks",
      "item": [
        {
          "name": "Get my KYB application",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/merchants/kyb",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "merchants",
                "kyb"
              ]
            },
            "description": "Returns the merchant's current KYB application status and data. \n**Frontend Note**: Call this on mount to check if the user is `Approved`, `Submitted`, or still in `Draft`. If no application exists yet, the backend creates an empty Draft automatically and returns it.\n"
          },
          "response": []
        },
        {
          "name": "Save KYB application draft (Initialization)",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "PUT",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/merchants/kyb",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "merchants",
                "kyb"
              ]
            },
            "description": "Upserts the KYB application details. Always saves the state as \"Draft\".\n**Frontend Note**: Since we are using Didit.me for the actual heavy lifting (document uploads, IDs), you only need to pass the basic company name and registration number here. Didit handles the rest during the hosted flow.\n",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"companyName\": \"Airpero Technologies Limited\",\n  \"registrationNumber\": \"RC1234567\"\n}",
              "options": {
                "raw": {  
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Start KYB verification (Get Didit Link)",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/merchants/kyb/submit",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "merchants",
                "kyb",
                "submit"
              ]
            },
            "description": "Creates a Didit KYB session and returns the hosted verification URL for the merchant to complete their KYB.\n**Frontend Note**: Call this when the user clicks \"Start Verification\". Take the `verificationUrl` returned in the response and redirect the user's browser to it. Didit handles the UI from there.\n",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"status\": \"active\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        }
      ]
    },
    {
      "name": "16. Merchant - Subscriptions",
      "description": "Merchant SaaS subscription plan lookup, subscription upgrade/downgrade, invoices, and billing history",
      "item": [
        {
          "name": "Browse available subscription plans",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/merchants/subscriptions/plans",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "merchants",
                "subscriptions",
                "plans"
              ]
            },
            "description": "Returns all **active** subscription plans. The `annualPrice` field is pre-calculated\nfor display — use it to show the yearly cost before the merchant pays.\n\n**Frontend Note:** Call this to populate your pricing/plans page. Each plan object\ncontains `monthlyPrice` (base), `annualPrice` (pre-calculated), `annualDiscountPercentage`,\n`currency`, `benefits` (bullet points), and `transactionLimit`.\n"
          },
          "response": []
        },
        {
          "name": "Get my current subscription",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/merchants/subscriptions/me",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "merchants",
                "subscriptions",
                "me"
              ]
            },
            "description": "Returns the merchant's current active or cancelled (pending expiry) subscription,\nincluding the full plan details.\n\n**Frontend Note:** Call this on dashboard load to check if the merchant has an active plan.\nUse the `status` field to drive your UI:\n- `active` → show plan name, end date, benefits\n- `cancelled` → show \"Expires on [endDate]\" banner, offer re-subscribe option\n- `null` data → no subscription, show the pricing plans page\n"
          },
          "response": []
        },
        {
          "name": "Subscribe to a plan",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/merchants/subscriptions",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "merchants",
                "subscriptions"
              ]
            },
            "description": "Subscribes the merchant to a plan by **immediately deducting the subscription price from their wallet balance** in the plan's currency.\n\n**How it works:**\n1. The merchant selects a plan and billing interval (`monthly` or `yearly`).\n2. The backend calculates the charge:\n   - **Monthly:** `monthlyPrice`\n   - **Yearly:** `monthlyPrice × 12 × (1 - annualDiscountPercentage/100)`\n3. The charge is deducted from the merchant's wallet in the **plan's currency** (e.g. NGN).\n4. A subscription record is created with `status: active`, `startDate: today`, and `endDate: today + 1 month or year`.\n5. An invoice is generated automatically with `paymentStatus: paid`.\n6. The subscription is immediately active — merchant benefits apply instantly.\n\n**Requirements:**\n- Merchant must **not** have an existing active subscription (use change-plan to switch).\n- Merchant's wallet balance must be >= the subscription price in the plan's currency.\n\n**Frontend Note:** Before showing the \"Subscribe\" button, check the merchant's balance from `GET /merchants/me` → `balance` and compare with the plan price.\n",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"planId\": \"a1b2c3d4-e5f6-7890-abcd-ef1234567890\",\n  \"billingInterval\": \"monthly\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Upgrade or downgrade subscription plan",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "PATCH",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/merchants/subscriptions/change-plan",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "merchants",
                "subscriptions",
                "change-plan"
              ]
            },
            "description": "Switches the merchant to a different plan or billing interval with **prorated pricing**.\n\n**How proration works:**\n1. Backend calculates how many days are remaining on the current plan.\n2. An \"unused credit\" is computed: `currentPlanPrice × (remainingDays / totalDays)`.\n3. Prorated cost = `newPlanPrice − unusedCredit`.\n4. **Upgrade (newPrice > oldPrice):** The prorated cost is deducted from the wallet.\n5. **Downgrade (newPrice < oldPrice):** If credit > newPrice, the surplus is **refunded to the wallet**.\n6. The old subscription is immediately expired and a new one starts today.\n7. A new invoice is created for the prorated amount.\n\n> You can also use this to switch billing interval on the **same plan** (e.g. monthly → yearly).\n",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"newPlanId\": \"b2c3d4e5-f6a7-8901-bcde-f12345678901\",\n  \"newBillingInterval\": \"yearly\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Cancel subscription",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/merchants/subscriptions/cancel",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "merchants",
                "subscriptions",
                "cancel"
              ]
            },
            "description": "Cancels the merchant's active subscription.\n\n**Important:** Cancellation does **NOT** immediately remove access.\n- `autoRenew` is set to `false` — the plan will NOT renew at end of billing period.\n- The merchant keeps full plan benefits until `endDate`.\n- After `endDate`, the system automatically expires the subscription.\n\n**Frontend Note:** Show the `expiresOn` date in a banner so the merchant knows they still have access.\n",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"status\": \"active\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Get subscription history",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/merchants/subscriptions/history",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "merchants",
                "subscriptions",
                "history"
              ]
            },
            "description": "Returns all past and current subscriptions for the merchant, ordered newest first.\nEach record includes the plan details and (if it was a plan change) the previous plan name.\n"
          },
          "response": []
        },
        {
          "name": "Get subscription invoices (billing receipts)",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/merchants/subscriptions/invoices",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "merchants",
                "subscriptions",
                "invoices"
              ]
            },
            "description": "Returns all payment records generated when the merchant subscribed or changed plans.\nOrdered newest first. Each invoice includes the plan name, amount, currency, billing period, and payment status.\n"
          },
          "response": []
        }
      ]
    },
    {
      "name": "17. Merchant - Dashboard & Wallets & Payouts",
      "description": "Merchant balance check, multi-currency wallets, currency swap, payout execution, pricing, exchange rates, and IP whitelisting",
      "item": [
        {
          "name": "Get authenticated merchant details",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/merchants/me",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "merchants",
                "me"
              ]
            },
            "description": "Returns the merchant profile plus a computed `kybStatus` field: \"Not Started\", \"Draft\", \"Submitted\", \"Under Review\", \"Additional Documents Required\", \"Approved\", or \"Rejected\". KYB status updates asynchronously (via webhook, with a 30-minute polling fallback) — it will not necessarily reflect a change the instant the merchant finishes the hosted Didit verification flow."
          },
          "response": []
        },
        {
          "name": "Get aggregated financial stats for the merchant dashboard",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/merchants/stats",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "merchants",
                "stats"
              ]
            },
            "description": "Get aggregated financial stats for the merchant dashboard"
          },
          "response": []
        },
        {
          "name": "List all transactions across all customers for this merchant",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/merchants/transactions",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "merchants",
                "transactions"
              ]
            },
            "description": "List all transactions across all customers for this merchant"
          },
          "response": []
        },
        {
          "name": "List all customers under this merchant",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/merchants/customers",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "merchants",
                "customers"
              ]
            },
            "description": "List all customers under this merchant"
          },
          "response": []
        },
        {
          "name": "Get all IP whitelists for merchant",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/merchants/ip-whitelist",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "merchants",
                "ip-whitelist"
              ]
            },
            "description": "Get all IP whitelists for merchant"
          },
          "response": []
        },
        {
          "name": "Add a new IP to whitelist",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/merchants/ip-whitelist",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "merchants",
                "ip-whitelist"
              ]
            },
            "description": "Add a new IP to whitelist",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"ipAddress\": \"203.0.113.45\",\n  \"description\": \"Remote Developer VPN\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Delete an IP from whitelist",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "DELETE",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/merchants/ip-whitelist/:id",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "merchants",
                "ip-whitelist",
                ":id"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{id}}",
                  "description": "Path variable id"
                }
              ]
            },
            "description": "Delete an IP from whitelist"
          },
          "response": []
        },
        {
          "name": "Initiate a Payout (API Keys or JWT)",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "x-public-key",
                "value": "{{apiKey}}",
                "description": "Optional API Public Key for S2S"
              },
              {
                "key": "x-private-key",
                "value": "{{secretKey}}",
                "description": "Optional API Private Key for S2S"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/merchants/payout",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "merchants",
                "payout"
              ]
            },
            "description": "Pays out from the merchant's own wallet balance. There are exactly two possible responses you should expect from this call — no others:\n1. A confirmed SUCCESS, returned immediately (200).\n2. PENDING (202) — covers everything short of a confirmed success: a timeout, a network error, or even an explicit failure from the provider on this first, single attempt. Money stays debited and no refund happens here. A background job repeatedly reconfirms the real outcome with the provider before anything is ever finalized as failed.\nThis call never returns a \"failed\" outcome synchronously. If a PENDING transaction is later confirmed failed, that only happens asynchronously via the background reconciliation job — check the transaction's status later (e.g. via /transactions/requery or your transaction history) to find out.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"amount\": 1000,\n  \"accountNumber\": \"0123456789\",\n  \"bankCode\": \"90052\",\n  \"accountName\": \"John Doe\",\n  \"narration\": \"Monthly Settlement\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Get service pricings",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "x-public-key",
                "value": "{{apiKey}}",
                "description": "Optional API Public Key for S2S"
              },
              {
                "key": "x-private-key",
                "value": "{{secretKey}}",
                "description": "Optional API Private Key for S2S"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/merchants/pricing",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "merchants",
                "pricing"
              ]
            },
            "description": "Get service pricings"
          },
          "response": []
        },
        {
          "name": "Get exchange rates",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "x-public-key",
                "value": "{{apiKey}}",
                "description": "Optional API Public Key for S2S"
              },
              {
                "key": "x-private-key",
                "value": "{{secretKey}}",
                "description": "Optional API Private Key for S2S"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/merchants/rates",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "merchants",
                "rates"
              ]
            },
            "description": "Returns configured exchange rates. Without `targetCurrency`, returns an array of every rate configured for `baseCurrency` (defaults to NGN). With both `baseCurrency` and `targetCurrency`, returns a single rate object instead of an array. `platformRate` already includes the platform's margin and is what's actually used for swaps — `liveRate` is the raw upstream rate before margin."
          },
          "response": []
        },
        {
          "name": "List the merchant's wallet balances",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "x-public-key",
                "value": "{{apiKey}}",
                "description": "Optional API Public Key for S2S"
              },
              {
                "key": "x-private-key",
                "value": "{{secretKey}}",
                "description": "Optional API Private Key for S2S"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/merchants/wallets",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "merchants",
                "wallets"
              ]
            },
            "description": "Returns the merchant's native NGN balance plus any other currency wallets that have been enabled for merchants by an admin (see `/admin/currencies/{code}/virtual-account-status`). A wallet's `status` is `active` or `inactive` — inactive wallets keep their balance but can't be swapped into or out of."
          },
          "response": []
        },
        {
          "name": "Swap between the merchant's own currency wallets",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "x-public-key",
                "value": "{{apiKey}}",
                "description": "Optional API Public Key for S2S"
              },
              {
                "key": "x-private-key",
                "value": "{{secretKey}}",
                "description": "Optional API Private Key for S2S"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/merchants/wallets/swap",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "merchants",
                "wallets",
                "swap"
              ]
            },
            "description": "`amount` is denominated in `targetCurrency` — e.g. `{ baseCurrency: \"NGN\", targetCurrency: \"USD\", amount: 100 }` converts NGN into exactly 100 USD, debiting the computed NGN cost (at the admin-configured platform rate) from the NGN wallet. Swapping the reverse direction requires the admin to have separately configured that direction's exchange rate — it is not automatically inverted. Both currencies must have `virtualAccountStatus: active` (NGN is always allowed).",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"baseCurrency\": \"NGN\",\n  \"targetCurrency\": \"USD\",\n  \"amount\": 100\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        }
      ]
    },
    {
      "name": "18. Merchant - Webhook Logs",
      "description": "Merchant dashboard incoming and outgoing webhook delivery logs and manual retry/resend options",
      "item": [
        {
          "name": "List outgoing webhook logs",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/merchants/webhooks/outgoing",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "merchants",
                "webhooks",
                "outgoing"
              ]
            },
            "description": "Retrieve a paginated list of webhooks sent from Airpero to the merchant's configured webhook URL."
          },
          "response": []
        },
        {
          "name": "Resend an outgoing webhook",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/merchants/webhooks/outgoing/:id/resend",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "merchants",
                "webhooks",
                "outgoing",
                ":id",
                "resend"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{id}}",
                  "description": "Path variable id"
                }
              ]
            },
            "description": "Manually trigger a redelivery of a previously logged outgoing webhook.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"event\": \"transaction.success\",\n  \"data\": {\n    \"reference\": \"REF123\",\n    \"amount\": 1000\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "List incoming 9PSB webhook logs",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/merchants/webhooks/incoming",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "merchants",
                "webhooks",
                "incoming"
              ]
            },
            "description": "Retrieve a paginated list of raw webhooks received from 9PSB that are associated with the merchant's account or their customers."
          },
          "response": []
        },
        {
          "name": "Retry an incoming webhook",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/merchants/webhooks/incoming/:id/retry",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "merchants",
                "webhooks",
                "incoming",
                ":id",
                "retry"
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{id}}",
                  "description": "Path variable id"
                }
              ]
            },
            "description": "Manually trigger the processing of a raw incoming webhook. \n- If the transaction was already successful, it will only resend the notification to the merchant.\n- If the transaction has not been processed, it will attempt to credit/debit the customer and then notify the merchant.\n",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"event\": \"transaction.success\",\n  \"data\": {\n    \"reference\": \"REF123\",\n    \"amount\": 1000\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        }
      ]
    },
    {
      "name": "19. Customer Management & KYC",
      "description": "Customer creation via Server-to-Server API Keys, balance queries, financial reports, customer payouts, debits/credits, BVN verification, and ID verification",
      "item": [
        {
          "name": "Create a new Customer + Virtual Account (API Keys ONLY)",
          "request": {
            "auth": {
              "type": "apikey",
              "apikey": [
                {
                  "key": "key",
                  "value": "x-public-key",
                  "type": "string"
                },
                {
                  "key": "value",
                  "value": "{{apiKey}}",
                  "type": "string"
                },
                {
                  "key": "in",
                  "value": "header",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "x-public-key",
                "value": "{{apiKey}}",
                "description": "Merchant Public Key"
              },
              {
                "key": "x-private-key",
                "value": "{{secretKey}}",
                "description": "Merchant Private Key"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/customers",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "customers"
              ]
            },
            "description": "Create a new Customer + Virtual Account (API Keys ONLY)",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"fullName\": \"sample_fullName\",\n  \"email\": \"sample_email\",\n  \"phoneNumber\": \"sample_phoneNumber\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Get full customer details",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/customers/:customerId",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "customers",
                ":customerId"
              ],
              "variable": [
                {
                  "key": "customerId",
                  "value": "{{customerId}}",
                  "description": "Path variable customerId"
                }
              ]
            },
            "description": "Get full customer details"
          },
          "response": []
        },
        {
          "name": "Get customer balances",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/customers/:customerId/balance",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "customers",
                ":customerId",
                "balance"
              ],
              "variable": [
                {
                  "key": "customerId",
                  "value": "{{customerId}}",
                  "description": "Path variable customerId"
                }
              ]
            },
            "description": "Get customer balances"
          },
          "response": []
        },
        {
          "name": "Get customer transaction summary & analytics",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/customers/:customerId/report",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "customers",
                ":customerId",
                "report"
              ],
              "variable": [
                {
                  "key": "customerId",
                  "value": "{{customerId}}",
                  "description": "Path variable customerId"
                }
              ]
            },
            "description": "Get customer transaction summary & analytics"
          },
          "response": []
        },
        {
          "name": "Get granular transaction history for a customer",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/customers/:customerId/transactions",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "customers",
                ":customerId",
                "transactions"
              ],
              "variable": [
                {
                  "key": "customerId",
                  "value": "{{customerId}}",
                  "description": "Path variable customerId"
                }
              ]
            },
            "description": "Get granular transaction history for a customer"
          },
          "response": []
        },
        {
          "name": "Initiate a Payout for a Customer (Moves funds from Customer Balance)",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/customers/:customerId/payout",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "customers",
                ":customerId",
                "payout"
              ],
              "variable": [
                {
                  "key": "customerId",
                  "value": "{{customerId}}",
                  "description": "Path variable customerId"
                }
              ]
            },
            "description": "Pays out from the specified customer's balance. There are exactly two possible responses you should expect from this call — no others:\n1. A confirmed SUCCESS, returned immediately (200).\n2. PENDING (202) — covers everything short of a confirmed success: a timeout, a network error, or even an explicit failure from the provider on this first, single attempt. Money stays debited and no refund happens here. A background job repeatedly reconfirms the real outcome with the provider before anything is ever finalized as failed.\nThis call never returns a \"failed\" outcome synchronously. If a PENDING transaction is later confirmed failed, that only happens asynchronously via the background reconciliation job — check the transaction's status later (e.g. via /transactions/requery or your transaction history) to find out.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"amount\": 2000,\n  \"bankCode\": \"90052\",\n  \"accountNumber\": \"0123456789\",\n  \"narration\": \"Payment for services\",\n  \"accountName\": \"John Doe\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Manually debit a customer's balance (Moves funds to Merchant Wallet)",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/customers/:customerId/debit",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "customers",
                ":customerId",
                "debit"
              ],
              "variable": [
                {
                  "key": "customerId",
                  "value": "{{customerId}}",
                  "description": "Path variable customerId"
                }
              ]
            },
            "description": "Manually debit a customer's balance (Moves funds to Merchant Wallet)",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"amount\": 500,\n  \"serviceId\": \"s1s2s3s4-s5s6-s7s8-s9s0-s1s2s3s4s5s6\",\n  \"reason\": \"sample_reason\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Directly credit a customer's balance from the Merchant Wallet",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/customers/:customerId/credit",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "customers",
                ":customerId",
                "credit"
              ],
              "variable": [
                {
                  "key": "customerId",
                  "value": "{{customerId}}",
                  "description": "Path variable customerId"
                }
              ]
            },
            "description": "Directly credit a customer's balance from the Merchant Wallet",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"amount\": 2000,\n  \"serviceId\": \"sample_serviceId\",\n  \"narration\": \"sample_narration\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Verify customer BVN (Stage 1 KYC)",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/customers/:customerId/kyc/bvn",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "customers",
                ":customerId",
                "kyc",
                "bvn"
              ],
              "variable": [
                {
                  "key": "customerId",
                  "value": "{{customerId}}",
                  "description": "Path variable customerId"
                }
              ]
            },
            "description": "Verify customer BVN (Stage 1 KYC)",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"bvn\": \"22222222222\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Verify customer ID (Stage 2 KYC)",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/customers/:customerId/kyc/id",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "customers",
                ":customerId",
                "kyc",
                "id"
              ],
              "variable": [
                {
                  "key": "customerId",
                  "value": "{{customerId}}",
                  "description": "Path variable customerId"
                }
              ]
            },
            "description": "Verify customer ID (Stage 2 KYC)",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"idType\": \"NIN\",\n  \"idValue\": \"12345678901\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        }
      ]
    },
    {
      "name": "20. Customer Virtual Cards",
      "description": "Customer card creation, Payscribe identity registration, card listing, top-up, withdrawal, freeze, unfreeze, and termination",
      "item": [
        {
          "name": "Register customer for card issuance",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/customers/:customerId/cards/register",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "customers",
                ":customerId",
                "cards",
                "register"
              ],
              "variable": [
                {
                  "key": "customerId",
                  "value": "{{customerId}}",
                  "description": "Path variable customerId"
                }
              ]
            },
            "description": "Register customer for card issuance",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"bvn\": \"22222222222\",\n  \"dateOfBirth\": \"1990-05-15\",\n  \"address\": \"123 Main Street, Lagos\",\n  \"selfieUrl\": \"https://example.com/selfie.jpg\",\n  \"idDocument\": \"https://example.com/id.jpg\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Create a new virtual card",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/customers/:customerId/cards",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "customers",
                ":customerId",
                "cards"
              ],
              "variable": [
                {
                  "key": "customerId",
                  "value": "{{customerId}}",
                  "description": "Path variable customerId"
                }
              ]
            },
            "description": "Creates a new USD virtual card for a customer. Customer must already be\nregistered on PayScribe via the `/cards/register` endpoint first.\nFunds are deducted from the customer's USD service balance.\n",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"amount\": 10,\n  \"brand\": \"mastercard\",\n  \"currency\": \"USD\",\n  \"dob\": \"1990-01-01\",\n  \"address\": \"123 Main Street, Lagos\",\n  \"selfieUrl\": \"https://example.com/selfie.jpg\",\n  \"idDocument\": \"https://example.com/id.jpg\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Get all cards for a customer",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/customers/:customerId/cards",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "customers",
                ":customerId",
                "cards"
              ],
              "variable": [
                {
                  "key": "customerId",
                  "value": "{{customerId}}",
                  "description": "Path variable customerId"
                }
              ]
            },
            "description": "Returns all virtual cards for a customer (CVV excluded). \nMerchant can only view cards belonging to their own customers.\nA customer can have multiple cards.\n"
          },
          "response": []
        },
        {
          "name": "Top up a virtual card",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/customers/:customerId/cards/:cardId/topup",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "customers",
                ":customerId",
                "cards",
                ":cardId",
                "topup"
              ],
              "variable": [
                {
                  "key": "customerId",
                  "value": "{{customerId}}",
                  "description": "Path variable customerId"
                },
                {
                  "key": "cardId",
                  "value": "{{cardId}}",
                  "description": "Path variable cardId"
                }
              ]
            },
            "description": "Top up a virtual card",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"amount\": 50\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Withdraw from a virtual card",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/customers/:customerId/cards/:cardId/withdraw",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "customers",
                ":customerId",
                "cards",
                ":cardId",
                "withdraw"
              ],
              "variable": [
                {
                  "key": "customerId",
                  "value": "{{customerId}}",
                  "description": "Path variable customerId"
                },
                {
                  "key": "cardId",
                  "value": "{{cardId}}",
                  "description": "Path variable cardId"
                }
              ]
            },
            "description": "Withdraw from a virtual card",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"amount\": 20\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Freeze a virtual card",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/customers/:customerId/cards/:cardId/freeze",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "customers",
                ":customerId",
                "cards",
                ":cardId",
                "freeze"
              ],
              "variable": [
                {
                  "key": "customerId",
                  "value": "{{customerId}}",
                  "description": "Path variable customerId"
                },
                {
                  "key": "cardId",
                  "value": "{{cardId}}",
                  "description": "Path variable cardId"
                }
              ]
            },
            "description": "Freeze a virtual card",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"status\": \"active\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Unfreeze a virtual card",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/customers/:customerId/cards/:cardId/unfreeze",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "customers",
                ":customerId",
                "cards",
                ":cardId",
                "unfreeze"
              ],
              "variable": [
                {
                  "key": "customerId",
                  "value": "{{customerId}}",
                  "description": "Path variable customerId"
                },
                {
                  "key": "cardId",
                  "value": "{{cardId}}",
                  "description": "Path variable cardId"
                }
              ]
            },
            "description": "Unfreeze a virtual card",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"status\": \"active\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Terminate a virtual card",
          "request": {
            "auth": {
              "type": "bearer",
              "bearer": [
                {
                  "key": "token",
                  "value": "{{merchantToken}}",
                  "type": "string"
                }
              ]
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/customers/:customerId/cards/:cardId/terminate",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "customers",
                ":customerId",
                "cards",
                ":cardId",
                "terminate"
              ],
              "variable": [
                {
                  "key": "customerId",
                  "value": "{{customerId}}",
                  "description": "Path variable customerId"
                },
                {
                  "key": "cardId",
                  "value": "{{cardId}}",
                  "description": "Path variable cardId"
                }
              ]
            },
            "description": "Permanently terminates a virtual card. Remaining balance is refunded\nto the customer's USD service account.\n\n**Note:** Merchants cannot update card balances (topup/withdraw). Those operations\nare restricted to server-to-server API key access only.\n",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"status\": \"active\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        }
      ]
    },
    {
      "name": "21. Banks & Transaction Requery",
      "description": "Supported bank listing, account resolution/name enquiry, and transaction status requery tools",
      "item": [
        {
          "name": "List all supported Nigerian Banks",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/banks",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "banks"
              ]
            },
            "description": "List all supported Nigerian Banks"
          },
          "response": []
        },
        {
          "name": "Account Name Enquiry",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/banks/enquiry",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "banks",
                "enquiry"
              ]
            },
            "description": "Account Name Enquiry",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"accountNumber\": \"sample_accountNumber\",\n  \"bankCode\": \"sample_bankCode\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Re-query a transaction status",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/transactions/requery",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "transactions",
                "requery"
              ]
            },
            "description": "Re-query a transaction status",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"transactionId\": \"sample_transactionId\",\n  \"accountNo\": \"sample_accountNo\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        }
      ]
    },
    {
      "name": "22. Inbound Provider Webhooks",
      "description": "Callback webhooks for payment gateway (9PSB), card provider (Payscribe), and identity verifier (Didit)",
      "item": [
        {
          "name": "Webhook receiver for 9PSB",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/webhooks/9psb",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "webhooks",
                "9psb"
              ]
            },
            "description": "Endpoint for receiving webhook callbacks from 9PSB for virtual account transactions.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"transaction\": \"sample_transaction\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "Webhook receiver for Payscribe",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/webhooks/payscribe",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "webhooks",
                "payscribe"
              ]
            },
            "description": "Endpoint for receiving webhook callbacks from Payscribe for virtual card operations.",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"event\": \"card.transaction.success\",\n  \"data\": \"sample_data\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        },
        {
          "name": "POST /api/v1/webhooks/didit",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/webhooks/didit",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "webhooks",
                "didit"
              ]
            },
            "description": "POST /api/v1/webhooks/didit",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"event\": \"transaction.success\",\n  \"data\": {\n    \"reference\": \"REF123\",\n    \"amount\": 1000\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "response": []
        }
      ]
    }
  ],
  "variable": [
    {
      "key": "baseUrl",
      "value": "http://localhost:8200",
      "type": "string",
      "description": "Base API host URL"
    },
    {
      "key": "adminToken",
      "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
      "type": "string",
      "description": "JWT Token for Admin / SuperAdmin requests"
    },
    {
      "key": "merchantToken",
      "value": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
      "type": "string",
      "description": "JWT Token for Merchant Dashboard requests"
    },
    {
      "key": "apiKey",
      "value": "pk_live_airpero_sample_public_key",
      "type": "string",
      "description": "Merchant Public Key for S2S API authentication (x-public-key)"
    },
    {
      "key": "secretKey",
      "value": "sk_live_airpero_sample_private_key",
      "type": "string",
      "description": "Merchant Private Key for S2S API authentication (x-private-key)"
    },
    {
      "key": "merchantId",
      "value": "1",
      "type": "string",
      "description": "Sample Merchant ID parameter"
    },
    {
      "key": "customerId",
      "value": "1",
      "type": "string",
      "description": "Sample Customer ID parameter"
    },
    {
      "key": "cardId",
      "value": "1",
      "type": "string",
      "description": "Sample Card ID parameter"
    },
    {
      "key": "serviceId",
      "value": "1",
      "type": "string",
      "description": "Sample Service ID parameter"
    },
    {
      "key": "stageId",
      "value": "1",
      "type": "string",
      "description": "Sample KYC Stage ID parameter"
    },
    {
      "key": "id",
      "value": "1",
      "type": "string",
      "description": "Generic entity ID parameter"
    }
  ]
}