# Directory Structure
```
├── .github
│   └── workflows
│       └── publish.yml
├── .gitignore
├── .idx
│   └── dev.nix
├── .vscode
│   ├── extensions.json
│   └── settings.json
├── bin
│   └── generate-openapi-typescript
├── CONTRIBUTING.md
├── Dockerfile
├── LICENSE
├── package-lock.json
├── package.json
├── README.md
├── server.json
├── src
│   ├── client
│   │   ├── client.ts
│   │   ├── http
│   │   │   └── index.ts
│   │   ├── index.ts
│   │   ├── lib
│   │   │   ├── checkout.ts
│   │   │   ├── plan.ts
│   │   │   └── transactions.ts
│   │   ├── middleware
│   │   │   └── authMiddlewareV3.ts
│   │   ├── schema.ts
│   │   ├── specs
│   │   │   └── v3
│   │   │       ├── checkout.yaml
│   │   │       ├── plan.yaml
│   │   │       └── transactions.yaml
│   │   └── types
│   │       ├── v3
│   │       │   ├── checkout.d.ts
│   │       │   ├── plans.d.ts
│   │       │   └── transactions.d.ts
│   │       └── v3.d.ts
│   ├── config
│   │   └── index.ts
│   ├── index.ts
│   ├── prompts
│   │   ├── index.ts
│   │   └── transactions.ts
│   ├── server.ts
│   ├── tools
│   │   ├── checkout.ts
│   │   ├── get_transaction_timeline.ts
│   │   ├── index.ts
│   │   ├── plan.ts
│   │   ├── required.ts
│   │   ├── retry_transaction.ts
│   │   └── transaction.ts
│   └── types
│       ├── checkout
│       │   ├── index.ts
│       │   └── schema.ts
│       ├── index.ts
│       ├── plan
│       │   └── schema.ts
│       └── transaction
│           └── schema.ts
└── tsconfig.json
```
# Files
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
```
/node_modules
/build
src/example.ts
.mcpre*
```
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
```markdown
# mcp-flutterwave
An [MCP (Model Context Protocol)](https://modelcontextprotocol.io) server that enables AI assistants to interact with Flutterwave, providing tools for confirming transactions, send failed hooks, and more.
## Warning!!!
This MCP is in active development.
## Features
- Confirm Transactions (Already included)
- Retry Failed Transactions (Automatically retry transactions with recoverable errors) [✓]
- Retrieve Transaction History (Fetch and analyze past transactions) [✓]
- Send Failed Hooks (Already included)
- Generate Payment Links [✓]
- Automated Customer Support (AI chatbot integrated with Flutterwave for transaction inquiries) [✓]
## Available Tools
- `get-transactions`: Get the final status of a transaction with a transaction ID
- `resent-failed-webhook`: Resend failed webhook for a transaction
- `create-checkout`: Create a payment link for customers
- `disable-checkout`: Disable a checkout transaction link
- `retry-transaction`: Analyze and provide guidance for retrying a failed transaction
- `get-transaction-timeline`: Get the timeline/history of events for a transaction
## Installation
### Via npm (Recommended)
```bash
npm install -g mcp-flutterwave
```
### Via GitHub
```bash
git clone https://github.com/bajoski34/mcp-flutterwave.git
cd mcp-flutterwave
npm install
npm run build
```
## Usage with Claude Desktop
Add the following to your `claude_desktop_config.json`. See [here](https://modelcontextprotocol.io/quickstart/user) for more details.
### Using npm installation
```json
{
  "mcpServers": {
    "flutterwave": {
      "command": "mcp-flutterwave",
      "args": [
        "--tools=create_checkout,disable_checkout,read_transaction,resend_transaction_webhook"
      ],
      "env": {
        "FLW_SECRET_KEY": "YOUR_SECRET_KEY"
      }
    }
  }
}
```
### Using local build
```json
{
  "mcpServers": {
    "flutterwave": {
      "command": "node",
      "args": [
        "/path/to/mcp-flutterwave/build/index.js",
        "--tools=create_checkout,disable_checkout,read_transaction,resend_transaction_webhook"
      ],
      "env": {
        "FLW_SECRET_KEY": "YOUR_SECRET_KEY"
      }
    }
  }
}
```
## Setup Steps
1. **Install the package**
   ```bash
   npm install -g mcp-flutterwave
   ```
2. **Get your Flutterwave secret key**
   - Log into your Flutterwave dashboard
   - Go to Settings > API Keys
   - Copy your Secret Key
3. **Configure Claude Desktop**
   - Add the configuration to your `claude_desktop_config.json`
   - Replace `YOUR_SECRET_KEY` with your actual Flutterwave secret key
4. **Start using with Claude**
   - Open Claude Desktop
   - Ask questions related to Flutterwave transactions, payments, etc.
## Contributing
We welcome contributions! Please read our [Contributing Guide](./CONTRIBUTING.md) for details on how to get started, development guidelines, and how to submit changes.
```
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
```markdown
# Contributing to mcp-flutterwave
Thank you for your interest in contributing to mcp-flutterwave! This document provides guidelines and information for contributors.
## Getting Started
### Prerequisites
- Node.js (v18 or higher)
- npm or yarn
- A Flutterwave account with API access
- Basic knowledge of TypeScript and the Model Context Protocol (MCP)
### Development Setup
1. **Fork and clone the repository**
   ```bash
   git clone https://github.com/your-username/mcp-flutterwave.git
   cd mcp-flutterwave
   ```
2. **Install dependencies**
   ```bash
   npm install
   ```
3. **Set up environment variables**
   ```bash
   cp .env.example .env
   # Add your Flutterwave secret key
   echo "FLW_SECRET_KEY=your_secret_key_here" >> .env
   ```
4. **Build the project**
   ```bash
   npm run build
   ```
5. **Test the MCP server**
   ```bash
   node build/index.js --tools=all
   ```
## Development Guidelines
### Code Style
- Use TypeScript for all new code
- Follow the existing code style and formatting
- Use meaningful variable and function names
- Add JSDoc comments for public APIs
- Ensure proper error handling
### Project Structure
```
src/
├── client/           # Flutterwave API client
│   ├── http/        # HTTP client configuration
│   ├── lib/         # API endpoint implementations
│   ├── specs/       # OpenAPI specifications
│   └── types/       # Generated TypeScript types
├── config/          # Configuration files
├── tools/           # MCP tool implementations
├── types/           # Type definitions and schemas
└── server.ts        # MCP server setup
```
### Adding New Tools
1. **Create the tool implementation** in `src/tools/`
   ```typescript
   // src/tools/your-tool.ts
   import { server } from "../server.js";
   import { z } from "zod";
   export async function yourToolFunction(params: YourParams) {
     // Implementation
     return {
       content: [{ type: "text" as const, text: "Result" }]
     };
   }
   export function registerYourTool() {
     server.tool(
       "your.tool.name",
       "Description of your tool",
       YourParamsSchema.shape,
       async (args) => {
         return await yourToolFunction(args);
       }
     );
   }
   ```
2. **Add the schema** in `src/types/your-tool/schema.ts`
   ```typescript
   import { z } from "zod";
   export const YourParamsSchema = z.object({
     param1: z.string().min(1, "Required parameter"),
     param2: z.number().optional()
   });
   ```
3. **Register the tool** in `src/registered-tools.ts`
4. **Update documentation** and tool lists in relevant files
### API Client Development
When adding new Flutterwave API endpoints:
1. **Add OpenAPI spec** in `src/client/specs/v3/`
2. **Generate types** using `npm run build:types`
3. **Implement client class** in `src/client/lib/`
4. **Export from main client** in `src/client/index.ts`
### Testing
- Write unit tests for new functionality
- Test with actual Flutterwave API when possible
- Ensure error handling works correctly
- Test MCP tool integration with Claude Desktop
### Commit Guidelines
- Use conventional commit messages:
  - `feat:` for new features
  - `fix:` for bug fixes
  - `docs:` for documentation changes
  - `refactor:` for code refactoring
  - `test:` for adding tests
  - `chore:` for maintenance tasks
Example:
```
feat: add subscription management tools
fix: handle null responses in checkout creation
docs: update README with new tool examples
```
## Supported Tools
Current tools that can be extended or improved:
- **Transactions**: Get transaction details, resend webhooks
- **Checkout**: Create payment links, disable links
- **Plans**: Create and retrieve subscription plans
- **Refunds**: Process transaction refunds
- **Subscriptions**: Manage customer subscriptions
## Common Issues and Solutions
### TypeScript Errors
- Ensure all types are properly imported
- Use `as const` for literal types in MCP responses
- Check that Zod schemas match the expected API parameters
### MCP Integration Issues
- Verify tool schemas use `.shape` property for registration
- Ensure return objects match MCP content format
- Check that all async functions properly handle errors
### API Client Issues
- Verify OpenAPI specifications are accurate
- Regenerate types after spec changes: `npm run build:types`
- Check HTTP client configuration in `src/client/http/`
## Submitting Changes
1. **Create a feature branch**
   ```bash
   git checkout -b feature/your-feature-name
   ```
2. **Make your changes** following the guidelines above
3. **Test your changes**
   ```bash
   npm run build
   npm test # if tests are available
   ```
4. **Commit your changes**
   ```bash
   git add .
   git commit -m "feat: describe your changes"
   ```
5. **Push and create a pull request**
   ```bash
   git push origin feature/your-feature-name
   ```
6. **Fill out the PR template** with:
   - Description of changes
   - Testing performed
   - Any breaking changes
   - Screenshots if applicable
## Code Review Process
- All contributions require review
- Address feedback promptly
- Ensure CI checks pass
- Maintain backward compatibility when possible
## Getting Help
- Open an issue for bugs or feature requests
- Join discussions in existing issues
- Check the [MCP documentation](https://modelcontextprotocol.io) for protocol details
- Review [Flutterwave API docs](https://developer.flutterwave.com) for API details
## License
By contributing, you agree that your contributions will be licensed under the same license as the project.
```
--------------------------------------------------------------------------------
/src/client/schema.ts:
--------------------------------------------------------------------------------
```typescript
```
--------------------------------------------------------------------------------
/src/types/checkout/index.ts:
--------------------------------------------------------------------------------
```typescript
export * from "./schema.js"; 
```
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
```json
{
    "recommendations": [
        "github.vscode-github-actions"
    ]
}
```
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
```json
{
    "IDX.aI.enableInlineCompletion": true,
    "IDX.aI.enableCodebaseIndexing": true
}
```
--------------------------------------------------------------------------------
/src/prompts/index.ts:
--------------------------------------------------------------------------------
```typescript
import { registerTransactionsPrompts } from './transactions.js';
export function registerPrompts() {
  registerTransactionsPrompts();
}
```
--------------------------------------------------------------------------------
/src/types/transaction/schema.ts:
--------------------------------------------------------------------------------
```typescript
import { z } from 'zod';
export const TransactionSchema = {
    tx_id: z.string().min(1, 'Transaction ID is required').describe('Transaction ID'),
}
```
--------------------------------------------------------------------------------
/src/client/middleware/authMiddlewareV3.ts:
--------------------------------------------------------------------------------
```typescript
import { Middleware } from "openapi-fetch";
export const authMiddlewareV3: Middleware = {
    async onRequest({ request }) {
      request.headers.set("Authorization", "Bearer " + process.env.FLW_SECRET_KEY);
      return request;
    }
};
export default authMiddlewareV3;
```
--------------------------------------------------------------------------------
/src/client/index.ts:
--------------------------------------------------------------------------------
```typescript
import transactions from "./lib/transactions.js"
import checkout from "./lib/checkout.js";
import plans from "./lib/plan.js";
export default class Flutterwave {
    static transactions() {
        return transactions;
    }
    static checkout() {
        return checkout;
    }
    static plans() {
        return new plans;
    }
}
```
--------------------------------------------------------------------------------
/src/tools/index.ts:
--------------------------------------------------------------------------------
```typescript
import {registerCheckoutTools} from './checkout.js';
import { registerTransactionTools } from './transaction.js';
import { registerRequiredTools } from './required.js';
import { registerPlanTools } from './plan.js';
export function registerTools() {
  registerRequiredTools();
  registerTransactionTools();
  registerCheckoutTools();
  registerPlanTools();
}
```
--------------------------------------------------------------------------------
/src/server.ts:
--------------------------------------------------------------------------------
```typescript
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { registerTools } from "./tools/index.js";
import { registerPrompts } from "./prompts/index.js";
// Create server instance.
export const server = new McpServer({
    name: "flutterwave",
    version: "1.2.2",
});
// Register tools with the server.
registerTools();
registerPrompts();
export default server;
```
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
```json
{
    "compilerOptions": {
        "target": "ES2022",
        "module": "Node16",
        "moduleResolution": "Node16",
        "outDir": "./build",
        "rootDir": "./src",
        "strict": true,
        "esModuleInterop": true,
        "skipLibCheck": true,
        "forceConsistentCasingInFileNames": true
    },
    "include": [
        "src/**/*"
    ],
    "exclude": [
        "node_modules"
    ]
}
```
--------------------------------------------------------------------------------
/src/types/index.ts:
--------------------------------------------------------------------------------
```typescript
export type Options = {
    tools?: string[];
    apiKey?: string;
};
export type CheckoutPayload = {
    tx_ref: string,
    amount: string,
    currency: string,
    redirect_url: string,
    customer: {
        email: string,
        name: string,
        phonenumber: string,
    },
    customizations: {
        title: string,
    },
    configurations: {
        session_duration: number,
        max_retry_attempt: number
    },
}
```
--------------------------------------------------------------------------------
/src/client/client.ts:
--------------------------------------------------------------------------------
```typescript
import createClient, { Middleware } from "openapi-fetch";
import type { paths } from "./types/v3.js";
import authMiddlewareV3 from "./middleware/authMiddlewareV3.js";
const FLW_API_VERSION = process.env.FLW_VERSION || 'v3';
const FLW_API_BASE = "https://api.flutterwave.com/" + FLW_API_VERSION;
const USER_AGENT = "flutterwave-mcp/0.1.0";
 
const client = createClient<paths>({ baseUrl: FLW_API_BASE, headers: { "User-Agent": USER_AGENT } });
client.use(authMiddlewareV3);
export default client
```
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
```dockerfile
FROM node:20.19.5-alpine3.22 AS builder
WORKDIR /app
ENV DOCKER=true
# Copy package files and install dependencies
COPY package*.json ./
RUN npm ci
# Copy source code
COPY tsconfig.json ./
COPY src/ ./src/
# Build the application
RUN npm run build
# Start a new stage for a smaller production image
FROM node:20.19.5-alpine3.22
WORKDIR /app
# Set environment variables
ENV DOCKER=true
ENV NODE_ENV=production
ENV FLW_SECRET_KEY=${FLW_SECRET_KEY}
# Copy package files and install production dependencies only
COPY package*.json ./
RUN npm ci --omit=dev
# Copy the built application from the builder stage
COPY --from=builder /app/build ./build
# Run the application
CMD ["node", "build/index.js"] 
```
--------------------------------------------------------------------------------
/src/types/plan/schema.ts:
--------------------------------------------------------------------------------
```typescript
import { z } from 'zod';
export const CreatePlanPayloadSchema = {
    name: z.string().min(1, "Name is required"),
    amount: z.number().positive("Amount must be a positive number"),
    interval: z.enum(['daily', 'weekly', 'monthly', 'yearly']).refine(val => ['daily', 'weekly', 'monthly', 'yearly'].includes(val), { message: "Interval must be one of 'daily', 'weekly', 'monthly', 'yearly'" }),
    duration: z.number().int().positive("Duration must be a positive integer"),
};
export const GetPlansFiltersSchema = {
    name: z.string().min(1).optional(),
    amount: z.number().positive().optional(),
    interval: z.enum(['daily', 'weekly', 'monthly', 'yearly']).optional(),
    status: z.enum(['active', 'inactive']).optional(),
    from: z.string().optional(),
    to: z.string().optional(),
};
```
--------------------------------------------------------------------------------
/server.json:
--------------------------------------------------------------------------------
```json
{
  "$schema": "https://static.modelcontextprotocol.io/schemas/2025-09-29/server.schema.json",
  "name": "io.github.bajoski34/mcp-flutterwave",
  "description": "MCP Server to interact with Flutterwave APIs.",
  "repository": {
    "url": "https://github.com/bajoski34/mcp-flutterwave",
    "source": "github"
  },
  "version": "1.2.2",
  "packages": [
    {
      "registryType": "npm",
      "registryBaseUrl": "https://registry.npmjs.org",
      "identifier": "mcp-flutterwave",
      "version": "1.2.2",
      "transport": {
        "type": "stdio"
      },
      "environmentVariables": [
        {
          "description": "Your SECRET API key for the service",
          "isRequired": true,
          "format": "string",
          "isSecret": true,
          "name": "FLW_SECRET_KEY"
        }
      ]
    }
  ]
}
```
--------------------------------------------------------------------------------
/src/config/index.ts:
--------------------------------------------------------------------------------
```typescript
import { version } from 'os';
import {z} from 'zod';
// environment variable schema for validation
const envSchema = z.object({
  FLW_SECRET_KEY: z.string().min(1, 'Flutterwave Secret Key is required'),
  NODE_ENV: z
    .enum(['development', 'production', 'test'])
    .optional()
    .default('development'),
});
// Parse and validate environment variables
const envParse = envSchema.safeParse(process.env);
if (!envParse.success) {
  console.error('❌ Invalid environment variables:', envParse.error.format());
  throw new Error('Invalid environment variables');
}
// Export validated config
export const config = {
  flutterwave: {
    secretKey: envParse.data.FLW_SECRET_KEY,
    apiUrl: 'https://api.flutterwave.com',
    version: 'v3',
  },
  server: {
    environment: envParse.data.NODE_ENV,
  },
} as const;
```
--------------------------------------------------------------------------------
/src/tools/required.ts:
--------------------------------------------------------------------------------
```typescript
import { ToolCallback } from "@modelcontextprotocol/sdk/server/mcp.js";
import { type Tool } from "@modelcontextprotocol/sdk/types.js";
import { z } from "zod";
import { server } from "../server.js";
const tools:any[] = [];
/**
 * Register tool for the Flutterwave MCP Server to function
 */
// tools.push({
//     name: "sample",
//     description: "Sample Tool",
//     inputSchema: { sample: z.string().min(1, "Sample is required").describe("Sample") },
//     cb: ((args: any) => {
//         return {
//             content: [{ type: "text", text: `Sample Tool Executed with args: ${JSON.stringify(args)}` }] };
//     }),
// });
export async function registerRequiredTools() {
    // Register required tools with the server.
    for (const tool of tools) {
        server.tool(tool.name, tool.description, tool.inputSchema, tool.cb);
    }
}
```
--------------------------------------------------------------------------------
/src/types/checkout/schema.ts:
--------------------------------------------------------------------------------
```typescript
import { z } from 'zod';
export const CheckoutPayloadSchema = {
    tx_ref: z.string().min(1, "Transaction reference is required"),
    amount: z.string().min(1, "Amount is required"),
    currency: z.string().min(1, "Currency is required"),
    redirect_url: z.string().url("Redirect URL must be a valid URL"),
    customer: z.object({
        email: z.string().email("Invalid email address"),
        name: z.string().min(1, "Customer name is required"),
        phonenumber: z.string().min(1, "Customer phone number is required"),
    }),
    customizations: z.object({
        title: z.string().min(1, "Title is required"),
    }),
    configurations: z.object({
        session_duration: z.number().int().positive("Session duration must be a positive integer"),
        max_retry_attempt: z.number().int().nonnegative("Max retry attempt must be a non-negative integer")
    }),
};
export const DisableCheckoutSchema = {
    link: z.string().url("Checkout link must be a valid URL"),
};
```
--------------------------------------------------------------------------------
/src/client/http/index.ts:
--------------------------------------------------------------------------------
```typescript
import createClient from "openapi-fetch";
import type { paths as checkoutPaths } from "../types/v3/checkout.js";
import type { paths as transactionPaths } from "../types/v3/transactions.js";
import type { paths as planPaths } from "../types/v3/plans.js";
import authMiddlewareV3 from "../middleware/authMiddlewareV3.js";
import { config } from "../../config/index.js";
const FLW_API_VERSION = process.env.FLW_VERSION || config.flutterwave.version;
const FLW_API_BASE = config.flutterwave.apiUrl + '/' + FLW_API_VERSION;
const USER_AGENT = "flutterwave-mcp/0.1.0";
 
const transactionClient = createClient<transactionPaths>({ baseUrl: FLW_API_BASE, headers: { "User-Agent": USER_AGENT } });
transactionClient.use(authMiddlewareV3);
const checkoutClient = createClient<checkoutPaths>({ baseUrl: FLW_API_BASE, headers: { "User-Agent": USER_AGENT } });
checkoutClient.use(authMiddlewareV3);
const planClient = createClient<planPaths>({ baseUrl: FLW_API_BASE, headers: { "User-Agent": USER_AGENT } });
planClient.use(authMiddlewareV3);
export {
    transactionClient,
    checkoutClient,
    planClient
}
```
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
```json
{
  "name": "mcp-flutterwave",
  "type": "module",
  "bin": {
    "mcp-flutterwave": "build/index.js"
  },
  "version": "1.2.2",
  "mcpName": "io.github.bajoski34/mcp-flutterwave",
  "repository": {
    "type": "git",
    "url": "https://github.com/bajoski34/mcp-flutterwave.git"
  },
  "description": "MCP Server to interact with Flutterwave APIs.",
  "main": "build/index.js",
  "scripts": {
    "build": "npm run build:types &&tsc && node -e \"require('fs').chmodSync('build/index.js', '755')\"",
    "clean": "rm -rf build",
    "build:types": "./bin/generate-openapi-typescript"
  },
  "files": [
    "build"
  ],
  "keywords": [
    "mcp",
    "model-context-protocol",
    "flutterwave",
    "payment",
    "fintech",
    "ai"
  ],
  "author": "Abraham Olaobaju <[email protected]>",
  "license": "MIT",
  "dependencies": {
    "@modelcontextprotocol/sdk": "^1.18.2",
    "colors": "^1.4.0",
    "flutterwave-node-v3": "^1.1.15",
    "openapi-fetch": "^0.14.0",
    "ts-node": "^10.9.2",
    "zod": "^3.24.2"
  },
  "devDependencies": {
    "@types/node": "^22.13.10",
    "nodemon": "^3.1.9",
    "openapi-typescript": "^7.6.1",
    "typescript": "^5.8.2",
    "zod-to-json-schema": "^3.24.6"
  }
}
```
--------------------------------------------------------------------------------
/src/client/lib/plan.ts:
--------------------------------------------------------------------------------
```typescript
import { planClient as client } from "../http/index.js";
import type { paths } from "../types/v3/plans.js";
type CreatePlanPayload = (
  paths["/plans"]["post"]["requestBody"]
  & { content: { "application/json": unknown } }
)["content"]["application/json"];
type CreatePlanResponse = paths["/plans"]["post"]["responses"]["200"]["content"]["application/json"];
type GetPlanResponse = paths["/plans"]["get"]["responses"]["200"]["content"]["application/json"];
type GetPlanParams = paths["/plans"]["get"]["parameters"]["query"];
export default class Plan {
    async create(payload: CreatePlanPayload): Promise<{ status: number; data: CreatePlanResponse | string | null }> {
        try {
        const response = await client.POST("/plans", { body: payload });
        return { 
            status: response.response?.status ?? 500, 
            data: response.data ?? null 
        };
        } catch (error) {
        return { status: 500, data: (error as any)?.message || 'An error occurred'};
        }
    }
    async get(params?: GetPlanParams): Promise<{ status: number; data: GetPlanResponse | null }> {
        try {
        const response = await client.GET("/plans", { 
            query: params || {
                page: 1,
                status: "active",
                from: "",
                to: "",
                amount: 0,
                interval: ""
            }
        });
        return { 
            status: response.response?.status ?? 500, 
            data: response.data ?? null 
        };
        } catch (error) {
        return { status: 500, data: null };
        }
    }
}
```
--------------------------------------------------------------------------------
/src/client/lib/checkout.ts:
--------------------------------------------------------------------------------
```typescript
import { checkoutClient as client } from "../http/index.js";
type CheckoutPayload = {
    tx_ref: string,
    amount: string,
    currency: string,
    redirect_url: string,
    customer: {
        email: string,
        name: string,
        phonenumber: string,
    },
    customizations: {
        title: string,
    },
    configurations: {
        session_duration: number,
        max_retry_attempt: number
    },
}
/**
 * This checkout create paymrnt.
 * https://developer.flutterwave.com/docs/flutterwave-standard-1
 * 
*/
async function create(payment_data: CheckoutPayload) : Promise<{ data: {
    data: any; link: string 
}, status: number } | undefined> {
    const { data, error } = await client.POST("/payments", {
        body: {
            ...payment_data
        }
    });
    if (error) {
        console.error(error);
        return;
    }
    return data;
}
// {
//     "status": "success",
//     "message": "LINK DISABLED",
//     "data": true
// }
/**
 * Disable a checkout link.
 * https://developer.flutterwave.com/v3.0.0/docs/flutterwave-standard-1#how-to-disable-a-payment-link-via-api
 * @param payment_link 
 * @returns 
 */
async function disable(payment_link: string): Promise<{
    status: string;
    message: string;
    data: null;
} | undefined> {
    const { data, error } = await client.POST("/payments/link/disable", {
        body:{
            link: payment_link
        }
    });
    if (error) {
        console.error(error);
        throw new Error('Failed to disable checkout link', { cause: error });
    }
    // Ensure returned object always has data: null
    return {
        status: data?.status || 'error',
        message: data?.message || 'An error occurred',
        data: null
    };
}
export default {
    create,
    disable_link: disable
}
```
--------------------------------------------------------------------------------
/src/tools/retry_transaction.ts:
--------------------------------------------------------------------------------
```typescript
import Flutterwave from "../client/index.js";
export default async ({ tx_id }: { tx_id: string }) => {
    if (!process.env.FLW_SECRET_KEY) {
        return {
            content: [{ type: "text", text: "API key is missing. Please check configuration." }],
        };
    }
    const transactions = Flutterwave.transactions();
    try {
        const response = await transactions.retry_transaction(tx_id);
        if (!response || response.status === 'error') {
            return {
                content: [{ 
                    type: "text", 
                    text: response?.message || `Unable to retry transaction ${tx_id}` 
                }],
            };
        }
        if (response.status === 'info' && response.data) {
            const data = response.data;
            return {
                content: [
                    {
                        type: "text",
                        text: `Transaction retry analysis completed for ${tx_id}:\n` +
                              `Status: ${data.status}\n` +
                              `Original Reference: ${data.original_tx_ref}\n` +
                              `Amount: ${data.amount} ${data.currency}\n` +
                              `Customer: ${data.customer_email}\n\n` +
                              `${response.message}`
                    },
                ],
            };
        }
        return {
            content: [
                {
                    type: "text",
                    text: `Transaction retry completed: ${response.message}`,
                },
            ],
        };
    } catch (error) {
        console.error(`Error retrying transaction ${tx_id}:`, error);
        return {
            content: [{ type: "text", text: `Error retrying transaction ${tx_id}` }],
        };
    }
};
```
--------------------------------------------------------------------------------
/src/prompts/transactions.ts:
--------------------------------------------------------------------------------
```typescript
import {server} from '../server.js';
const transactionInsightsPrompt = `
You are a helpful assistant connecting to Flutterwave Server. Your goal is to provide the user with actionable insights into transactions, including revenue, volume, success/failure rates, and trends.
Available Tools:
1. \`list_transactions\`: Fetches detailed transaction records (amount, currency, status, customer, etc.).
2. \`get_transaction_totals\`: Returns aggregated metrics such as total revenue, transaction count, success rate, and failure rate.
3. \`list_customers\`: Provides information about customers to segment transactions and identify top spenders.
Workflow:
1. When a user asks about transaction insights (e.g., "How are my transactions this month?"), call \`get_transaction_totals\` with appropriate date filters.
2. Use \`list_transactions\` for deeper analysis like top payment methods, currencies, or customer segments.
3. Highlight key metrics:
   - Total revenue
   - Number of successful vs failed transactions
   - Average transaction value
   - Top payment methods and currencies
   - Top customers by volume or value
4. Identify trends such as:
   - Day with highest sales
   - Increase/decrease compared to previous period
   - Most common reasons for failed transactions (if available)
5. Present the insights in a concise, structured way (tables, bullet points, percentages).
6. Offer follow-up insights (e.g., "Would you like to see a breakdown by country or payment method?").
7. Focus on turning raw transaction data into clear business insights.
`;
export function registerTransactionsPrompts() {
  server.prompt(
    'show-transaction-insights',
    'Give me insights into my transactions this month',
    {},
    async () => ({
      messages: [
        {
          role: 'assistant',
          content: {
            type: 'text',
            text: transactionInsightsPrompt,
          },
        },
      ],
    })
  );
}
```
--------------------------------------------------------------------------------
/src/tools/get_transaction_timeline.ts:
--------------------------------------------------------------------------------
```typescript
import Flutterwave from "../client/index.js";
export default async ({ tx_id }: { tx_id: string }) => {
    if (!process.env.FLW_SECRET_KEY) {
        return {
            content: [{ type: "text", text: "API key is missing. Please check configuration." }],
        };
    }
    const transactions = Flutterwave.transactions();
    try {
        const { status, data } = await transactions.timeline(tx_id) || { status: null, data: null };
        if(typeof status == 'number' && status >= 400) {
            return {
                content: [{ type: "text", text: `Unable to retrieve timeline for ${tx_id}` }],
            };
        }
        
        if(!data) {
            return {
                content: [{ type: "text", text: `Unable to retrieve timeline for ${tx_id}` }],
            };
        }
        if(!(data as any)?.status) {
            return {
                content: [{ type: "text", text: `Unable to retrieve timeline for ${tx_id}` }],
            };
        }
        // Format the timeline data for display
        let timelineText = `Transaction Timeline for ${tx_id}:\n\n`;
        
        if ((data as any).data && Array.isArray((data as any).data)) {
            (data as any).data.forEach((event: any, index: number) => {
                timelineText += `${index + 1}. ${event.event || 'Event'}: ${event.description || 'No description'}\n`;
                if (event.created_at) {
                    timelineText += `   Time: ${event.created_at}\n`;
                }
                timelineText += '\n';
            });
        } else {
            timelineText += 'No timeline events available for this transaction.';
        }
        return {
            content: [
                {
                    type: "text",
                    text: timelineText,
                },
            ],
        };
    } catch (error) {
        console.error(`Error fetching timeline for ${tx_id}:`, error);
        return {
            content: [{ type: "text", text: `Error retrieving timeline for ${tx_id}` }],
        };
    }
};
```
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
```typescript
#!/usr/bin/env node
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import server from "./server.js";
import { Options } from "./types/index.js";
import { config } from "./config/index.js";
const ACCEPTED_ARGS = ['tools'];
const ACCEPTED_TOOLS = [
    'create_checkout',
    'disable_checkout',
    'create_refund',
    'read_transactions',
    'read_transaction',
    'read_transaction_timeline',
    'resend_transaction_webhook',
    'create_plan',
    'read_plan',
    'read_subscription'
];
export function parseArgs(args: string[]): Options {
    const options: Options = {};
    args.forEach((arg) => {
        if (arg.startsWith('--')) {
            const [key, value] = arg.slice(2).split('=');
            if (key == 'tools') {
                options.tools = value.split(',');
            } else {
                throw new Error(
                    `Invalid argument: ${key}. Accepted arguments are: ${ACCEPTED_ARGS.join(
                        ', '
                    )}`
                );
            }
        }
    });
    // Check if required tools arguments is present.
    if (!options.tools) {
        throw new Error('The --tools arguments must be provided.');
    }
    // Validate tools against accepted enum values.
    options.tools.forEach((tool: string) => {
        if (tool == 'all') {
            return;
        }
        if (!ACCEPTED_TOOLS.includes(tool.trim())) {
            throw new Error(
                `Invalid tool: ${tool}. Accepted tools are: ${ACCEPTED_TOOLS.join(
                    ', '
                )}`
            );
        }
    });
    // Check if API key is either provided in args or set in environment variables
    const apiKey = process.env.FLW_SECRET_KEY;
    if (!apiKey) {
        throw new Error(
            'Flutterwave Secret key not provided. Please either pass it as an argument --secret-key=$KEY or set the FLW_SECRET_KEY environment variable.'
        );
    }
    options.apiKey = apiKey;
    return options;
}
async function main() {
    const options = parseArgs(process.argv.slice(2));
    const transport = new StdioServerTransport();
    // Handle process termination
    process.on('SIGINT', async () => {
      console.error('Shutting down Flutterwave MCP Server...');
      await server.close();
      process.exit(0);
    });
    process.on('SIGTERM', async () => {
      console.error('Shutting down Flutterwave MCP Server...');
      await server.close();
      process.exit(0);
    });
    await server.connect(transport);
    console.error("Flutterwave MCP Server running on stdio");
}
main().catch((error) => {
    console.error("Fatal error in main():", error);
    process.exit(1);
});
```
--------------------------------------------------------------------------------
/src/tools/plan.ts:
--------------------------------------------------------------------------------
```typescript
import Flutterwave from "../client/index.js";
import { CheckoutPayload } from "../types/index.js";
import { server } from "../server.js";
import { CreatePlanPayloadSchema, GetPlansFiltersSchema } from "../types/plan/schema.js";
export async function createPlan(payload: { name: string; amount: number; interval: string; duration?: number; currency?: string; description?: string; }) {
    const plans = Flutterwave.plans();
     
    try {
        const { status, data } = await plans.create({
            ...payload,
            duration: payload.duration ?? 0, // Provide a default value if undefined
        }) || { status: null, data: null };
        if(typeof status == 'number' && status >= 400)
            return {
                content: [{ type: "text" as const, text: `Unable to create plan ${ payload.name } json: ${ JSON.stringify(data) }` }],
            };
        
        if(!data)
            return {
                content: [{ type: "text" as const, text: `Unable to create plan ${ payload.name } json: {message: "No response from server"}` }],
            };
        return {
            content: [
                {
                    type: "text" as const,
                    text: `Plan created with ID: ${ (data as { data?: { id?: string } }).data?.id }`,
                },
            ],
        };
    } catch (error) {
        return {
            content: [{ type: "text" as const, text: `Error Occured on creating plan ${ payload.name } json: ${ JSON.stringify(error) }` }],
        };
    }
}
export async function getPlans(filters?: { name?: string; amount?: number; interval?: string; status?: string; from?: string; to?: string; }) {
    const plans = Flutterwave.plans();
    
    try {
        const { status, data } = await plans.get({
            ...filters
        }) || { status: null, data: null };
        if(typeof status == 'number' && status >= 400)
            return {
                content: [{ type: "text" as const, text: `Unable to retrieve plans` }],
            };
        
        if(!data)
            return {
                content: [{ type: "text" as const, text: `Unable to retrieve plans` }],
            };
        if(!data?.status)
            return {
                content: [{ type: "text" as const, text: `Error Occured on retrieving plans json: ${ JSON.stringify(data) }` }],
            };
        return {
            content: [
                {
                    type: "text" as const,
                    text: `Plans retrieved: ${ JSON.stringify(data.data) }`,
                },
            ],
        };
    } catch (error) {
        return {
            content: [{ type: "text" as const, text: `Error Occured on retrieving plans json: ${ JSON.stringify(error) }` }],
        };
    }
}
export async function registerPlanTools() {
    server.tool(
        "create_payment_plan",
        "Create a payment plan with Flutterwave.",
        CreatePlanPayloadSchema,
        async (input) => await createPlan(input)
    )
    server.tool(
        "get_payment_plans",
        "Get payment plans with optional filters",
        GetPlansFiltersSchema,
        async (input) => await getPlans(input)
    )
}
```
--------------------------------------------------------------------------------
/src/tools/checkout.ts:
--------------------------------------------------------------------------------
```typescript
import Flutterwave from "../client/index.js";
import { CheckoutPayload } from "../types/index.js";
import { server } from "../server.js";
import { CheckoutPayloadSchema, DisableCheckoutSchema } from "../types/checkout/index.js";
export async function createCheckout(payload: CheckoutPayload) {
    const transactions = Flutterwave.checkout();
    try {
        const { status, data } = await transactions.create(payload) || { status: null, data: null };
        if(typeof status == 'number' && status >= 400)
            return {
                content: [{ type: "text" as const, text: `Unable to create a checkout url for ${ payload.customer.name }` }],
            };
        
        if(!data)
            return {
                content: [{ type: "text" as const, text: `Unable to create a checkout url for ${ payload.customer.name }` }],
            };
        if(!data?.data?.status)
            return {
                content: [{ type: "text" as const, text: `Error Occured on creating checkout url for ${ payload.customer.name } json: ${ JSON.stringify(data) }` }],
            };
        return {
            content: [
                {
                    type: "text" as const,
                    text: `Checkout link at: ${ data.data?.link }`,
                },
            ],
        };
    } catch (error) {
        return {
            content: [{ type: "text" as const, text: `Error Occured on creating checkout url for ${ payload.customer.name } json: ${ JSON.stringify(error) }` }],
        };
    }
}
export async function disableCheckout(link: string) {
    const transactions = Flutterwave.checkout();
    try {
        const { status, data } = await transactions.disable_link(link) || { status: null, data: null };
        if(typeof status == 'number' && status >= 400)
            return {
                content: [{ type: "text" as const, text: `Unable to disable checkout link ${ link } json: ${ JSON.stringify(data) }` }],
            };
        
        if(!data)
            return {
                content: [{ type: "text" as const, text: `Unable to disable checkout link ${ link }` }],
            };
        return {
            content: [
                {
                    type: "text" as const,
                    text: `Successfully disabled the link.`,
                },
            ],
        };
    } catch (error) {
        return {
            content: [{ type: "text" as const, text: `Error Occured on diabling the checkout: ${ link } json: ${ JSON.stringify(error) }` }],
        };
    }
}
export function registerCheckoutTools() {
    server.tool(
        "create_checkout",
        "Create a checkout link with Flutterwave.",
        CheckoutPayloadSchema,
        async (args) => {
            try {
                return await createCheckout(args);
            } catch (error) {
                return {
                    content: [{ type: "text" as const, text: `Error Occured on creating checkout url for ${ args.customer.name }` }],
                };
            }
        }
    );
    server.tool(
        "disable_checkout",
        "Disable a checkout link on Flutterwave.",
        DisableCheckoutSchema,
        async (args) => {
            return await disableCheckout(args.link);
        }
    );
}
```
--------------------------------------------------------------------------------
/src/client/specs/v3/checkout.yaml:
--------------------------------------------------------------------------------
```yaml
openapi: 3.0.3
info:
  title: Flutterwave Transactions API
  description: API for managing and retrieving transaction details via Flutterwave.
  version: 1.0.0
