Developer Documentation

Integrate NovaPay into your application to accept cryptocurrency payments. Merchant access is onboarding-controlled: complete account setup and any required review before using issued API credentials for server-to-server calls.

Quick Start

  1. Create a merchant account and submit your business details to begin onboarding
  2. Complete any required review before relying on issued API Keys or IPN Secrets in production
  3. Use the API Key in the X-API-Key header for approved payment endpoints
  4. Create orders, get deposit addresses, and verify webhook signatures using your IPN Secret

Your key is only used in-browser and never stored.

Quick Select
https://api.sha3.net

All payment API calls require an API Key sent in the X-API-Key header. API keys are activation-gated and should only be treated as usable after the merchant account has completed the required onboarding and review steps.

API Key (Server-to-Server)

Include your API key in every request to /v1/pay/ endpoints.

http
GET /v1/pay/deposit-address?user_id=user123&currency=USDT_TRC20
Host: api.sha3.net
X-API-Key: your-api-key-here

⚠️ Never expose your API Key in client-side code. All payment API calls should be made from your server.

Onboarding is controlled. Creating an account does not automatically mean the merchant is approved for unrestricted production use, payouts, or live credential issuance.

API Key Format

API keys are random alphanumeric strings. They are stored as SHA-256 hashes in the database — the raw key is only shown once at creation time. Keep it secure.

NovaPay follows the Google JSON Style Guide. Success and failure are indicated by HTTP status codes — there is no top-level success or ok field.

✅ Success (HTTP 2xx)

json
{
  "data": {
    "order_id": "abc-123",
    "status": "pending"
  }
}

❌ Error (HTTP 4xx / 5xx)

json
{
  "error": {
    "code": "INVALID_AMOUNT",
    "message": "Amount must be positive"
  }
}

• Always check HTTP status code first: 2xx = success, 4xx/5xx = error

error.code is a machine-readable string constant (e.g. INVALID_CURRENCY) — use it for programmatic error handling

error.message is human-readable, may change — do not match on it

• Amounts are always decimal strings (e.g. "10.000000"), never floats

EnvironmentAPI (Gateway)
Productionhttps://api.sha3.net

API (Gateway) — single public entry point for all /v1/pay/ endpoints. Production sits behind CloudFront for edge caching and DDoS protection.

Portal API is an internal service (no public ingress). All portal routes go through the Gateway at /v1/portal/.

checkout_url returned by order creation is a relative path (e.g. /checkout/<order_id>). Prepend your frontend domain to build the full URL.

These endpoints require the X-API-Key header. All payment endpoints use the /v1/pay/ prefix.

POST/v1/pay/orders🔐 API Key

Create a new payment order. Returns a checkout URL that you can redirect your customer to.

Request Body

ParameterTypeRequiredDescription
amountstringRequiredOrder amount as a decimal string (e.g. "10.00")
currencystringRequiredCrypto currency code (e.g. "USDT_TRC20", "ETH"). Use GET /v1/currencies for the full list.
descriptionstringOptionalOrder description shown on the checkout page
metadataobjectOptionalArbitrary key-value metadata (your internal order ID, user info, etc.)
redirect_urlstringOptionalURL to redirect after successful payment
cancel_urlstringOptionalURL to redirect on cancellation
bash
curl -X POST https://api.sha3.net/v1/pay/orders \
  -H "X-API-Key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": "10.00",
    "currency": "USDT_TRC20",
    "description": "Premium Plan",
    "redirect_url": "https://yoursite.com/success",
    "cancel_url": "https://yoursite.com/cancel"
  }'

Response

json
{
  "data": {
    "order_id": "550e8400-e29b-41d4-a716-446655440000",
    "checkout_url": "/checkout/550e8400-e29b-41d4-a716-446655440000",
    "expires_at": "2026-02-25T12:00:00Z"
  }
}

💡 checkout_url is a relative path. Prepend your frontend domain to get the full URL, e.g. https://www.sha3.net/checkout/...

GET/v1/pay/orders/{order_id}🔐 API Key

Get order details by ID.

bash
curl https://api.sha3.net/v1/pay/orders/550e8400-e29b-41d4-a716-446655440000 \
  -H "X-API-Key: your-api-key"

Response

json
{
  "data": {
    "order_id": "550e8400-e29b-41d4-a716-446655440000",
    "amount": "10.00",
    "currency": "USDT_TRC20",
    "status": "pending",
    "selected_crypto": null,
    "deposit_address": null,
    "deposit_id": null,
    "description": "Premium Plan",
    "metadata": null,
    "redirect_url": "https://yoursite.com/success",
    "cancel_url": "https://yoursite.com/cancel",
    "expires_at": "2026-02-25T12:00:00Z",
    "created_at": "2026-02-25T11:00:00Z",
    "updated_at": "2026-02-25T11:00:00Z"
  }
}
GET/v1/pay/orders🔐 API Key

List orders for the authenticated merchant.

ParameterTypeRequiredDescription
statusstringOptionalFilter by status: pending, paid, expired, cancelled
limitintegerOptionalMax results (default: 20, max: 100)
offsetintegerOptionalPagination offset (default: 0)
POST/v1/pay/orders/{order_id}/select🔐 API Key

Select the cryptocurrency for an order. This is called by the hosted checkout page when the customer picks their payment currency — you typically do not need to call this directly.

ParameterTypeRequiredDescription
currencystringRequiredCrypto currency code (e.g. "USDT_TRC20", "ETH")

Response

json
{
  "data": {
    "order_id": "550e8400-...",
    "status": "pending",
    "selected_crypto": "USDT_TRC20",
    "deposit_address": "TXqH4v...",
    ...
  }
}
GET/v1/pay/deposit-address🔐 API Key

