Welcome to Fundsvera API

Fundsvera provides a comprehensive suite of payment and virtual account payment collections APIs. Our infrastructure enables businesses to accept payments, create, manage, and monitor virtual accounts seamlessly.

Free API Integration Support! 🎉

We offer FREE integration assistance to help you get started quickly. Our team of experts is ready to help you integrate our APIs seamlessly.

Contact Our Integration Team

Core Features

  • Payment collections
  • Virtual account creation for customers
  • Real-time transaction monitoring
  • Webhook notifications for events
  • Secure authentication with API keys
  • Comprehensive transaction history
Base URL: https://fundsvera.co/api/v1

Authentication

All API requests require authentication using your API keys in the request headers.

API Credentials

After business onboarding, you will receive:

  • Public Key - Your business public identifier
  • Secret Key - Your private authentication key (keep secret!)

Required Headers

HeaderFormatRequiredDescription
Authorization Bearer {secret_key} Yes Your business secret key
Public-Key {public_key} Yes Your business public key
Content-Type application/json Yes Request body format

Create Virtual Account

Create a virtual bank account for a customer. If an account already exists, it will be returned instead of creating a duplicate.

POST
https://fundsvera.co/api/v1/create-virtual-account

Request Parameters

ParameterTypeRequiredValidationDescription
email string Yes Valid email format Customer's email address
name string Yes Alphanumeric, spaces, dashes Customer's full name
bank_code string Yes Must be "100033" Bank code (currently Palmpay)
phone string No Exactly 11 digits Customer's phone number

Example Request

{
    "email": "[email protected]",
    "name": "John Doe",
    "bank_code": "100033",
    "phone": "08012345678"
}

Success Response (200 OK)

{
    "status": "SUCCESS",
    "message": "Virtual account number is now created and activated",
    "customer": {
        "customer_email": "[email protected]",
        "customer_phone": "08012345678",
        "customer_name": "John Doe"
    },
    "virtual_account": {
        "bank_name": "Palmpay",
        "account_name": "Fundsvera - Joh Fv",
        "account_number": "1234567890",
        "bank_code": "100033",
        "account_status": "Active"
    },
    "business": {
        "business_name": "Your Business Name",
        "business_email": "[email protected]"
    }
}

Get Virtual Account

Retrieve details of a specific virtual account.

GET
https://fundsvera.co/api/v1/virtual-account/{account_number}
This endpoint is coming soon. Stay tuned for updates!

Webhooks Overview

Webhooks allow you to receive real-time notifications about events happening in your account.

What are Webhooks?

Webhooks are HTTP callbacks that Fundsvera sends to your server when specific events occur. Instead of polling our API for updates, you can configure a webhook endpoint to receive notifications instantly.

Need Help Setting Up Webhooks?

Our integration team can help you set up and test webhooks for free!

Get Free Webhook Support

Webhook Events

Transaction Events

Event NameDescriptionTrigger
transaction.initiatedA transaction has been initiatedCustomer starts a payment
transaction.completedA transaction has been completed successfullyPayment is successfully processed
transaction.failedA transaction has failedPayment processing failed
transaction.reversedA transaction has been reversedRefund or reversal processed

Virtual Account Events

Event NameDescriptionTrigger
va.createdVirtual account createdNew virtual account is created
va.activatedVirtual account activatedAccount status changed to Active

Webhook Payload Example

{
    "event": "transaction.completed",
    "timestamp": "2024-01-15T10:30:00Z",
    "data": {
        "transaction_id": "TX123456789",
        "amount": 5000.00,
        "currency": "NGN",
        "account_number": "1234567890",
        "customer_email": "[email protected]",
        "customer_name": "John Doe",
        "reference": "REF123456",
        "status": "successful"
    }
}

Webhook Security

Fundsvera signs all webhook payloads to ensure they're genuinely from us.

Signature Verification

Each webhook request includes a signature in the X-Fundsvera-Signature header.

Verification Code Examples

<?php
function verifyWebhookSignature($payload, $signature, $webhookSecret) {
    $computedSignature = hash_hmac('sha256', $payload, $webhookSecret);
    return hash_equals($computedSignature, $signature);
}

// Get webhook data
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_FUNDSVERA_SIGNATURE'] ?? '';
$webhookSecret = 'your_webhook_secret';

