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_keyfor development and sandbox testing. - Switch to
live_secret_keyafter 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-IPX-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"
}