POST https://mybundlepay.com/ng/api/v2/virtual-card/topup

KEY USAGE POLICY

Important: Use your test_secret_key for sandbox testing. Switch to live_secret_key only when you are ready to go live.

  • Test calls return mock data and do not process real transactions.
  • Live calls top-up real virtual cards.
  • Ensure your server IP is whitelisted before calling live endpoints.

⚠️ Do not use live keys for testing — unauthorized IPs will be blocked.

HEADERS

Authorization * string

Send your {secret_key} as a Bearer token in the header.

Content-Type * application/json

All requests must use JSON body format.

IP WHITELISTING

Only authorized server IPs can access this endpoint. Whitelist your IP in MyBundlePay Dashboard.

BODY PARAMS

Parameter Required Description
amount Amount to fund the card (USD). Minimum $1.
card_account_id Unique card account ID (from card creation response).
reference Unique reference for tracking this top-up request.

<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://mybundlepay.com/ng/api/v2/virtual-card/topup',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS =>'{
    "amount": 10,
    "card_account_id": "xxxxxxxxxxxxxxxxxxxxxxxx",
    "reference": "TOPUP-MBP-00001"
}',
  CURLOPT_HTTPHEADER => array(
    'Content-Type: application/json',
    'Authorization: Bearer {secret_key}'
  ),
));

$response = curl_exec($curl);
curl_close($curl);
echo $response;
?>

const axios = require('axios');

const data = {
  amount: 10,
  card_account_id: "xxxxxxxxxxxxxxxxxxxxxxxx",
  reference: "TOPUP-MBP-00001"
};

axios.post("https://mybundlepay.com/ng/api/v2/virtual-card/topup", data, {
  headers: {
    "Content-Type": "application/json",
    "Authorization": "Bearer {secret_key}"
  }
})
.then(res => console.log(res.data))
.catch(err => console.error(err.response ? err.response.data : err.message));
✅ Success Response

{
    "status": "success",
    "statusCode": 200,
    "message": "card topup successful",
    "amount": 10,
    "narration": "MYBUNDLEPAY CARD FUNDING",
    "card_account_id": "xxxxxxxxxxxxxxxxxxxxxxxx",
    "reference": "TOPUP-xxxxxxxxx",
    "mode": "test"
}
❌ Error Response (IP Not Authorized)

{
  "status": "failed",
  "code": "IP_NOT_AUTHORIZED",
  "message": "Your IP is not authorized for API access.",
  "ip": "54.86.50.139",
  "mode": "live"
}
❌ Invalid Amount

{
    "status": "failed",
    "code": "INVALID_AMOUNT",
    "message": "Minimum topup amount is 1.",
    "mode": "test"
}
❌ Missing Params

{
    "status": "failed",
    "message": "All fields are required: amount, card_account_id, reference.",
    "mode": "test"
}
❌ Duplicate Reference

{
    "status": "failed",
    "message": "Reference already exists.",
    "mode": "test"
}