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. You will use it to generate the HMAC signatures.Generate HMAC Signature
The signature is generated by hashing the concatenation of your current timestamp and the compact JSON body using your api_secret.
import hmac, hashlib, time, json
# ── Credentials ──────────────────────────────────────────────
api_key = "npk_live_xxxxxxxxxxxx"
api_secret = "npks_xxxxxxxxxxxxxxxx"
# ── Request Config ────────────────────────────────────────────
url = "https://api.gammapay.io/v1/USDTTRC20/invoices"
body_data = {
"amount": "50.0",
"currency": "USD",
"description": "API Invoice",
"customer_email": "api@example.com",
"wallet_id": "ef894934-b0f4-441b-9adb-e586a4111e82"
}
# ── Generate Signature ────────────────────────────────────────
timestamp = str(int(time.time())) # Fresh timestamp every run
body_json = json.dumps(body_data, separators=(',', ':')) # Compact JSON (no spaces)
payload = f"{timestamp}.{body_json}" # Format: timestamp.body
signature = hmac.new(
api_secret.encode(),
payload.encode(),
hashlib.sha256
).hexdigest()
# ── Print curl Command ────────────────────────────────────────
print(f"""curl -X POST '{url}' \
-H 'Content-Type: application/json' \
-H 'X-API-Key: {api_key}' \
-H 'X-Timestamp: {timestamp}' \
-H 'X-Signature: sha256={signature}' \
-d '{body_json}'""")Make Your First Request
Run the curl command generated above to create an invoice.
curl -X POST 'https://api.gammapay.io/v1/USDTTRC20/invoices' \
-H 'Content-Type: application/json' \
-H 'X-API-Key: npk_live_xxxxxxxxxxxx' \
-H 'X-Timestamp: 1745223600' \
-H 'X-Signature: sha256=a7f3d92e1b...' \
-d '{"amount":"50.0","currency":"USD","wallet_id":"ef89..."}'{
"success": true,
"message": "Invoice created successfully.",
"data": {
"invoice_id": "NP-20260421-A7KZ",
"url": "https://pay.gammapay.io/NP-20260421-A7KZ",
"address": "bc1q...",
"network": "TRON",
"amount": { "coin": "49.9010", "fiat": "50.00", "fiat_currency": "USD" },
"status": "pending"
}
}Listen to Webhook
When the payment is detected or confirmed, GammaPay sends a POST request to your webhook URL.
app.post('/webhook/gammapay', express.raw({ type: 'application/json' }), (req, res) => {
const sig = req.headers['x-gammapay-signature']; // sha256=...
const ts = req.headers['x-gammapay-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_type === 'payment.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. The data object remains identical.Authentication & Headers
GammaPay uses HMAC signature verification for most API endpoints to ensure requests are authentic and haven't been tampered with.
- Where to get your keys: Log into the dashboard, go to Wallets, click on your target wallet, and open the API Keys tab.
- What to send: Every API request must include the three HTTP headers detailed in the table below.
| 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 | No | Unique key to prevent duplicate POST requests (24h TTL). |
Rate Limits
Rate limits are applied per API key. Free plans allow 100 requests/min (burst 150/10s). Premium plans allow 500 requests/min (burst 750/10s). Rate limit status is returned in the response headers:
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1745223660
Retry-After: 13 // Only present on 429 Error
API Responses: Error Codes
| Error Code | HTTP | Retriable | Description |
|---|---|---|---|
| VALIDATION_ERROR | 400 | No | Missing or invalid fields in the payload. |
| INVALID_CREDENTIALS | 401 | No | API key is missing, invalid, or inactive. |
| INVALID_SIGNATURE | 401 | No | HMAC signature mismatch. |
| NONCE_REPLAY | 401 | No | Nonce already used (replay attack prevention). |
| NONCE_EXPIRED | 401 | No | Nonce timestamp older than 5 minutes. |
| FORBIDDEN | 403 | No | API key lacks required scope. |
| NOT_FOUND | 404 | No | The requested resource was not found. |
| IDEMPOTENCY_CONFLICT | 409 | No | Same idempotency key used with different payload. |
| INVOICE_ALREADY_PAID | 409 | No | Cannot modify an invoice already marked paid. |
| INSUFFICIENT_AMOUNT | 400 | No | Amount below the minimum required for this coin. |
| INVOICE_EXPIRED | 410 | No | Invoice past expiry time. |
| COIN_NOT_SUPPORTED | 400 | No | Coin not live on this account plan. |
| WALLET_LOCKED | 423 | Yes | Wallet is temporarily locked by admin. |
| RATE_LIMIT_EXCEEDED | 429 | Yes | Rate limit exceeded. Check Retry-After header. |
| SERVER_ERROR | 500 | Yes | Internal server error. Retry with backoff. |
Wallet API Reference
/v1/dashboard/walletsCreate a new wallet. Returns your `api_secret` which is only shown once.
| Parameter | Type | Description |
|---|---|---|
| name * | string | Wallet name |
| coin_symbol * | string | e.g., USDTTRC20, BTC |
| webhook_url | string | Your server endpoint for notifications |
| is_testnet | boolean | Use testnet architecture |
curl -X POST 'https://api.gammapay.io/v1/dashboard/wallets' \
-H 'Content-Type: application/json' \
-H 'X-API-Key: npk_live_xxxxxxxxxxxx' \
-H 'X-Timestamp: 1745223600' \
-H 'X-Signature: sha256=...' \
-d '{
"name": "My USDT Wallet",
"coin_symbol": "USDTTRC20"
}'{
"success": true,
"message": "Wallet created.",
"data": {
"id": "wlt_3f2504e0-4f89",
"name": "My USDT Wallet",
"coin_symbol": "USDTTRC20",
"api_key": "npk_live_xxxxxxxxxxxxxxxxxxx",
"api_secret": "nps_live_xxxxxxxxxxxxxxxxxxx"
}
}/v1/dashboard/walletsFetch a paginated list of all wallets in your account.
| Parameter | Type | Description |
|---|---|---|
| coin_symbol | string | Filter by coin symbol |
| page | int | Page number (default 1) |
| limit | int | Items per page (default 20, max 100) |
curl -X GET 'https://api.gammapay.io/v1/dashboard/wallets' \
-H 'X-API-Key: npk_live_xxxxxxxxxxxx' \
-H 'X-Timestamp: 1745223600' \
-H 'X-Signature: sha256=...'{
"success": true,
"message": "OK",
"data": {
"items": [
{
"id": "wlt_3f2504e0-4f89",
"name": "Treasury USDT",
"coin_symbol": "USDTTRC20",
"available_balance": "45000.50"
}
]
}
}/v1/dashboard/wallets/:wallet_idGet detailed information about a specific wallet, including its balance.
| Parameter | Type | Description |
|---|
{
"success": true,
"message": "OK",
"data": {
"id": "wlt_3f2504e0",
"name": "My USDT Wallet",
"available_balance": "1250.00",
"pending_balance": "50.00"
},
"meta": { "timestamp": "2026-04-21T09:00:00Z" }
}/v1/dashboard/wallets/:wallet_id/transactionsGet a paginated list of transactions for a specific wallet.
| Parameter | Type | Description |
|---|---|---|
| page | int | Page number (default 1) |
| limit | int | Items per page (default 20, max 100) |
{
"success": true,
"message": "OK",
"data": {
"items": [...],
"pagination": { "page": 1, "limit": 20, "total": 45, "total_pages": 3, "has_next": true }
},
"meta": { "timestamp": "2026-04-21T09:00:00Z" }
}/v1/dashboard/wallets/:wallet_id/rotate-keyRotate the API key for a wallet. The old key remains valid for a 1-hour grace period.
| Parameter | Type | Description |
|---|
curl -X POST 'https://api.gammapay.io/v1/dashboard/wallets/:id/rotate-key' \
-H 'X-API-Key: npk_live_xxxxxxxxxxxx' \
-H 'X-Timestamp: 1745223600' \
-H 'X-Signature: sha256=...'{
"success": true,
"message": "API key rotated.",
"data": {
"api_key": "npk_live_NEW_xxxxxxxx",
"api_secret": "npks_NEW_xxxxxxxx",
"old_key_expires_at": "2026-04-21T10:00:00Z"
}
}Invoices API Reference
How it Works
When you create an invoice, GammaPay allocates a unique blockchain deposit address. We monitor this address on-chain. When funds arrive, the status updates automatically.
Crypto vs USD
If currency="USD", we lock the exchange rate at creation time. If currency="USDT", no conversion happens and the amount is fixed in coins.
/v1/:coin/invoicesGenerate a payment request.
| Parameter | Type | Description |
|---|---|---|
| amount * | string | Amount in coin or USD |
| currency | string | Default 'USD' |
| expire_time | integer | Minutes until expiry (default 60) |
| notify_url | string | Webhook callback URL |
| custom_data | object | Arbitrary JSON metadata |
curl -X POST 'https://api.gammapay.io/v1/USDTTRC20/invoices' \
-H 'Content-Type: application/json' \
-H 'X-API-Key: npk_live_xxxxxxxxxxxx' \
-H 'X-Timestamp: 1745223600' \
-H 'X-Signature: sha256=...' \
-d '{
"amount": "50.00",
"currency": "USD",
"notify_url": "https://yoursite.com/webhook"
}'{
"success": true,
"message": "Invoice created.",
"data": {
"invoice_id": "NP-20260421-A7KZ",
"url": "https://pay.gammapay.io/NP-20260421-A7KZ",
"address": "bc1q...",
"network": "TRON",
"amount": { "coin": "99.9010", "fiat": "99.99", "fiat_currency": "USD" },
"status": "pending",
"expires_at": "2026-04-21T10:00:00Z"
}
}/v1/:coin/invoices/:invoice_idGet detailed information about an invoice.
| Parameter | Type | Description |
|---|
curl -X GET 'https://api.gammapay.io/v1/USDTTRC20/invoices/:invoice_id' \
-H 'X-API-Key: npk_live_xxxxxxxxxxxx' \
-H 'X-Timestamp: 1745223600' \
-H 'X-Signature: sha256=...'{
"success": true,
"data": {
"invoice_id": "NP-20260421-A7KZ",
"status": "paid",
"received_amount_coin": "99.9010",
"paid_at": "2026-04-21T09:12:00Z"
}
}/v1/:coin/invoicesList paginated invoices filtered by status or date.
| Parameter | Type | Description |
|---|---|---|
| status | string | pending, confirming, paid, expired, underpaid |
{
"success": true,
"message": "OK",
"data": {
"items": [...],
"pagination": { "page": 1, "limit": 20, "total": 143, "total_pages": 8 }
},
"meta": { "timestamp": "2026-04-21T09:00:00Z" }
}Invoice Status Flow
pending → detected (in mempool) → confirming (on-chain) → paidAlternate flows:
→
expired (no payment before expiry)→
underpaid (expired with partial payment)Edge Cases (Crypto-Specific)
- Underpayment: Status becomes
underpaidafter expiry. Developer decides whether to accept or request top-up. - Overpayment: Marked
paid. Excess funds credited to wallet balance. - Multiple Transactions: Remains
confirminguntil total received >= expected. - Wrong Network/Token: If a customer sends ETH to a TRC20 address, funds are lost forever. Clearly show the network (
Network) on your checkout UI.
Webhooks (IPNS)
Webhooks enable you to receive automatic updates on transactions. When a transaction status changes, GammaPay will send a POST request with JSON data to your notify_url. All webhooks include the X-Gammapay-Signature, X-Gammapay-Timestamp, and X-Gammapay-Event headers.
Event Types
GammaPay sends the following events. Your server should return a 200 OK within 30 seconds.
Lifecycle Flow & Payloads
payment.detectedVisible in mempool{
"event_id": "evt_01JXYZ...",
"event_type": "payment.detected",
"created_at": "2026-05-01T10:00:00Z",
"data": {
"invoice_id": "NP-20260501-ABCD",
"invoice_uuid": "3f2504e0-...",
"status": "detected",
"txid": "abc123def456...",
"amount_received_coin": "49.527343",
"amount_expected_coin": "49.527343",
"coin_symbol": "USDTTRC20",
"confirmations": 0,
"required_confirmations": 10,
"network": "tron"
}
}payment.confirmedFully paid & confirmed{
"event_id": "evt_01HV3X...",
"event_type": "payment.confirmed",
"created_at": "2026-04-21T09:02:15Z",
"data": {
"invoice_id": "NP-20260421-A7KZ",
"invoice_uuid": "3f2504e0-...",
"status": "paid",
"txid": "a1b2c3d4e5f6...",
"amount_received_coin": "99.9010",
"amount_received_fiat": "100.00",
"fiat_currency": "USD",
"coin_symbol": "USDTTRC20",
"confirmations": 19,
"required_confirmations": 19,
"paid_at": "2026-04-21T09:02:15Z"
}
}payment.underpaidPartial payment received{
"event_id": "evt_01JXYZ...",
"event_type": "payment.underpaid",
"created_at": "2026-05-01T11:00:00Z",
"data": {
"invoice_id": "NP-20260501-ABCD",
"invoice_uuid": "3f2504e0-...",
"status": "underpaid",
"amount_received_coin": "40.000000",
"amount_expected_coin": "49.527343",
"shortfall_coin": "9.527343"
}
}Webhook Security & Retries
Validation Steps
- Extract
X-Gammapay-TimestampandX-Gammapay-Signatureheaders. - Check
|now - timestamp| < 300seconds (replay protection). - Compute:
HMAC-SHA256(secret, `${timestamp}.${rawBody}`) - Compare using
timingSafeEqual.
| Retry Attempt | Delay |
|---|---|
| 1 (initial) | Immediate |
| 2 | 1 minute |
| 3 | 5 minutes |
| 4 | 30 minutes |
| 5 | 2 hours |
Webhook API
/v1/dashboard/webhooksList recent webhook deliveries and their status.
curl -X GET 'https://api.gammapay.io/v1/dashboard/webhooks' \
-H 'X-API-Key: npk_live_xxxxxxxxxxxx' \
-H 'X-Timestamp: 1745223600' \
-H 'X-Signature: sha256=...'{
"success": true,
"data": {
"items": [
{ "id": "wh_123", "event_type": "payment.confirmed", "status": "delivered", "response_code": 200 }
]
}
}/v1/dashboard/webhooks/:idDelete a webhook configuration.
curl -X DELETE 'https://api.gammapay.io/v1/dashboard/webhooks/:id' \
-H 'X-API-Key: npk_live_xxxxxxxxxxxx' \
-H 'X-Timestamp: 1745223600' \
-H 'X-Signature: sha256=...'{ "success": true, "message": "Webhook deleted." }Developer Guides
Accept a Payment
The standard flow involves creating an invoice, redirecting the user to the url, and listening for the payment.confirmed webhook.
Best Practice
Always use an X-Idempotency-Key when creating invoices to prevent double-charging if your request retries due to network issues.
Crypto vs USD Payments
USD Mode: You define the price in USD (e.g. 50.00). GammaPay calculates the required crypto amount (e.g. 49.95 USDT) at the moment of invoice creation based on current market rates.
Native Mode: You define the price in the native coin (e.g. 100 USDT). No conversion is performed, and the customer must pay exactly that amount in coins.
Handling Underpayments
Underpayments occur if a customer sends less than the required amount or if they send funds after the invoice has expired.
- Monitor for the
payment.underpaidevent. - You can manually mark the invoice as paid in the dashboard if the shortfall is negligible.
- Otherwise, the invoice remains unpaid until the remaining balance is sent to the same address.
Test Your Integration
Use our sandbox environment to test without real funds.
Security Best Practices
- Never share your
api_secret. It should only be stored on your secure backend server, never in a frontend application or committed to version control. - Verify Webhook Signatures. Always validate the HMAC signature of incoming webhooks using your
api_secretto ensure they originate from GammaPay and haven't been spoofed. - Rotate API Keys. If you suspect your secret is compromised, use the dashboard or API to rotate your keys immediately.