Skip to content
Translated page. The English version is the source of truth.

POST /apiv2/withdraw ​

Netts bakiyenizden herhangi bir TRON adresine TRX çekin. İstek anında bir sipariş numarası döndürür; asıl zincir üstü (on-chain) ödeme arka uç tarafından asenkron olarak gerçekleştirilir (~5 dakika içinde). Sonucu durum uç noktasını sorgulayarak (polling) veya bir webhook yapılandırarak takip edin.

ℹ️ Nasıl çalışır. Çekim talebi vermek tutarı anında bakiyenizden ayırır (rezerve eder) (sipariş kabul edildiği anda bakiye düşülür). Ardından bir arka plan arka plan programı (daemon) TRX'i gönderir ve siparişi completed veya failed olarak işaretler. İlk yanıtta eşzamanlı zincir üstü sonuç bulunmaz — her zaman önce bir pending onayı alırsınız.

Uç Nokta URL'si ​

POST https://netts.io/apiv2/withdraw

İstek Başlıkları ​

BaşlıkGerekliAçıklama
Content-TypeEvetapplication/json
X-API-KEYEvetNetts kontrol panelindeki API anahtarınız
X-Real-IPEvetBeyaz listenizdeki IP adresi
X-Idempotency-KeyHayırÇift çekim olmadan güvenli bir şekilde yeniden denemek için isteğe bağlı istemci tarafından oluşturulan anahtar (base64). Atlanırsa, sunucu otomatik olarak bir tane türetir. Bu değer orderId değeriniz olur.

İstek Gövdesi ​

json
{
    "amount": 15,
    "address": "TXXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}

Parametreler ​

ParametreTürGerekliAçıklama
amountnumberEvetTRX cinsinden brüt tutar (en az 3). Ücret bu tutardan düşülür — alıcıya amount − fee (net) ulaşır.
addressstringEvetHedef TRON adresi (T…, 34 karakter, base58).
sub_and_robot_outbooleanHayırRobot/alt kullanıcı ödeme modu: 1 TRX yerine 2 TRX ücret uygular. Varsayılan false.

Ücret. Brüt amount üzerinden sabit bir ücret kesilir: normalde 1 TRX veya sub_and_robot_out = true olduğunda 2 TRX. amount − fee ≤ 0 ise sipariş reddedilir.

Örnek İstekler ​

Aşağıdaki örnekler ayrıca X-Idempotency-Key oluşturur ve gönderir, böylece yanlışlıkla yapılan tekrarlar ikinci bir çekim oluşturmaz. Tüm kurallar için Idempotency (Tekilleştirme) bölümüne bakın.

cURL ​

bash
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 ​

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)}")

Yanıt ​

Kabul Edildi — çekim sıraya alındı (202 Accepted) ​

Tutar bakiyenizden rezerve edilir ve ödeme planlanır. completed / failed durumuna gelene kadar durum uç noktasını sorgulayın (veya webhook'u bekleyin).

json
{
    "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"
        }
    }
}

Yanıt Alanları ​

AlanTürAçıklama
detail.codeinteger10000 kabul edildi
detail.statusstringpending
detail.data.orderIdstringSipariş numarası — 43 karakterlik URL güvenli bir dize. Durum uç noktası için kullanılır ve siparişi webhook yüklerinde tanımlar.
detail.data.amountnumberTalep edilen brüt tutar (TRX)
detail.data.feenumberKesilen ücret (1 veya 2 TRX)
detail.data.netnumberAlıcının alacağı tutar (amount − fee)
detail.data.addressstringHedef adres

Durum Uç Noktası ​

GET https://netts.io/apiv2/withdraw/status/{orderId}

Başlıklar: X-API-KEY + X-Real-IP (sipariş, kimliği doğrulanmış kullanıcıya ait olmalıdır). orderId URL için güvenlidir — URL kodlaması (URL-encoding) gerekmeden olduğu gibi iletin.

Sipariş durumuHTTPcodestatus
Tamamlandı (TRX gönderildi)20010000completed (processed_at ile birlikte)
Sıraya alındı / gönderiliyor20010001pending
Başarısız2005003failed (error_message ile birlikte)
Bulunamadı / size ait değil404-1—
json
{
    "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"
        }
    }
}

Alt kullanıcı hesapları ​

