Important: Never expose your API key in client-side code.
Endpoints
Create Payment
Create a new payment link.
Request Body
Field
Type
Required
Description
merchant
string
Yes
Ethereum address to receive payment
chainId
string
Yes
Target blockchain chain ID
token
string
Yes
Token contract address. For ERC-20 tokens, use the contract address. For native tokens (ETH, BNB, MATIC), use the zero address: 0x0000000000000000000000000000000000000000. See Supported Networks & Tokens for the full list.
amount
string
Yes
Payment amount (human-readable, e.g., "100.00")
orderId
string
Yes
Your internal order reference (max 100 chars)
description
string
No
Payment description (max 200 chars)
redirectUrl
string
No
URL to redirect payer after payment. Payment ID appended as ?makapay=ID (max 2000 chars)
expiresAt
number
No
Unix timestamp (ms) when payment expires. Shows countdown timer to payer.
blockConfirmations
number
No
Required confirmations (default: 1, max: 100)
gasless
boolean
No
Enable gasless mode (default: false). Note: Only works with stablecoins (USDT, USDC, DAI) or tokens with a known price. Automatically converts to false for non-stablecoins without a price.
payerCoversFee
boolean
No
Payer covers fees (default: false)
customPriceUsd
string
No
USD price per token for custom tokens (e.g., "0.00001234"). Used as fallback if Alchemy and TrustedOracle have no price. Required for tokens with no automatic price source.
Example Request (ERC-20 Token)
Example Request (Native Token)
Accept payment in ETH on Ethereum mainnet by passing the zero address as token:
Response
Response Fields
Field
Type
Description
url
string
Payment page URL to share with customer
Error Responses
Status
Error
Description
400
Invalid form data
Request validation failed
401
Unauthorized
Invalid or missing API key
503
Oracle price unavailable
Price oracle temporarily unavailable (retry)
500
Failed to create payment
Internal server error
Get Balance
Get your Gas Tank balance.
Example Request
Response
Response Fields
Field
Type
Description
balance
string
Current Gas Tank balance in USDT (6 decimals)
Verify Payment Redirect
Verify that a payment redirect is authentic. Use this after receiving a redirect from MakaPay to confirm the payment was actually completed.
Note: This endpoint does not require authentication, as the hash serves as verification.
Query Parameters
Parameter
Type
Required
Description
id
string
Yes
The payment ID from the redirect (makapay param)
hash
string
Yes
The verification hash from the redirect
Example Request
Success Response
Response Fields
Field
Type
Description
valid
boolean
Whether the hash is valid
verified
boolean
Whether hash is valid AND payment is completed
payment
object
Payment details (only if valid)
payment.completedAt
number
Unix timestamp when payment was completed (only if completed)
error
string
Error message (only if invalid)
Error Responses
Status
Error
Description
400
Missing payment ID
No id parameter provided
400
Missing hash
No hash parameter provided
400
Invalid hash
Hash does not match payment data
404
Payment not found
Payment ID does not exist
Redirect Verification Flow
When you configure a redirectUrl for a payment, MakaPay will redirect the payer to your URL after successful payment with these query parameters:
Query Parameters
Parameter
Description
makapay
The unique payment ID
success
Always "true" (redirect only happens on success)
hash
HMAC-SHA256 signature (server-signed, cannot be forged)
Security
The hash parameter is an HMAC-SHA256 signature computed with a server-side secret. This ensures:
Attackers cannot forge redirect URLs - The secret is never exposed
Merchants must verify via API - Only MakaPay's server can validate the signature
Important: Always verify redirects using the /api/payments/verify endpoint. Never trust redirect parameters alone.
Verification Steps
Extract parameters from the redirect URL
Call the verify endpoint to confirm authenticity:
Check the response:
verified: true = Payment is complete and authentic
verified: false = Do not trust the redirect
Example Implementation (Node.js)
Payment Expiration
You can set an expiration time on payment links to create urgency or limit the validity period. When a payment expires, the payer will see an "Expired" status instead of being able to pay.
How It Works
Set expiration when creating a payment using the expiresAt field (Unix timestamp in milliseconds)
Countdown timer is shown to the payer on the payment page
Automatic expiration - a background job checks and expires payments every minute
Grace period - payments already received are processed even if the link expires
Common Expiration Durations
Duration
Calculation
1 hour
Date.now() + 3600000
24 hours
Date.now() + 86400000
7 days
Date.now() + 604800000
Custom
new Date('2025-01-20T12:00:00Z').getTime()
Example: Payment with 1-Hour Expiration
Example: Dynamic Expiration (Node.js)
Payment States After Expiration
Status
Description
expired
Payment link expired before any payment was received
completed
Payment was received before expiration and processed
pending
Payment partially received, may still be processed
Best Practices
Use expiration for time-sensitive offers - flash sales, limited-time discounts
Allow reasonable time - consider timezone differences and payment processing time
Communicate clearly - show expiration time in your UI before redirecting to payment
Handle expired state - provide a way for customers to request a new payment link
Public Endpoints
The following endpoints are public and do not require authentication. They are useful for resolving token information before creating a payment.
Get Token Price
Look up the current USD price for any token. The price is resolved using a two-step waterfall:
Alchemy — checked first using chainId + address. Works for most popular tokens on major chains.
TrustedOracle — fallback if Alchemy has no price. The oracle looks up prices by symbol, so the optional symbol parameter is needed for this fallback to work. If you omit symbol and Alchemy doesn't have the price, the endpoint returns 404.
Note: This endpoint does not require authentication.
Query Parameters
Parameter
Type
Required
Description
chainId
string
Yes
Blockchain chain ID (e.g., 1 for Ethereum, 137 for Polygon)
address
string
Yes
Token contract address (checksummed or lowercase)
symbol
string
No
Token symbol (e.g., ETH, BNB). Only needed for the TrustedOracle fallback — if Alchemy already has a price for this token, the symbol is not used. Pass it when you want full coverage across both price sources.
Example Request
Response
Response Fields
Field
Type
Description
chainId
number
The chain ID queried
address
string
Token contract address (lowercased)
symbol
string | null
Token symbol (uppercased), or null if not provided
priceUsd
string
USD price as a human-readable decimal string
source
string
Price source used: "alchemy" or "trusted_oracle"
timestamp
string
ISO 8601 timestamp of the response
Error Responses
Status
Error
Description
400
chainId and address are required
Missing required parameters
400
chainId must be a number
Invalid chain ID format
400
Invalid token address
Address is not a valid Ethereum address
404
Price not available for this token
No price source could resolve a price
500
Failed to fetch token price
Internal server error
Get Token Metadata
Resolve token metadata (name, symbol, decimals, logo) for any ERC-20 token. Uses Alchemy metadata with on-chain contract read as fallback.
Note: This endpoint does not require authentication.
Query Parameters
Parameter
Type
Required
Description
chainId
string
Yes
Blockchain chain ID
address
string
Yes
Token contract address
Example Request
Response
Response Fields
Field
Type
Description
name
string | null
Token name from metadata
symbol
string | null
Token ticker symbol
decimals
number
Token decimals (e.g., 6 for USDT, 18 for ETH)
logo
string | null
URL to the token logo image
hasAlchemyPrice
boolean
Whether Alchemy has a price feed for this token
priceUsd
string | undefined
Current USD price if available from Alchemy
address
string
Token contract address (lowercased)
chainId
number
The chain ID queried
Error Responses
Status
Error
Description
400
chainId and address are required
Missing required parameters
400
chainId must be a number
Invalid chain ID format
400
Invalid token address
Address is not a valid Ethereum address
400
Cannot read token contract
Contract doesn't exist at this address/chain or is not an ERC-20 token
500
Failed to fetch token metadata
Internal server error
Get Oracle Price
Fetch the price of a token directly from the MakaPay TrustedOracle smart contract on MakaChain. This is the same oracle used internally for gas fee calculations and as the fallback in the /tokens/price waterfall.
Unlike /tokens/price (which resolves by chain + address), this endpoint resolves by symbol only — it does not need a chain ID or contract address. Use this when you already know the token symbol and just need its USD price.
Note: This endpoint does not require authentication.
Query Parameters
Parameter
Type
Required
Description
symbol
string
Yes
Token symbol (e.g., ETH, BNB, USDT). Case-insensitive. USDT0 is automatically normalized to USDT.
Example Request
Response
Response Fields
Field
Type
Description
symbol
string
Normalized token symbol (uppercased)
priceRaw
string
Raw price as a big integer string (18 decimals of precision)
priceUsd
string
USD price as a human-readable decimal string
decimals
number
Precision of priceRaw (always 18)
Error Responses
Status
Error
Description
400
Symbol parameter is required
Missing symbol query parameter
404
Price not available for {SYMBOL}
Oracle has no price registered for this token
500
Failed to fetch price
Internal server error
Supported Symbols
The oracle supports all tokens that have been registered by the MakaPay operator. Common symbols include:
Symbol
Description
ETH
Ethereum
BNB
BNB (Binance Smart Chain)
MATIC
Polygon
USDT
Tether USD (also matches USDT0)
USDC
USD Coin
XRP
XRP
TRX
Tron
MAKA
MAKA Token
Supported Networks & Tokens
Mainnet
Ethereum (Chain ID: 1)
Token
Contract Address
Decimals
Type
ETH
0x0000000000000000000000000000000000000000
18
Native
USDT
0xdAC17F958D2ee523a2206206994597C13D831ec7
6
Stablecoin
USDC
0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
6
Stablecoin
MAKA
0x9FF7B37b84C05DfB08b4f50ADb17a80a3FEfD6eD
18
Token
Polygon (Chain ID: 137)
Token
Contract Address
Decimals
Type
MATIC
0x0000000000000000000000000000000000000000
18
Native
USDT0
0xc2132D05D31c914a87C6611C10748AEb04B58e8F
6
Stablecoin
USDC
0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359
6
Stablecoin
BNB Smart Chain (Chain ID: 56)
Token
Contract Address
Decimals
Type
BNB
0x0000000000000000000000000000000000000000
18
Native
USDT
0x55d398326f99059ff775485246999027b3197955
18
Stablecoin
USDC
0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d
18
Stablecoin
XRP
0x1d2f0da169ceb9fc7b3144628db156f3f6c60dbe
18
Token
TRX
0xce7de646e7208a4ef112cb6ed5038fa6cc6b12e3
6
Token
Base (Chain ID: 8453)
Token
Contract Address
Decimals
Type
ETH
0x0000000000000000000000000000000000000000
18
Native
USDC
0x833589fcd6edb6e08f4c7c32d4f71b54bda02913
6
Stablecoin
Arbitrum One (Chain ID: 42161)
Token
Contract Address
Decimals
Type
ETH
0x0000000000000000000000000000000000000000
18
Native
USDT
0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9
6
Stablecoin
USDC
0xaf88d065e77c8cC2239327C5EDb3A432268e5831
6
Stablecoin
MakaChain (Chain ID: 777178)
Token
Contract Address
Decimals
Type
USDT
0x30C28E393E0732335235685B345c95E6465Ad8A5
6
Stablecoin
USDC
0x1C978Ed2de920eA6c5844d011Ab9f574979F82A6
6
Stablecoin
Native tokens use the zero address (0x000...000). When creating a payment with a native token, pass the zero address as the token parameter.
Testnet
Sepolia (Chain ID: 11155111)
Token
Contract Address
Decimals
Type
ETH
0x0000000000000000000000000000000000000000
18
Native
USDT
0x3B62e45fB977773c2eF0404d80e0C59de22A97ec
6
Stablecoin
USDC
0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238
6
Stablecoin
MakaChain Testnet (Chain ID: 777177)
Token
Contract Address
Decimals
Type
USDT
0x309F410f92A98e43E1EEF623015a2e784F80ed72
6
Stablecoin
USDC
0x1C978Ed2de920eA6c5844d011Ab9f574979F82A6
6
Stablecoin
Webhooks
Configure webhooks to receive real-time payment notifications.
Setup
Go to Dashboard > Webhooks
Enter your webhook URL (HTTPS required)
Save configuration
Webhook Payload
Event Types
Event
Description
payment.completed
Payment successfully settled
payment.failed
Settlement failed
payment.expired
Payment link expired
Retry Policy
Failed deliveries are retried up to 3 times
Retry intervals: 1 minute, 5 minutes, 30 minutes
View delivery logs in the dashboard
Code Examples
Node.js
Python
PHP
Rate Limits
Endpoint
Rate Limit
POST /payments
100 requests/minute
GET /balance
60 requests/minute
Vault config endpoints
100 requests/minute
POST /vault/v1/users
100 requests/minute
GET /vault/v1/deposits
100 requests/minute
GET /vault/v1/business/:id/tokens
60 requests/minute (per IP)
Exceeding rate limits returns HTTP 429 (Too Many Requests).
Error Handling
Error Response Format
Common Errors
Status
Error
Solution
400
Invalid Merchant address format
Verify the merchant address is a valid Ethereum address
400
Invalid Token address format
Verify the token contract address
400
Invalid network selected
Use a supported chain ID
400
Amount must be a positive number
Ensure amount is > 0
401
Unauthorized
Check your API key
503
Oracle price unavailable
Retry after a few seconds
Vault Configuration API
Configure your vault account, manage accepted tokens, and set up webhooks — all via the API. These endpoints require authentication via the x-api-key header.
Create a new vault account. Call this once to initialize your vault.
Request Body
Field
Type
Required
Description
businessName
string
Yes
Your business display name
walletAddress
string
Yes
EVM address where processed funds are sent
enabledTokens
array
No
Initial tokens to enable (see below)
Each item in enabledTokens:
Field
Type
Required
Description
chainId
number
Yes
Blockchain chain ID
token
string
Yes
Token contract address
tokenSymbol
string
Yes
Token symbol (max 20 chars)
Example Request
Response (201 Created)
Error Responses
Status
Error
Description
400
businessName is required
Missing business name
400
walletAddress is required
Missing wallet address
400
Invalid EVM address
Wallet address is not a valid Ethereum address
401
Unauthorized
Missing or invalid API key
409
Vault already configured
Vault already exists for this API key
Get Vault Configuration
Retrieve your current vault configuration.
Example Request
Response
Error Responses
Status
Error
Description
401
Unauthorized
Missing or invalid API key
404
Vault not configured
No vault exists for this API key
Update Vault Settings
Update your vault's business name, wallet address, or active status.
Request Body
All fields are optional — include only what you want to change.
Field
Type
Required
Description
businessName
string
No
New business name
walletAddress
string
No
New wallet address (valid EVM address)
isActive
boolean
No
Enable/disable the vault
Example Request
Response
Error Responses
Status
Error
Description
400
Invalid EVM address
New wallet address is invalid
401
Unauthorized
Missing or invalid API key
404
Vault not configured
No vault exists for this API key
Add Token
Enable a new token for deposits on your vault.
Request Body
Field
Type
Required
Description
chainId
number
Yes
Blockchain chain ID (1–999999999)
token
string
Yes
Token contract address
tokenSymbol
string
Yes
Token ticker symbol (max 20 chars)
minDepositAmountCents
number
No
Minimum deposit in USD cents
maxDepositAmountCents
number
No
Maximum deposit in USD cents
Example Request
Response (201 Created)
Error Responses
Status
Error
Description
400
chainId is required
Missing chain ID
400
tokenSymbol is required
Missing token symbol
400
tokenSymbol too long
Symbol exceeds 20 characters
401
Unauthorized
Missing or invalid API key
404
Vault not configured
No vault exists for this API key
409
Token already enabled
Token already exists on this chain
Remove Token
Remove a token from your vault's accepted list.
Request Body
Field
Type
Required
Description
chainId
number
Yes
Chain ID of the token to remove
token
string
Yes
Token contract address
Example Request
Response
Error Responses
Status
Error
Description
400
chainId and token are required
Missing required fields
401
Unauthorized
Missing or invalid API key
404
Token not found
Token is not in the enabled list
Get Webhook Configuration
Retrieve your current webhook settings.
Example Request
Response
Note: The full secret is only shown when first creating the webhook or after regenerating. Subsequent reads show a masked preview.
Error Responses
Status
Error
Description
401
Unauthorized
Missing or invalid API key
404
No webhook configured
No webhook has been set up
Create / Update Webhook
Set up or update your vault webhook endpoint. The webhook URL must use HTTPS.
Request Body
Field
Type
Required
Description
url
string
Yes
Webhook URL (must be HTTPS)
events
string[]
No
Events to subscribe to (default: all)
isActive
boolean
No
Enable/disable webhook (default: true)
Available events: deposit.completed, deposit.failed, deposit.detected, deposit.processing
Example Request
Response (first time — includes secret)
Response (update — secret is masked)
Important: Save the secret from the first response — it is only shown once. Use it to verify webhook signatures.
Error Responses
Status
Error
Description
400
Webhook URL must use HTTPS
URL protocol is not HTTPS
400
Invalid webhook URL
URL format is invalid
401
Unauthorized
Missing or invalid API key
404
Vault not configured
No vault exists for this API key
Delete Webhook
Remove the webhook configuration entirely.
Example Request
Response
Error Responses
Status
Error
Description
401
Unauthorized
Missing or invalid API key
404
No webhook configured
No webhook exists to delete
Regenerate Webhook Secret
Generate a new HMAC secret for webhook signature verification. The old secret immediately stops working.
Warning: If you regenerate the secret while webhook deliveries are in the retry queue, those retries will use the new secret. Ensure your server is updated to verify with the new secret before triggering a regeneration, or briefly pause the webhook (isActive: false) while rotating.
Request Body
Example Request
Response
Important: Save this new secret immediately. The old secret is permanently invalidated. Update your webhook handler with the new secret.
Error Responses
Status
Error
Description
401
Unauthorized
Missing or invalid API key
404
No webhook configured
Must create a webhook first
Payment Webhook Configuration API
Manage payment webhook settings programmatically via API key. This mirrors the Vault Webhook API but for standard payment notifications.
GET /api/v1/webhooks
Get the current webhook configuration.
Headers:
Header
Required
Description
x-api-key
Yes
Your MakaPay API key
Response:
curl example:
PUT /api/v1/webhooks
Create or update webhook configuration. On first creation, a dedicated webhook secret (whsec_...) is generated and returned.
Headers:
Header
Required
Description
x-api-key
Yes
Your MakaPay API key
Content-Type
Yes
application/json
Request Body:
Field
Type
Required
Description
url
string
Yes
Webhook URL (must be HTTPS)
events
string[]
No
Events to subscribe to. Default: ["payment.completed", "payment.withdrawn"]
isActive
boolean
No
Whether the webhook is active. Default: true
Valid events:
payment.completed — Payment confirmed and funds received
payment.withdrawn — Funds withdrawn to merchant wallet
payment.awaiting_gas — Payment needs gas tank top-up
payment.failed — Payment failed
payment.expired — Payment expired before completion
Response (creation — includes full secret):
Response (update — secret is masked):
curl example:
DELETE /api/v1/webhooks
Remove the webhook configuration entirely.
Headers:
Header
Required
Description
x-api-key
Yes
Your MakaPay API key
Response:
curl example:
POST /api/v1/webhooks
Regenerate the webhook signing secret. The old secret is immediately invalidated.
Warning: If you regenerate the secret while webhook deliveries are in the retry queue, those retries will use the new secret. Ensure your server is updated to verify with the new secret before triggering a regeneration, or briefly pause the webhook (isActive: false) while rotating.
Headers:
Header
Required
Description
x-api-key
Yes
Your MakaPay API key
Content-Type
Yes
application/json
Request Body:
Response:
curl example:
SDK (Coming Soon)
Official SDKs for popular languages:
JavaScript/TypeScript: npm install @makapay/sdk
Python: pip install makapay
PHP: composer require makapay/sdk
Go: go get github.com/makapay/go-sdk
Changelog
v1.3.0 (Current)
Added Payment Webhook Configuration API — manage payment webhooks via API key
Dedicated webhook secrets (whsec_...) for payment webhooks (separate from API key)
Event filtering — subscribe only to the payment events you care about
Backward compatible — existing webhooks without secrets continue working
v1.2.0
Added Vault Configuration API — setup, update, and manage vault accounts via API
# With symbol — enables both Alchemy and oracle fallback
curl "https://app.makapay.io/api/tokens/price?chainId=1&address=0xdAC17F958D2ee523a2206206994597C13D831ec7&symbol=USDT"
# Without symbol — Alchemy only, no oracle fallback
curl "https://app.makapay.io/api/tokens/price?chainId=1&address=0xdAC17F958D2ee523a2206206994597C13D831ec7"