POST /apiv2/withdraw
Netts bakiyenizden bir TRON adresine TRX çekin. İstek anında bir sipariş numarası döndürür; asıl zincir üstü ö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. Bir çekim işlemi başlatmak tutarı bakiyenizden anında rezerve eder (sipariş kabul edildiği anda bakiye borçlandırılır). Ardından bir arka uç arka plan programı TRX'i gönderir ve siparişi
completedveyafailedolarak işaretler. İlk yanıtta eşzamanlı bir zincir üstü sonuç yoktur — her zaman önce birpendingbildirimi alırsınız.Sipariş kabul edilmeden önce hedef adres kontrol edilir. Bu adrese çekim yapılamıyorsa veya kontrol şu anda tamamlanamıyorsa istek reddedilir: hiçbir sipariş oluşturulmaz ve bakiyenizden hiçbir şey rezerve edilmez.
Uç Nokta URL'si
POST https://netts.io/apiv2/withdrawİstek Başlıkları
| Başlık | Gerekli | Açıklama |
|---|---|---|
| Content-Type | Evet | application/json |
| X-API-KEY | Evet | Netts kontrol panelindeki API anahtarınız |
| X-Idempotency-Key | Hayı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 bilginiz haline gelir. |
İstek Gövdesi
{
"amount": 15,
"address": "TXXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}Parametreler
| Parametre | Tür | Gerekli | Açıklama |
|---|---|---|---|
| amount | number | Evet | TRX cinsinden brüt tutar (en az 3). Ücret bu tutardan düşülür — alıcıya amount − fee (net) ulaşır. |
| address | string | Evet | Hedef TRON adresi (T…, 34 karakter, base58). Sipariş kabul edilmeden önce kontrol edilir. |
| sub_and_robot_out | boolean | Hayır | Robot/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 veyasub_and_robot_out = trueolduğunda 2 TRX. Eğeramount − fee ≤ 0ise sipariş reddedilir.
Örnek İstekler
Aşağıdaki örnekler ayrıca yanlışlıkla yapılan bir tekrarda ikinci bir çekim oluşturulmaması için
X-Idempotency-Keyoluşturur ve gönderir. Tüm kurallar için Eşgüçlülük bölümüne bakın.
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-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-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 ulaşana kadar durum uç noktasını sorgulayın (veya webhook'u bekleyin).
{
"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ı
| Alan | Tür | Açıklama |
|---|---|---|
| detail.code | integer | 10000 kabul edildi |
| detail.status | string | pending |
| detail.data.orderId | string | Sipariş numarası — 43 karakterlik URL uyumlu dize. Durum uç noktası için kullanın; ayrıca webhook yüklerinde siparişi tanımlar. |
| detail.data.amount | number | İstenen brüt tutar (TRX) |
| detail.data.fee | number | Kesilen ücret (1 veya 2 TRX) |
| detail.data.net | number | Alıcının aldığı tutar (amount − fee) |
| detail.data.address | string | Hedef adres |
Durum Uç Noktası
GET https://netts.io/apiv2/withdraw/status/{orderId}Başlıklar: X-API-KEY (sipariş kimliği doğrulanmış kullanıcıya ait olmalıdır). orderId URL uyumludur — olduğu gibi iletin, URL kodlaması (URL-encoding) gerekmez.
| Sipariş durumu | HTTP | code | status |
|---|---|---|---|
| Tamamlandı (TRX gönderildi) | 200 | 10000 | completed (processed_at ile birlikte) |
| Sıraya alındı / gönderiliyor | 200 | 10001 | pending |
| Başarısız oldu | 200 | 5003 | failed (error_message ile birlikte) |
| Bulunamadı / size ait değil | 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"
}
}
}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 aynı POST /apiv2/withdraw uç noktasını çağırır; çekim tutarı o alt kullanıcının kendi bakiyesinden düşülür ve isteğin belirttiği address adresine gönderilir. Aynı minimum tutar, aynı ücret (1 TRX), aynı adres kontrolü, aynı iş akışı geçerlidir. Ayrı bir alt kullanıcı uç noktası yoktur — ana hesap veya alt kullanıcı olsun, her hesap her zaman yalnızca kendi anahtarıyla kendi bakiyesini çeker.
Webhook'lar
Sorgulama (polling) yapmak yerine, bir kez bir webhook yapılandırın; Netts, çekim işlemlerinizin her biri uç duruma (completed / failed) ulaştığında imzalı bir bildirim POST edecektir. Webhook kullanıcı başına saklanır ve o hesabın çekimlerine uygulanır. 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 # unsubscribeBaşlıklar: X-API-KEY.
// POST body
{
"callback_url": "https://your-server.example/netts/withdraw-hook",
"secret": "your_shared_secret_min_8_chars",
"enabled": true
}| Parametre | Tür | Gerekli | Açıklama |
|---|---|---|---|
| callback_url | string | Evet | POST isteğini alan http(s) URL'si (≤ 2048 karakter) |
| secret | string | Evet | Her bir yükü imzalamak için kullanılan paylaşılan gizli anahtar (8…256 karakter) |
| enabled | boolean | Hayır | Yapılandırmayı silmeden teslimatı açma/kapatma. Varsayılan true |
GET, { callback_url, enabled, secret_set, updated_at } döndürür — gizli anahtarın kendisi asla geri döndürülmez.
Teslimat yükü
Netts, X-Netts-Signature: base64( HMAC-SHA256( secret, raw_body ) ) başlığı ve aşağıdaki JSON gövdesi ile callback_url adresinize bir POST gönderir:
{
"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,completedveyafaileddeğerini alır (faileddurumundaerror_messagedoldurulur).
İmzayı doğrulama
İmza, gövdenin standartlaştırılmış (canonical) JSON'ı üzerinden hesaplanır: anahtarlar sıralanmış, boşluksuz (separators=(",", ":")). Aynı şekilde yeniden hesaplayın ve karşılaştırın.
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ğrulayın. Ayrıştırılan JSON'ı yeniden serileştirirseniz, standartlaştırılmış biçimi yeniden üretin:
json.dumps(payload, ensure_ascii=False, separators=(",",":"), sort_keys=True).
Teslimat garantileri
- Bildirimi 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 penceresi içinde sipariş başına en fazla 3 deneme yapılır (yeniden deneme bekleme süresi ≈ 5 dakika). Bundan sonra teslimattan vazgeçilir — durum uç noktasına geri dönün.
- Teslimatlar tekilleştirilir (de-duplicated): her sipariş en fazla bir kez başarıyla teslim edilir.
- İşleyicinizi
orderIdüzerinde eşgüçlü (idempotent) hale getirin.
Hata Yanıtları
Kimlik Doğrulama Hatası (401)
{ "detail": { "code": -1, "msg": "Invalid API key or IP not in whitelist" } }Yetersiz Bakiye (403)
{ "detail": { "code": 1004, "status": "failed", "msg": "Insufficient balance: 2.0 < 15 TRX" } }Adres Kullanılamıyor (403)
Bu hedef adrese çekimler kabul edilmez. Hiçbir sipariş oluşturulmaz ve hiçbir şey rezerve edilmez. Farklı bir adres kullanın veya destek ile iletişime geçin.
{ "detail": { "code": 1006, "status": "failed", "msg": "Withdrawals to this address are not available. Contact support." } }Adres Kontrolü Kullanılamıyor (503)
Hedef adres şu anda kontrol edilemedi. Hiçbir sipariş oluşturulmaz ve hiçbir şey rezerve edilmez. Kısa bir süre sonra yeniden deneyin — aynı X-Idempotency-Key tekrar kullanılabilir.
{ "detail": { "code": 1009, "status": "failed", "msg": "Address check is temporarily unavailable. No request was created. Retry shortly." } }Bekleyen Çekim Mevcut (409)
Kendi bakiyenizde aynı anda yalnızca bir bekleyen çekim işlemine sahip olabilirsiniz. Mevcut olan işlenene kadar bekleyin.
{ "detail": { "code": 4090, "status": "failed", "msg": "You have a pending withdrawal. Wait until it is processed." } }Doğrulama Hatası (400)
{ "detail": { "code": 5004, "status": "failed", "msg": "Minimum withdrawal is 3 TRX" } }Hata Kodu Referansı
| Kod | Açıklama | HTTP Durumu |
|---|---|---|
10000 | Kabul edildi (çekim sıraya alındı) / Tamamlandı (durum uç noktası) | 202 / 200 |
10001 | Beklemede — sıraya alındı veya gönderiliyor (durum uç noktası) | 200 |
208 | Zaten kabul edilmiş bir isteğin kopyası — önbelleğe alınmış yanıt | 208 |
- | Aynı istek hâlâ işleniyor (henüz yeniden denemeyin) | 409 |
4090 | Zaten bekleyen bir çekim işleminiz var | 409 |
-1 | Geçersiz API anahtarı / IP beyaz listede değil veya sipariş bulunamadı | 401 / 404 |
1004 | Yetersiz bakiye | 403 |
1006 | Bu adrese çekimler kullanılamıyor | 403 |
1009 | Adres kontrolü geçici olarak kullanılamıyor — sipariş oluşturulmadı, kısa süre sonra tekrar deneyin | 503 |
5004 | Doğrulama hatası (tutar < 3, ücret ≥ tutar, hatalı adres, hatalı eşgüçlülük anahtarı) | 400 |
5003 | Çekim başarısız oldu / hizmet kullanılamıyor | 200 (durum) / 503 |
5000 | Dahili sunucu hatası | 500 |
Hız Sınırları
API anahtarı başına sınırlandırılmıştır (X-API-KEY başlığı):
| Dönem | Sınır |
|---|---|
| 1 saniye | 5 istek |
| 1 dakika | 150 istek |
Hız Sınırı Aşıldı (429)
{ "message": "API rate limit exceeded" }Eşgüçlülük
İ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 ) ) biçiminde — 43 karakterlik URL uyumlu bir dizedir, burada:
- secret = API anahtarınız (
X-API-KEY); - message =
:ile birleştirilmiş alanlar —address:amount:nonce.
nonce, aynı mantıksal siparişin yeniden denemeleri arasında sabit, ancak farklı siparişler arasında farklı olan herhangi bir değerdir — örneğin bu sipariş için tuttuğunuz bir UUID veya kaba bir zaman damgası aralığı. Anahtarı sipariş başına bir kez oluşturun ve her yeniden denemede tamamen aynı değeri yeniden gönderin.
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-safeDoğrulama. Sağlanan bir
X-Idempotency-Key,A–Z a–z 0–9 + / = _ -karakter kümesinden 16–64 karakter uzunluğunda olmalıdır. Hatalı biçimlendirilmiş veya aşırı uzun bir anahtar HTTP 400 (code 5004) ile reddedilir.
| Durum Kodu | Anlamı |
|---|---|
| 202 | Kabul edildi (ilk istek) |
| 208 | Zaten kabul edildi — önbelleğe alınmış yanıt döndürüldü (ikinci bir çekim yapılmaz) |
| 409 | Aynı 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 (örn. 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
409alırsınız; bekleyin ve yeniden deneyin.
Notlar
- Asenkron ödeme. Yanıt her zaman bir
pendingbildirimidir; TRX bir arka uç arka plan programı tarafından, genellikle ~5 dakika içinde gönderilir. Sonuç için durum uç noktasını veya bir webhook kullanın. - Bakiye, sipariş kabul edildiğinde anında rezerve edilir (TRX nihai olarak gönderildiğinde değil).
- Minimum: 3 TRX. Ücret: 1 TRX (veya
sub_and_robot_outile 2 TRX), brütamountüzerinden kesilir; alıcınet = amount − feetutarını alır. - Kendi bakiyenizde aynı anda bir bekleyen işlem (
code 4090). - Hedef adres kontrolü. Her istek sipariş kabul edilmeden önce kontrol edilir:
code 1006(HTTP 403) — bu adrese çekimler kullanılamaz;code 1009(HTTP 503) — kontrol geçici olarak kullanılamıyor, kısa süre sonra tekrar deneyin. Her iki durumda da sipariş oluşturulmaz. - Alt kullanıcılar tıpkı normal kullanıcılar gibi çekim yapar — aynı
POST /apiv2/withdrawuç noktası, aynı kurallar, ancak alt kullanıcının kendi API anahtarı ile doğrulanmış olarak. Bir alt kullanıcı, belirttiğiaddressadresine kendi bakiyesini çeker. Ayrı bir alt kullanıcı uç noktası yoktur. - orderId 43 karakterlik URL uyumlu bir dizedir; durum URL'sinde olduğu gibi iletin (kodlama gerekmez).
- Webhook'lar: kullanıcı başına,
X-Netts-Signatureile imzalanmış; 21 dakikalık bir zaman aralığında en fazla 3 deneme.POST /apiv2/withdraw/webhooküzerinden yapılandırın.