Alt kullanıcı çekimleri, normal kullanıcılarla tamamen aynı şekilde çalışır — yalnızca alt kullanıcının kendi API anahtarı kullanılır. Bir alt kullanıcı, kendi anahtarıyla doğrulanarak bu aynı POST /apiv2/withdraw uç noktasını çağırır; çekim ilgili alt kullanıcının kendi bakiyesinden düşülür ve isteğin belirttiği address değerine gönderilir. Aynı minimum, aynı ücret (1 TRX), aynı akış. Ayrı bir alt kullanıcı uç noktası yoktur — ister ana ister alt kullanıcı olsun her hesap, yalnızca kendi anahtarıyla kendi bakiyesini çeker.

Webhook'lar ​

Sürekli sorgulama (polling) yapmak yerine bir kez webhook yapılandırın; Netts, çekimlerinizin her biri nihai bir duruma (completed / failed) ulaştığında imzalı bir bildirim gönderecektir (POST). Webhook kullanıcı başına saklanır ve o hesabın çekimleri için geçerlidir. Yapılandırılmış bir webhook yoksa, yalnızca durum uç noktasını sorgulayın.

Yapılandırma / görüntüleme / kaldırma ​

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

Başlıklar: X-API-KEY + X-Real-IP.

json
// POST body
{
    "callback_url": "https://your-server.example/netts/withdraw-hook",
    "secret": "your_shared_secret_min_8_chars",
    "enabled": true
}
ParametreTürGerekliAçıklama
callback_urlstringEvetPOST isteğini alan http(s) URL'si (≤ 2048 karakter)
secretstringEvetHer yükü imzalamak için kullanılan paylaşılan gizli anahtar (8…256 karakter)
enabledbooleanHayırYapılandırmayı silmeden iletimi açıp kapatın. Varsayılan true

GET isteği { callback_url, enabled, secret_set, updated_at } döndürür — gizli anahtarın kendisi asla geri döndürülmez.

İletim yükü ​

Netts, X-Netts-Signature: base64( HMAC-SHA256( secret, raw_body ) ) başlığı ve bu JSON gövdesi ile callback_url adresinize bir POST gönderir:

json
{
    "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 değeri completed veya failed olur (failed durumunda error_message doldurulur).

İmzayı doğrulama ​

İmza, gövdenin kanonik JSON'u üzerinden hesaplanır: anahtarlar sıralanmış, boşluksuz (separators=(",", ":")). Aynı şekilde yeniden hesaplayın ve karşılaştırın.

python
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): ...

Her zaman alınan ham baytlar (raw bytes) üzerinden doğrulama yapın. Ayrıştırılmış JSON'u yeniden seri hale getirirseniz, kanonik biçimi yeniden oluşturun: json.dumps(payload, ensure_ascii=False, separators=(",",":"), sort_keys=True).

İletim garantileri ​

  • Onaylamak için HTTP 2xx ile yanıt verin. Diğer tüm yanıtlar (veya zaman aşımı) başarısız bir deneme olarak kabul edilir.
  • Siparişin oluşturulduğu andan itibaren 21 dakikalık bir zaman aralığında sipariş başına en fazla 3 deneme yapılır (yeniden deneme bekleme süresi ≈ 5 dakika). Bundan sonra iletimden vazgeçilir — durum uç noktasına geri dönün.
  • İletimler tekilleştirilir: her sipariş başarıyla en fazla bir kez iletilir.
  • İşleyicinizi orderId üzerinde idempotent (aynı işlem tekrarlandığında sonucu değişmeyen) yapın.

Hata Yanıtları ​

Kimlik Doğrulama Hatası (401) ​

json
{ "detail": { "code": -1, "msg": "Invalid API key or IP not in whitelist" } }

Yetersiz Bakiye (403) ​

json
{ "detail": { "code": 1004, "status": "failed", "msg": "Insufficient balance: 2.0 < 15 TRX" } }

Bekleyen Çekim Mevcut (409) ​

Kendi bakiyenizde aynı anda yalnızca bir bekleyen çekim olabilir. Mevcut olan işlenene kadar bekleyin.

json
{ "detail": { "code": 4090, "status": "failed", "msg": "You have a pending withdrawal. Wait until it is processed." } }

Doğrulama Hatası (400) ​

json
{ "detail": { "code": 5004, "status": "failed", "msg": "Minimum withdrawal is 3 TRX" } }

Hata Kodu Referansı ​

