A REST API for issuing Visa and Mastercard virtual cards programmatically. Designed for business owners who need to issue cards at scale.
The Virtual Card API lets you issue, list, and inspect virtual cards from your own systems. The API follows REST conventions: predictable URLs, JSON-encoded request bodies, JSON-encoded responses, and standard HTTP status codes.
To use the API you need:
All requests must include your API key. Three carriers are accepted (in order of preference):
Authorization: Bearer sk_live_YOUR_API_KEY
X-API-Key: sk_live_YOUR_API_KEY
?api_key=sk_live_YOUR_API_KEY
All endpoints are served under:
https://gpaynow.net/api/v1
Example: to call /cards/issue the full URL is https://gpaynow.net/api/v1/cards/issue.
Error responses use a consistent envelope:
{
"status": "error",
"remark": "insufficient_balance",
"message": "Insufficient balance. Required: 1.00, available: 0.50"
}
| Code | Remark | Meaning |
|---|---|---|
200 | — | Request succeeded. |
201 | — | Card was issued. |
400 | bad_brand | Brand parameter is invalid. |
401 | missing_token | No API key was supplied. |
401 | invalid_token | The token is invalid or revoked. |
402 | insufficient_balance | Wallet balance is too low to cover the fee. |
403 | api_disabled_for_user | Your account does not have API access. |
403 | kyc_required | KYC verification is required. |
403 | user_banned | Your account is banned. |
422 | validation_failed | Payload validation error — see data.errors. |
429 | rate_limited | Too many requests in the last minute. |
429 | daily_limit | Daily card-issuance cap reached. |
503 | system_disabled | API is disabled by the administrator. |
To protect the platform we enforce two limits:
When you exceed a limit you receive HTTP 429 with a remark of either rate_limited or daily_limit.
Returns the service descriptor — useful as a probe / health check.
{
"status": "success",
"data": {
"service": "Virtual Card API",
"version": "v1",
"enabled": true,
"fees": { "visa": 1.00, "mastercard": 1.00, "currency": "USD" },
"limits": { "rate_per_minute": 60, "daily_card_limit": 100 },
"allowed_brands": ["visa", "mastercard"]
}
}
Returns information about the calling user and the token in use.
{
"status": "success",
"data": {
"user": { "id": 42, "username": "acme", "balance": 124.50, "currency": "USD" },
"token": {
"id": 7,
"name": "Production",
"masked": "sk_live_abcd••••••••wxyz",
"total_requests": 1248,
"total_cards_issued": 86,
"total_spent": 86.00,
"last_used_at": "2026-04-28T10:14:00+00:00"
}
}
}
Quick wallet-balance check.
{ "status": "success", "data": { "balance": 124.50, "currency": "USD" } }
Issues a new virtual card and debits the issuance fee from your wallet.
| Parameter | Type | Required | Description |
|---|---|---|---|
brand | string | yes | visa or mastercard |
billing_name | string | no | Defaults to your full name. |
billing_address | string | no | Street address. |
billing_city | string | no | — |
billing_state | string | no | — |
billing_zip | string | no | Postal code. |
billing_country | string | no | Country name or ISO code. |
curl -X POST https://gpaynow.net/api/v1/cards/issue \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"brand": "visa",
"billing_name": "Acme Inc.",
"billing_zip": "10001",
"billing_country": "US"
}'
{
"status": "success",
"message": "Card issued successfully.",
"data": {
"card": {
"id": 8421,
"brand": "Visa",
"card_number": "4539821345678901",
"last4": "8901",
"expiry_date": "08/29",
"cvv": "721",
"billing": {
"name": "Acme Inc.", "address": null, "city": null, "state": null,
"zip": "10001", "country": "US"
},
"status": "active",
"issued_via": "api",
"created_at": "2026-04-28T10:14:00+00:00"
},
"fee_charged": 1.00,
"new_balance": 99.00
}
}
Lists cards owned by the authenticated user. Card numbers and CVVs are masked in the list view — call GET /cards/{id} to retrieve the full PAN.
| Parameter | Type | Default | Description |
|---|---|---|---|
per_page | integer | 20 | 1–100 items per page |
page | integer | 1 | Page number |
brand | string | — | Filter by brand: visa | mastercard |
{
"status": "success",
"data": {
"cards": [
{
"id": 8421, "brand": "Visa",
"card_number": "•••• •••• •••• 8901",
"last4": "8901", "expiry_date": "08/29", "cvv": "•••",
"billing": { ... }, "status": "active",
"issued_via": "api", "created_at": "2026-04-28T10:14:00+00:00"
}
],
"pagination": { "total": 86, "per_page": 20, "current_page": 1, "last_page": 5 }
}
}
Returns full details for a single card, including the full card number and CVV.
| Parameter | Type | Description |
|---|---|---|
id | integer | Card ID — returned by POST /cards/issue or GET /cards. |
404 not_found — card does not exist or does not belong to you.
| Field | Type | Description |
|---|---|---|
id | integer | Unique identifier. |
brand | string | Visa | Mastercard |
card_number | string | Full PAN on issuance and on GET /cards/{id}; masked otherwise. |
last4 | string | Last four digits. |
expiry_date | string | MM/YY format. |
cvv | string | Three-digit security code. |
billing | object | name, address, city, state, zip, country |
status | string | active | inactive |
issued_via | string | api | manual | purchase |
created_at | string | ISO-8601 timestamp. |
curl -X POST https://gpaynow.net/api/v1/cards/issue \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"brand":"mastercard","billing_zip":"10001"}'
const res = await fetch('https://gpaynow.net/api/v1/cards/issue', {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + process.env.API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({ brand: 'visa' })
});
const json = await res.json();
console.log(json.data.card);
import os, requests
resp = requests.post(
"https://gpaynow.net/api/v1/cards/issue",
headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
json={"brand": "visa"},
timeout=15,
)
resp.raise_for_status()
card = resp.json()["data"]["card"]
print(card["card_number"], card["expiry_date"], card["cvv"])
$ch = curl_init('https://gpaynow.net/api/v1/cards/issue');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('API_KEY'),
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode(['brand' => 'visa']),
]);
$body = curl_exec($ch);
curl_close($ch);
$data = json_decode($body, true);
print_r($data['data']['card']);
const axios = require('axios');
const { data } = await axios.post(
'https://gpaynow.net/api/v1/cards/issue',
{ brand: 'mastercard' },
{ headers: { Authorization: `Bearer ${process.env.API_KEY}` } }
);
console.log(data.data.card);
Initial release. Supports Visa & Mastercard issuance, balance/account/list/show endpoints, bearer auth, per-user gating, rate limiting.