{
    "openapi": "3.1.0",
    "jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
    "info": {
        "title": "FahiPay Wallet API",
        "version": "2027-07-01",
        "description": "Wallet balances, limits, usage, and transaction history for personal FahiPay accounts. Authenticate using X-API-Key from https://fahipay.mv/dev/. Amounts are in MVR. GET /balance returns success and a data array; GET /usage returns success and data. GET /transactions returns success, data, and pagination; use limit (default 10, maximum 100) and before to paginate.\n\nMissing an API feature? Email info@fahipay.mv with what you are building and the feature you need."
    },
    "servers": [
        {
            "url": "https://api.fahipay.mv/wallet",
            "description": "FahiPay Wallet API"
        }
    ],
    "tags": [
        {
            "name": "Wallet",
            "description": "Wallet balances, limits, usage, and transaction history for personal accounts. Authenticate using X-API-Key from https://fahipay.mv/dev/. Monetary values are in MVR."
        }
    ],
    "security": [
        {
            "WalletApiKey": []
        }
    ],
    "paths": {
        "/balance": {
            "get": {
                "tags": [
                    "Wallet"
                ],
                "summary": "Get wallet balance",
                "operationId": "getWalletBalance",
                "description": "Retrieve wallet balances for your personal account. The response contains success: true and a data array of account balance records. Amounts are in MVR: 359.49 means MVR 359.49. Preserve account_number as a string.",
                "security": [
                    {
                        "WalletApiKey": []
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Wallet balance records.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "success",
                                        "data"
                                    ],
                                    "properties": {
                                        "success": {
                                            "type": "boolean",
                                            "const": true
                                        },
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/WalletBalance"
                                            }
                                        }
                                    }
                                },
                                "example": {
                                    "success": true,
                                    "data": [
                                        {
                                            "account_number": "123456789012",
                                            "currency": "MVR",
                                            "ledger_balance": 1500.5,
                                            "available_balance": 1500.5,
                                            "hold_balance": 0
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/usage": {
            "get": {
                "tags": [
                    "Wallet"
                ],
                "summary": "Get limits and usage",
                "operationId": "getWalletUsage",
                "description": "Retrieve your account tier, per-transaction limit, daily, weekly, and monthly limits, current usage, remaining allowance, and reset times. Amounts are in MVR. Use reset_at for the next reset in each period; the sample dates and limits illustrate one account and are not universal limits. These wallet limits are separate from the limits approved on a customer authorization.",
                "security": [
                    {
                        "WalletApiKey": []
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Account tier, limits, usage, remaining allowance, and reset times.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/WalletUsage"
                                },
                                "example": {
                                    "success": true,
                                    "data": {
                                        "tier": "basic",
                                        "limits": {
                                            "per_transaction": 11500,
                                            "daily": 30500,
                                            "weekly": 77000,
                                            "monthly": 231500
                                        },
                                        "usage": {
                                            "daily": 0,
                                            "weekly": 1565.92,
                                            "monthly": 11830.67
                                        },
                                        "remaining": {
                                            "per_transaction": 11500,
                                            "daily": 30500,
                                            "weekly": 75434.08,
                                            "monthly": 219669.33
                                        },
                                        "reset_at": {
                                            "daily": "2026-09-11T00:00:00+05:00",
                                            "weekly": "2026-09-13T00:00:00+05:00",
                                            "monthly": "2026-10-01T00:00:00+05:00"
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        },
        "/transactions": {
            "get": {
                "tags": [
                    "Wallet"
                ],
                "summary": "List transactions",
                "operationId": "listWalletTransactions",
                "description": "Retrieve successful and failed transactions for your personal wallet, ordered from most recently recorded to oldest. Amounts are signed JSON numbers in MVR. A successful API request can include failed transactions; check each record's status.\n\nUse limit to choose a page size from 1 to 100 (default 10). The response example shows the default page size of 10. To retrieve the next page, pass pagination.next_cursor as before. The cursor transaction is excluded from the next page. Stop when pagination.has_more is false; the final page may contain fewer records or be empty.\n\nAn invalid or unavailable cursor returns HTTP 400 with invalid_pagination. Use the cursor returned by the API; if it is no longer accepted, restart without before. Omit before to refresh the latest transactions. Page numbers, offsets, and total record counts are not supported.",
                "security": [
                    {
                        "WalletApiKey": []
                    }
                ],
                "parameters": [
                    {
                        "name": "limit",
                        "in": "query",
                        "required": false,
                        "description": "Number of records per page, from 1 to 100. Defaults to 10. Use whole numbers without leading zeroes.",
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 100,
                            "default": 10
                        }
                    },
                    {
                        "name": "before",
                        "in": "query",
                        "required": false,
                        "description": "The pagination.next_cursor returned by the previous response. Omit for the first page. The cursor transaction is excluded from the next page.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Paginated transaction history. All example transaction references, dates, merchant names, bill details, and amounts are fictional.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/WalletTransactionsResponse"
                                },
                                "examples": {
                                    "transactions": {
                                        "summary": "Default page of 10 fictional transactions",
                                        "value": {
                                            "success": true,
                                            "data": [
                                                {
                                                    "tid": "FP20260110120000DEMO",
                                                    "time": "2026-01-10T12:00:00+05:00",
                                                    "type": "payment",
                                                    "name": "Example Store",
                                                    "details": "Example order DEMO-001",
                                                    "amount": -25,
                                                    "status": "success"
                                                },
                                                {
                                                    "tid": "FP20260109120000DEMO",
                                                    "time": "2026-01-09T12:00:00+05:00",
                                                    "type": "payment",
                                                    "name": "Mobile bill payment",
                                                    "details": "Example bill DEMO-002",
                                                    "amount": -249.5,
                                                    "status": "success"
                                                },
                                                {
                                                    "tid": "FP20260108120000DEMO",
                                                    "time": "2026-01-08T12:00:00+05:00",
                                                    "type": "payment",
                                                    "name": "Internet bill payment",
                                                    "details": "Example bill DEMO-003",
                                                    "amount": -100,
                                                    "status": "success"
                                                },
                                                {
                                                    "tid": "FP20260107120000DEMO",
                                                    "time": "2026-01-07T12:00:00+05:00",
                                                    "type": "payment",
                                                    "name": "Mobile bill payment",
                                                    "details": "Example bill DEMO-004",
                                                    "amount": -50,
                                                    "status": "success"
                                                },
                                                {
                                                    "tid": "FP20260106120000DEMO",
                                                    "time": "2026-01-06T12:00:00+05:00",
                                                    "type": "payment",
                                                    "name": "Utility bill payment",
                                                    "details": "Example bill DEMO-005",
                                                    "amount": -75.25,
                                                    "status": "success"
                                                },
                                                {
                                                    "tid": "FP20260105120000DEMO",
                                                    "time": "2026-01-05T12:00:00+05:00",
                                                    "type": "payment",
                                                    "name": "Internet bill payment",
                                                    "details": "Example bill DEMO-006",
                                                    "amount": -150,
                                                    "status": "success"
                                                },
                                                {
                                                    "tid": "FP20260104120000DEMO",
                                                    "time": "2026-01-04T12:00:00+05:00",
                                                    "type": "payment",
                                                    "name": "Water bill payment",
                                                    "details": "Example bill DEMO-007",
                                                    "amount": -200,
                                                    "status": "success"
                                                },
                                                {
                                                    "tid": "FP20260103120000DEMO",
                                                    "time": "2026-01-03T12:00:00+05:00",
                                                    "type": "payment",
                                                    "name": "Electricity bill payment",
                                                    "details": "Example bill DEMO-008",
                                                    "amount": -125,
                                                    "status": "success"
                                                },
                                                {
                                                    "tid": "FP20260102120000DEMO",
                                                    "time": "2026-01-02T12:00:00+05:00",
                                                    "type": "payment",
                                                    "name": "Council bill payment",
                                                    "details": "Example bill DEMO-009",
                                                    "amount": -60,
                                                    "status": "success"
                                                },
                                                {
                                                    "tid": "FP20260101120000DEMO",
                                                    "time": "2026-01-01T12:00:00+05:00",
                                                    "type": "payment",
                                                    "name": "Mobile bill payment",
                                                    "details": "Example bill DEMO-010",
                                                    "amount": -300,
                                                    "status": "success"
                                                }
                                            ],
                                            "pagination": {
                                                "limit": 10,
                                                "has_more": true,
                                                "next_cursor": "FP20260101120000DEMO"
                                            }
                                        }
                                    },
                                    "lastPage": {
                                        "summary": "Empty final page",
                                        "value": {
                                            "success": true,
                                            "data": [],
                                            "pagination": {
                                                "limit": 10,
                                                "has_more": false,
                                                "next_cursor": null
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "Invalid page size or cursor. Use limit from 1 to 100 and a cursor returned by the API. If a cursor is no longer accepted, restart without before.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/WalletErrorResponse"
                                },
                                "example": {
                                    "success": false,
                                    "error": {
                                        "code": "invalid_pagination",
                                        "message": "Invalid page size or cursor."
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Authentication failed. Check your Wallet API key from FahiPay Developers.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/WalletErrorResponse"
                                },
                                "example": {
                                    "success": false,
                                    "error": {
                                        "code": "unauthorized",
                                        "message": "You are not logged in."
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "The endpoint was not found. Check the request URL.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/WalletErrorResponse"
                                },
                                "example": {
                                    "success": false,
                                    "error": {
                                        "code": "not_found",
                                        "message": "Endpoint not found."
                                    }
                                }
                            }
                        }
                    },
                    "405": {
                        "description": "Only GET requests are supported. Check the Allow response header.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/WalletErrorResponse"
                                },
                                "example": {
                                    "success": false,
                                    "error": {
                                        "code": "method_not_allowed",
                                        "message": "Method not allowed."
                                    }
                                }
                            }
                        },
                        "headers": {
                            "Allow": {
                                "schema": {
                                    "type": "string"
                                },
                                "example": "GET"
                            }
                        }
                    },
                    "429": {
                        "description": "Too many requests or a temporary access restriction. Your account can make 60 requests per 60-second window shared across wallet endpoints. Wait before retrying and follow Retry-After when present.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/WalletErrorResponse"
                                },
                                "example": {
                                    "success": false,
                                    "error": {
                                        "code": "rate_limited",
                                        "message": "Too many requests."
                                    }
                                }
                            }
                        },
                        "headers": {
                            "Retry-After": {
                                "description": "When present, the number of seconds to wait before retrying. Temporary access restrictions may omit it.",
                                "schema": {
                                    "type": "integer",
                                    "minimum": 0
                                },
                                "example": 20
                            }
                        }
                    },
                    "500": {
                        "description": "The request could not be completed. Retry with a delay; contact support if it persists.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/WalletErrorResponse"
                                },
                                "example": {
                                    "success": false,
                                    "error": {
                                        "code": "internal_error",
                                        "message": "An unexpected error occurred."
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    },
    "components": {
        "securitySchemes": {
            "WalletApiKey": {
                "type": "apiKey",
                "in": "header",
                "name": "X-API-Key",
                "description": "Wallet API key from https://fahipay.mv/dev/, for personal accounts. Enter the key without a prefix. Keep it on your server. This scheme applies to Wallet endpoints; merchant endpoints use merchant credentials."
            }
        },
        "schemas": {
            "WalletBalance": {
                "type": "object",
                "properties": {
                    "account_number": {
                        "type": "string",
                        "description": "Account number. Preserve it as a string, including any leading zeroes.",
                        "example": "500080001000"
                    },
                    "currency": {
                        "type": "string",
                        "description": "Currency of the balance amounts.",
                        "example": "MVR"
                    },
                    "ledger_balance": {
                        "type": "number",
                        "description": "Ledger balance. Expressed in MVR, including decimal amounts."
                    },
                    "available_balance": {
                        "type": "number",
                        "description": "Balance available to use. Expressed in MVR, including decimal amounts."
                    },
                    "hold_balance": {
                        "type": "number",
                        "description": "Balance currently on hold. Expressed in MVR, including decimal amounts."
                    }
                }
            },
            "WalletUsage": {
                "type": "object",
                "properties": {
                    "success": {
                        "type": "boolean",
                        "description": "Whether the request succeeded."
                    },
                    "data": {
                        "type": "object",
                        "properties": {
                            "tier": {
                                "type": "string",
                                "description": "The account tier.",
                                "example": "basic"
                            },
                            "limits": {
                                "type": "object",
                                "properties": {
                                    "per_transaction": {
                                        "type": "number",
                                        "description": "Applicable limit (per transaction). Expressed in MVR, including decimal amounts."
                                    },
                                    "daily": {
                                        "type": "number",
                                        "description": "Applicable limit (daily). Expressed in MVR, including decimal amounts."
                                    },
                                    "weekly": {
                                        "type": "number",
                                        "description": "Applicable limit (weekly). Expressed in MVR, including decimal amounts."
                                    },
                                    "monthly": {
                                        "type": "number",
                                        "description": "Applicable limit (monthly). Expressed in MVR, including decimal amounts."
                                    }
                                }
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "daily": {
                                        "type": "number",
                                        "description": "Amount used in the current period (daily). Expressed in MVR, including decimal amounts."
                                    },
                                    "weekly": {
                                        "type": "number",
                                        "description": "Amount used in the current period (weekly). Expressed in MVR, including decimal amounts."
                                    },
                                    "monthly": {
                                        "type": "number",
                                        "description": "Amount used in the current period (monthly). Expressed in MVR, including decimal amounts."
                                    }
                                }
                            },
                            "remaining": {
                                "type": "object",
                                "properties": {
                                    "per_transaction": {
                                        "type": "number",
                                        "description": "Remaining allowance (per transaction). Expressed in MVR, including decimal amounts."
                                    },
                                    "daily": {
                                        "type": "number",
                                        "description": "Remaining allowance (daily). Expressed in MVR, including decimal amounts."
                                    },
                                    "weekly": {
                                        "type": "number",
                                        "description": "Remaining allowance (weekly). Expressed in MVR, including decimal amounts."
                                    },
                                    "monthly": {
                                        "type": "number",
                                        "description": "Remaining allowance (monthly). Expressed in MVR, including decimal amounts."
                                    }
                                }
                            },
                            "reset_at": {
                                "type": "object",
                                "properties": {
                                    "daily": {
                                        "type": "string",
                                        "format": "date-time",
                                        "description": "Next reset time for the daily period, including the timezone offset. Use the returned time when displaying when the allowance resets."
                                    },
                                    "weekly": {
                                        "type": "string",
                                        "format": "date-time",
                                        "description": "Next reset time for the weekly period, including the timezone offset. Use the returned time when displaying when the allowance resets."
                                    },
                                    "monthly": {
                                        "type": "string",
                                        "format": "date-time",
                                        "description": "Next reset time for the monthly period, including the timezone offset. Use the returned time when displaying when the allowance resets."
                                    }
                                }
                            }
                        }
                    }
                }
            },
            "WalletTransaction": {
                "type": "object",
                "required": [
                    "tid",
                    "time",
                    "type",
                    "name",
                    "details",
                    "amount",
                    "status"
                ],
                "properties": {
                    "tid": {
                        "type": "string",
                        "description": "FahiPay transaction reference."
                    },
                    "time": {
                        "type": "string",
                        "format": "date-time",
                        "description": "Transaction timestamp, including its timezone offset."
                    },
                    "type": {
                        "type": "string",
                        "description": "Transaction type."
                    },
                    "name": {
                        "type": "string",
                        "description": "Transaction name."
                    },
                    "details": {
                        "type": "string",
                        "description": "Transaction description."
                    },
                    "amount": {
                        "type": "number",
                        "description": "Signed transaction amount in MVR. Check status to determine the transaction outcome; an amount on a failed transaction does not mean funds moved."
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "success",
                            "failed"
                        ],
                        "description": "Outcome of this individual transaction, independent of the top-level request success flag."
                    }
                }
            },
            "WalletTransactionPagination": {
                "type": "object",
                "required": [
                    "limit",
                    "has_more",
                    "next_cursor"
                ],
                "properties": {
                    "limit": {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 100,
                        "description": "Requested page size, or the default of 10."
                    },
                    "has_more": {
                        "type": "boolean",
                        "description": "Whether another page is available. Stop when false."
                    },
                    "next_cursor": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Pass this reference as before to retrieve the next page. Null when no more records are available."
                    }
                }
            },
            "WalletTransactionsResponse": {
                "type": "object",
                "required": [
                    "success",
                    "data",
                    "pagination"
                ],
                "properties": {
                    "success": {
                        "type": "boolean",
                        "const": true,
                        "description": "Whether the API request succeeded. Check each transaction status for its outcome."
                    },
                    "data": {
                        "type": "array",
                        "description": "Successful and failed transactions, ordered from most recently recorded to oldest. The array may be empty.",
                        "items": {
                            "$ref": "#/components/schemas/WalletTransaction"
                        }
                    },
                    "pagination": {
                        "$ref": "#/components/schemas/WalletTransactionPagination"
                    }
                }
            },
            "WalletErrorResponse": {
                "type": "object",
                "required": [
                    "success",
                    "error"
                ],
                "properties": {
                    "success": {
                        "type": "boolean",
                        "const": false
                    },
                    "error": {
                        "type": "object",
                        "required": [
                            "code",
                            "message"
                        ],
                        "properties": {
                            "code": {
                                "type": "string",
                                "description": "Machine-readable error code."
                            },
                            "message": {
                                "type": "string",
                                "description": "Human-readable explanation."
                            }
                        }
                    }
                }
            }
        }
    }
}