if (verifyWebhookSignature($payload, $signature, $webhookSecret)) {
    $data = json_decode($payload, true);
    
    // Process the webhook
    if ($data['event'] == 'transaction.completed') {
        // Handle successful transaction
        file_put_contents('transactions.log', print_r($data, true), FILE_APPEND);
    }
    
    http_response_code(200);
    echo json_encode(['status' => 'received']);
} else {
    http_response_code(401);
    echo json_encode(['error' => 'Invalid signature']);
}
?>
const crypto = require('crypto');

function verifyWebhookSignature(payload, signature, webhookSecret) {
    const computedSignature = crypto
        .createHmac('sha256', webhookSecret)
        .update(payload)
        .digest('hex');
    return crypto.timingSafeEqual(
        Buffer.from(computedSignature),
        Buffer.from(signature)
    );
}

// Express.js example
app.post('/webhook', (req, res) => {
    const payload = JSON.stringify(req.body);
    const signature = req.headers['x-fundsvera-signature'];
    const webhookSecret = 'your_webhook_secret';
    
    if (verifyWebhookSignature(payload, signature, webhookSecret)) {
        const event = req.body;
        
        if (event.event === 'transaction.completed') {
            console.log('Transaction completed:', event.data);
            // Process transaction
        }
        
        res.status(200).json({ status: 'received' });
    } else {
        res.status(401).json({ error: 'Invalid signature' });
    }
});
import hmac
import hashlib
import json
from flask import Flask, request, jsonify

app = Flask(__name__)
WEBHOOK_SECRET = 'your_webhook_secret'

def verify_signature(payload, signature):
    computed = hmac.new(
        WEBHOOK_SECRET.encode('utf-8'),
        payload.encode('utf-8'),
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(computed, signature)

@app.route('/webhook', methods=['POST'])
def webhook():
    payload = request.get_data(as_text=True)
    signature = request.headers.get('X-Fundsvera-Signature', '')
    
    if verify_signature(payload, signature):
        data = request.get_json()
        
        if data.get('event') == 'transaction.completed':
            # Process successful transaction
            print(f"Transaction completed: {data['data']}")
        
        return jsonify({'status': 'received'}), 200
    else:
        return jsonify({'error': 'Invalid signature'}), 401

if __name__ == '__main__':
    app.run(port=3000)

Code Samples

Ready-to-use code examples for integrating with Fundsvera API.

Free Integration Support

Can't figure out the integration? Our team will help you for FREE!

Schedule Free Integration Help

Create Virtual Account - API Request

<?php
$curl = curl_init();

curl_setopt_array($curl, [
    CURLOPT_URL => 'https://fundsvera.co/api/v1/create-virtual-account',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer YOUR_SECRET_KEY',
        'Public-Key: YOUR_PUBLIC_KEY',
        'Content-Type: application/json'
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'email' => '[email protected]',
        'name' => 'John Doe',
        'bank_code' => '100033',
        'phone' => '08012345678'
    ])
]);

$response = curl_exec($curl);
$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);


?>
const axios = require('axios');

async function createVirtualAccount() {
    try {
        const response = await axios.post(
            'https://fundsvera.co/api/v1/create-virtual-account',
            {
                email: '[email protected]',
                name: 'John Doe',
                bank_code: '100033',
                phone: '08012345678'
            },
            {
                headers: {
                    'Authorization': 'Bearer YOUR_SECRET_KEY',
                    'Public-Key': 'YOUR_PUBLIC_KEY',
                    'Content-Type': 'application/json'
                }
            }
        );
  }
}
createVirtualAccount();
import requests

url = "https://fundsvera.co/api/v1/create-virtual-account"

headers = {
    "Authorization": "Bearer YOUR_SECRET_KEY",
    "Public-Key": "YOUR_PUBLIC_KEY",
    "Content-Type": "application/json"
}

payload = {
    "email": "[email protected]",
    "name": "John Doe",
    "bank_code": "100033",
    "phone": "08012345678"
}

response = requests.post(url, json=payload, headers=headers)

curl -X POST https://fundsvera.co/api/v1/create-virtual-account \
  -H "Authorization: Bearer YOUR_SECRET_KEY" \
  -H "Public-Key: YOUR_PUBLIC_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "name": "John Doe",
    "bank_code": "100033",
    "phone": "08012345678"
  }'

Webhook Handler - Receive Notifications

<?php
// webhook.php - Your webhook endpoint
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_FUNDSVERA_SIGNATURE'] ?? '';
$webhookSecret = 'your_webhook_secret';

// Verify signature
$computedSignature = hash_hmac('sha256', $payload, $webhookSecret);