Get or allocate a permanent deposit address for a user. The same user always gets the same address (idempotent). Addresses are assigned from the address pool or generated on-demand via the wallet service.

ParameterTypeRequiredDescription
user_idstringRequiredUnique user identifier in your system
currencystringRequiredCurrency code (e.g. "USDT_TRC20", "ETH")
bash
curl "https://api.sha3.net/v1/pay/deposit-address?user_id=user123&currency=USDT_TRC20" \
  -H "X-API-Key: your-api-key"

Response

json
{
  "data": {
    "address": "TXqH4v...",
    "currency": "USDT_TRC20",
    "network": "tron",
    "chain_id": 728126428,
    "user_id": "user123",
    "created_at": "2026-02-25T10:30:00Z"
  }
}
GET/v1/pay/deposits🔐 API Key

List deposits for the authenticated merchant.

ParameterTypeRequiredDescription
user_idstringOptionalFilter by user ID
limitintegerOptionalMax results (default: 20, max: 100)
offsetintegerOptionalPagination offset (default: 0)

Response

json
{
  "data": {
    "deposits": [
      {
        "deposit_id": "dep_abc123",
        "user_id": "user123",
        "address": "TXqH4v...",
        "currency": "USDT_TRC20",
        "chain_id": 728126428,
        "tx_hash": "0xabc...",
        "amount": "100.000000",
        "fee_amount": "1.000000",
        "net_amount": "99.000000",
        "status": "settled",
        "created_at": "2026-02-25T10:00:00Z",
        "confirmed_at": "2026-02-25T10:05:00Z",
        "settled_at": "2026-02-25T10:05:10Z"
      }
    ],
    "total": 1,
    "limit": 20,
    "offset": 0
  }
}
GET/v1/pay/deposit/{deposit_id}🔐 API Key

Get a specific deposit by ID.

GET/v1/pay/balance🔐 API Key

Get the merchant's balance across all currencies. Available is spendable; frozen is held pending withdrawal completion.

json
{
  "data": {
    "balances": [
      { "currency": "USDT_TRC20", "chain_id": 728126428, "available": "1250.50", "frozen": "0.00" },
      { "currency": "ETH", "chain_id": 1, "available": "0.85", "frozen": "0.10" }
    ]
  }
}
POST/v1/pay/withdrawals🔐 API Key

Create a withdrawal request. The amount is immediately frozen from available balance. Withdrawals within configured limits auto-approve; larger amounts stay pending until signer approval, then move through broadcasting → processing → completed.

Request Body

ParameterTypeRequiredDescription
to_addressstringRequiredDestination wallet address (EIP-55 checksum for EVM chains)
chain_idintegerRequiredTarget blockchain chain ID (e.g. 728126428 for Tron, 1 for Ethereum)
token_addressstringOptionalToken contract address. Omit or set null for native coins (ETH, TRX)
amountstringRequiredAmount as a plain decimal string in token units (e.g. "100.000000" for USDT or "0.5" for ETH). Scientific notation and wei-style smallest-unit integers are not accepted.
bash
curl -X POST https://api.sha3.net/v1/pay/withdrawals \
  -H "X-API-Key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "to_address": "TXqH4v...",
    "chain_id": 728126428,
    "token_address": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
    "amount": "100.000000"
  }'

Response

json
{
  "data": {
    "id": 42,
    "to_address": "TXqH4v...",
    "chain_id": 728126428,
    "token_address": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
    "amount": "100.000000",
    "fee_amount": "0",
    "status": "pending",
    "tx_hash": null,
    "confirmations": 0,
    "error_msg": null,
    "requested_at": "2026-02-25T10:00:00Z",
    "approved_at": null,
    "completed_at": null,
    "created_at": "2026-02-25T10:00:00Z"
  }
}

⚠️ Withdrawals exceeding your account's single-tx or daily limits stay pending until approval is submitted through POST /v1/withdrawals/{id}/approve with a signer key. Approved withdrawals then progress through broadcasting and processing before completion.

GET/v1/pay/withdrawals🔐 API Key

List withdrawals for the authenticated merchant.

ParameterTypeRequiredDescription
statusstringOptionalFilter by status: pending, approved, broadcasting, processing, completed, failed
limitintegerOptionalMax results (default: 20, max: 100)
offsetintegerOptionalPagination offset (default: 0)

Response

json
{
  "data": {
    "withdrawals": [...],
    "total": 10,
    "limit": 20,
    "offset": 0
  }
}
GET/v1/pay/withdrawals/{id}🔐 API Key

Get a specific withdrawal by numeric ID.

POST/v1/withdrawals/{id}/approve🔐 Signer Key

Approve or reject a pending withdrawal using a signer key. This route is only for configured signers and only works while the withdrawal is still pending.

Required Header

http
X-Signer-Key: sk_live_xxx

Request Body

ParameterTypeRequiredDescription
actionstringRequiredEither approve or reject
commentstringOptionalOptional reviewer comment stored with the approval record
chain_idintegerRequiredChain id used when resolving the applicable multisig policy
token_addressstringOptionalToken contract address for token withdrawals; omit or null for native assets
bash
curl -X POST https://api.sha3.net/v1/withdrawals/42/approve \
  -H "X-Signer-Key: your-signer-key" \
  -H "Content-Type: application/json" \
  -d '{
    "action": "approve",
    "comment": "Within treasury policy",
    "chain_id": 728126428,
    "token_address": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t"
  }'

Rejecting a pending withdrawal moves it to failed and refunds the frozen balance back to available.