POST /apiv2/withdraw
अपने Netts बैलेंस से किसी भी TRON पते पर TRX की निकासी (withdraw) करें। यह अनुरोध तुरंत एक ऑर्डर नंबर लौटाता है; वास्तविक ऑन-चेन भुगतान बैकएंड द्वारा एसिंक्रोनस रूप से किया जाता है (~5 मिनट के भीतर)। परिणाम को स्टेटस एंडपॉइंट को पोल करके या वेबहुक कॉन्फ़िगर करके ट्रैक करें।
ℹ️ यह कैसे काम करता है। निकासी का अनुरोध करने पर आपके बैलेंस से राशि तुरंत रिज़र्व हो जाती है (ऑर्डर स्वीकार होते ही बैलेंस डेबिट हो जाता है)। इसके बाद एक बैकएंड डेमन TRX भेजता है और ऑर्डर को
completedयाfailedके रूप में चिह्नित करता है। प्रारंभिक प्रतिक्रिया में कोई सिंक्रोनस ऑन-चेन परिणाम नहीं होता है — आपको हमेशा पहले एकpendingपावती (acknowledgement) मिलती है।
एंडपॉइंट URL
POST https://netts.io/apiv2/withdrawअनुरोध हेडर
| हेडर | आवश्यक | विवरण |
|---|---|---|
| Content-Type | हाँ | application/json |
| X-API-KEY | हाँ | Netts डैशबोर्ड से आपकी API कुंजी |
| X-Real-IP | हाँ | आपकी श्वेतसूची (whitelist) से IP पता |
| X-Idempotency-Key | नहीं | दोहराव से बचने के लिए क्लाइंट द्वारा जनरेट की गई वैकल्पिक कुंजी (base64)। यदि छोड़ दिया जाए, तो सर्वर स्वचालित रूप से एक कुंजी बना लेता है। यह मान आपकी orderId बन जाता है। |
अनुरोध बॉडी
{
"amount": 15,
"address": "TXXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}पैरामीटर्स
| पैरामीटर | प्रकार | आवश्यक | विवरण |
|---|---|---|---|
| amount | number | हाँ | TRX में सकल (Gross) राशि (न्यूनतम 3)। शुल्क इसी राशि से काटा जाता है — प्राप्तकर्ता को amount − fee (net) प्राप्त होता है। |
| address | string | हाँ | गंतव्य TRON पता (T…, 34 वर्ण, base58)। |
| sub_and_robot_out | boolean | नहीं | रोबोट/सब भुगतान मोड: 1 TRX के बजाय 2 TRX शुल्क लागू करता है। डिफ़ॉल्ट false। |
शुल्क। सकल
amountसे एक निश्चित शुल्क काटा जाता है: सामान्य रूप से 1 TRX, या जबsub_and_robot_out = trueहो तो 2 TRX। यदिamount − fee ≤ 0हो तो ऑर्डर अस्वीकार कर दिया जाता है।
उदाहरण अनुरोध
नीचे दिए गए उदाहरण
X-Idempotency-Keyबनाते और भेजते भी हैं ताकि अनजाने में दोहराने पर दूसरी निकासी न बने। पूरे नियमों के लिए Idempotency देखें।
cURL
API_KEY="your_api_key"
ADDR="TXXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
AMOUNT=15
NONCE=$(( $(date +%s) / 2 )) # stable for retries within a 2s window; or your own order UUID
# X-Idempotency-Key = base64url( HMAC-SHA256( API_KEY, "addr:amount:nonce" ) )
IDEMP=$(printf '%s' "${ADDR}:${AMOUNT}:${NONCE}" \
| openssl dgst -sha256 -hmac "$API_KEY" -binary | basenc --base64url | tr -d '=')
curl -X POST https://netts.io/apiv2/withdraw \
-H "Content-Type: application/json" \
-H "X-API-KEY: $API_KEY" \
-H "X-Real-IP: your_whitelisted_ip" \
-H "X-Idempotency-Key: $IDEMP" \
-d "{\"amount\": $AMOUNT, \"address\": \"$ADDR\"}"Python
import time, hmac, hashlib, base64, requests
API_KEY = "your_api_key"
url = "https://netts.io/apiv2/withdraw"
payload = {"amount": 15, "address": "TXXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}
# X-Idempotency-Key = base64url( HMAC-SHA256( API_KEY, "addr:amount:nonce" ) ), padding stripped.
# Generate ONCE per order and resend the same value on every retry.
nonce = str(int(time.time() // 2)) # 2s bucket; or your own order UUID
message = f"{payload['address']}:{payload['amount']}:{nonce}"
idem_key = base64.urlsafe_b64encode(
hmac.new(API_KEY.encode(), message.encode(), hashlib.sha256).digest()
).decode().rstrip("=")
headers = {
"Content-Type": "application/json",
"X-API-KEY": API_KEY,
"X-Real-IP": "your_whitelisted_ip",
"X-Idempotency-Key": idem_key,
}
resp = requests.post(url, headers=headers, json=payload)
detail = resp.json().get("detail", {})
if resp.status_code == 202 and detail.get("status") == "pending":
d = detail["data"]
print(f"Order ID: {d['orderId']}") # use it for the status endpoint / webhook
print(f"Net to recipient: {d['net']} TRX (fee {d['fee']})")
else:
print(f"Code {detail.get('code')}: {detail.get('msg', detail)}")प्रतिक्रिया
स्वीकृत — निकासी कतारबद्ध (202 Accepted)
राशि आपके बैलेंस से रिज़र्व कर ली गई है और भुगतान शेड्यूल कर दिया गया है। स्टेटस एंडपॉइंट को पोल करें (या वेबहुक की प्रतीक्षा करें) जब तक कि यह completed / failed न हो जाए।
{
"detail": {
"code": 10000,
"status": "pending",
"msg": "Withdrawal request accepted, processing within 5 minutes.",
"data": {
"orderId": "EXAMPLEorderId0000000000000000000000000000Aa",
"amount": 15.0,
"fee": 1.0,
"net": 14.0,
"address": "TXXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
}
}प्रतिक्रिया फ़ील्ड
| फ़ील्ड | प्रकार | विवरण |
|---|---|---|
| detail.code | integer | 10000 स्वीकृत |
| detail.status | string | pending |
| detail.data.orderId | string | ऑर्डर संख्या — एक 43-वर्णों वाली URL-सुरक्षित स्ट्रिंग। स्टेटस एंडपॉइंट के लिए इसका उपयोग करें और यह वेबहुक पेलोड में ऑर्डर की पहचान करता है। |
| detail.data.amount | number | अनुरोधित सकल राशि (TRX) |
| detail.data.fee | number | काटा गया शुल्क (1 या 2 TRX) |
| detail.data.net | number | प्राप्तकर्ता को मिलने वाली राशि (amount − fee) |
| detail.data.address | string | गंतव्य पता |
स्टेटस एंडपॉइंट
GET https://netts.io/apiv2/withdraw/status/{orderId}हेडर्स: X-API-KEY + X-Real-IP (ऑर्डर प्रमाणित उपयोगकर्ता का ही होना चाहिए)। orderId URL-सुरक्षित है — इसे बिना किसी बदलाव के (as-is) पास करें, किसी URL-एन्कोडिंग की आवश्यकता नहीं है।
| ऑर्डर स्थिति | HTTP | code | status |
|---|---|---|---|
| पूर्ण (TRX भेज दिया गया) | 200 | 10000 | completed (processed_at के साथ) |
| कतारबद्ध / भेजा जा रहा है | 200 | 10001 | pending |
| विफल | 200 | 5003 | failed (error_message के साथ) |
| नहीं मिला / आपका नहीं है | 404 | -1 | — |
{
"detail": {
"code": 10000,
"status": "completed",
"data": {
"orderId": "EXAMPLEorderId0000000000000000000000000000Aa",
"amount": 15.0, "fee": 1.0, "net": 14.0,
"address": "TXXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"processed_at": "2026-01-01 00:00:00+00:00"
}
}
}सब-यूज़र खाते
सब-यूज़र निकासी बिल्कुल नियमित उपयोगकर्ताओं की तरह ही काम करती है — केवल सब-यूज़र की अपनी API कुंजी के साथ। एक सब-यूज़र अपनी स्वयं की कुंजी के साथ प्रमाणित होकर इसी POST /apiv2/withdraw एंडपॉइंट को कॉल करता है; निकासी उस सब-यूज़र के अपने बैलेंस से काटी जाती है और अनुरोध में निर्दिष्ट किसी भी address पर भेजी जाती है। समान न्यूनतम, समान शुल्क (1 TRX), समान प्रवाह। कोई अलग सब-यूज़र एंडपॉइंट नहीं है — प्रत्येक खाता, मूल (parent) या सब-यूज़र, केवल अपनी कुंजी के साथ अपने ही बैलेंस से निकासी करता है।
वेबहुक
पोलिंग के बजाय, एक बार वेबहुक कॉन्फ़िगर करें और जब आपकी प्रत्येक निकासी अंतिम स्थिति (completed / failed) पर पहुँच जाएगी, तो Netts एक हस्ताक्षरित (signed) सूचना POST करेगा। वेबहुक प्रति उपयोगकर्ता संग्रहीत किया जाता है और उस खाते की निकासी पर लागू होता है। यदि कोई वेबहुक कॉन्फ़िगर नहीं है, तो बस स्टेटस एंडपॉइंट को पोल करें।
कॉन्फ़िगर करें / देखें / हटाएं
POST https://netts.io/apiv2/withdraw/webhook # create or update
GET https://netts.io/apiv2/withdraw/webhook # view current config (secret is never returned)
DELETE https://netts.io/apiv2/withdraw/webhook # unsubscribeहेडर्स: X-API-KEY + X-Real-IP।
// POST body
{
"callback_url": "https://your-server.example/netts/withdraw-hook",
"secret": "your_shared_secret_min_8_chars",
"enabled": true
}| पैरामीटर | प्रकार | आवश्यक | विवरण |
|---|---|---|---|
| callback_url | string | हाँ | http(s) URL (≤ 2048 वर्ण) जो POST प्राप्त करता है |
| secret | string | हाँ | प्रत्येक पेलोड पर हस्ताक्षर करने के लिए उपयोग किया जाने वाला साझा रहस्य (8…256 वर्ण) |
| enabled | boolean | नहीं | कॉन्फ़िगरेशन हटाए बिना डिलीवरी चालू/बंद करें। डिफ़ॉल्ट true |
GET { callback_url, enabled, secret_set, updated_at } लौटाता है — सीक्रेट स्वयं कभी भी वापस नहीं दिखाया जाता है।
डिलीवरी पेलोड
Netts आपके callback_url पर हेडर X-Netts-Signature: base64( HMAC-SHA256( secret, raw_body ) ) और इस JSON बॉडी के साथ एक POST भेजता है:
{
"orderId": "EXAMPLEorderId0000000000000000000000000000Aa",
"status": "completed",
"amount": 15.0,
"fee": 1.0,
"net": 14.0,
"address": "TXXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"processed_at": "2026-01-01 00:00:00+00:00",
"error_message": null
}statuscompletedयाfailedहै (failedहोने पर,error_messageपॉप्युलेट होता है)।
हस्ताक्षर का सत्यापन करना
हस्ताक्षर की गणना बॉडी के कैनोनिकल JSON पर की जाती है: कुंजियाँ क्रमबद्ध (sorted), कोई स्पेस नहीं (separators=(",", ":"))। उसी तरह पुनर्गणना करें और तुलना करें।
import hmac, hashlib, base64, json
def verify(raw_body: bytes, signature_header: str, secret: str) -> bool:
expected = base64.b64encode(
hmac.new(secret.encode(), raw_body, hashlib.sha256).digest()
).decode()
return hmac.compare_digest(expected, signature_header)
# Flask example: verify against the EXACT bytes received, then parse.
# if verify(request.get_data(), request.headers["X-Netts-Signature"], SECRET): ...हमेशा प्राप्त कच्चे बाइट्स (raw received bytes) के आधार पर सत्यापित करें। यदि आप पार्स किए गए JSON को पुन: क्रमबद्ध करते हैं, तो कैनोनिकल रूप पुन: प्रस्तुत करें:
json.dumps(payload, ensure_ascii=False, separators=(",",":"), sort_keys=True)।
डिलीवरी गारंटी
- पावती (acknowledge) देने के लिए HTTP 2xx के साथ प्रतिक्रिया दें। किसी भी अन्य प्रतिक्रिया (या टाइमआउट) को एक विफल प्रयास माना जाता है।
- प्रति ऑर्डर अधिकतम 3 प्रयास, ऑर्डर बनने के समय से 21 मिनट की विंडो के भीतर (पुनः प्रयास बैकऑफ़ ≈ 5 मिनट)। उसके बाद, डिलीवरी छोड़ दी जाती है — स्टेटस एंडपॉइंट का उपयोग करें।
- डिलीवरी डुप्लिकेट-मुक्त (de-duplicated) होती हैं: प्रत्येक ऑर्डर अधिकतम एक बार सफलतापूर्वक डिलीवर किया जाता है।
- अपने हैंडलर को
orderIdपर idempotent बनाएं।
त्रुटि प्रतिक्रियाएँ
प्रमाणीकरण त्रुटि (401)
{ "detail": { "code": -1, "msg": "Invalid API key or IP not in whitelist" } }अपर्याप्त बैलेंस (403)
{ "detail": { "code": 1004, "status": "failed", "msg": "Insufficient balance: 2.0 < 15 TRX" } }लंबित निकासी मौजूद है (409)
आपके अपने बैलेंस पर एक समय में केवल एक ही लंबित निकासी हो सकती है। वर्तमान निकासी के प्रोसेस होने तक प्रतीक्षा करें।
{ "detail": { "code": 4090, "status": "failed", "msg": "You have a pending withdrawal. Wait until it is processed." } }सत्यापन त्रुटि (400)
{ "detail": { "code": 5004, "status": "failed", "msg": "Minimum withdrawal is 3 TRX" } }त्रुटि कोड संदर्भ
| कोड | विवरण | HTTP स्थिति |
|---|---|---|
10000 | स्वीकृत (निकासी कतारबद्ध) / पूर्ण (स्टेटस एंडपॉइंट) | 202 / 200 |
10001 | लंबित — कतारबद्ध या भेजा जा रहा है (स्टेटस एंडपॉइंट) | 200 |
208 | पहले से स्वीकृत अनुरोध का डुप्लिकेट — कैश्ड प्रतिक्रिया | 208 |
- | वही अनुरोध अभी भी प्रोसेस हो रहा है (अभी पुनः प्रयास न करें) | 409 |
4090 | आपकी पहले से ही एक निकासी लंबित है | 409 |
-1 | अमान्य API कुंजी / IP श्वेतसूची में नहीं है, या ऑर्डर नहीं मिला | 401 / 404 |
1004 | अपर्याप्त बैलेंस | 403 |
5004 | सत्यापन त्रुटि (राशि < 3, शुल्क ≥ राशि, गलत पता, गलत idempotency कुंजी) | 400 |
5003 | निकासी विफल / सेवा अनुपलब्ध | 200 (status) / 503 |
5000 | आंतरिक सर्वर त्रुटि | 500 |
दर सीमाएं (Rate Limits)
प्रति API कुंजी सीमित (हेडर X-API-KEY):
| अवधि | सीमा |
|---|---|
| 1 सेकंड | 5 अनुरोध |
| 1 मिनट | 150 अनुरोध |
दर सीमा पार हो गई (429)
{ "message": "API rate limit exceeded" }Idempotency
वैकल्पिक X-Idempotency-Key हेडर भेजें ताकि अनजाने में दोहराने पर दूसरी निकासी न बने — मूल प्रतिक्रिया HTTP 208 के साथ लौटाई जाती है। यदि आप हेडर नहीं भेजते हैं, तो सर्वर कम समय की विंडो के भीतर आपके अनुरोध पैरामीटर से स्वचालित रूप से एक कुंजी प्राप्त कर लेता है। यह कुंजी आपकी orderId भी है।
कुंजी कैसे बनाएं
कुंजी base64url( HMAC-SHA256( secret, message ) ) से = पैडिंग हटाकर बनाई जाती है — एक 43-वर्णों वाली URL-सुरक्षित स्ट्रिंग, जहाँ:
- secret = आपकी API कुंजी (
X-API-KEY); - message =
:से जुड़े फ़ील्ड्स —address:amount:nonce।
nonce कोई भी मान हो सकता है जो समान तार्किक ऑर्डर के पुनः प्रयासों में स्थिर रहे लेकिन अलग-अलग ऑर्डरों के बीच भिन्न हो — जैसे कि एक UUID जो आप उस ऑर्डर के लिए रखते हैं, या एक मोटा टाइमस्टैम्प बकेट। प्रति ऑर्डर एक बार कुंजी जनरेट करें और प्रत्येक पुनः प्रयास पर वही मान दोबारा भेजें।
import hmac, hashlib, base64, time
def make_idempotency_key(api_key, address, amount, nonce=None):
if nonce is None:
nonce = str(int(time.time() // 2)) # 2-second bucket; or your own order UUID
message = f"{address}:{amount}:{nonce}"
digest = hmac.new(api_key.encode(), message.encode(), hashlib.sha256).digest()
return base64.urlsafe_b64encode(digest).decode().rstrip("=") # 43-char URL-safeसत्यापन। प्रदान की गई
X-Idempotency-Keyवर्ण सेटA–Z a–z 0–9 + / = _ -से 16–64 वर्ण की होनी चाहिए। एक विकृत या अत्यधिक लंबी कुंजी को HTTP 400 (code 5004) के साथ अस्वीकार कर दिया जाता है।
| स्थिति कोड | अर्थ |
|---|---|
| 202 | स्वीकृत (पहला अनुरोध) |
| 208 | पहले ही स्वीकृत — कैश्ड प्रतिक्रिया लौटाई गई (कोई दूसरी निकासी नहीं) |
| 409 | वही अनुरोध वर्तमान में प्रोसेस हो रहा है — प्रतीक्षा करें, अभी पुनः प्रयास न करें |
विफलता के बाद पुनः प्रयास करना। केवल स्वीकृत परिणाम कैश्ड होते हैं। यदि पिछला प्रयास विफल रहा (उदा. अपर्याप्त बैलेंस, सत्यापन), तो आप सुरक्षित रूप से समान कुंजी के साथ पुनः प्रयास कर सकते हैं — पुरानी त्रुटि लौटाने के बजाय अनुरोध का पुनः प्रयास किया जाता है। जब कोई प्रयास अभी भी प्रगति पर हो तो आपको
409मिलता है; प्रतीक्षा करें और पुनः प्रयास करें।
टिप्पणियाँ
- एसिंक्रोनस भुगतान। प्रतिक्रिया हमेशा एक
pendingपावती होती है; TRX एक बैकएंड डेमन द्वारा भेजा जाता है, आमतौर पर ~5 मिनट के भीतर। परिणाम के लिए स्टेटस एंडपॉइंट या वेबहुक का उपयोग करें। - ऑर्डर स्वीकृत होने पर बैलेंस तुरंत रिज़र्व हो जाता है (न कि तब जब TRX अंततः भेजा जाता है)।
- न्यूनतम: 3 TRX। शुल्क: 1 TRX (या
sub_and_robot_outके साथ 2 TRX), सकलamountसे काटा जाता है; प्राप्तकर्ता कोnet = amount − feeप्राप्त होता है। - आपके अपने बैलेंस पर एक समय में एक लंबित (
code 4090)। - सब-यूज़र बिल्कुल नियमित उपयोगकर्ताओं की तरह निकासी करते हैं — समान
POST /apiv2/withdrawएंडपॉइंट, समान नियम, लेकिन सब-यूज़र की अपनी API कुंजी के साथ प्रमाणित। एक सब-यूज़र अपने द्वारा निर्दिष्ट किसी भीaddressपर अपने स्वयं के बैलेंस की निकासी करता है। कोई अलग सब-यूज़र एंडपॉइंट नहीं है। - orderId एक 43-वर्णों वाली URL-सुरक्षित स्ट्रिंग है; इसे स्टेटस URL में जैसा है वैसा ही पास करें (किसी एन्कोडिंग की आवश्यकता नहीं है)।
- वेबहुक: प्रति-उपयोगकर्ता,
X-Netts-Signatureके साथ हस्ताक्षरित; 21 मिनट की विंडो के भीतर अधिकतम 3 प्रयास।POST /apiv2/withdraw/webhookके माध्यम से कॉन्फ़िगर करें।