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 without debiting the user.
  • Live calls create real virtual cards and debit user balance.

⚠️ 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 on MyBundlePay. Required for live mode and test mode.
cardBrand Card brand. Example: Visa or MasterCard.
cardType Type of card. Currently only virtual is supported.
reference Unique reference per card creation request.
customerId ✅ (test only) Required only in test mode. Not needed for live mode.
firstName ⚠️ Optional Customer’s first name. Only used in test mode.
lastName ⚠️ Optional Customer’s last name. Only used 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": "Visa",
    "cardType": "virtual",
    "reference": "MBP-TEST-0001",
    "firstName": "John",
    "lastName": "Smith",
    "customerId": "xxxxxxxxxxxxxxxxxxx"
  }',
  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: "Visa",
  cardType: "virtual",
  reference: "MBP-TEST-0001",
  firstName: "John",
  lastName: "Smith",
  customerId: "xxxxxxxxxxxxxxxxxxx"
};

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": "Virtual card created successfully on MyBundlePay.",
  "mode": "test",
  "data": {
    "card_Id": "xxxxxxxxxxxxxx",
    "cardNumber": "xxxxxxxxxxxxxxxx",
    "card_pan": "000000*********0000",
    "cvv2": "123",
    "cardType": "virtual",
    "cardBrand": "Visa",
    "card_status": "ACTIVE",
    "card_reference": "TEST-REF-GWTRDYTCUG",
    "full_card_details": {
      "name": "John Doe",
      "expiryMonth": "05",
      "expiryYear": "25",
      "status": "active",
      "is2FAEnabled": true,
      "is2FAEnrolled": true,
      "balance": 0,
      "billingAddress": {
        "line1": "address",
        "line2": "",
        "city": "city",
        "state": "state",
        "country": "US",
        "postalCode": "0000"
      }
    }
  }
}
Error Response

{
  "status": "failed",
  "message": "Missing or invalid parameters.",
  "errors": {
    "customerId": ["The customer id field is required."]
  },
  "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"
}
Error Response

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