servers:
  - url: https://api.flutterwave.com/v3
paths:
  /payments:
      post:
        summary: Process a payment through Flutterwave
        description: Initiates a payment process through Flutterwave using a unique transaction reference.
        operationId: createPayment
        requestBody:
          description: Payment data for the transaction
          content:
            application/json:
              schema:
                type: object
                properties:
                  tx_ref:
                    type: string
                    example: 'txnref_djsdkjsnkdjvnsdfj'
                  amount:
                    type: string
                    example: '7500'
                  currency:
                    type: string
                    example: 'NGN'
                  redirect_url:
                    type: string
                    example: 'https://example_company.com/success'
                  customer:
                    type: object
                    properties:
                      email:
                        type: string
                        example: '[email protected]'
                      name:
                        type: string
                        example: 'Flutterwave Developers'
                      phonenumber:
                        type: string
                        example: '09012345678'
                  customizations:
                    type: object
                    properties:
                      title:
                        type: string
                        example: 'Flutterwave Standard Payment'
                required:
                  - tx_ref
                  - amount
                  - currency
                  - redirect_url
                  - customer
                  - customizations
  /payments/link/disable:
    post:
      summary: Disable a Flutterwave payment link
      description: Disables a specific payment link for the given URL.
      operationId: disablePaymentLink
      requestBody:
        description: Payment link data to disable
        content:
          application/json:
            schema:
              type: object
              properties:
                link:
                  type: string
                  example: 'https://checkout.flutterwave.com/v3/hosted/pay/flwlnk-01j8hkejppgm821xv8mfxfpgrb'
              required:
                - link
      responses:
        '200':
          description: Payment link disabled successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: 'success'
                  message:
                    type: string
                    example: 'Payment link has been disabled successfully'
        '400':
          description: Bad request, invalid data
        '401':
          description: Unauthorized, invalid API key
        '404':
          description: Payment link not found
        '500':
          description: Internal server error
