Skip to content

API Reference

Full SoloPay REST API specification.

Base URL

EnvironmentURL
Productionhttps://gateway.solonetwork.io/api/v1
Staginghttps://gateway.dev.solonetwork.io/api/v1
Developmenthttp://localhost:3001/api/v1

Authentication

MethodHeaderEndpoints
Public Keyx-public-keyPOST /payments, GET /payments/:id, POST /payments/:id/relay, GET /payments/:id/relay, GET /payments/:id/gas-status, POST /payments/request-gas
API Keyx-api-keyGET /merchant/*, POST /merchant/payment-methods, POST /refunds
None-GET /chains, GET /chains/tokens

Payments

POST /payments

Create a payment. Auth: x-public-key + Origin

json
{
  "orderId": "order-001",
  "amount": 10.5,
  "tokenAddress": "0xE4C687167705Abf55d709395f92e254bdF5825a2",
  "successUrl": "https://example.com/success",
  "failUrl": "https://example.com/fail",
  "currency": "USD"
}

Response (201)

json
{
  "success": true,
  "data": {
    "paymentId": "0xabc123...",
    "orderId": "order-001",
    "chainId": 80002,
    "tokenAddress": "0xE4C687167705Abf55d709395f92e254bdF5825a2",
    "tokenSymbol": "SUT",
    "tokenDecimals": 18,
    "gatewayAddress": "0x...",
    "forwarderAddress": "0x...",
    "amount": "10500000000000000000",
    "recipientAddress": "0xMerchantWallet...",
    "merchantId": "0x...",
    "deadline": "1706281200",
    "successUrl": "https://example.com/success",
    "failUrl": "https://example.com/fail",
    "expiresAt": "2024-01-26T12:35:00.000Z",
    "tokenPermitSupported": true,
    "isFaucetEnabled": true,
    "currency": "USD",
    "fiatAmount": 10.5,
    "tokenPrice": 1.0
  }
}

GET /payments/:id

Get payment status. Auth: x-public-key

Status values: CREATED, PAID, REFUND_SUBMITTED, REFUNDED, INVALID, EXPIRED, FAILED. Payment success = PAID (funds transferred directly to merchant).

Response (200)

json
{
  "success": true,
  "data": {
    "paymentId": "0xabc123...",
    "orderId": "order-001",
    "status": "PAID",
    "chainId": 80002,
    "tokenAddress": "0xE4C687167705Abf55d709395f92e254bdF5825a2",
    "tokenSymbol": "SUT",
    "tokenDecimals": 18,
    "tokenPermitSupported": true,
    "isFaucetEnabled": true,
    "gatewayAddress": "0x...",
    "forwarderAddress": "0x...",
    "amount": "10500000000000000000",
    "recipientAddress": "0xMerchantWallet...",
    "merchantId": "0x...",
    "deadline": "1706281200",
    "successUrl": "https://example.com/success",
    "failUrl": "https://example.com/fail",
    "expiresAt": "2024-01-26T12:35:00.000Z",
    "txHash": "0xdef789...",
    "payerAddress": "0x...",
    "createdAt": "2024-01-26T12:30:00Z",
    "currency": "USD",
    "fiatAmount": 10.5,
    "tokenPrice": 1.0
  }
}
  • txHash — Hash of the pay transaction. Present once the payment is PAID or later.
  • deadline — Signature deadline (Unix timestamp) for the payment request; used when status is not yet terminal.

POST /payments/:id/relay

Submit a Gasless payment (ERC-2771). Auth: x-public-key + Origin

json
{
  "paymentId": "0xabc123...",
  "forwarderAddress": "0x...",
  "forwardRequest": {
    "from": "0x...",
    "to": "0x...",
    "value": "0",
    "gas": "200000",
    "nonce": "1",
    "deadline": "1706281200",
    "data": "0x...",
    "signature": "0x..."
  }
}

Response (202)

json
{
  "success": true,
  "data": {
    "status": "submitted",
    "message": "Gasless transaction submitted"
  }
}

GET /payments/:id/relay

Get relay status. Auth: x-public-key

json
{
  "success": true,
  "data": {
    "status": "CONFIRMED",
    "transactionHash": "0xdef789...",
    "errorMessage": null,
    "createdAt": "2024-01-26T12:34:00Z",
    "updatedAt": "2024-01-26T12:35:42Z"
  }
}

Status values: QUEUEDSUBMITTEDCONFIRMED (or FAILED)


GET /payments/:id/gas-status

Check whether a wallet can receive a one-time native-token grant for the token approval transaction. Auth: x-public-key

bash
curl "https://gateway.dev.solonetwork.io/api/v1/payments/0xabc123.../gas-status?walletAddress=0xPayer..." \
  -H "x-public-key: pk_xxxxx"
json
{
  "needsGas": true,
  "hasEnoughTokenBalance": true,
  "alreadyGranted": false,
  "canReceiveGas": true
}

The merchant must have the faucet enabled (isFaucetEnabled: true on the payment response). A wallet can receive at most one grant per chain, and a payment can fund at most one grant.

FieldDescription
needsGasNative balance is below the estimated approve cost
hasEnoughTokenBalanceWallet holds at least the payment token amount
alreadyGrantedThis wallet already received a grant on this chain
canReceiveGasneedsGas && !alreadyGranted && hasEnoughTokenBalance

canReceiveGas is wallet-level only

canReceiveGas does not detect whether this payment already funded a grant for another wallet. A subsequent request-gas call may still return PAYMENT_ALREADY_GRANTED. Handle that error when calling POST /payments/request-gas.

Error responses

HTTPCodeCause
403FAUCET_DISABLEDFaucet is not enabled for this merchant (not a 200 with canReceiveGas: false)
404NOT_FOUNDPayment does not exist or does not belong to the authenticated merchant

See Error Codes for all gas faucet errors.


POST /payments/request-gas

Request the one-time native-token grant used to submit an ERC-20 approve transaction. Auth: x-public-key + Origin

bash
curl -X POST https://gateway.dev.solonetwork.io/api/v1/payments/request-gas \
  -H "x-public-key: pk_xxxxx" \
  -H "Origin: https://yourshop.com" \
  -H "Content-Type: application/json" \
  -d '{
    "paymentId": "0xabc123...",
    "walletAddress": "0xPayer..."
  }'
json
{
  "txHash": "0xdef789...",
  "amount": "10000000000000000",
  "chainId": 80002
}

A grant is issued only when the payment belongs to the authenticated merchant, the wallet has enough payment tokens, and its native balance is below the estimated approval cost. The response is returned after the grant transaction is confirmed on-chain, so you can submit approve as soon as this call succeeds.

When ALLOWED_WIDGET_ORIGIN is set on the gateway, Origin must match that value exactly. Browsers set Origin automatically on fetch; server-side callers must set it explicitly. See Authentication.

Error responses

HTTPCodeCause
403FAUCET_DISABLEDFaucet is not enabled for this merchant
403FORBIDDENOrigin does not match ALLOWED_WIDGET_ORIGIN
404NOT_FOUNDPayment does not exist or does not belong to the authenticated merchant
400INSUFFICIENT_TOKEN_BALANCEWallet token balance is below the payment amount
400ALREADY_HAS_GASWallet already has enough native token for approve
400ALREADY_GRANTEDWallet already received a grant on this chain
400PAYMENT_ALREADY_GRANTEDThis payment already funded a grant
409GRANT_IN_PROGRESSAnother grant request for this payment is in progress

See Error Codes for details.


Merchant

GET /merchant

Get merchant info. Auth: x-api-key

json
{
  "success": true,
  "data": {
    "merchant": {
      "id": 1,
      "merchant_key": "my-store",
      "name": "My Store",
      "chain_id": 80002,
      "chain": { "id": 1, "network_id": 80002, "name": "Polygon Amoy", "is_testnet": true },
      "webhook_url": null,
      "public_key": "pk_xxx",
      "is_enabled": true,
      "payment_methods": [...]
    },
    "chainTokens": [...]
  }
}

GET /merchant/payment-methods

List payment methods. Auth: x-api-key


POST /merchant/payment-methods

Add a payment method. Auth: x-api-key

json
{ "tokenAddress": "0x...", "is_enabled": true }

PATCH /merchant/payment-methods/:id

Update a payment method. Auth: x-api-key

json
{ "is_enabled": false }

GET /merchant/payments

List payments. Auth: x-api-key. Query: orderId


GET /merchant/payments/:id

Get payment detail. Auth: x-api-key


Chains

GET /chains

Get supported chains. No auth required.

json
{
  "success": true,
  "data": {
    "chains": [
      { "id": 1, "network_id": 80002, "name": "Polygon Amoy", "is_testnet": true },
      { "id": 2, "network_id": 97, "name": "BSC Testnet", "is_testnet": true },
      { "id": 3, "network_id": 11155111, "name": "Sepolia", "is_testnet": true }
    ]
  }
}

GET /chains/tokens

Get all chains with their tokens. No auth required.


Health

GET /health

Server health check. No auth required.

json
{ "status": "ok", "timestamp": "2024-01-26T12:00:00.000Z" }

Next Steps

Non-custodial Web3 payment infrastructure for ERC-20 checkout, sponsored gas, and wallet-to-wallet settlement.