KodAçıklamaHTTP Durumu
10000Kabul edildi (çekim sıraya alındı) / Tamamlandı (durum uç noktası)202 / 200
10001Beklemede — sıraya alındı veya gönderiliyor (durum uç noktası)200
208Zaten kabul edilmiş bir isteğin kopyası — önbelleğe alınmış yanıt208
-Aynı istek hâlâ işleniyor (henüz tekrar denemeyin)409
4090Zaten bekleyen bir çekiminiz var409
-1Geçersiz API anahtarı / IP beyaz listede değil veya sipariş bulunamadı401 / 404
1004Yetersiz bakiye403
5004Doğrulama hatası (tutar < 3, ücret ≥ tutar, hatalı adres, hatalı idempotency anahtarı)400
5003Çekim başarısız oldu / hizmet kullanılamıyor200 (durum) / 503
5000Dahili sunucu hatası500

Hız Limitleri ​

API anahtarı başına sınırlandırılmıştır (X-API-KEY başlığı):

DönemLimit
1 saniye5 istek
1 dakika150 istek

Hız Limiti Aşıldı (429) ​

json
{ "message": "API rate limit exceeded" }

Idempotency ​

İsteğe bağlı X-Idempotency-Key başlığını gönderin, böylece yanlışlıkla yapılan bir tekrar ikinci bir çekim oluşturmaz — orijinal yanıt HTTP 208 ile döndürülür. Başlığı göndermezseniz, sunucu kısa bir zaman aralığında istek parametrelerinizden otomatik olarak bir anahtar türetir. Bu anahtar aynı zamanda sizin orderId değerinizdir.

Anahtar nasıl oluşturulur ​

Anahtar, = dolgusu kaldırılmış base64url( HMAC-SHA256( secret, message ) ) değeridir — 43 karakterlik URL güvenli bir dizedir, burada:

  • secret = API anahtarınız (X-API-KEY);
  • message = alanların : ile birleştirilmiş halidir — address:amount:nonce.

nonce, aynı mantıksal siparişin yeniden denemeleri arasında sabit kalan ancak farklı siparişler arasında değişiklik gösteren herhangi bir değerdir — ör. o sipariş için tuttuğunuz bir UUID veya kaba bir zaman damgası grubu. Anahtarı sipariş başına bir kez oluşturun ve her yeniden denemede birebir aynı değeri tekrar gönderin.

python
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

Doğrulama. Sağlanan X-Idempotency-Key, A–Z a–z 0–9 + / = _ - karakter kümesinden 16–64 karakter uzunluğunda olmalıdır. Hatalı biçimlendirilmiş veya fazla uzun bir anahtar HTTP 400 (code 5004) ile reddedilir.

Durum KoduAnlamı
202Kabul edildi (ilk istek)
208Zaten kabul edildi — önbelleğe alınmış yanıt döndürüldü (ikinci bir çekim yapılmaz)
409Aynı istek şu anda işleniyor — bekleyin, henüz yeniden denemeyin

Başarısızlıktan sonra yeniden deneme. Yalnızca kabul edilen sonuçlar önbelleğe alınır. Önceki deneme başarısız olduysa (ör. yetersiz bakiye, doğrulama), güvenle aynı anahtarla yeniden deneyebilirsiniz — eski hatayı döndürmek yerine istek tekrar denenir. Bir deneme hâlâ devam ederken 409 alırsınız; bekleyin ve yeniden deneyin.

Notlar ​

  • Asenkron ödeme. Yanıt her zaman bir pending onayıdır; TRX, arka plan programı tarafından genellikle ~5 dakika içinde gönderilir. Sonuç için durum uç noktasını veya bir webhook'u kullanın.
  • Sipariş kabul edildiğinde bakiye anında rezerve edilir (TRX nihai olarak gönderildiğinde değil).
  • Minimum: 3 TRX. Ücret: 1 TRX (veya sub_and_robot_out ile 2 TRX), brüt amount üzerinden kesilir; alıcı net = amount − fee tutarını alır.
  • Kendi bakiyenizde aynı anda tek bir bekleyen işlem olabilir (code 4090).
  • Alt kullanıcılar tamamen normal kullanıcılar gibi çekim yapar — aynı POST /apiv2/withdraw uç noktası, aynı kurallar, ancak alt kullanıcının kendi API anahtarı ile doğrulanır. Bir alt kullanıcı belirttiği herhangi bir address adresine kendi bakiyesini çeker. Ayrı bir alt kullanıcı uç noktası yoktur.
  • orderId, 43 karakterlik URL güvenli bir dizedir; durum URL'sinde olduğu gibi iletin (kodlama gerekmez).
  • Webhook'lar: kullanıcı başınadır, X-Netts-Signature ile imzalanır; 21 dakikalık bir pencere içinde en fazla 3 deneme yapılır. POST /apiv2/withdraw/webhook üzerinden yapılandırın.