components:
  schemas:
    Transaction:
      type: object
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
```
--------------------------------------------------------------------------------
/src/client/lib/transactions.ts:
--------------------------------------------------------------------------------
```typescript
import { transactionClient as client } from "../http/index.js";
/**
 * This endpoint helps you query the details of a transaction.
 * https://developer.flutterwave.com/reference/verify-transaction.
 * @param tx_id 
 * @returns 
 */
async function get(tx_id: string) {
    const { data, error } = await client.GET("/transactions/{id}/verify", {
        params: {
            path: { id: tx_id },
        },
    });
    if (error) {
        console.error(error);
        return;
    }
    return data;
}
/**
 * This endpoint helps you query the details of a transaction using the transaction reference.
 * https://developer.flutterwave.com/reference/verify-transaction-with-tx_ref
 * @param tx_ref 
 * @returns 
 */
async function get_with_reference(tx_ref: string) {
    const { data, error } = await client.GET("/transactions/verify_by_reference", {
        params: {
            query: { tx_ref },
        },
    });
    if (error) {
        console.error(error);
        return;
    }
    return data;
}
/**
 * This endpoint helps you resend webhooks from failed sending queues to your server.
 * https://developer.flutterwave.com/reference/resend-transaction-webhook
 */
async function send_failed_webhook(tx_id: string) {
    const { data, error } = await client.POST("/transactions/{id}/resend-hook", {
        params: {
            path: { id: tx_id },
        },
    });
    if (error) {
        console.error(error);
        return;
    }
    return data;
}
/**
 * Review the timeline for a transaction from initiation to completion.
 * https://developer.flutterwave.com/reference/get-transaction-events
 */
