POST /apiv2/withdraw
اپنے Netts بیلنس سے کسی بھی TRON ایڈریس پر TRX کا انخلا (ودڈرا) کریں۔ یہ درخواست فوری طور پر ایک آرڈر نمبر واپس کرتی ہے؛ اصل آن چین ادائیگی پس پردہ (بیک اینڈ) غیر مطابقت پذیر طور پر (تقریباً 5 منٹ کے اندر) انجام دی جاتی ہے۔ نتیجے کو ٹریک کرنے کے لیے اسٹیٹس اینڈ پوائنٹ کو پول کریں یا ایک webhook ترتیب دیں۔
ℹ️ یہ کیسے کام کرتا ہے۔ انخلا کی درخواست دینے سے آپ کے بیلنس سے رقم فوری طور پر مخصوص (ریزرو) ہو جاتی ہے (آرڈر قبول ہوتے ہی بیلنس کاٹ لیا جاتا ہے)۔ اس کے بعد ایک بیک اینڈ ڈیمن TRX بھیجتا ہے اور آرڈر کو
completedیاfailedکے طور پر نشان زد کرتا ہے۔ ابتدائی جواب میں کوئی ہم وقت ساز (synchronous) آن چین نتیجہ نہیں ہوتا — آپ کو ہمیشہ پہلےpendingکی توثیق ملتی ہے۔
اینڈ پوائنٹ URL
POST https://netts.io/apiv2/withdrawدرخواست کے ہیڈرز
| ہیڈر | لازمی | تفصیل |
|---|---|---|
| Content-Type | ہاں | application/json |
| X-API-KEY | ہاں | Netts ڈیش بورڈ سے آپ کی API کلید |
| X-Real-IP | ہاں | آپ کی وائٹ لسٹ سے 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)
رقم آپ کے بیلنس سے مخصوص کر لی گئی ہے اور ادائیگی کا شیڈول طے کر دیا گیا ہے۔ اسٹیٹس اینڈ پوائنٹ کو پول کریں (یا webhook کا انتظار کریں) جب تک کہ یہ 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-safe سٹرنگ۔ اسے اسٹیٹس اینڈ پوائنٹ کے لیے استعمال کریں اور یہ webhook پیلوڈز میں آرڈر کی شناخت کرتا ہے۔ |
| 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-safe) ہے — اسے جیسا ہے ویسا ہی پاس کریں، کسی URL-encoding کی ضرورت نہیں۔
| آرڈر کی حالت | 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)، وہی طریقہ کار۔ کوئی الگ ذیلی صارف اینڈ پوائنٹ نہیں ہے — ہر اکاؤنٹ، خواہ بنیادی ہو یا ذیلی صارف، ہمیشہ صرف اپنی کلید سے اپنا بیلنس ہی نکالتا ہے۔
Webhooks
پولنگ کے بجائے، ایک بار webhook ترتیب دیں اور جب بھی آپ کا کوئی انخلا حتمی حالت (completed / failed) پر پہنچے گا تو Netts ایک دستخط شدہ اطلاع POST کرے گا۔ webhook فی صارف محفوظ کیا جاتا ہے اور اس اکاؤنٹ کے تمام انخلا پر لاگو ہوتا ہے۔ اگر کوئی webhook ترتیب نہ دیا گیا ہو، تو بس اسٹیٹس اینڈ پوائنٹ کو پول کریں۔
ترتیب دینا / دیکھنا / ہٹانا
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
}statusیا توcompletedہوتا ہے یا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 bytes) کے خلاف تصدیق کریں۔ اگر آپ پارس شدہ JSON کو دوبارہ سیریلائز کرتے ہیں، تو کینونیکل شکل کو دوبارہ بنائیں:
json.dumps(payload, ensure_ascii=False, separators=(",",":"), sort_keys=True)۔
ڈلیوری کی ضمانتیں
- تصدیق کے لیے HTTP 2xx کے ساتھ جواب دیں۔ کوئی بھی دوسرا جواب (یا ٹائم آؤٹ) ناکام کوشش تصور کیا جائے گا۔
- آرڈر بننے کے وقت سے 21 منٹ کی ونڈو کے اندر، فی آرڈر زیادہ سے زیادہ 3 کوششیں (دوبارہ کوشش کا وقفہ ≈ 5 منٹ)۔ اس کے بعد، ڈلیوری ترک کر دی جاتی ہے — متبادل کے طور پر اسٹیٹس اینڈ پوائنٹ استعمال کریں۔
- ڈلیوریز کو ڈپلیکیٹ سے پاک کیا جاتا ہے: ہر آرڈر زیادہ سے زیادہ ایک بار کامیابی کے ساتھ پہنچایا جاتا ہے۔
- اپنے ہینڈلر کو
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 | پہلے سے قبول شدہ درخواست کی نقل — محفوظ شدہ (cached) جواب | 208 |
- | وہی درخواست ابھی پروسیس ہو رہی ہے (ابھی دوبارہ کوشش نہ کریں) | 409 |
4090 | آپ کا ایک انخلا پہلے ہی زیر التوا ہے | 409 |
-1 | غلط API کلید / IP وائٹ لسٹ میں نہیں ہے، یا آرڈر نہیں ملا | 401 / 404 |
1004 | ناکافی بیلنس | 403 |
5004 | توثیقی خرابی (رقم < 3، فیس ≥ رقم، غلط ایڈریس، غلط idempotency key) | 400 |
5003 | انخلا ناکام ہو گیا / سروس دستیاب نہیں ہے | 200 (اسٹیٹس) / 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-safe سٹرنگ، جہاں:
- 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 | وہی درخواست فی الحال پروسیس ہو رہی ہے — انتظار کریں، ابھی دوبارہ کوشش نہ کریں |
ناکامی کے بعد دوبارہ کوشش کرنا۔ صرف قبول شدہ نتائج ہی محفوظ (cache) کیے جاتے ہیں۔ اگر پچھلی کوشش ناکام ہو گئی تھی (مثلاً ناکافی بیلنس، توثیق)، تو آپ محفوظ طریقے سے اسی کلید کے ساتھ دوبارہ کوشش کر سکتے ہیں — پرانی خرابی واپس کرنے کے بجائے درخواست کی دوبارہ کوشش کی جاتی ہے۔ جب تک کوئی کوشش جاری ہو آپ کو
409ملتا ہے؛ انتظار کریں اور دوبارہ کوشش کریں۔
نوٹس
- غیر مطابقت پذیر ادائیگی۔ جواب ہمیشہ
pendingکی توثیق ہوتا ہے؛ TRX ایک بیک اینڈ ڈیمن کے ذریعے بھیجا جاتا ہے، عام طور پر تقریباً 5 منٹ کے اندر۔ نتیجے کے لیے اسٹیٹس اینڈ پوائنٹ یا webhook کا استعمال کریں۔ - آرڈر قبول ہوتے ہی بیلنس فوری طور پر مخصوص کر لیا جاتا ہے (نہ کہ اس وقت جب 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-safe سٹرنگ ہے؛ اسٹیٹس URL میں اسے جیسا ہے ویسا ہی پاس کریں (کسی انکوڈنگ کی ضرورت نہیں)۔
- Webhooks: فی صارف،
X-Netts-Signatureکے ساتھ دستخط شدہ؛ 21 منٹ کی ونڈو کے اندر 3 کوششوں تک۔POST /apiv2/withdraw/webhookکے ذریعے ترتیب دیں۔