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 TeamCore Features
- Payment collections
- Virtual account creation for customers
- Real-time transaction monitoring
- Webhook notifications for events
- Secure authentication with API keys
- Comprehensive transaction history
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
| Header | Format | Required | Description |
|---|---|---|---|
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.
Request Parameters
| Parameter | Type | Required | Validation | Description |
|---|---|---|---|---|
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.
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 SupportWebhook Events
Transaction Events
| Event Name | Description | Trigger |
|---|---|---|
transaction.initiated | A transaction has been initiated | Customer starts a payment |
transaction.completed | A transaction has been completed successfully | Payment is successfully processed |
transaction.failed | A transaction has failed | Payment processing failed |
transaction.reversed | A transaction has been reversed | Refund or reversal processed |
Virtual Account Events
| Event Name | Description | Trigger |
|---|---|---|
va.created | Virtual account created | New virtual account is created |
va.activated | Virtual account activated | Account 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 HelpCreate 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
Error Codes
HTTP Status Codes
| Status | Code | Description |
|---|---|---|
| 200 | OK | Request successful |
| 400 | Bad Request | Invalid parameters |
| 401 | Unauthorized | Invalid API keys |
| 403 | Forbidden | Insufficient permissions |
| 404 | Not Found | Resource not found |
| 500 | Server Error | Internal server issue |
Still having issues?
Our support team is available 24/7 to help you resolve any errors.
Get Free Support