async function timeline(tx_id: string) {
    const { data, error } = await client.POST("/transactions/{id}/events", {
        params: {
            path: { id: tx_id },
        },
    });
    if (error) {
        console.error(error);
        return;
    }
    return data;
}
/**
 * Retry a failed transaction by creating a new transaction with the same details
 * This is a wrapper function that gets the original transaction and recreates it
 */
async function retry_transaction(tx_id: string) {
    try {
        // First get the original transaction details
        const original = await get(tx_id);
        
        if (!original || !original.data) {
            return {
                status: 'error',
                message: 'Could not retrieve original transaction details',
                data: null
            };
        }
        const txData = original.data;
        
        // Check if transaction is in a retriable state
        if (txData.status === 'successful') {
            return {
                status: 'error',
                message: 'Transaction is already successful, cannot retry',
                data: null
            };
        }
        return {
            status: 'info',
            message: 'Transaction retry initiated. Please create a new transaction with the same details.',
            data: {
                original_tx_ref: txData.tx_ref,
                amount: txData.amount,
                currency: txData.currency,
                customer_email: (txData as any).customer?.email,
                status: txData.status
            }
        };
        
    } catch (error) {
        console.error('Error retrying transaction:', error);
        return {
            status: 'error',
            message: 'Failed to retry transaction',
            data: null
        };
    }
}
export default {
    get,
    get_with_reference,
    timeline,
    send_failed_webhook,
    retry_transaction
}
```
--------------------------------------------------------------------------------
/.github/workflows/publish.yml:
--------------------------------------------------------------------------------
```yaml
name: Publish Package
on:
  release:
    types: [published]
  workflow_dispatch:
    inputs:
      version:
        description: 'Version to publish'
        required: true
        default: 'patch'
        type: choice
        options:
        - patch
        - minor
        - major
