Order Endpoints
Create and manage payment orders through the HashNut API.
Create Payment Order
Creates a new payment order and returns payment details including a payment URL.
Endpoint: POST /api/v3.0.0/pay/createPayOrderOnSplitWalletWithApiKey
Request
Headers:
hashnut-request-uuid: <uuid>
hashnut-request-timestamp: <timestamp>
hashnut-request-sign: <signature>
Content-Type: application/json
Body:
{
"accessKeyId": "string",
"merchantOrderId": "string",
"chainCode": "string",
"coinCode": "string",
"amount": 0.01,
"callBackUrl": "string",
"frontendCallbackUrl": "string",
"receiptAddress": "string",
"splitterAddress": "string"
}
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
accessKeyId | string | ✅ Yes | Your merchant access key ID |
merchantOrderId | string | ✅ Yes | Unique merchant order ID (max 255 characters, must be unique per merchant) |
chainCode | string | ✅ Yes | Chain code. Supported values: "erc20", "bsc-erc20", "polygon-erc20", "tron-trc20" |
coinCode | string | ✅ Yes | Currency code (e.g., "usdt", "usdc", "MockUSDT") - case-sensitive |
amount | decimal | ✅ Yes | Payment amount in base unit (e.g., 0.01 for 0.01 USDT). Minimum: 0.01. Round to 2 decimal places. |
callBackUrl | string | ⚠️ Optional | Backend webhook URL for payment status updates |
frontendCallbackUrl | string | ⚠️ Optional | Frontend redirect URL after payment completion |
receiptAddress | string | ⚠️ Optional | Custom merchant receiving address. Must match format: EVM (0x...) or TRON (T...). If not provided, uses default from account. |
splitterAddress | string | ⚠️ Optional | Splitter contract address (smart contract for receiving payments). Must be EVM format (0x...). |
Response
Success Response (200 OK):
{
"code": 0,
"msg": "success",
"data": {
"payOrderId": "01KBZ292SK2GKFK97916F5EC3B",
"accessSign": "D3DE7E4002057C0EAED1BE2268DA53CC9058DCFC9DCAF50D999AF270A7B033C5",
"merchantOrderId": "e30ff306-5552-497d-9083-fd6e943dfd73"
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
payOrderId | string | HashNut platform order ID (unique identifier) |
accessSign | string | Access signature for querying order status |
merchantOrderId | string | Echo of merchant order ID |
Payment URL Construction
After receiving the response, construct the payment URL:
https://testnet.hashnut.io/pay?accessSign={accessSign}&merchantOrderId={merchantOrderId}&payOrderId={payOrderId}&chainCode={chainCode}
Example:
https://testnet.hashnut.io/pay?accessSign=D3DE7E4002057C0EAED1BE2268DA53CC9058DCFC9DCAF50D999AF270A7B033C5&merchantOrderId=e30ff306-5552-497d-9083-fd6e943dfd73&payOrderId=01KBZ292SK2GKFK97916F5EC3B&chainCode=erc20
Error Responses
Invalid Signature (401):
{
"code": -2,
"msg": "Invalid signature or credentials",
"data": null
}
Invalid Parameters (400):
{
"code": -2,
"msg": "Invalid parameters",
"data": null
}
Common Errors:
-2: Authentication/signature error, invalid credentials, or missing required fields- Other codes: See Error Codes
Code Examples
- JavaScript
- Python
- cURL
const response = await fetch(
'https://testnet.hashnut.io/api/v3.0.0/pay/createPayOrderOnSplitWalletWithApiKey',
{
method: 'POST',
headers: {
'hashnut-request-uuid': uuid,
'hashnut-request-timestamp': timestamp,
'hashnut-request-sign': signature,
'Content-Type': 'application/json'
},
body: JSON.stringify({
accessKeyId: 'YOUR_ACCESS_KEY_ID',
merchantOrderId: `order-${Date.now()}`,
chainCode: 'erc20',
coinCode: 'usdt',
amount: 0.01,
callBackUrl: 'https://your-site.com/webhook',
frontendCallbackUrl: 'https://your-site.com/payment/success'
})
}
);
const result = await response.json();
if (result.code === 0) {
const paymentUrl = `https://testnet.hashnut.io/pay?accessSign=${result.data.accessSign}&merchantOrderId=${result.data.merchantOrderId}&payOrderId=${result.data.payOrderId}&chainCode=erc20`;
console.log('Payment URL:', paymentUrl);
}
import requests
response = requests.post(
'https://testnet.hashnut.io/api/v3.0.0/pay/createPayOrderOnSplitWalletWithApiKey',
headers={
'hashnut-request-uuid': uuid,
'hashnut-request-timestamp': timestamp,
'hashnut-request-sign': signature,
'Content-Type': 'application/json'
},
json={
'accessKeyId': 'YOUR_ACCESS_KEY_ID',
'merchantOrderId': f'order-{int(time.time())}',
'chainCode': 'erc20',
'coinCode': 'usdt',
'amount': 0.01,
'callBackUrl': 'https://your-site.com/webhook',
'frontendCallbackUrl': 'https://your-site.com/payment/success'
}
)
result = response.json()
if result['code'] == 0:
payment_url = f"https://testnet.hashnut.io/pay?accessSign={result['data']['accessSign']}&merchantOrderId={result['data']['merchantOrderId']}&payOrderId={result['data']['payOrderId']}&chainCode=erc20"
print(f'Payment URL: {payment_url}')
curl -X POST 'https://testnet.hashnut.io/api/v3.0.0/pay/createPayOrderOnSplitWalletWithApiKey' \
-H 'hashnut-request-uuid: 550e8400-e29b-41d4-a716-446655440000' \
-H 'hashnut-request-timestamp: 1704067200000' \
-H 'hashnut-request-sign: <your-signature>' \
-H 'Content-Type: application/json' \
-d '{
"accessKeyId": "YOUR_ACCESS_KEY_ID",
"merchantOrderId": "order-123",
"chainCode": "erc20",
"coinCode": "usdt",
"amount": 0.01,
"callBackUrl": "https://your-site.com/webhook",
"frontendCallbackUrl": "https://your-site.com/payment/success"
}'
Query Payment Order Status
Queries the current status of a payment order using the access sign.
Endpoint: POST /api/v3.0.0/pay/queryPayOrderWithAccessSign
Request
Headers:
Content-Type: application/json
Note: This endpoint does NOT require signature authentication (uses accessSign instead).
Body:
{
"merchantOrderId": "string",
"payOrderId": "string",
"accessSign": "string"
}
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
merchantOrderId | string | ✅ Yes | Your merchant order ID |
payOrderId | string | ✅ Yes | HashNut platform order ID |
accessSign | string | ✅ Yes | Access signature from create order response |
Response
Success Response (200 OK):
{
"code": 0,
"msg": "success",
"data": {
"merchantAddress": "0x1234...",
"chain": "Ethereum",
"chainCode": "erc20",
"coinCode": "usdt",
"createChannel": 0,
"accessChannel": 0,
"merchantOrderId": "e30ff306-5552-497d-9083-fd6e943dfd73",
"payOrderId": "01KBZ292SK2GKFK97916F5EC3B",
"tokenAddress": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
"receiptAddress": "0x5678...",
"amount": 0.01,
"state": 4,
"accessSign": "D3DE7E4002057C0EAED1BE2268DA53CC9058DCFC9DCAF50D999AF270A7B033C5",
"payTxId": "0xabcdef1234567890...",
"confirmCount": "12",
"walletConnectEnable": true,
"bridgeServerAddress": "https://bridge.hashnut.io",
"eip712ChainId": "1",
"chainId": "1",
"callBackUrl": "https://merchant.com/api/payment/webhook",
"createTime": "2024-01-01T00:00:00Z",
"rate": 1.0,
"obtainAmount": 0.01,
"platformFee": 0
}
}
Response Fields
| Field | Type | Description |
|---|---|---|
merchantAddress | string | Merchant wallet address |
chain | string | Chain name (e.g., "Ethereum", "BSC") |
chainCode | string | Chain code (e.g., "erc20") |
coinCode | string | Currency code (e.g., "usdt") |
merchantOrderId | string | Merchant order ID |
payOrderId | string | HashNut platform order ID |
tokenAddress | string | Token contract address |
receiptAddress | string | Receiving address |
amount | decimal | Payment amount |
state | integer | Order state (see Order States) |
accessSign | string | Access signature |
payTxId | string | Transaction hash (if paid) |
confirmCount | string | Confirmation count |
walletConnectEnable | boolean | Whether WalletConnect is enabled |
bridgeServerAddress | string | Bridge server address |
eip712ChainId | string | EIP-712 chain ID |
chainId | string | Chain ID |
callBackUrl | string | Webhook callback URL |
createTime | string | Creation timestamp (ISO format) |
rate | decimal | Exchange rate (if applicable) |
obtainAmount | decimal | Amount obtained by merchant |
platformFee | decimal | Platform fee |
Order States
| State | Code | Description |
|---|---|---|
| Unpaid | 0 | Order created, awaiting payment |
| Not Completed | 1 | Payment initiated but not completed |
| Waiting for Confirmation | 2 | Transaction broadcast, awaiting confirmation |
| Confirming | 3 | Transaction confirmed, verifying payment |
| Success | 4 | Payment complete and verified |
| Failed | -1 | Payment transaction failed |
| Expired | -2 | Order expired without payment |
| Cancelled | -3 | Order cancelled by merchant |
See Order States for detailed information.
Code Examples
- JavaScript
- Python
- cURL
const response = await fetch(
'https://testnet.hashnut.io/api/v3.0.0/pay/queryPayOrderWithAccessSign',
{
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
merchantOrderId: 'order-123',
payOrderId: '01KBZ292SK2GKFK97916F5EC3B',
accessSign: 'D3DE7E4002057C0EAED1BE2268DA53CC9058DCFC9DCAF50D999AF270A7B033C5'
})
}
);
const result = await response.json();
if (result.code === 0) {
const order = result.data;
console.log('Order State:', order.state);
console.log('Amount:', order.amount);
if (order.state === 4) {
console.log('Payment successful!');
}
}
import requests
response = requests.post(
'https://testnet.hashnut.io/api/v3.0.0/pay/queryPayOrderWithAccessSign',
headers={'Content-Type': 'application/json'},
json={
'merchantOrderId': 'order-123',
'payOrderId': '01KBZ292SK2GKFK97916F5EC3B',
'accessSign': 'D3DE7E4002057C0EAED1BE2268DA53CC9058DCFC9DCAF50D999AF270A7B033C5'
}
)
result = response.json()
if result['code'] == 0:
order = result['data']
print(f"Order State: {order['state']}")
print(f"Amount: {order['amount']}")
if order['state'] == 4:
print('Payment successful!')
curl -X POST 'https://testnet.hashnut.io/api/v3.0.0/pay/queryPayOrderWithAccessSign' \
-H 'Content-Type: application/json' \
-d '{
"merchantOrderId": "order-123",
"payOrderId": "01KBZ292SK2GKFK97916F5EC3B",
"accessSign": "D3DE7E4002057C0EAED1BE2268DA53CC9058DCFC9DCAF50D999AF270A7B033C5"
}'
Best Practices
- Always Query After Webhook: Even after receiving a webhook, query the order status to get the latest state
- Handle All States: Implement handling for all order states, especially terminal states (Success, Failed, Expired, Cancelled)
- Polling: If not using webhooks, poll order status regularly (but not too frequently)
- Error Handling: Always check
response.code === 0before processing data - Idempotency: Use
merchantOrderIdto ensure order uniqueness and prevent duplicates
Next Steps
- Learn about Webhooks for real-time notifications
- Understand Order States in detail
- Explore Config Endpoints for supported chains and tokens
Ready to create orders? Check out Quick Start →