{
  "openapi": "3.0.3",
  "info": {
    "title": "RushPay Core API",
    "version": "2.1.0",
    "description": "RushPay Core v2 is a JSON REST API for merchant checkout, wallet payments, mobile money, card funding, gift cards, settlements, and signed webhooks. Merchant server routes authenticate with the X-API-Key header. Browser checkout uses a short-lived X-RushPay-Widget-Session token scoped to a single payment_reference. Dashboard routes use a Bearer access token.",
    "contact": {
      "name": "RushPay Developer Support",
      "url": "https://core.rushpay.cash/api-docs"
    }
  },
  "servers": [
    {
      "url": "https://core.rushpay.cash",
      "description": "Production"
    }
  ],
  "tags": [
    { "name": "Merchant Applications", "description": "Create and manage API applications (Bearer auth)." },
    { "name": "Merchant Payments", "description": "Create checkouts, issue widget sessions, and verify payments." },
    { "name": "Wallet & Platform", "description": "Deposits, transfers, withdrawals, and transaction history." }
  ],
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "Merchant API key. Server-side only; never expose in the browser."
      },
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Access token from POST /api/v1/auth/login. Used for dashboard routes."
      },
      "WidgetSession": {
        "type": "apiKey",
        "in": "header",
        "name": "X-RushPay-Widget-Session",
        "description": "Short-lived widget session token scoped to one payment_reference."
      }
    },
    "schemas": {
      "SuccessEnvelope": {
        "type": "object",
        "properties": {
          "success": { "type": "boolean", "example": true },
          "data": { "type": "object", "additionalProperties": true }
        },
        "required": ["success"]
      },
      "ErrorEnvelope": {
        "type": "object",
        "properties": {
          "success": { "type": "boolean", "example": false },
          "message": { "type": "string", "example": "Human-readable explanation" },
          "code": { "type": "string", "example": "validation_error" }
        },
        "required": ["success", "message"]
      },
      "PaymentCreateRequest": {
        "type": "object",
        "required": ["amount"],
        "properties": {
          "amount": { "type": "string", "description": "Amount in GHS major units.", "example": "149.99" },
          "description": { "type": "string", "example": "Order #1042" },
          "callback_url": { "type": "string", "format": "uri", "example": "https://store.example/webhooks/rushpay" },
          "metadata": { "type": "object", "additionalProperties": true, "example": { "order_id": "1042", "customer_email": "ama@example.com" } }
        }
      },
      "WidgetSessionRequest": {
        "type": "object",
        "required": ["payment_reference"],
        "properties": {
          "payment_reference": { "type": "string", "example": "API1710000000000000123456" }
        }
      },
      "UpdateMerchantRequest": {
        "type": "object",
        "required": ["payment_reference"],
        "properties": {
          "payment_reference": { "type": "string", "example": "API1710000000000000123456" },
          "description": { "type": "string", "example": "Order #1042 - paid checkout" },
          "metadata": { "type": "object", "additionalProperties": true, "example": { "order_id": "1042", "platform": "woocommerce" } }
        }
      },
      "ApplicationCreateRequest": {
        "type": "object",
        "required": ["name"],
        "properties": {
          "name": { "type": "string", "example": "My Store" },
          "description": { "type": "string", "example": "Production checkout" },
          "webhook_url": { "type": "string", "format": "uri", "example": "https://store.example/webhooks/rushpay" }
        }
      },
      "ApplicationRevokeRequest": {
        "type": "object",
        "required": ["public_id"],
        "properties": {
          "public_id": { "type": "string", "example": "app_xxxxxxxx" }
        }
      }
    },
    "responses": {
      "Success": {
        "description": "Successful response.",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SuccessEnvelope" } } }
      },
      "BadRequest": {
        "description": "Validation error.",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorEnvelope" } } }
      },
      "Unauthorized": {
        "description": "Missing or invalid credentials.",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorEnvelope" } } }
      }
    }
  },
  "security": [{ "ApiKeyAuth": [] }],
  "paths": {
    "/api/v1/merchant/applications": {
      "post": {
        "tags": ["Merchant Applications"],
        "summary": "Create an API application",
        "description": "Create an API application. The response shows api_key, api_secret, and webhook_secret once.",
        "security": [{ "BearerAuth": [] }],
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApplicationCreateRequest" } } }
        },
        "responses": {
          "200": { "$ref": "#/components/responses/Success" },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      },
      "get": {
        "tags": ["Merchant Applications"],
        "summary": "List API applications",
        "description": "List your API applications. Secrets are not returned again.",
        "security": [{ "BearerAuth": [] }],
        "responses": {
          "200": { "$ref": "#/components/responses/Success" },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    },
    "/api/v1/merchant/applications/revoke": {
      "post": {
        "tags": ["Merchant Applications"],
        "summary": "Revoke an API application",
        "description": "Deactivate an API application by public_id.",
        "security": [{ "BearerAuth": [] }],
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApplicationRevokeRequest" } } }
        },
        "responses": {
          "200": { "$ref": "#/components/responses/Success" },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    },
    "/api/v1/merchant/payments/create": {
      "post": {
        "tags": ["Merchant Payments"],
        "summary": "Create a checkout",
        "description": "Create a pending merchant checkout. Amount is in GHS major units as a string or number.",
        "security": [{ "ApiKeyAuth": [] }],
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PaymentCreateRequest" } } }
        },
        "responses": {
          "200": { "$ref": "#/components/responses/Success" },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    },
    "/api/v1/merchant/payments/widget-session": {
      "post": {
        "tags": ["Merchant Payments"],
        "summary": "Create a widget session",
        "description": "Issue a short-lived widget_session_token for embedded checkout. Send only this token to the browser.",
        "security": [{ "ApiKeyAuth": [] }],
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "$ref": "#/components/schemas/WidgetSessionRequest" } } }
        },
        "responses": {
          "200": { "$ref": "#/components/responses/Success" },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    },
    "/api/v1/merchant/payments/update-merchant": {
      "post": {
        "tags": ["Merchant Payments"],
        "summary": "Update merchant metadata",
        "description": "Merge merchant metadata and/or update description after payment creation. Useful for legacy checkout flows.",
        "security": [{ "ApiKeyAuth": [] }],
        "requestBody": {
          "required": true,
          "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateMerchantRequest" } } }
        },
        "responses": {
          "200": { "$ref": "#/components/responses/Success" },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    },
    "/api/v1/merchant/payments/status": {
      "get": {
        "tags": ["Merchant Payments"],
        "summary": "Get payment status",
        "description": "Poll payment status. Server checks use X-API-Key; widget checks can use X-RushPay-Widget-Session.",
        "security": [{ "ApiKeyAuth": [] }, { "WidgetSession": [] }],
        "parameters": [
          {
            "name": "payment_reference",
            "in": "query",
            "required": true,
            "schema": { "type": "string" },
            "example": "API1710000000000000123456"
          }
        ],
        "responses": {
          "200": { "$ref": "#/components/responses/Success" },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    },
    "/api/v1/merchant/payments/widget-context": {
      "get": {
        "tags": ["Merchant Payments"],
        "summary": "Get widget context",
        "description": "Return checkout amount, description, status, and funding fee data for the widget.",
        "security": [{ "WidgetSession": [] }],
        "responses": {
          "200": { "$ref": "#/components/responses/Success" },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    },
    "/api/v1/merchant/payments/pay": {
      "post": {
        "tags": ["Merchant Payments"],
        "summary": "Complete a wallet payment",
        "description": "Complete a wallet payment with email/account password or Bearer auth plus PIN. Optional giftcard_code can cover part of the amount.",
        "security": [{ "WidgetSession": [] }],
        "responses": {
          "200": { "$ref": "#/components/responses/Success" },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    },
    "/api/v1/merchant/payments/initiate-mobile-money": {
      "post": {
        "tags": ["Merchant Payments"],
        "summary": "Initiate mobile money funding",
        "description": "Start guest mobile money funding for the checkout.",
        "security": [{ "WidgetSession": [] }],
        "responses": {
          "200": { "$ref": "#/components/responses/Success" },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    },
    "/api/v1/merchant/payments/initiate-card": {
      "post": {
        "tags": ["Merchant Payments"],
        "summary": "Initiate card funding",
        "description": "Start guest card funding through Paystack inline.",
        "security": [{ "WidgetSession": [] }],
        "responses": {
          "200": { "$ref": "#/components/responses/Success" },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    },
    "/api/v1/merchant/payments/submit-momo-otp": {
      "post": {
        "tags": ["Merchant Payments"],
        "summary": "Submit mobile money OTP",
        "description": "Submit provider OTP when mobile money requires it.",
        "security": [{ "WidgetSession": [] }],
        "responses": {
          "200": { "$ref": "#/components/responses/Success" },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    },
    "/api/v1/merchant/payments/validate-giftcard": {
      "post": {
        "tags": ["Merchant Payments"],
        "summary": "Validate a gift card",
        "description": "Check whether an RRC gift card can cover a merchant checkout.",
        "security": [{ "WidgetSession": [] }],
        "responses": {
          "200": { "$ref": "#/components/responses/Success" },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    },
    "/api/v1/merchant/payments/process-giftcard": {
      "post": {
        "tags": ["Merchant Payments"],
        "summary": "Process a gift card payment",
        "description": "Complete checkout fully with a gift card when the card balance covers the order.",
        "security": [{ "WidgetSession": [] }],
        "responses": {
          "200": { "$ref": "#/components/responses/Success" },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    },
    "/api/v1/merchant/balance": {
      "get": {
        "tags": ["Wallet & Platform"],
        "summary": "Get merchant balance",
        "description": "Return merchant wallet balance for the API application owner.",
        "security": [{ "ApiKeyAuth": [] }],
        "responses": {
          "200": { "$ref": "#/components/responses/Success" },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    },
    "/api/v1/merchant/transactions": {
      "get": {
        "tags": ["Wallet & Platform"],
        "summary": "List merchant transactions",
        "description": "Return merchant-scoped transaction history.",
        "security": [{ "ApiKeyAuth": [] }],
        "responses": {
          "200": { "$ref": "#/components/responses/Success" },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    },
    "/api/v1/deposits/initiate": {
      "post": {
        "tags": ["Wallet & Platform"],
        "summary": "Initiate a deposit",
        "description": "Start a Paystack deposit by mobile money or card.",
        "security": [{ "BearerAuth": [] }],
        "responses": {
          "200": { "$ref": "#/components/responses/Success" },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    },
    "/api/v1/transfers": {
      "post": {
        "tags": ["Wallet & Platform"],
        "summary": "Create a wallet transfer",
        "description": "Send a wallet transfer to another RushPay user. Requires Bearer auth plus PIN.",
        "security": [{ "BearerAuth": [] }],
        "responses": {
          "200": { "$ref": "#/components/responses/Success" },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    },
    "/api/v1/withdrawals/initiate": {
      "post": {
        "tags": ["Wallet & Platform"],
        "summary": "Initiate a withdrawal",
        "description": "Withdraw to bank or mobile money. Requires Bearer auth plus PIN.",
        "security": [{ "BearerAuth": [] }],
        "responses": {
          "200": { "$ref": "#/components/responses/Success" },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    },
    "/api/v1/transactions": {
      "get": {
        "tags": ["Wallet & Platform"],
        "summary": "List user transactions",
        "description": "List authenticated user transaction history.",
        "security": [{ "BearerAuth": [] }],
        "responses": {
          "200": { "$ref": "#/components/responses/Success" },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    }
  }
}