jobs:
  publish:
    runs-on: ubuntu-latest
    permissions:
      contents: write
      id-token: write
    
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0
          token: ${{ secrets.GITHUB_TOKEN }}
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '18'
          registry-url: 'https://registry.npmjs.org'
      - name: Install dependencies
        run: npm ci
      - name: Run tests
        run: npm test --if-present
      - name: Build project
        run: npm run build
      - name: Configure Git
        run: |
          git config --local user.email "[email protected]"
          git config --local user.name "GitHub Action"
      - name: Bump version (manual trigger)
        if: github.event_name == 'workflow_dispatch'
        run: |
          npm version ${{ github.event.inputs.version }} --no-git-tag-version
          # Update server.json version to match package.json
          VERSION=$(node -p "require('./package.json').version")
          jq --arg v "$VERSION" '.version = $v' server.json > tmp && mv tmp server.json
          git add package.json package-lock.json server.json
          git commit -m "chore: bump version to $VERSION"
          git push
      - name: Create tag (manual trigger)
        if: github.event_name == 'workflow_dispatch'
        run: |
          VERSION=$(node -p "require('./package.json').version")
          git tag "v$VERSION"
          git push origin "v$VERSION"
      - name: Update server.json version on release
        if: github.event_name == 'release'
        run: |
          VERSION=$(echo "${{ github.ref }}" | sed 's/refs\/tags\/v//')
          jq --arg v "$VERSION" '.version = $v' server.json > tmp && mv tmp server.json
          jq --arg v "$VERSION" '.packages[0].version = $v' server.json > tmp && mv tmp server.json
      - name: Publish to npm
        run: npm publish --provenance --access public
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
      - name: Create GitHub Release (manual trigger)
        if: github.event_name == 'workflow_dispatch'
        uses: actions/create-release@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          tag_name: v${{ steps.version.outputs.version }}
          release_name: Release v${{ steps.version.outputs.version }}
          body: |
            Release notes for version ${{ steps.version.outputs.version }}
            
            ## Changes
            - Updated MCP Flutterwave integration
            
            ## Installation
            ```bash
            npm install -g mcp-flutterwave
            ```
            
            ## Usage with Claude Desktop
            ```json
            {
              "mcpServers": {
                "flutterwave": {
                  "command": "mcp-flutterwave",
                  "env": {
                    "FLW_SECRET_KEY": "YOUR_SECRET_KEY"
                  }
                }
              }
            }
            ```
          draft: false
          prerelease: false
      - name: Install MCP Publisher
        run: |
          curl -L "https://github.com/modelcontextprotocol/registry/releases/download/v1.0.0/mcp-publisher_1.0.0_$(uname -s | tr '[:upper:]' '[:lower:]')_$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/').tar.gz" | tar xz mcp-publisher
      - name: Login to MCP Registry
        run: ./mcp-publisher login github-oidc
      - name: Publish to MCP Registry
        run: ./mcp-publisher publish
```
--------------------------------------------------------------------------------
/src/tools/transaction.ts:
--------------------------------------------------------------------------------
```typescript
import Flutterwave from "../client/index.js";
import { server } from "../server.js";
import { TransactionSchema } from "../types/transaction/schema.js";
export async function getTransaction({ tx_id }: { tx_id: string }) {
    const transactions = Flutterwave.transactions();
    try {
        const { status, data } = await transactions.get(tx_id) || { status: null, data: null };
        if(typeof status == 'number' && status >= 400)
            return {
                content: [{ type: "text" as const, text: `Unable to retrive ${tx_id}` }],
            };
        
        if(!data)
            return {
                content: [{ type: "text" as const, text: `Unable to retrive ${tx_id}` }],
            };
        if(!data.status)
            return {
                content: [{ type: "text" as const, text: `Unable to retrive ${tx_id}` }],
            };
        return {
            content: [
                {
                    type: "text" as const,
                    text: `Transaction Status: ${data.status}\nAmount: ${data.amount}\nCurrency: ${data.currency}`,
                },
            ],
        };
    } catch (error) {
        return {
            content: [{ type: "text" as const, text: `Unable to retrive ${tx_id}` }],
        };
    }
}
export async function getTransactionTimeline({ tx_id }: { tx_id: string }) {
    const transactions = Flutterwave.transactions();
    try {
        const { status, data } = await transactions.timeline(tx_id) || { status: null, data: null };
        if(typeof status == 'number' && status >= 400)
            return {
                content: [{ type: "text" as const, text: `Unable to retrive timeline for ${tx_id}` }],
            };
        
        if(!data)
            return {
                content: [{ type: "text" as const, text: `Unable to retrive timeline for ${tx_id}` }],
            };
        return {
            content: [
                {
                    type: "text" as const,
                    text: `Transaction Timeline: ${JSON.stringify(data)}`,
                },
            ],
        };
    } catch (error) {
        return {
            content: [{ type: "text" as const, text: `Unable to retrive timeline for ${tx_id}` }],
        };
    }
}
export async function resendFailedWebhook({ tx_id }: { tx_id: string }) {
    const transactions = Flutterwave.transactions();
    try {
        const response = await transactions.send_failed_webhook(tx_id);
        const { status, data } = response || { status: 200, data: { status: "successful" }};
        if (!data || !data.status) {
            return {
                content: [{ type: "text" as const, text: `Unable to retrieve ${tx_id}` }],
            };
        }
        if (typeof status === "number" && status >= 400) {
            return {
                content: [{ type: "text" as const, text: `Unable to retrieve ${tx_id}` }],
            };
        }
        return {
            content: [
                {
                    type: "text" as const,
                    text: `webhook Sent`,
                },
            ],
        };
    } catch (error) {
        console.error(`Error fetching transaction ${tx_id}:`, error);
        return {
            content: [{ type: "text" as const, text: `Error retrieving ${tx_id}` }],
        };
    }
};
export async function registerTransactionTools() {
    server.tool(
        "read_transaction",
        "Get Transaction Details",
        TransactionSchema,
        async (args) => {
            return await getTransaction(args);
        }
    );
    server.tool(
        "read_transaction_timeline",
        "Get Transaction Timeline",
        TransactionSchema,
        async (args) => {
            return await getTransactionTimeline(args);
        }
    );
    server.tool(
        "resend_transaction_webhook",
        "Resend Failed Webhook",
        TransactionSchema,
        async (args) => {
            return await resendFailedWebhook(args);
        }
    ); 
}
```
--------------------------------------------------------------------------------
/src/client/types/v3/checkout.d.ts:
--------------------------------------------------------------------------------
```typescript
/**
 * This file was auto-generated by openapi-typescript.
 * Do not make direct changes to the file.
 */