if (hash_equals($computedSignature, $signature)) {
    $data = json_decode($payload, true);
    
    switch($data['event']) {
        case 'transaction.completed':
            // Handle successful payment
            $amount = $data['data']['amount'];
            $account = $data['data']['account_number'];
            $ref = $data['data']['reference'];
            
            // Update your database
            // Send email notification
            // Trigger business logic
            
            error_log("Payment received: $amount on account $account");
            break;
            
        case 'transaction.failed':
            // Handle failed transaction
            error_log("Transaction failed: " . $data['data']['reference']);
            break;
            
        case 'va.created':
            // New virtual account created
            error_log("New VA created: " . $data['data']['account_number']);
            break;
    }
    
    http_response_code(200);
    echo json_encode(['status' => 'received']);
} else {
    http_response_code(401);
    echo json_encode(['error' => 'Invalid signature']);
}
?>
const express = require('express');
const crypto = require('crypto');
const app = express();

app.use(express.json());

const WEBHOOK_SECRET = 'your_webhook_secret';

function verifySignature(payload, signature) {
    const computed = crypto
        .createHmac('sha256', WEBHOOK_SECRET)
        .update(payload)
        .digest('hex');
    return crypto.timingSafeEqual(Buffer.from(computed), Buffer.from(signature));
}

app.post('/webhook', (req, res) => {
    const payload = JSON.stringify(req.body);
    const signature = req.headers['x-fundsvera-signature'];
    
    if (!verifySignature(payload, signature)) {
        return res.status(401).json({ error: 'Invalid signature' });
    }
    
    const event = req.body;
    
    // Handle different event types
    switch(event.event) {
        case 'transaction.completed':
            console.log(`✅ Payment received: ₦${event.data.amount}`);
            console.log(`Account: ${event.data.account_number}`);
            console.log(`Reference: ${event.data.reference}`);
            // Update your database here
            break;
            
        case 'transaction.failed':
            console.log(`❌ Transaction failed: ${event.data.reference}`);
            break;
            
        case 'va.created':
            console.log(`🎉 New VA created: ${event.data.virtual_account.account_number}`);
            break;
    }
    
    res.status(200).json({ status: 'received' });
});

app.listen(3000, () => {
    console.log('Webhook server running on port 3000');
});
from flask import Flask, request, jsonify
import hmac
import hashlib
import json
import logging

app = Flask(__name__)
WEBHOOK_SECRET = 'your_webhook_secret'

logging.basicConfig(level=logging.INFO)

def verify_signature(payload, signature):
    computed = hmac.new(
        WEBHOOK_SECRET.encode('utf-8'),
        payload.encode('utf-8'),
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(computed, signature)

@app.route('/webhook', methods=['POST'])
def webhook():
    payload = request.get_data(as_text=True)
    signature = request.headers.get('X-Fundsvera-Signature', '')
    
    if not verify_signature(payload, signature):
        return jsonify({'error': 'Invalid signature'}), 401
    
    data = request.get_json()
    event = data.get('event')
    
    if event == 'transaction.completed':
        tx_data = data['data']
        logging.info(f"Payment received: ₦{tx_data['amount']}")
        logging.info(f"Account: {tx_data['account_number']}")
        logging.info(f"Reference: {tx_data['reference']}")
        
        # Update your database here
        # Send notifications
        
    elif event == 'transaction.failed':
        logging.warning(f"Failed transaction: {data['data']['reference']}")
        
    elif event == 'va.created':
        logging.info(f"New VA: {data['data']['virtual_account']['account_number']}")
    
    return jsonify({'status': 'received'}), 200

if __name__ == '__main__':
    app.run(port=3000, debug=True)

Coming Soon

Upcoming Features

  • 📊 Transaction History - Retrieve detailed transaction history
  • 💰 Balance Inquiry - Check virtual account balances
  • 🔄 Bulk Operations - Create multiple accounts at once
  • 📱 USSD Integration - USSD payment capabilities
  • 📈 Analytics & Reporting - Advanced analytics dashboard

Be the first to know!

Subscribe to our newsletter for early access to new features.

Notify Me

Error Codes

HTTP Status Codes

StatusCodeDescription
200OKRequest successful
400Bad RequestInvalid parameters
401UnauthorizedInvalid API keys
403ForbiddenInsufficient permissions
404Not FoundResource not found
500Server ErrorInternal server issue

Still having issues?

Our support team is available 24/7 to help you resolve any errors.

Get Free Support