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

KEY USAGE POLICY

Important: Always begin your integration using your test_secret_key. This allows you to simulate virtual card creation without affecting live data.

  • Use test_secret_key for development and sandbox testing.
  • Switch to live_secret_key after approval.
  • Test calls return simulated responses.
  • Live calls create real virtual cards linked to real users.

⚠️ Do not go live without prior testing to avoid failed or blocked API requests.

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

Your server IP must be whitelisted in your MyBundlePay dashboard for security.

  • CF-Connecting-IP
  • X-Forwarded-For
  • $request->ip() (fallback)

BODY PARAMS

Parameter Required Description
customerEmail Customer’s registered email address on MyBundlePay enrolled.
cardBrand Card brand. Example: VisaCard or MasterCard.
cardType Type of card to be created. Example: virtual.
reference Unique reference for the card creation request (must be unique per card).
firstName ⚠️ Optional First name of customer. Only allowed in test mode.
lastName ⚠️ Optional Last name of customer. Only allowed in test mode.

<?php
$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://mybundlepay.com/ng/api/v2/virtual-card/create',
  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 =>'{
    "customerEmail": "johnsmith@example.com",
    "cardBrand": "VisaCard",
    "cardType": "virtual",
    "reference": "MBP-TEST-0001",
    "firstName": "John",
    "lastName": "Smith"
  }',
  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 = {
  customerEmail: "johnsmith@example.com",
  cardBrand: "VisaCard",
  cardType: "virtual",
  reference: "MBP-TEST-0001",
  firstName: "John",
  lastName: "Smith"
};

axios.post("https://mybundlepay.com/ng/api/v2/virtual-card/create", 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",
  "message": "MyBundlePay virtual card creation successful.",
  "data": {
    "id": "xxxxx-ef96-4e07-96e4-xxxxx",
    "balance": 200,
    "cardNumber": "4334510956482605",
    "last4": "2605",
    "cardName": "John Smith",
    "cardType": "virtual",
    "cardBrand": "VisaCard",
    "cvv2": "069",
    "expiry": "2028-11-01T00:00:00",
    "status": "active",
    "reference": "MBP-TEST-0001",
    "customerEmail": "johnsmith@example.com"
  },
  "mode": "test"
}
Error Response (Validation)

{
  "status": "failed",
  "message": "Missing or invalid parameters.",
  "errors": {
    "customerEmail": ["The customerEmail field is required."]
  }
}
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"
}
Error Response (Duplicate Reference)

{
  "status": "failed",
  "message": "A card with this reference MBP-TEST-0001 exist",
  "details": {
    "message": "A card with this reference MBP-TEST-0001 exist",
    "statusCode": 400
  },
  "mode": "test"
}
Error Response (Already Exists)

{
  "status": "failed",
  "message": "A virtual card already exists for this user email.",
  "mode": "live"
}