export interface paths {
    "/payments": {
        parameters: {
            query?: never;
            header?: never;
            path?: never;
            cookie?: never;
        };
        get?: never;
        put?: never;
        /**
         * Process a payment through Flutterwave
         * @description Initiates a payment process through Flutterwave using a unique transaction reference.
         */
        post: operations["createPayment"];
        delete?: never;
        options?: never;
        head?: never;
        patch?: never;
        trace?: never;
    };
    "/payments/link/disable": {
        parameters: {
            query?: never;
            header?: never;
            path?: never;
            cookie?: never;
        };
        get?: never;
        put?: never;
        /**
         * Disable a Flutterwave payment link
         * @description Disables a specific payment link for the given URL.
         */
        post: operations["disablePaymentLink"];
        delete?: never;
        options?: never;
        head?: never;
        patch?: never;
        trace?: never;
    };
}
export type webhooks = Record<string, never>;
export interface components {
    schemas: {
        Transaction: Record<string, never>;
    };
    responses: never;
    parameters: never;
    requestBodies: never;
    headers: never;
    pathItems: never;
}
export type $defs = Record<string, never>;
export interface operations {
    createPayment: {
        parameters: {
            query?: never;
            header?: never;
            path?: never;
            cookie?: never;
        };
        /** @description Payment data for the transaction */
        requestBody?: {
            content: {
                "application/json": {
                    /** @example txnref_djsdkjsnkdjvnsdfj */
                    tx_ref: string;
                    /** @example 7500 */
                    amount: string;
                    /** @example NGN */
                    currency: string;
                    /** @example https://example_company.com/success */
                    redirect_url: string;
                    customer: {
                        /** @example [email protected] */
                        email?: string;
                        /** @example Flutterwave Developers */
                        name?: string;
                        /** @example 09012345678 */
                        phonenumber?: string;
                    };
                    customizations: {
                        /** @example Flutterwave Standard Payment */
                        title?: string;
                    };
                };
            };
        };
        responses: never;
    };
    disablePaymentLink: {
        parameters: {
            query?: never;
            header?: never;
            path?: never;
            cookie?: never;
        };
        /** @description Payment link data to disable */
        requestBody?: {
            content: {
                "application/json": {
                    /** @example https://checkout.flutterwave.com/v3/hosted/pay/flwlnk-01j8hkejppgm821xv8mfxfpgrb */
                    link: string;
                };
            };
        };
        responses: {
            /** @description Payment link disabled successfully */
            200: {
                headers: {
                    [name: string]: unknown;
                };
                content: {
                    "application/json": {
                        /** @example success */
                        status?: string;
                        /** @example Payment link has been disabled successfully */
                        message?: string;
                    };
                };
            };
            /** @description Bad request, invalid data */
            400: {
                headers: {
                    [name: string]: unknown;
                };
                content?: never;
            };
            /** @description Unauthorized, invalid API key */
            401: {
                headers: {
                    [name: string]: unknown;
                };
                content?: never;
            };
            /** @description Payment link not found */
            404: {
                headers: {
                    [name: string]: unknown;
                };
                content?: never;
            };
            /** @description Internal server error */
            500: {
                headers: {
                    [name: string]: unknown;
                };
                content?: never;
            };
        };
    };
}
```
--------------------------------------------------------------------------------
/src/client/types/v3/plans.d.ts:
--------------------------------------------------------------------------------
```typescript
/**
 * This file was auto-generated by openapi-typescript.
 * Do not make direct changes to the file.
 */
export interface paths {
    "/plans": {
        parameters: {
            query?: never;
            header?: never;
            path?: never;
            cookie?: never;
        };
        /**
         * Retrieve all subscription plans
         * @description Fetch a list of all subscription plans.
         */
        get: operations["getPlans"];
        put?: never;
        /**
         * Create a new subscription plan
         * @description Create a new subscription plan with specified details.
         */
        post: operations["createPlan"];
        delete?: never;
        options?: never;
        head?: never;
        patch?: never;
        trace?: never;
    };
}
export type webhooks = Record<string, never>;
export interface components {
    schemas: never;
    responses: never;
    parameters: never;
    requestBodies: never;
    headers: never;
    pathItems: never;
}
export type $defs = Record<string, never>;
export interface operations {
    getPlans: {
        parameters: {
            query?: {
                /** @description Page number for pagination */
                page?: number;
                /** @description This is the exact amount set when creating the payment plan */
                amount?: number;
                /** @description This is the currency used for the payment plan */
                currency?: string;
                /** @description This is the status of the payment plan */
                status?: string;
                /** @description This is the interval of the payment plan */
                interval?: string;
                /** @description This is the start date for the payment plan */
                from?: string;
                /** @description This is the end date for the payment plan */
                to?: string;
            };
            header?: never;
            path?: never;
            cookie?: never;
        };
        requestBody?: never;
        responses: {
            /** @description A list of subscription plans */
            200: {
                headers: {
                    [name: string]: unknown;
                };
                content: {
                    "application/json": {
                        /** @example success */
                        status?: string;
                        /** @example Payment plans fetched */
                        message?: string;
                        meta?: {
                            page_info?: {
                                /** @example 10 */
                                current_page?: number;
                                /** @example 1 */
                                total_pages?: number;
                            };
                        };
                        data?: {
                            /** @example pln_123456789 */
                            id?: string;
                            /** @example Premium Plan */
                            name?: string;
                            /** @example 5000 */
                            amount?: number;
                            /** @example monthly */
                            interval?: string;
                            /** @example 12 */
                            duration?: number;
                            /** @example NGN */
                            currency?: string;
                            /** @example active */
                            status?: string;
                            /**
                             * Format: date-time
                             * @example 2023-01-01T00:00:00Z
                             */
                            created_at?: string;
                        }[];
                    };
                };
            };
        };
    };
    createPlan: {
        parameters: {
            query?: never;
            header?: never;
            path?: never;
            cookie?: never;
        };
        /** @description Plan data for the new subscription plan */
        requestBody?: {
            content: {
                "application/json": {
                    /** @example Premium Plan */
                    name: string;
                    /** @example 5000 */
                    amount: number;
                    /** @example monthly */
                    interval: string;
                    /** @example 12 */
                    duration: number;
                    /** @example NGN */
                    currency?: string;
                };
            };
        };
        responses: {
            /** @description Subscription plan created successfully */
            200: {
                headers: {
                    [name: string]: unknown;
                };
                content: {
                    "application/json": {
                        /** @example success */
                        status?: string;
                        /** @example Payment plan created */
                        message?: string;
                        data?: {
                            /** @example pln_123456789 */
                            id?: string;
                            /** @example Premium Plan */
                            name?: string;
                            /** @example 5000 */
                            amount?: number;
                            /** @example monthly */
                            interval?: string;
                            /** @example 12 */
                            duration?: number;
                            /** @example NGN */
                            currency?: string;
                            /** @example active */
                            status?: string;
                            /** @example pln_tok_abcdef123456 */
                            plan_token?: string;
                            /**
                             * Format: date-time
                             * @example 2023-01-01T00:00:00Z
                             */
                            created_at?: string;
                        };
                    };
                };
            };
        };
    };
}
```
--------------------------------------------------------------------------------
/src/client/specs/v3/plan.yaml:
--------------------------------------------------------------------------------
```yaml
openapi: 3.0.3
info:
  title: Flutterwave Transactions API
  description: API for managing and retrieving transaction details via Flutterwave.
  version: 1.0.0
servers:
  - url: https://api.flutterwave.com/v3
