Transfer NGN for free between customer wallets
curl --request POST \
--url https://api-production.fossapay.com/api/v1/wallets/fiat/transfers/wallet-to-wallet \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"fromAccount": "<string>",
"toAccount": "<string>",
"amount": 123,
"reference": "<string>",
"narration": "<string>"
}
'import requests
url = "https://api-production.fossapay.com/api/v1/wallets/fiat/transfers/wallet-to-wallet"
payload = {
"fromAccount": "<string>",
"toAccount": "<string>",
"amount": 123,
"reference": "<string>",
"narration": "<string>"
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
fromAccount: '<string>',
toAccount: '<string>',
amount: 123,
reference: '<string>',
narration: '<string>'
})
};
fetch('https://api-production.fossapay.com/api/v1/wallets/fiat/transfers/wallet-to-wallet', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api-production.fossapay.com/api/v1/wallets/fiat/transfers/wallet-to-wallet",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'fromAccount' => '<string>',
'toAccount' => '<string>',
'amount' => 123,
'reference' => '<string>',
'narration' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api-production.fossapay.com/api/v1/wallets/fiat/transfers/wallet-to-wallet"
payload := strings.NewReader("{\n \"fromAccount\": \"<string>\",\n \"toAccount\": \"<string>\",\n \"amount\": 123,\n \"reference\": \"<string>\",\n \"narration\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api-production.fossapay.com/api/v1/wallets/fiat/transfers/wallet-to-wallet")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"fromAccount\": \"<string>\",\n \"toAccount\": \"<string>\",\n \"amount\": 123,\n \"reference\": \"<string>\",\n \"narration\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api-production.fossapay.com/api/v1/wallets/fiat/transfers/wallet-to-wallet")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"fromAccount\": \"<string>\",\n \"toAccount\": \"<string>\",\n \"amount\": 123,\n \"reference\": \"<string>\",\n \"narration\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"status": "success",
"statusCode": 201,
"message": "Wallet transfer successfull"
}
{
"status": "error",
"statusCode": 403,
"message": "The destination wallet you are trying to access does not belong to your business"
}
NGN Transfers
Wallet-to-Wallet Transfer (Free)
Transfer NGN for free between two customers under the same business
POST
/
api
/
v1
/
wallets
/
fiat
/
transfers
/
wallet-to-wallet
Transfer NGN for free between customer wallets
curl --request POST \
--url https://api-production.fossapay.com/api/v1/wallets/fiat/transfers/wallet-to-wallet \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"fromAccount": "<string>",
"toAccount": "<string>",
"amount": 123,
"reference": "<string>",
"narration": "<string>"
}
'import requests
url = "https://api-production.fossapay.com/api/v1/wallets/fiat/transfers/wallet-to-wallet"
payload = {
"fromAccount": "<string>",
"toAccount": "<string>",
"amount": 123,
"reference": "<string>",
"narration": "<string>"
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
fromAccount: '<string>',
toAccount: '<string>',
amount: 123,
reference: '<string>',
narration: '<string>'
})
};
fetch('https://api-production.fossapay.com/api/v1/wallets/fiat/transfers/wallet-to-wallet', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api-production.fossapay.com/api/v1/wallets/fiat/transfers/wallet-to-wallet",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'fromAccount' => '<string>',
'toAccount' => '<string>',
'amount' => 123,
'reference' => '<string>',
'narration' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api-production.fossapay.com/api/v1/wallets/fiat/transfers/wallet-to-wallet"
payload := strings.NewReader("{\n \"fromAccount\": \"<string>\",\n \"toAccount\": \"<string>\",\n \"amount\": 123,\n \"reference\": \"<string>\",\n \"narration\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api-production.fossapay.com/api/v1/wallets/fiat/transfers/wallet-to-wallet")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"fromAccount\": \"<string>\",\n \"toAccount\": \"<string>\",\n \"amount\": 123,\n \"reference\": \"<string>\",\n \"narration\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api-production.fossapay.com/api/v1/wallets/fiat/transfers/wallet-to-wallet")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"fromAccount\": \"<string>\",\n \"toAccount\": \"<string>\",\n \"amount\": 123,\n \"reference\": \"<string>\",\n \"narration\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"status": "success",
"statusCode": 201,
"message": "Wallet transfer successfull"
}
{
"status": "error",
"statusCode": 403,
"message": "The destination wallet you are trying to access does not belong to your business"
}
Move funds instantly between two FossaPay NGN wallets belonging to customers under your business. Wallet-to-wallet transfers are free.
Use this endpoint only when both the sender and recipient are FossaPay customers created under the same business and both account numbers belong to their FossaPay NGN wallets.
To send money to an account at another bank, use the Inter-Bank Transfer endpoint instead.
Request
string
required
API Key for authentication
string
required
FossaPay NGN wallet account number belonging to the sending customer
string
required
FossaPay NGN wallet account number belonging to another customer under the same business
number
required
Transfer amount
string
required
A unique transfer reference. Do not reuse a reference from a failed, reversed, cancelled, or otherwise completed transfer.
string
required
A non-empty transfer narration or description, up to 255 characters. It may match your reference, but it does not need to.
Request Example
curl -X POST https://api-production.fossapay.com/api/v1/wallets/fiat/transfers/wallet-to-wallet \
-H "x-api-key: $FOSSAPAY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"fromAccount": "1234567890",
"toAccount": "0987654321",
"amount": 5000,
"reference": "transfer_ref_001",
"narration": "Payment for services"
}'
const response = await fetch('https://api-production.fossapay.com/api/v1/wallets/fiat/transfers/wallet-to-wallet', {
method: 'POST',
headers: {
'x-api-key': process.env.FOSSAPAY_API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({
fromAccount: '1234567890',
toAccount: '0987654321',
amount: 5000,
reference: 'transfer_ref_001',
narration: 'Payment for services'
})
});
const data = await response.json();
import os
import requests
url = "https://api-production.fossapay.com/api/v1/wallets/fiat/transfers/wallet-to-wallet"
headers = {
"x-api-key": os.environ["FOSSAPAY_API_KEY"],
"Content-Type": "application/json"
}
data = {
"fromAccount": "1234567890",
"toAccount": "0987654321",
"amount": 5000,
"reference": "transfer_ref_001",
"narration": "Payment for services"
}
response = requests.post(url, headers=headers, json=data)
data = response.json()
Response
No transfer fee is charged for a successful wallet-to-wallet transfer.string
success when the synchronous wallet transfer completes.number
HTTP status code. Successful submission currently returns
201.string
Human-readable response message
Response Example
{
"status": "success",
"statusCode": 201,
"message": "Wallet transfer successfull"
}
{
"status": "error",
"statusCode": 403,
"message": "The destination wallet you are trying to access does not belong to your business"
}
Errors
| Status | Typical cause |
|---|---|
400 | Insufficient funds, provider rejection, or the reference is already processing |
401 | Missing or invalid API key |
403 | Source or destination wallet belongs to another merchant |
404 | Source or destination account not found |
409 | Transaction reference has already been used |
422 | Missing field, non-positive amount, or invalid narration |
Confirm that both account numbers belong to customers under your business before initiating the free internal transfer. If a successful request is retried with its original reference, FossaPay returns the existing successful result without moving funds again.
Authorizations
Body
application/json

