Institutional-grade Payments API
Welcome to the GammaPay developer portal. Our API is built on REST principles, designed to help you integrate seamlessly with over 20+ blockchain networks using a single unified interface.
GammaPay is a next-generation crypto payment gateway that allows merchants to accept over 20+ digital assets with instant fiat conversion. Built for speed and security, our API uses industry-standard HMAC signatures to ensure every request is authentic.
Getting Started in 3 Steps
- Sign Up: Create an account at dashboard.gammapay.io
- Create a Wallet: Generate a wallet for your preferred coin (e.g. USDT, BTC).
- Get Keys: Access your
api_keyandapi_secretfrom settings.
Sandbox (Testing)
Use for development. Transactions are on testnet networks (Sepolia, Nile, etc). No real funds required.
Production
Use for real business transactions. Settlements are made in mainnet assets.
Production Base URL
https://api.gammapay.ioSDK & Libraries
Official wrappers for Node.js, Python, and PHP coming soon.
Quick Start
Create a payment invoice in under 2 minutes. You'll need an active API Key and Secret from your wallet settings.
Create a Wallet & Get Credentials
To use the GammaPay API, you must first create a wallet and generate API keys in your dashboard.
- Log in to dashboard.gammapay.io.
- Navigate to Wallets → New Wallet in the sidebar.
- Select your preferred network and coin (e.g., USDT on TRON) and click Create.
- Click on your new wallet, then go to the API Keys tab.
- Here you will find your
X-API-Keyand yourapi_secret.
api_secret is only shown once. Copy it and store it securely.Generate HMAC Signature
The signature is generated by hashing the concatenation of your current timestamp, the compact JSON body, and your idempotency key (if provided) using your api_secret.
import hmac, hashlib, time, json
import uuid
api_key = "npk_live_xxxxxxxxxxxx"
api_secret = "npks_xxxxxxxxxxxxxxxx"
url = "https://api.gammapay.io/v1/withdrawals"
body_data = {
"coin": "USDTTRC20",
"amount": "50.0",
"destination": "0x71C...",
"speed": "medium"
}
timestamp = str(int(time.time()))
body_json = json.dumps(body_data, separators=(',', ':'))
# Required for withdrawals to prevent duplicate operations
idempotency_key = str(uuid.uuid4())
# Format: timestamp.body[.idempotency_key]
payload = f"{timestamp}.{body_json}"
if idempotency_key:
payload += f".{idempotency_key}"
signature = hmac.new(
api_secret.encode(),
payload.encode(),
hashlib.sha256
).hexdigest()
print(f"X-Signature: sha256={signature}")
print(f"X-Timestamp: {timestamp}")
if idempotency_key:
print(f"X-Idempotency-Key: {idempotency_key}")// 1. Generate fresh timestamp
var timestamp = Math.floor(Date.now() / 1000).toString();
pm.environment.set("timestamp", timestamp);
// 2. Grab your API Secret
var apiSecret = pm.environment.get("api_secret"); // Or hardcode it
// 3. Grab the raw body EXACTLY as it is typed (Safe for GET requests)
var rawBody = (pm.request.body && pm.request.body.raw) ? pm.request.body.raw : "";
// 4. GENERATE a new Idempotency Key right here
var idempotencyKey = pm.variables.replaceIn('{{$guid}}');
pm.environment.set("resolved_idempotency_key", idempotencyKey);
// 5. Combine ALL THREE (Timestamp + Body + Idempotency Key)
var payload = timestamp + "." + rawBody + "." + idempotencyKey;
// 6. Generate signature using the new combined payload
var signature = CryptoJS.HmacSHA256(payload, apiSecret).toString(CryptoJS.enc.Hex);
// 7. Save the signature to the environment
pm.environment.set("hmac_signature", "sha256=" + signature);Make Your First Request
curl -X POST 'https://api.gammapay.io/v1/invoices' \
-H 'Content-Type: application/json' \
-H 'X-API-Key: npk_live_xxxxxxxxxxxx' \
-H 'X-Timestamp: 1745223600' \
-H 'X-Signature: sha256=a7f3d92e1b...' \
-d '{"coin":"USDTTRC20","amount":"50.0","currency":"USD","wallet_id":"ef89..."}'Listen to Webhook
When payment is detected, GammaPay sends a POST to your webhook URL.
app.post('/webhook/gammapay', express.raw({ type: 'application/json' }), (req, res) => {
const sig = req.headers['x-neonpay-signature'];
const ts = req.headers['x-neonpay-timestamp'];
const secret = process.env.WEBHOOK_SECRET;
const expected = crypto.createHmac('sha256', secret)
.update(`${ts}.${req.body}`).digest('hex');
if (sig !== `sha256=${expected}`) {
return res.status(401).send('Invalid signature');
}
const event = JSON.parse(req.body);
if (event.event === 'transaction.confirmed') {
// Fulfill order
}
res.sendStatus(200);
});The current API returns { flag, msg, data }. This documentation uses the canonical format { success, message, data, meta } which is the target schema for v1.1.
flag === 1 as success: true and flag === 0 as success: false.Authentication & Headers
GammaPay uses HMAC signature verification for all API endpoints.
- Where to get your keys: Dashboard → Wallets → select wallet → API Keys tab.
- What to send: Every API request must include the three HTTP headers below.
Because API credentials are tied to individual wallets, you cannot use the API to create your very first wallet. You must log into the GammaPay Dashboard UI and create your first wallet manually. Once created, you can reveal its API Key and Secret in the Dashboard, and use those credentials to authenticate HMAC requests (including creating additional wallets programmatically).
| Header | Required | Description |
|---|---|---|
| X-API-Key | Yes | Your public API key. Starts with `npk_live_` or `npk_test_`. |
| X-Timestamp | Yes | Unix timestamp in seconds. Rejected if skew > 300s. |
| X-Signature | Yes | HMAC-SHA256 signature prefixed with `sha256=`. |
| X-Idempotency-Key | Conditional | Required for withdrawals. UUID to prevent duplicate operations (24h TTL). |
Rate Limits
Rate limits are applied per API key.
| Plan | Requests/min | Burst (10s) |
|---|---|---|
| Free | 300 | 50 |
| Premium | 1000 | 170 |
X-RateLimit-Remaining: 287
X-RateLimit-Reset: 1745223660
Retry-After: 13 // Only present on 429 Error
Error Codes
| Code | HTTP | Retriable | Description |
|---|---|---|---|
| VALIDATION_ERROR | 400 | No | Missing or invalid fields. |
| INVALID_CREDENTIALS | 401 | No | API key missing, invalid, or inactive. |
| INVALID_SIGNATURE | 401 | No | HMAC signature mismatch. |
| NONCE_EXPIRED | 401 | No | Timestamp older than 5 minutes. |
| FORBIDDEN | 403 | No | API key lacks required scope. |
| NOT_FOUND | 404 | No | Resource not found. |
| IDEMPOTENCY_CONFLICT | 409 | No | Same key with different payload. |
| INSUFFICIENT_AMOUNT | 400 | No | Amount below minimum. |
| INVOICE_EXPIRED | 410 | No | Invoice past expiry. |
| WALLET_LOCKED | 423 | Yes | Wallet temporarily locked. |
| RATE_LIMIT_EXCEEDED | 429 | Yes | Retry with backoff. |
| SERVER_ERROR | 500 | Yes | Internal server error. |
Wallets
A wallet is the fundamental unit in GammaPay. Each wallet is associated with a single coin/network and provides isolated API credentials, deposit addresses, webhook configuration, whitelist rules, and transaction history.
API Credentials
Each wallet has its own API key + secret pair, isolated from other wallets.
HD Addresses
Generate unlimited BIP44-derived deposit addresses. One per invoice, never reused.
Whitelist
Withdrawals only go to verified, email-confirmed addresses.
Wallet Tabs (Dashboard)
When you open a wallet, the detail page shows the wallet name, total balance, coin symbol, and 8 tabs for managing every aspect of that wallet:
| Tab | Purpose |
|---|---|
| Transaction | View all incoming deposits and outgoing withdrawals with search, status/direction filters, list/grid views, and detail side-panel. |
| Addresses | Generate new HD-derived deposit addresses with a mandatory label (3–50 chars, must include a letter or number). QR codes auto-generated. Copy address, view HD index, list/grid toggle. |
| Whitelist | Manage withdrawal address whitelist. Add (requires 2FA + email verification), remove, verify pending addresses, copy, view status. |
| Credential | Reveal API key + secret (password + 2FA required), rotate keys, toggle API withdraw permission, update wallet password. |
| Webhook | Set/update webhook URL, test connection, reveal/rotate webhook secret, remove webhook, view full delivery log with retry status. |
| Deposit / Withdraw | Quick deposit (QR code + address copy), withdraw to whitelisted addresses (requires 2FA), fee estimation, speed selection, recent withdrawal history. |
| API Logs | Full audit trail of every API call: HTTP status, method + endpoint, source IP, response duration (ms), timestamp. |
| Chart | Visual analytics with balance over time (area chart), daily inbound/outbound volume (bar chart), 7d/30d/90d range selector. |
Creating a Wallet
The wallet creation wizard walks you through a 3-step process:
1 Wallet Basics
- Select Currency: Choose from mainnet or testnet coins (BTC, ETH, USDT, etc.)
- Wallet Name: A human-readable label
- Password:Used to encrypt wallet keys. You'll need this to reveal API credentials later.
- Invoice Branding (Optional): Upload a brand image (PNG or JPG, max 2MB) for your invoices.
2 Advanced Settings
- Webhooks: Set your Endpoint URL for real-time notifications and choose the number of network confirmations required.
- IP Whitelist: Restrict API access to specific IPs or domains. Leave blank to allow all traffic (not recommended).
3 Review
- Summary: Final review of all configurations, including wallet identity, security, API configuration, platform fee, and estimated network gas before confirming creation.
Create via API
You can also create a wallet programmatically via the HMAC API.
/v1/walletsCreate a new wallet programmatically.
| Body Field | Type | Description |
|---|---|---|
| coin_symbol * | string | The symbol of the coin (e.g., USDCERC20_SEP, BTC) |
| name * | string | A human-readable label for the wallet |
| withdrawal_type * | string | Must be 'automatic' or 'manual' |
| is_testnet | boolean | Set to true for testnet coins |
| webhook_url | string | URL to receive payment notifications |
| webhook_confirmation | number | Number of confirmations required for webhooks |
| ip_whitelist | string[] | Array of allowed IP addresses for API access |
| api_withdraw_enabled | boolean | Enable or disable API withdrawals |
| daily_withdrawal_limit | string | Maximum daily withdrawal amount in native coin units |
| transaction_speed | string | 'low', 'medium', or 'high' gas preference |
curl -X POST ${API_BASE}/v1/wallets \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_MASTER_API_KEY" \
-H "X-Timestamp: $(date +%s)" \
-H "X-Signature: sha256=..." \
-d '{
"coin_symbol": "USDCERC20_SEP",
"name": "API Created Wallet",
"withdrawal_type": "automatic",
"is_testnet": true,
"webhook_url": "https://api.yourdomain.com/webhooks",
"webhook_confirmation": 12,
"ip_whitelist": ["192.168.1.1", "10.0.0.0/24"],
"api_withdraw_enabled": false,
"transaction_speed": "medium"
}'{
"data": {
"balance": {
"available": "0",
"pending": "0",
"total": "0"
},
"credentials": {
"api_key": "wk_test_your_api_key_here",
"api_secret": "your_api_secret_here",
"key_version": 1,
"shown_once": true
},
"wallet": {
"api_withdraw_enabled": false,
"coin_symbol": "USDCERC20_SEP",
"confirmation_threshold": 12,
"created_at": "2026-08-01T12:20:34.564839Z",
"daily_withdrawal_limit": null,
"id": "7a2bc6e6-1a37-4f72-b6bd-272629ea49bc",
"ip_whitelist": [],
"is_active": true,
"is_testnet": true,
"logo_url": null,
"name": "API Created Wallet",
"transaction_speed": "low",
"withdrawal_type": "automatic"
}
},
"flag": 1,
"msg": "success"
}Get Wallet Detail
Retrieve the details of an existing wallet, including its configuration, balance, and API key metadata.
/v1/wallets/{wallet_id}Get wallet details including configuration and metadata.
curl -X GET \
${API_BASE}/v1/wallets/{wallet_id} \
-H "X-API-Key: YOUR_MASTER_API_KEY" \
-H "X-Timestamp: $(date +%s)" \
-H "X-Signature: sha256=..."{
"data": {
"api_key_meta": {
"created_at": "2026-08-01T12:20:34.564839Z",
"is_revealed": false,
"key_prefix": "wk_test_0743",
"key_version": 1,
"label": "default",
"last_used_at": null,
"last_used_ip": null,
"request_count": 0,
"reveal_supported": true,
"revealed_at": null,
"scopes": [
"*"
]
},
"pending_ops_count": 0,
"wallet": {
"api_key": null,
"api_secret": null,
"api_withdraw_enabled": false,
"balance": {
"available": "0",
"pending": "0",
"total": "0"
},
"coin_symbol": "USDCERC20_SEP",
"confirmation_threshold": 12,
"created_at": "2026-08-01T12:20:34.564839Z",
"daily_withdrawal_limit": null,
"id": "7a2bc6e6-1a37-4f72-b6bd-272629ea49bc",
"ip_whitelist": [],
"is_active": true,
"is_testnet": true,
"key_version": null,
"logo_url": null,
"name": "API Created Wallet",
"shown_once": null,
"transaction_speed": "low",
"withdrawal_type": "automatic"
},
"webhook": null
},
"flag": 1,
"msg": "success"
}Update Wallet
Update the configuration of an existing wallet. All body parameters are optional; only the provided fields will be modified.
/v1/wallets/{wallet_id}Update wallet settings like webhook configuration, limits, and transaction speed.
| Body Field | Type | Description |
|---|---|---|
| name | string | A human-readable label for the wallet |
| webhook_url | string | null | URL to receive payment notifications. Set to null to remove. |
| webhook_secret | string | Secret used to sign webhook payloads. |
| webhook_confirmation | number | Number of network confirmations required before webhook triggers. |
| ip_whitelist | string[] | Array of allowed IP addresses for API access. Empty array clears the whitelist. |
| logo_url | string | null | URL of the wallet logo image. Set to null to remove. |
| api_withdraw_enabled | boolean | Enable or disable programmatic withdrawals. |
| daily_withdrawal_limit | string | null | Maximum daily withdrawal amount in native coin units. Set to null for unlimited. |
| transaction_speed | string | Gas preference: 'low', 'medium', or 'high'. |
curl -X PATCH \
${API_BASE}/v1/wallets/{wallet_id} \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_MASTER_API_KEY" \
-H "X-Timestamp: $(date +%s)" \
-H "X-Signature: sha256=..." \
-d '{
"name": "Updated Wallet Name",
"transaction_speed": "high",
"api_withdraw_enabled": true
}'{
"data": {
"api_withdraw_enabled": true,
"coin_symbol": "USDCERC20_SEP",
"confirmation_threshold": 12,
"created_at": "2026-08-01T12:20:34.564839Z",
"daily_withdrawal_limit": null,
"id": "7a2bc6e6-1a37-4f72-b6bd-272629ea49bc",
"ip_whitelist": [],
"is_active": true,
"is_testnet": true,
"logo_url": null,
"name": "Updated Wallet Name",
"transaction_speed": "high",
"withdrawal_type": "automatic"
},
"flag": 1,
"msg": "Wallet updated successfully"
}API Credentials (Per-Wallet)
Every wallet has its own isolated API key pair. These credentials are used to authenticate API requests for that specific wallet.
Reveal Keys
Requires your dashboard password (+ 2FA code if enabled). The API secret is shown only once. After revealing, you cannot reveal again — only rotate.
Rotate Keys
Generates a new API key + secret pair. The previous keys are immediately invalidated. All active integrations must be updated. Requires password verification.
Enable API Withdraw
A toggle to allow or disallow withdrawals via API. When disabled, withdrawals can only be initiated from the dashboard UI. Acts as an additional safety layer.
/v1/wallets/{wallet_id}/api-keysGenerate a new API key and secret pair for the specified wallet. The secret will only be shown once in the response. Store it securely.
| Body Field | Type | Description |
|---|---|---|
| label | string | A human-readable label for the API key (defaults to 'API Key {version}') |
| scopes | string[] | Array of permissions to grant this key. Options: 'read', 'write', '*' |
| expires_at | string | ISO8601 timestamp for when this key should expire. If omitted, the key never expires. |
curl -X POST \
${API_BASE}/v1/wallets/{wallet_id}/api-keys \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_MASTER_API_KEY" \
-H "X-Timestamp: $(date +%s)" \
-H "X-Signature: sha256=..." \
-d '{
"label": "New API Key",
"scopes": ["read", "write"]
}'{
"data": {
"api_key": "wk_test_5fe719d9e8e746eab4072695ce014660",
"api_secret": "8de101ca807ef1cb2213ba32f4458dc9e28028d627d824dcc58d2284db0e405f",
"expires_at": null,
"key_prefix": "wk_test_5fe7",
"key_version": 2,
"label": "New API Key",
"scopes": [
"read",
"write"
],
"shown_once": true
},
"flag": 1,
"msg": "success"
}/v1/wallets/{wallet_id}/api-keys/rotateRotate the API key for a wallet. This endpoint requires step-up authentication (dashboard password) in the JSON body, even when called programmatically via HMAC.
| Body Field | Type | Description |
|---|---|---|
| current_password * | string | Your dashboard account password |
| totp_code | string | Your 6-digit 2FA code, if two-factor authentication is enabled |
curl -X POST ${API_BASE}/v1/wallets/{wallet_id}/api-keys/rotate \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_WALLET_API_KEY" \
-H "X-Timestamp: $(date +%s)" \
-H "X-Signature: sha256=..." \
-d '{
"current_password": "your_dashboard_password_here"
}'{
"data": {
"api_key": "wk_test_b2924767c134445fb0636a0bf4158f10",
"api_secret": "093a640b78ddc334a7860fe391d3ff669aa95d83ac1061239ce7e29577e4b4a6",
"key_version": 3,
"previous_key_expires_at": "2026-08-01T14:14:33.389313171Z",
"shown_once": true
},
"flag": 1,
"msg": "success"
}Deposit Addresses
GammaPay uses BIP44 HD derivation (m/44'/coin_type'/0'/0/index) to generate unique deposit addresses for each wallet.
- One address per invoice — addresses are never reused across invoices to maintain privacy and simplify tracking.
- Labels (required):A label is mandatory when generating an address via API or dashboard (e.g., "Customer #1234"). Rules: 3–50 characters after trim, not whitespace-only, and must contain at least one letter or number. Missing or invalid label returns
400with a clear error message. - QR Codes: Each address comes with an auto-generated QR code for easy display.
- Monitoring: All generated addresses are automatically monitored by the blockchain scanner.
/v1/{coin}/addressesGenerate a new HD deposit address (HMAC wallet API). label is mandatory.
| Body Field | Type | Description |
|---|---|---|
| label * | string | Required. 3–50 chars, not whitespace-only, must include a letter or number |
curl -X POST ${API_BASE}/v1/USDCERC20_SEP/addresses \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-H "X-Timestamp: $(date +%s)" \
-H "X-Signature: sha256=..." \
-d '{"label":"test"}'{
"data": {
"address": "0x6fd7ed3cb6fdfd7d9fce89eebd0533916d1a5ff7",
"coin": "USDCERC20_SEP",
"created_at": "2026-08-01T12:36:15.594508Z",
"hd_index": 5,
"label": "test",
"network": "Ethereum Sepolia",
"qr_code_url": "https://dev-neonpay.gammapay.io/pay/qr/0x6fd7ed3cb6fdfd7d9fce89eebd0533916d1a5ff7?coin=USDCERC20_SEP"
},
"flag": 1,
"msg": "success"
}Wallet Settings & Controls
| Setting | Type | Description |
|---|---|---|
| Wallet Name | string | Human-readable identifier or label for the wallet. |
| Daily Withdrawal Limit | string | Max amount withdrawable in 24h. Blank = no limit. |
| Webhook URL | string | Endpoint for receiving real-time payment notifications. |
| Webhook Secret | string | Cryptographic secret used to sign webhook payloads. |
| Confirmation Threshold | 1–300 | Block confirmations required before triggering webhook/status update. |
| Transaction Speed | low|medium|high | Affects network fee multiplier. High = faster confirmation, higher fee. |
| IP Whitelist | string[] | Restrict API access to specific IPs/domains. Blank = allow all. |
| API Withdraw Enabled | boolean | Toggle whether withdrawals can be initiated via API. |
| Logo URL | string | URL of the image used for custom invoice branding. |
Invoices API Reference
/v1/invoicesGenerate a payment request.
| Body Field | Type | Description |
|---|---|---|
| coin * | string | Coin symbol (e.g. USDCERC20_SEP) |
| amount * | string | Amount in coin or USD |
| title * | string | Title of the invoice |
| currency | string | Default 'USD'. Use coin symbol for native. |
| expire_time | integer | Minutes until expiry (default 60) |
| notify_url | string | Webhook callback URL |
| description | string | Detailed description of the invoice |
| customer_email | string | Email of the customer |
| customer_name | string | Name of the customer |
| custom_data | object | Arbitrary JSON metadata |
| success_url | string | Redirect URL on successful payment |
| cancel_url | string | Redirect URL on cancellation |
| send_email | boolean | Whether to send an email to the customer |
| subtitle | string | Subtitle of the invoice |
curl -X POST '${API_BASE}/v1/invoices' \
-H 'Content-Type: application/json' \
-H 'X-API-Key: YOUR_API_KEY' \
-H 'X-Timestamp: $(date +%s)' \
-H 'X-Signature: sha256=...' \
-d '{
"coin": "USDCERC20_SEP",
"amount": "5",
"currency": "USD",
"expire_time": 60,
"notify_url": "https://api.yourdomain.com/webhook",
"custom_data": {
"transactionId": "c3c32fcd-ebf7-4b44-8300-3a7d5f5f87e4",
"userId": 1
},
"title": "Test Invoice"
}'{
"data": {
"address": "0x8d5fd9645777c2469bd8507cf10b1268e349d4ac",
"amount": {
"coin": "5",
"fiat": "5",
"fiat_currency": "USD"
},
"created_at": "2026-08-01T11:44:32.469809Z",
"expires_at": "2026-08-01T12:44:32.469348092Z",
"id": "33fbc2e3-8441-4e45-ac16-61d3a0b075dc",
"invoice_id": "inv_2503a52d02ba",
"status": "pending",
"url": "https://dev-neonpay.gammapay.io/pay/inv_2503a52d02ba"
},
"flag": 1,
"msg": "success"
}/v1/${coin ? coin.symbol : ":coin"}/invoices/:invoice_idGet detailed information about an invoice.
curl -X GET \
${API_BASE}/v1/${coin ? coin.symbol : "USDCERC20_SEP"}/invoices/:invoice_id \
-H "X-API-Key: YOUR_WALLET_API_KEY" \
-H "X-Timestamp: $(date +%s)" \
-H "X-Signature: sha256=..."{
"data": {
"address": "0x8d5fd9645777c2469bd8507cf10b1268e349d4ac",
"amount": {
"coin": "5.00000000",
"fiat": "5.00",
"fiat_currency": "USD"
},
"coin_name": "USDC ERC20 Sepolia",
"coin_symbol": "USDCERC20_SEP",
"created_at": "2026-08-01T11:44:32.469809Z",
"custom_data": {
"transactionId": "c3c32fcd-ebf7-4b44-8380-3a7d5f5f87e4",
"userId": 1
},
"customer_email": null,
"customer_name": null,
"description": null,
"exchange_rate": "1.00080000",
"expire_at": "2026-08-01T12:44:32.469348Z",
"id": "33fbc2e3-8441-4e45-ac16-61d3a0b075dc",
"invoice_id": "inv_2503a52d02ba",
"network": "Ethereum Sepolia",
"paid_amount": "0",
"paid_at": null,
"payment_uri": "ethereum:0x94a9d9ac8a22534e3faca9f4e7f2e2cf85d5e4c8@11155111/transfer?address=0x8d5fd9645777c2469bd8507cf10b1268e349d4ac&uint256=5000000",
"status": "expired",
"subtitle": null,
"title": "Test Invoice",
"url": "https://dev-neonpay.gammapay.io/pay/inv_2503a52d02ba"
},
"flag": 1,
"msg": "success"
}/v1/${coin ? coin.symbol : ":coin"}/invoicesList paginated invoices filtered by status or date.
| Query Parameter | Type | Description |
|---|---|---|
| status | string | Filter by status: pending, partially_paid, paid, overpaid, expired, underpaid |
| page | number | Page number for pagination (default: 1) |
| per_page | number | Number of records per page (default: 20) |
curl -X GET \
"${API_BASE}/v1/${coin ? coin.symbol : "USDCERC20_SEP"}/invoices?page=1&per_page=20" \
-H "X-API-Key: YOUR_WALLET_API_KEY" \
-H "X-Timestamp: $(date +%s)" \
-H "X-Signature: sha256=..."{
"data": {
"invoices": [
{
"address": "0x4cefd24a4d63a3652ed8ac528b281efe292eb15b",
"amount": {
"coin": "5.00000000",
"fiat": "5.00",
"fiat_currency": "USD"
},
"coin_name": "USDC ERC20 Sepolia",
"coin_symbol": "USDCERC20_SEP",
"created_at": "2026-08-01T12:29:09.179077Z",
"custom_data": {
"transactionId": "c3c32fcd-ebf7-4b44-8380-3a7d5f5f87e4",
"userId": 1
},
"customer_email": null,
"customer_name": null,
"description": null,
"exchange_rate": "1.00080000",
"expire_at": "2026-08-01T13:29:09.178650Z",
"id": "40497706-718c-4c72-a78a-80ce240e66c3",
"invoice_id": "inv_a7b306da8d45",
"network": "Ethereum Sepolia",
"paid_amount": "0",
"paid_at": null,
"payment_uri": "ethereum:0x94a9d9ac8a22534e3faca9f4e7f2e2cf85d5e4c8@11155111/transfer?address=0x4cefd24a4d63a3652ed8ac528b281efe292eb15b&uint256=5000000",
"status": "pending",
"subtitle": null,
"title": "Test Invoice",
"url": "https://dev-neonpay.gammapay.io/pay/inv_a7b306da8d45"
}
],
"pagination": {
"limit": 20,
"page": 1,
"total": 143,
"total_pages": 8
}
},
"flag": 1,
"msg": "success"
}Invoice Status Flow
The status field in the API response strictly follows this lifecycle:
pending (awaiting payment) → confirming (transaction detected, accumulating confirmations) → paid (full amount confirmed on-chain)Alternate flows:
→
partially_paid (partial payment confirmed, awaiting more funds)→
expired (time window elapsed with zero payments)→
underpaid (expired while in partially_paid state)→
overpaid (total confirmed funds exceed required amount)Edge Cases & Transactions
- Transaction Confirmation Flow: When a payment is detected, the invoice status changes to
confirming. Once the transaction reaches the required confirmations, the status updates topaid(if full amount) orpartially_paid(if partial amount). Check the invoice's associated transactions endpoint to track confirmation progress. - Partial Payments: If the confirmed amount is less than the invoice total, status becomes
partially_paid. The invoice remains open for additional payments until expiry or the full amount is received. - Underpayment: Status becomes
underpaidafter expiry if the invoice was inpartially_paidstate. - Overpayment: Marked
overpaid. Excess funds are credited to your wallet balance. - Wrong Network/Token: Funds sent on the wrong network or as the wrong token are lost permanently and will not be detected.
Withdrawals
Withdrawals allow you to send funds from your wallet to an external address. Due to security requirements:
- 2FA is mandatory for all withdrawals (dashboard or API).
- Manual review: All withdrawals undergo internal security review (3-step approval).
- One pending at a time: You cannot submit a new withdrawal while one is pending review.
- Idempotency key required: The HMAC signature for withdrawals includes the idempotency key.
Withdrawal Signature (includes Idempotency Key)
payload = timestamp + "." + rawBody + "." + idempotencyKey
signature = HMAC-SHA256(api_secret, payload)/v1/withdrawalsInitiate a new withdrawal to a whitelisted external address.
| Body Field | Type | Description |
|---|---|---|
| destination_address * | string | Destination blockchain address |
| amount * | string | Amount in coin |
| note | string | Optional note |
curl -X POST 'https://api.gammapay.io/v1/withdrawals' \
-H 'Content-Type: application/json' \
-H 'X-API-Key: npk_live_xxxxxxxxxxxx' \
-H 'X-Timestamp: 1781926509' \
-H 'X-Signature: sha256=1c42a9...' \
-H 'X-Idempotency-Key: 9eb581a2-ca56-447f-908f-26959444b9a1' \
-d '{"destination_address":"0x7066...","amount":"1","note":"Test"}'{
"flag": 1,
"msg": "Withdrawal request submitted and pending admin review.",
"data": {
"id": "68a0cf9f-94eb-4f73-9c3b-e5f419beee99",
"amount": "1.00000000",
"status": "pending_review",
"fee_amount": "0.002",
"net_amount": "0.998",
"created_at": "2026-06-20T03:35:09Z"
}
}/v1/withdrawals/:idRetrieve details of a specific withdrawal.
{
"flag": 1,
"data": {
"id": "68a0cf9f-...",
"amount": "1.00000000",
"status": "completed",
"tx_hash": "0xeb563d72...",
"reviewed_at": "2026-06-20T04:12:02Z",
"confirmed_at": "2026-06-20T04:25:00Z"
}
}/v1/withdrawalsList paginated withdrawals.
| Query Parameter | Type | Description |
|---|---|---|
| page | int | Page number |
| per_page | int | Items per page |
{
"flag": 1,
"data": { "page": 1, "per_page": 20, "total": 11, "withdrawals": [...] }
}/v1/withdrawals/estimateEstimate the network fee for a withdrawal without creating it.
| Body Field | Type | Description |
|---|---|---|
| destination_address * | string | Destination address |
| amount * | string | Amount in coin |
{
"flag": 1,
"data": {
"amount": "0.5",
"fee_amount": "0.001",
"net_amount": "0.499",
"withdrawal_speed": "standard"
}
}Webhooks (IPN)
Webhooks provide real-time notifications when transaction states change. Configure a webhook URL per wallet in the dashboard.
Dashboard Webhook Management
- Set URL: Enter an HTTPS endpoint and run a connection test before saving.
- Test: Sends a test payload to verify your endpoint responds with 200 OK.
- Webhook Secret: Each wallet has a unique HMAC secret for verifying webhook authenticity. Reveal it with password + 2FA.
- Rotate Secret: Invalidates the current secret and generates a new one.
- Remove: Deletes the webhook configuration entirely.
- Delivery Logs: View all webhook delivery attempts with status, response code, timestamps, and retry count.
Event Types
| Event | Trigger |
|---|---|
| transaction.confirmed | Payment fully confirmed on-chain |
| transaction.detected | Payment detected in mempool (unconfirmed) |
| payment.underpaid | Invoice expired with partial payment |
| withdrawal.created | New withdrawal request submitted |
| withdrawal.completed | Withdrawal broadcast and confirmed on-chain |
| withdrawal.failed | Withdrawal rejected or broadcast failed |
Sample Payloads
{
"event": "transaction.confirmed",
"amount": "15.00000000",
"coin": "USDTERC20_SEP",
"confirmed_at": "2026-06-20T03:10:35Z",
"net_amount": "14.97000000",
"platform_fee": "0.03000000",
"transaction_id": "ec0334e-3eb6-43cf-aa95-c7be9bec950b",
"tx_hash": "0xeb563d72419ce89c591c6ed981c43672527050986c...",
"wallet_id": "5e9c5b14-0bae-415d-aca2-725962c68ab8"
}Webhook Signature Verification
- Extract
X-Neonpay-TimestampandX-Neonpay-Signatureheaders. - Check
|now - timestamp| < 300seconds. - Compute:
HMAC-SHA256(webhook_secret, timestamp + "." + rawBody) - Compare using
timingSafeEqual.
Retry Schedule
| Attempt | Delay |
|---|---|
| 1 | Immediate |
| 2 | 1 minute |
| 3 | 5 minutes |
| 4 | 30 minutes |
| 5 | 2 hours |
| 6 | 12 hours |
After 6 failed attempts, the event is moved to a dead letter queue and the merchant is alerted via email.
Security Features
GammaPay implements multiple layers of security to protect your funds and account. These features are available in the Security section of your dashboard.
Two-Factor Authentication
TOTP-based 2FA with anti-phishing image protection and backup recovery codes.
IP Whitelisting
Restrict API access to approved IP addresses only.
Login Shield
Blocks login from unrecognized devices until email confirmation.
Session Management
View and terminate active sessions. Configurable session timeout.
Two-Factor Authentication (2FA)
TOTP (Time-based One-Time Password) adds a second layer of security. It is required for dashboard withdrawals, security settings changes, and API key operations.
Setup Flow
- Verify Password: Enter your current account password to initiate setup.
- Scan QR Code: Scan the displayed QR code with your authenticator app (Google Authenticator, Authy, 1Password, etc.). Or manually enter the secret key.
- Select Anti-Phishing Image: Choose a personalized image from categories (Animals, Vehicles, Objects). This image appears in all security emails from GammaPay.
- Verify Code: Enter the 6-digit code from your authenticator app to confirm setup.
- Save Recovery Codes: Download and securely store your one-time backup recovery codes. These are the only way to regain access if you lose your authenticator device.
Anti-Phishing Image Protection
During 2FA setup, you select a personalized security image. This image is embedded in all official GammaPay emails (whitelist verification, login alerts, etc.).
How it protects you:
- Every security-sensitive email from GammaPay includes YOUR chosen image.
- If you receive an email claiming to be from GammaPay but the image is wrong or missing — it's a phishing attempt.
- You can change your anti-phishing image at any time from Security settings.
- Images are categorized into Animals, Vehicles, and Objects for easy selection.
IP Whitelisting (Account-Level)
When enabled, API requests are only accepted from IP addresses you specify. This is a global toggle that applies to all wallets on your account.
- Toggle on/off from Security → IP Whitelisting
- Configure IPs per-wallet in the wallet settings (Deposit & Withdraw tab → Security Whitelist section)
- Supports IPv4 and IPv6 addresses only (domains are not supported)
- Requests from non-whitelisted IPs receive a 403 Forbidden response
Login Shield
Login Shield adds an extra verification step when logging in from an unrecognized device or IP address.
- When enabled, login from a new device/location triggers an email confirmation.
- The account remains locked until the email link is clicked.
- Prevents unauthorized access even if password is compromised (without 2FA).
- Toggle on/off from Security settings.
Session Management
- Active Sessions: View all currently active sessions (device, IP, browser, last active time).
- Terminate Sessions: Remotely log out any active session from the Active Sessions page.
- Session Timeout: Configure auto-logout after inactivity (configurable from Notifications settings).
- Login History: Full audit log of all login attempts (successful and failed) with IP, timestamp, and device info.
API Logs
Every API request made against your wallet is logged and available for inspection in the API Logs tab of each wallet. This provides a complete audit trail for debugging and security monitoring.
Log Entry Fields
| Field | Description |
|---|---|
| Status Code | HTTP response code (200, 400, 401, 403, 429, 500, etc.) |
| Method & Endpoint | HTTP method (GET/POST/PATCH/DELETE) and the full endpoint path |
| IP Address | Source IP of the request |
| Duration | Request processing time in milliseconds |
| Date | Full timestamp of when the request was received |
| Description | Error description (shown for failed requests) |
Debugging Tips
- 401 errors: Check your HMAC signature calculation. Ensure timestamp skew is within 300 seconds.
- 403 errors: Your IP may not be whitelisted, or the API key lacks required permissions.
- 429 errors:You're hitting rate limits. Implement exponential backoff.
- High latency: If duration exceeds 5000ms, check if your request payload is unusually large.
- Unexpected IPs: If you see requests from unknown IPs, rotate your API keys immediately and enable IP whitelisting.
Notifications
Configure how and when GammaPay notifies you about account activity. Navigate to Settings → Notifications in your dashboard.
Notification Types
| Category | Push | Description | |
|---|---|---|---|
| Security | ✓ | ✓ | Login alerts, 2FA changes, password updates |
| Transactions | ✓ | ✓ | Incoming deposits, withdrawal confirmations |
| Invoices | ✓ | ✓ | Invoice paid, expired, underpaid |
| System | ✓ | ✓ | Maintenance, feature updates, plan changes |
| Weekly Summary | ✓ | — | Weekly digest of transaction volume and revenue |
Configuration Options
- Email on Login: Receive an email every time your account is accessed.
- Transaction Alerts: Get notified for every incoming/outgoing transaction.
- Language: Set preferred language for notifications.
- Currency: Default fiat currency for amount displays.
- Timezone: Affects all timestamp formatting in notifications.
- Session Timeout: Auto-logout after configurable inactivity period (in minutes).
Developer Guides
Accept a Payment (Full Flow)
- Create a wallet for the desired coin in the dashboard.
- Get your API credentials from the wallet's API Keys tab.
- Call
POST /v1/invoicesto create a payment request (passing the coin in the JSON body). - Redirect the customer to the returned
urlor display theaddresswith amount. - Listen for the
transaction.confirmedwebhook event. - Verify the webhook signature using your wallet's webhook secret.
- Fulfill the order once payment is confirmed.
Best Practice
Always use an X-Idempotency-Key when creating invoices to prevent double-charging on network retries.
Crypto vs USD Payments
USD Mode
Set currency: "USD". GammaPay locks the exchange rate at invoice creation and calculates the required crypto amount.
Native Coin Mode
Set currency: "USDTTRC20". No conversion. Customer pays the exact coin amount specified.
Handling Underpayments
- Monitor for the
payment.underpaidwebhook event. - The webhook payload includes
amount_received_coinandshortfall_coin. - You can manually mark the invoice as paid in the dashboard if the shortfall is negligible.
- Otherwise, the invoice remains underpaid until the remaining balance is sent to the same address.
Test Your Integration
- Use testnet coins: Create wallets for testnet assets (ETH Sepolia, USDT Nile, etc.).
- Faucets: Get free testnet tokens from Sepolia faucets for ETH/ERC20 or Nile faucet for TRC20.
- Webhook testing:Use the built-in "Test Webhook" button in the dashboard or tools like webhook.site.
- API Logs: Monitor all requests in real-time from the API Logs tab.
Security Best Practices
- Never share your
api_secret— store it only on your backend server, never in frontend code or version control. - Enable 2FA immediately— it's required for withdrawals and provides critical protection.
- Verify webhook signatures — always validate the HMAC signature before processing webhook events.
- Use IP whitelisting — restrict API access to your known server IPs.
- Set daily withdrawal limits — cap exposure in case of credential compromise.
- Rotate keys periodically — rotate API keys and webhook secrets on a regular schedule.
- Monitor API logs — watch for unexpected IPs or unusual request patterns.
- Use idempotency keys — prevent duplicate charges from retry logic.