paths:
  /plans:
    post:
      summary: Create a new subscription plan
      description: Create a new subscription plan with specified details.
      operationId: createPlan
      requestBody:
        description: Plan data for the new subscription plan
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  example: 'Premium Plan'
                amount:
                  type: integer
                  example: 5000
                interval:
                  type: string
                  example: 'monthly'
                duration:
                  type: integer
                  example: 12
                currency:
                  type: string
                  example: 'NGN'
              required:
                - name
                - amount
                - interval
                - duration
      responses:
        '200':
          description: Subscription plan created successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: 'success'
                  message:
                    type: string
                    example: 'Payment plan created'
                  data:
                    type: object
                    properties:
                      id:
                        type: string
                        example: 'pln_123456789'
                      name:
                        type: string
                        example: 'Premium Plan'
                      amount:
                        type: integer
                        example: 5000
                      interval:
                        type: string
                        example: 'monthly'
                      duration:
                        type: integer
                        example: 12
                      currency:
                        type: string
                        example: 'NGN'
                      status:
                        type: string
                        example: 'active'
                      plan_token:
                        type: string
                        example: 'pln_tok_abcdef123456'
                      created_at:
                        type: string
                        format: date-time
                        example: '2023-01-01T00:00:00Z'
    get:
      summary: Retrieve all subscription plans
      description: Fetch a list of all subscription plans.
      operationId: getPlans
      parameters:
        - in: query
          name: page
          schema:
            type: integer
            example: 1
          description: Page number for pagination
        - in: query
          name: amount
          schema:
            type: integer
            example: 10
          description: This is the exact amount set when creating the payment plan
        - in: query
          name: currency
          schema:
            type: string
            example: 'NGN'
          description: This is the currency used for the payment plan
        - in: query
          name: status
          schema:
            type: string
            example: 'active'
          description: This is the status of the payment plan
        - in: query
          name: interval
          schema:
            type: string
            example: 'monthly'
          description: This is the interval of the payment plan
        - in: query
          name: from
          schema:
            type: string
            example: '2023-01-01'
          description: This is the start date for the payment plan
        - in: query
          name: to
          schema:
            type: string
            example: '2023-12-31'
          description: This is the end date for the payment plan
      responses:
        '200':
          description: A list of subscription plans
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: 'success'
                  message:
                    type: string
                    example: 'Payment plans fetched'
                  meta:
                    type: object
                    properties:
                      page_info:
                        type: object
                        properties:
                          current_page:
                            type: integer
                            example: 10
                          total_pages:
                            type: integer
                            example: 1 
                  data:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: string
                          example: 'pln_123456789'
                        name:
                          type: string
                          example: 'Premium Plan'
                        amount:
                          type: integer
                          example: 5000
                        interval:
                          type: string
                          example: 'monthly'
                        duration:
                          type: integer
                          example: 12
                        currency:
                          type: string
                          example: 'NGN'
                        status:
                          type: string
                          example: 'active'
                        created_at:
                          type: string
                          format: date-time
                          example: '2023-01-01T00:00:00Z'
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
```
--------------------------------------------------------------------------------
/src/client/specs/v3/transactions.yaml:
--------------------------------------------------------------------------------
```yaml
openapi: 3.0.3
info:
  title: Flutterwave Transactions API
  description: API for managing and retrieving transaction details via Flutterwave.
  version: 1.0.0
servers:
  - url: https://api.flutterwave.com/v3
paths:
  /payments:
      post:
        summary: Process a payment through Flutterwave
        description: Initiates a payment process through Flutterwave using a unique transaction reference.
        operationId: createPayment
        requestBody:
          description: Payment data for the transaction
          content:
            application/json:
              schema:
                type: object
                properties:
                  tx_ref:
                    type: string
                    example: 'txnref_djsdkjsnkdjvnsdfj'
                  amount:
                    type: string
                    example: '7500'
                  currency:
                    type: string
                    example: 'NGN'
                  redirect_url:
                    type: string
                    example: 'https://example_company.com/success'
                  customer:
                    type: object
                    properties:
                      email:
                        type: string
                        example: '[email protected]'
                      name:
                        type: string
                        example: 'Flutterwave Developers'
                      phonenumber:
                        type: string
                        example: '09012345678'
                  customizations:
                    type: object
                    properties:
                      title:
                        type: string
                        example: 'Flutterwave Standard Payment'
                required:
                  - tx_ref
                  - amount
                  - currency
                  - redirect_url
                  - customer
                  - customizations
  /transactions/{id}/verify:
    get:
      summary: Retrieve transaction details
      description: Fetch the final status of a transaction using its transaction ID.
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
          description: The unique transaction ID.
      responses:
        "200":
          description: Successfully retrieved transaction details.
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  message:
                    type: string
                    example: Transaction fetched successfully
                  data:
                    type: object
                    properties:
                      id:
                        type: integer
                        example: 4975363
                      tx_ref:
                        type: string
                        example: "1710840858755-RND_83"
                      amount:
                        type: number
                        format: float
                        example: 1000
                      currency:
                        type: string
                        example: NGN
                      status:
                        type: string
                        example: successful
                      created_at:
                        type: string
                        format: date-time
                        example: "2024-03-19T09:34:27.000Z"
        "400":
          description: Bad request, invalid transaction ID.
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: error
                  message:
                    type: string
                    example: "Invalid Transaction ID"
                  data:
                    type: object
                    nullable: true
        "404":
          description: Transaction not found.
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: error
                  message:
                    type: string
                    example: "Transaction not found"
                  data:
                    type: object
                    nullable: true
  /transactions/verify_by_reference:
    get:
      summary: Retrieve transaction details
      description: Fetch the final status of a transaction using its transaction ID.
      parameters:
        - name: tx_ref
          in: query
          required: true
          schema:
            type: string
          description: The unique transaction ID.
      responses:
        "200":
          description: Successfully retrieved transaction details.
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  message:
                    type: string
                    example: Transaction fetched successfully
                  data:
                    type: object
                    properties:
                      id:
                        type: integer
                        example: 4975363
                      tx_ref:
                        type: string
                        example: "1710840858755-RND_83"
                      amount:
                        type: number
                        format: float
                        example: 1000
                      currency:
                        type: string
                        example: NGN
                      status:
                        type: string
                        example: successful
                      created_at:
                        type: string
                        format: date-time
                        example: "2024-03-19T09:34:27.000Z"
        "400":
          description: Bad request, invalid transaction ID.
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: error
                  message:
                    type: string
                    example: "Invalid Transaction ID"
                  data:
                    type: object
                    nullable: true
        "404":
          description: Transaction not found.
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: error
                  message:
                    type: string
                    example: "Transaction not found"
                  data:
                    type: object
                    nullable: true
  /transactions/{id}/resend-hook:
    post:
      summary: Resend failed webhook
      description: Resend failed webhook
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
          description: The unique transaction ID.
  /transactions/{id}/events:
      post:
        summary: Resend failed webhook.
        description: Resend failed webhook.
        parameters:
          - name: id
            in: path
            required: true
            schema:
              type: string
            description: The unique transaction ID.
      security:
        - bearerAuth: []
components:
  schemas:
    Transaction:
      type: object
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
```
--------------------------------------------------------------------------------
/src/client/types/v3.d.ts:
--------------------------------------------------------------------------------
```typescript
/**
 * This file was auto-generated by openapi-typescript.
 * Do not make direct changes to the file.
 */
export interface paths {
    "/payments": {
        parameters: {
            query?: never;
            header?: never;
            path?: never;
            cookie?: never;
        };
        get?: never;
        put?: never;
        /**
         * Process a payment through Flutterwave
         * @description Initiates a payment process through Flutterwave using a unique transaction reference.
         */
        post: operations["createPayment"];
        delete?: never;
        options?: never;
        head?: never;
        patch?: never;
        trace?: never;
    };
    "/transactions/{id}/verify": {
        parameters: {
            query?: never;
            header?: never;
            path?: never;
            cookie?: never;
        };
        /**
         * Retrieve transaction details
         * @description Fetch the final status of a transaction using its transaction ID.
         */
        get: {
            parameters: {
                query?: never;
                header?: never;
                path: {
                    /** @description The unique transaction ID. */
                    id: string;
                };
                cookie?: never;
            };
            requestBody?: never;
            responses: {
                /** @description Successfully retrieved transaction details. */
                200: {
                    headers: {
                        [name: string]: unknown;
                    };
                    content: {
                        "application/json": {
                            /** @example success */
                            status?: string;
                            /** @example Transaction fetched successfully */
                            message?: string;
                            data?: {
                                /** @example 4975363 */
                                id?: number;
                                /** @example 1710840858755-RND_83 */
                                tx_ref?: string;
                                /**
                                 * Format: float
                                 * @example 1000
                                 */
                                amount?: number;
                                /** @example NGN */
                                currency?: string;
                                /** @example successful */
                                status?: string;
                                /**
                                 * Format: date-time
                                 * @example 2024-03-19T09:34:27.000Z
                                 */
                                created_at?: string;
                            };
                        };
                    };
                };
                /** @description Bad request, invalid transaction ID. */
                400: {
                    headers: {
                        [name: string]: unknown;
                    };
                    content: {
                        "application/json": {
                            /** @example error */
                            status?: string;
                            /** @example Invalid Transaction ID */
                            message?: string;
                            data?: Record<string, never> | null;
                        };
                    };
                };
                /** @description Transaction not found. */
                404: {
                    headers: {
                        [name: string]: unknown;
                    };
                    content: {
                        "application/json": {
                            /** @example error */
                            status?: string;
                            /** @example Transaction not found */
                            message?: string;
                            data?: Record<string, never> | null;
                        };
                    };
                };
            };
        };
        put?: never;
        post?: never;
        delete?: never;
        options?: never;
        head?: never;
        patch?: never;
        trace?: never;
    };
    "/transactions/verify_by_reference": {
        parameters: {
            query?: never;
            header?: never;
            path?: never;
            cookie?: never;
        };
        /**
         * Retrieve transaction details
         * @description Fetch the final status of a transaction using its transaction ID.
         */
        get: {
            parameters: {
                query: {
                    /** @description The unique transaction ID. */
                    tx_ref: string;
                };
                header?: never;
                path?: never;
                cookie?: never;
            };
            requestBody?: never;
            responses: {
                /** @description Successfully retrieved transaction details. */
                200: {
                    headers: {
                        [name: string]: unknown;
                    };
                    content: {
                        "application/json": {
                            /** @example success */
                            status?: string;
                            /** @example Transaction fetched successfully */
                            message?: string;
                            data?: {
                                /** @example 4975363 */
                                id?: number;
                                /** @example 1710840858755-RND_83 */
                                tx_ref?: string;
                                /**
                                 * Format: float
                                 * @example 1000
                                 */
                                amount?: number;
                                /** @example NGN */
                                currency?: string;
                                /** @example successful */
                                status?: string;
                                /**
                                 * Format: date-time
                                 * @example 2024-03-19T09:34:27.000Z
                                 */
                                created_at?: string;
                            };
                        };
                    };
                };
                /** @description Bad request, invalid transaction ID. */
                400: {
                    headers: {
                        [name: string]: unknown;
                    };
                    content: {
                        "application/json": {
                            /** @example error */
                            status?: string;
                            /** @example Invalid Transaction ID */
                            message?: string;
                            data?: Record<string, never> | null;
                        };
                    };
                };
                /** @description Transaction not found. */
                404: {
                    headers: {
                        [name: string]: unknown;
                    };
                    content: {
                        "application/json": {
                            /** @example error */
                            status?: string;
                            /** @example Transaction not found */
                            message?: string;
                            data?: Record<string, never> | null;
                        };
                    };
                };
            };
        };
        put?: never;
        post?: never;
        delete?: never;
        options?: never;
        head?: never;
        patch?: never;
        trace?: never;
    };
    "/transactions/{id}/resend-hook": {
        parameters: {
            query?: never;
            header?: never;
            path?: never;
            cookie?: never;
        };
        get?: never;
        put?: never;
        /**
         * Resend failed webhook
         * @description Resend failed webhook
         */
        post: {
            parameters: {
                query?: never;
                header?: never;
                path: {
                    /** @description The unique transaction ID. */
                    id: string;
                };
                cookie?: never;
            };
            requestBody?: never;
            responses: never;
        };
        delete?: never;
        options?: never;
        head?: never;
        patch?: never;
        trace?: never;
    };
    "/transactions/{id}/events": {
        parameters: {
            query?: never;
            header?: never;
            path?: never;
            cookie?: never;
        };
        get?: never;
        put?: never;
        /**
         * Resend failed webhook.
         * @description Resend failed webhook.
         */
        post: {
            parameters: {
                query?: never;
                header?: never;
                path: {
                    /** @description The unique transaction ID. */
                    id: string;
                };
                cookie?: never;
            };
            requestBody?: never;
            responses: never;
        };
        delete?: never;
        options?: never;
        head?: never;
        patch?: never;
        trace?: never;
    };
}
export type webhooks = Record<string, never>;
export interface components {
    schemas: {
        Transaction: Record<string, never>;
    };
    responses: never;
    parameters: never;
    requestBodies: never;
    headers: never;
    pathItems: never;
}
export type $defs = Record<string, never>;
export interface operations {
    createPayment: {
        parameters: {
            query?: never;
            header?: never;
            path?: never;
            cookie?: never;
        };
        /** @description Payment data for the transaction */
        requestBody?: {
            content: {
                "application/json": {
                    /** @example txnref_djsdkjsnkdjvnsdfj */
                    tx_ref: string;
                    /** @example 7500 */
                    amount: string;
                    /** @example NGN */
                    currency: string;
                    /** @example https://example_company.com/success */
                    redirect_url: string;
                    customer: {
                        /** @example [email protected] */
                        email?: string;
                        /** @example Flutterwave Developers */
                        name?: string;
                        /** @example 09012345678 */
                        phonenumber?: string;
                    };
                    customizations: {
                        /** @example Flutterwave Standard Payment */
                        title?: string;
                    };
                };
            };
        };
        responses: never;
    };
}
```
--------------------------------------------------------------------------------
/src/client/types/v3/transactions.d.ts:
--------------------------------------------------------------------------------
```typescript
/**
 * This file was auto-generated by openapi-typescript.
 * Do not make direct changes to the file.
 */
export interface paths {
    "/payments": {
        parameters: {
            query?: never;
            header?: never;
            path?: never;
            cookie?: never;
        };
        get?: never;
        put?: never;
        /**
         * Process a payment through Flutterwave
         * @description Initiates a payment process through Flutterwave using a unique transaction reference.
         */
        post: operations["createPayment"];
        delete?: never;
        options?: never;
        head?: never;
        patch?: never;
        trace?: never;
    };
    "/transactions/{id}/verify": {
        parameters: {
            query?: never;
            header?: never;
            path?: never;
            cookie?: never;
        };
        /**
         * Retrieve transaction details
         * @description Fetch the final status of a transaction using its transaction ID.
         */
        get: {
            parameters: {
                query?: never;
                header?: never;
                path: {
                    /** @description The unique transaction ID. */
                    id: string;
                };
                cookie?: never;
            };
            requestBody?: never;
            responses: {
                /** @description Successfully retrieved transaction details. */
                200: {
                    headers: {
                        [name: string]: unknown;
                    };
                    content: {
                        "application/json": {
                            /** @example success */
                            status?: string;
                            /** @example Transaction fetched successfully */
                            message?: string;
                            data?: {
                                /** @example 4975363 */
                                id?: number;
                                /** @example 1710840858755-RND_83 */
                                tx_ref?: string;
                                /**
                                 * Format: float
                                 * @example 1000
                                 */
                                amount?: number;
                                /** @example NGN */
                                currency?: string;
                                /** @example successful */
                                status?: string;
                                /**
                                 * Format: date-time
                                 * @example 2024-03-19T09:34:27.000Z
                                 */
                                created_at?: string;
                            };
                        };
                    };
                };
                /** @description Bad request, invalid transaction ID. */
                400: {
                    headers: {
                        [name: string]: unknown;
                    };
                    content: {
                        "application/json": {
                            /** @example error */
                            status?: string;
                            /** @example Invalid Transaction ID */
                            message?: string;
                            data?: Record<string, never> | null;
                        };
                    };
                };
                /** @description Transaction not found. */
                404: {
                    headers: {
                        [name: string]: unknown;
                    };
                    content: {
                        "application/json": {
                            /** @example error */
                            status?: string;
                            /** @example Transaction not found */
                            message?: string;
                            data?: Record<string, never> | null;
                        };
                    };
                };
            };
        };
        put?: never;
        post?: never;
        delete?: never;
        options?: never;
        head?: never;
        patch?: never;
        trace?: never;
    };
    "/transactions/verify_by_reference": {
        parameters: {
            query?: never;
            header?: never;
            path?: never;
            cookie?: never;
        };
        /**
         * Retrieve transaction details
         * @description Fetch the final status of a transaction using its transaction ID.
         */
        get: {
            parameters: {
                query: {
                    /** @description The unique transaction ID. */
                    tx_ref: string;
                };
                header?: never;
                path?: never;
                cookie?: never;
            };
            requestBody?: never;
            responses: {
                /** @description Successfully retrieved transaction details. */
                200: {
                    headers: {
                        [name: string]: unknown;
                    };
                    content: {
                        "application/json": {
                            /** @example success */
                            status?: string;
                            /** @example Transaction fetched successfully */
                            message?: string;
                            data?: {
                                /** @example 4975363 */
                                id?: number;
                                /** @example 1710840858755-RND_83 */
                                tx_ref?: string;
                                /**
                                 * Format: float
                                 * @example 1000
                                 */
                                amount?: number;
                                /** @example NGN */
                                currency?: string;
                                /** @example successful */
                                status?: string;
                                /**
                                 * Format: date-time
                                 * @example 2024-03-19T09:34:27.000Z
                                 */
                                created_at?: string;
                            };
                        };
                    };
                };
                /** @description Bad request, invalid transaction ID. */
                400: {
                    headers: {
                        [name: string]: unknown;
                    };
                    content: {
                        "application/json": {
                            /** @example error */
                            status?: string;
                            /** @example Invalid Transaction ID */
                            message?: string;
                            data?: Record<string, never> | null;
                        };
                    };
                };
                /** @description Transaction not found. */
                404: {
                    headers: {
                        [name: string]: unknown;
                    };
                    content: {
                        "application/json": {
                            /** @example error */
                            status?: string;
                            /** @example Transaction not found */
                            message?: string;
                            data?: Record<string, never> | null;
                        };
                    };
                };
            };
        };
        put?: never;
        post?: never;
        delete?: never;
        options?: never;
        head?: never;
        patch?: never;
        trace?: never;
    };
    "/transactions/{id}/resend-hook": {
        parameters: {
            query?: never;
            header?: never;
            path?: never;
            cookie?: never;
        };
        get?: never;
        put?: never;
        /**
         * Resend failed webhook
         * @description Resend failed webhook
         */
        post: {
            parameters: {
                query?: never;
                header?: never;
                path: {
                    /** @description The unique transaction ID. */
                    id: string;
                };
                cookie?: never;
            };
            requestBody?: never;
            responses: never;
        };
        delete?: never;
        options?: never;
        head?: never;
        patch?: never;
        trace?: never;
    };
    "/transactions/{id}/events": {
        parameters: {
            query?: never;
            header?: never;
            path?: never;
            cookie?: never;
        };
        get?: never;
        put?: never;
        /**
         * Resend failed webhook.
         * @description Resend failed webhook.
         */
        post: {
            parameters: {
                query?: never;
                header?: never;
                path: {
                    /** @description The unique transaction ID. */
                    id: string;
                };
                cookie?: never;
            };
            requestBody?: never;
            responses: never;
        };
        delete?: never;
        options?: never;
        head?: never;
        patch?: never;
        trace?: never;
    };
}
export type webhooks = Record<string, never>;
export interface components {
    schemas: {
        Transaction: Record<string, never>;
    };
    responses: never;
    parameters: never;
    requestBodies: never;
    headers: never;
    pathItems: never;
}
export type $defs = Record<string, never>;
export interface operations {
    createPayment: {
        parameters: {
            query?: never;
            header?: never;
            path?: never;
            cookie?: never;
        };
        /** @description Payment data for the transaction */
        requestBody?: {
            content: {
                "application/json": {
                    /** @example txnref_djsdkjsnkdjvnsdfj */
                    tx_ref: string;
                    /** @example 7500 */
                    amount: string;
                    /** @example NGN */
                    currency: string;
                    /** @example https://example_company.com/success */
                    redirect_url: string;
                    customer: {
                        /** @example [email protected] */
                        email?: string;
                        /** @example Flutterwave Developers */
                        name?: string;
                        /** @example 09012345678 */
                        phonenumber?: string;
                    };
                    customizations: {
                        /** @example Flutterwave Standard Payment */
                        title?: string;
                    };
                };
            };
        };
        responses: never;
    };
}
```