Bu sayfada
Entegrasyon kılavuzu
Geliştirici belgeleri
Bir fatura oluşturun, müşteriyi ödeme sayfasına yönlendirin, ödendiğinde imzalı bir webhook alın. Aşağıdaki dört adımla başlayın.
Neler destekleniyor
Ödeme altyapısı USDT ve USDC kabul eder. Bu tablo, 4 Kasım 2026 tarihinde kontrol edilen GET /v1/services ile eşleşir. Ödeme yöntemi seçicinizi geliştirmeden önce güncel kataloğu okuyun.
| Varlık | Ağ | Onaylar |
|---|---|---|
| USDT | Tron | 20 |
| USDT | Ethereum | 12 |
| USDT | Solana | 32 |
| USDT | Polygon | 8 |
| USDT | Arbitrum | 12 |
| USDT | TON | 5 |
| USDC | Ethereum | 12 |
| USDC | Solana | 32 |
| USDC | Polygon | 8 |
| USDC | Base | 12 |
| USDC | Arbitrum | 12 |
Ödemeler gözetimlidir: fonlar platformun kontrol ettiği adreslere gelir. Satıcı bakiyeniz, size borçlu olunan tutardır. Ayrı bir ürün olan Telegram cüzdanı ise gözetimsizdir.
Sınırlamalar
- Ödeme gönderimi ve iadeler henüz canlı değildir:
GET /v1/services,boundaries.livePayoutsveboundaries.liveRefundsdeğerlerinifalseolarak bildirir. - Gelen ödemeler bir KYT sağlayıcısı tarafından taranmaz.
- Ücretlerin tutarın %20’sini aşacağı faturalar
AMOUNT_BELOW_MINIMUMile reddedilir. - Sözleşmeye bağlı SLA yoktur.
Başlangıç ücreti %0,40 artı ağ ücretidir. Toplam ve minimum tutar için bir ücret teklifi isteyin; fiyatlandırmaya bakın.
Kimlik doğrulama
Sunucudan sunucuya çağrılar x-api-key kullanır. Proje anahtarları tek bir satıcı projesiyle sınırlıdır. Bunları sunucunuzda tutun.
Test anahtarları ncp_test_… ile, canlı mod anahtarları ncp_live_… ile başlar. Daha önce oluşturulan anahtarlar ncp_sandbox_ ile başlar ve çalışmaya devam eder.
curl -sS "https://api.veilnebu.la/v1/balances" \
-H "x-api-key: $PROJECT_API_KEY"Yazma isteklerini imzalayın
GET istekleri yalnızca x-api-key gerektirir. Bir proje anahtarıyla kimliği doğrulanan her POST, PUT, PATCH ve DELETE isteği ayrıca iki başlık gerektirir; aksi takdirde API 401 Invalid API signature yanıtını verir:
x-ncp-timestamp: ISO-8601, şu andan en fazla 5 dakika farklı.x-ncp-signature:hex(HMAC-SHA256(your API key, "<timestamp>.<METHOD>.<path incl. query>.<raw body>")).
Metotları büyük harfle kullanın. Gönderdiğiniz baytları, yoldaki sorgu dizesi dahil, tam olarak imzalayın. Gövdesi olmayan bir istek boş bir dizeyi imzalar. Aşağıdaki yardımcılar proje anahtarınızı gerektirir; kabuk yardımcısı Bash, curl ve OpenSSL gerektirir, Node.js yardımcısı ise yerleşik fetch kullanır.
export API_BASE_URL="https://api.veilnebu.la"
export PROJECT_API_KEY="ncp_test_…"
ncp() {
local method="$1" path="$2" body="" ts sig
shift 2
if [ "$#" -gt 0 ]; then body="$1"; shift; fi
ts=$(date -u +%Y-%m-%dT%H:%M:%S.000Z) || return
sig=$(printf '%s.%s.%s.%s' "$ts" "$method" "$path" "$body" |
openssl dgst -sha256 -hmac "$PROJECT_API_KEY" -hex) || return
sig=${sig##* }
if [ -n "$body" ]; then
curl -sS --request "$method" "$API_BASE_URL$path" \
-H "x-api-key: $PROJECT_API_KEY" \
-H "x-ncp-timestamp: $ts" -H "x-ncp-signature: $sig" \
-H "content-type: application/json" --data-binary "$body" "$@"
else
curl -sS --request "$method" "$API_BASE_URL$path" \
-H "x-api-key: $PROJECT_API_KEY" \
-H "x-ncp-timestamp: $ts" -H "x-ncp-signature: $sig" "$@"
fi
}İlk faturanızı oluşturun
Panelde bir proje oluşturun, API anahtarını kopyalayın ve bir fatura oluşturun. Yanıt checkoutUrl içerir: müşterinizi oraya yönlendirin.
ncp POST /v1/payments '{
"amountMinor":"10000",
"currencyCode":"USD",
"settlementAssetCode":"USDT",
"externalId":"order-1001"
}' -H "idempotency-key: order-1001"Yanıttan bir bölüm. Kimlik her fatura için ayrı oluşturulur.
{
"id": "cm3k9x2f40001qz8e7h5v1abc",
"status": "new",
"amountMinor": "10000",
"currencyCode": "USD",
"settlementAssetCode": "USDT",
"checkoutUrl": "https://app.veilnebu.la/checkout/cm3k9x2f40001qz8e7h5v1abc"
}amountMinor, para biriminin en küçük birimindeki tam sayıyı içeren bir dizedir: 10000 = 100.00 USD. Ondalıklı amount alanı yalnızca tarayıcı uç noktası /v1/public/payments tarafından kabul edilir.
Tarayıcıdan ödeme sayfası ve izin verilen kaynaklar
Panelde yayımlanabilir bir anahtar oluşturun ve mağazanızın kullandığı kaynakları tam olarak listeleyin. Tarayıcı istekleri bu anahtarı x-publishable-key olarak POST /v1/public/payments adresine gönderir.
Kaynak, successUrl ve cancelUrl değerlerinin tümü anahtarın izin verilen kaynaklar listesinde olmalıdır. Kaynak; şema, ana bilgisayar ve isteğe bağlı bağlantı noktasından oluşur, yol veya joker karakter içermez. Eksik veya listede olmayan kaynaklar reddedilir.
Ondalıklı tutar, itibari para birimleri için en fazla iki ondalık basamak, kripto için ise varlığın kendi ondalık basamak sayısına kadar kabul eder (USDT ve USDC: bugün desteklediğimiz tüm ağlarda 6).
const response = await fetch('https://api.veilnebu.la/v1/public/payments', {
method: 'POST',
headers: {
'content-type': 'application/json',
'x-publishable-key': 'pk_test_…',
},
body: JSON.stringify({
amount: '100.00',
currencyCode: 'USD',
settlementAssetCode: 'USDT',
successUrl: 'https://shop.example/thanks',
cancelUrl: 'https://shop.example/cart',
}),
});
if (!response.ok) throw new Error(await response.text());
const invoice = await response.json();
window.location.assign(invoice.checkoutUrl);Ödeme durumları
| Durum | Sonraki işlem |
|---|---|
new | Ödeme sayfası bağlantısını paylaşın |
pending | Ödeme bekleniyor |
confirming | Onaylar bekleniyor |
paid | Mutabakata hazır |
partially_paid | Müşteriden ödemeyi tamamlamasını isteyin |
overpaid | Fazladan yatırılan tutarı inceleyin |
expired | Yeni bir fatura oluşturun |
cancelled | İşlem gerekmez |
failed | Ayrıntıları açın |
refunded | İşlem gerekmez |
Idempotency anahtarları
Fatura oluştururken, sipariş kimliğinizden türetilmiş sabit bir Idempotency-Key gönderin. Aynı anahtar ve gövdeyle yapılan yeniden deneme özgün faturayı döndürür. Anahtarı farklı bir gövdeyle yeniden kullanmak 409 döndürür. Zaman aşımından sonra yeniden denerken anahtarı ve gövdeyi değiştirmeyin.
İstek için ilk fatura örneğine bakın.
Hatalar
Hatalar JSON biçimindedir. message bir dizedir; doğrulama hatalarında ise dizelerden oluşan bir dizidir.
{
"statusCode": 401,
"error": "Unauthorized",
"message": "Invalid API key"
}| HTTP durumu | Anlamı ve yapılacak işlem |
|---|---|
400 | Geçersiz alan; "message" alanın adını belirtir. Yeniden denemeden önce düzeltin. |
401 | "Invalid API key" veya "Invalid API signature". Anahtarı, imzalanan baytları ve zaman damgasını kontrol edin. |
404 | "Payment invoice not found". Kimliği ve projeyi kontrol edin. |
409 | Farklı bir gövdeyle aynı "Idempotency-Key" veya "Insufficient merchant payable balance". |
429 | İstek sınırına ulaşıldı. Yeniden denemeden önce bekleyin. |
5xx | Aynı "Idempotency-Key" ve gövdeyle yeniden deneyin. |
Webhook’lar (HMAC-SHA256)
Her teslimat x-nebula-signature: t=<unix>,v1=<hex> taşır. HMAC’i, uç noktayı oluşturduğunuzda döndürülen uç nokta sırrıyla doğrulayın. Şu andan 300 saniyeden fazla farklı olan zaman damgalarını reddedin.
Node.js ile doğrulama
Node.js doğrulayıcısı yalnızca yerleşik crypto modülünü kullanır. İmza başlığını, ham gövde baytlarını ve uç nokta sırrını ona iletin.
import { createHmac, timingSafeEqual } from 'node:crypto';
export function verify(header, rawBody, secret) {
const parts = {};
for (const piece of (header ?? '').split(',')) {
const separator = piece.indexOf('=');
if (separator <= 0) continue;
parts[piece.slice(0, separator).trim()] = piece.slice(separator + 1).trim();
}
if (!/^[0-9]{1,16}$/.test(parts.t ?? '')) return false;
if (!/^[0-9a-f]{64}$/.test(parts.v1 ?? '')) return false;
if (Math.abs(Date.now() / 1000 - Number(parts.t)) > 300) return false;
const expected = createHmac('sha256', secret)
.update(parts.t + '.')
.update(rawBody)
.digest('hex');
if (expected.length !== parts.v1.length) return false;
return timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1));
}Doğrulamayı JSON ayrıştırmasından önce, ham istek gövdesi üzerinden yapın. Teslimat en az bir kez garantilidir: yükteki eventId ile eşleşen x-nebula-event-id değerine göre yinelenenleri ayıklayın. Otomatik yeniden denemeler teslimat kimliğini korur; elle yeniden gönderim, aynı olay kimliğiyle yeni bir teslimat kimliği oluşturur. 2xx yanıtı vermeden önce olayı kalıcı olarak kaydedin.
Webhook’ları yerelde test etme
Webhook URL’leri herkese açık bir internet ana bilgisayarı kullanmalıdır. Yerel ve özel adresler reddedilir. Alıcınızı herkese açık bir HTTPS tüneliyle dışarı açın, ardından URL’sini imzalama yardımcısıyla kaydedin.
ncp POST /v1/webhooks/endpoints '{
"url":"https://receiver.example/webhook",
"events":["payment.paid","payment.reorged"]
}'URL’yi kendi alıcınızın adresiyle değiştirin. Oluşturma sırasında döndürülen uç nokta sırrını kaydedin.
Olay türleri
Ödeme gönderimi ve iadeler henüz canlı değildir (GET /v1/services, boundaries.livePayouts değerini false olarak bildirir). O zamana kadar ödeme gönderimleri ve ödeme gönderimi grupları transferi yalnızca bakiyenize kaydeder; payout.completed ve refund.completed, fonların çıktığı anlamına gelmez.
Aşağıdaki katalog GET /v1/services ile eşleşir. Katalogda bir kaydın bulunması, ilgili para hareketinin canlı olduğu anlamına gelmez.
| Olay | Anlamı |
|---|---|
webhook. | Bir webhook uç noktası için istenen test teslimatı. |
payment. | Müşteri bir ödeme yöntemi seçti; ilk yatırma bekleniyor. |
payment. | Yatırma görüldü; gerekli onaylar bekleniyor. |
payment. | Fatura tamamen ödendi ve deftere işlendi. |
payment. | İstenenden az tutar alındı; kalanı bekleniyor. |
payment. | İstenenden fazla tutar alındı; fazla ödemeyle birlikte deftere işlendi. |
payment. | Faturanın süresi, yeterli fon gelmeden doldu. |
payment. | Fatura, ödeme yapılmadan önce iptal edildi. |
payment. | Ödeme bir zincir, ücret politikası veya gözlem hatası nedeniyle başarısız oldu. |
payment. | Zaten hesaba geçirilmiş bir yatırma için bilgilendirme amaçlı risk olayı. Gelen ödemeler için KYT taraması canlı değildir. |
payment. | Onaylanmış bir yatırma, zincir yeniden düzenlenmesi nedeniyle düştü; fatura artık ödenmiş değildir, bu yüzden siparişin teslimini durdurun veya geri alın. |
payment. | Desteklenmeyen bir token yatırıldı; hesaba geçirilmedi. |
payout. | Ödeme gönderiminin işlenme durumu. Canlı transferler açık değildir. |
payout. | Ödeme gönderimi bakiyeye kaydedildi; bu, fonların çıktığı anlamına gelmez. |
payout. | Ödeme gönderimi başarısız oldu. |
payout. | Ödeme gönderimi tamamlanmadan önce iptal edildi. |
refund. | İadenin işlenme durumu. Canlı iadeler açık değildir. |
refund. | İade bakiyeye kaydedildi; bu, fonların çıktığı anlamına gelmez. |
refund. | İade başarısız oldu. |
internal_transfer. | Satıcıdan satıcıya bakiye transferi gönderen için gerçekleştirildi. |
internal_transfer. | Satıcıdan satıcıya bakiye transferi alıcının hesabına geçirildi. |
static_wallet. | Bir müşteri için uzun ömürlü bir yatırma adresi oluşturuldu. |
static_wallet. | Bir statik cüzdan engellendi. |
static_wallet. | Bir statik cüzdanın engeli kaldırıldı. |
static_wallet. | Statik cüzdana bir yatırma görüldü ve deftere işlendi. |
dispute. | Bir fatura için itiraz açıldı. |
dispute. | Bir itiraz çözüldü. Çözüm tek başına zincir üzerinde bir iadeyi kanıtlamaz. |
dispute. | Bir itiraz reddedildi; satıcının bir işlem yapması gerekmez. |
subscription. | Bir faturalandırma dönemi yeni bir fatura oluşturdu. |
Yeniden deneme politikası
Uç noktanız 2xx ile yanıt vermezse toplam 8 kez deneriz: ilk deneme, ardından 1 dakika, 5 dakika, 30 dakika, 2 saat, 6 saat, 12 saat ve 24 saat sonra yeniden denemeler. Her bekleme süresi önceki başarısız denemeden sonra başlar. Ağ hataları ve zaman aşımları da başarısızlık sayılır. Test teslimatlarında tek deneme yapılır.
Son başarısızlıktan sonra teslimat başarısız olarak işaretlenir; POST /v1/webhooks/deliveries/{deliveryId}/resend ile yeniden gönderin. Yedek yöntem olarak GET /v1/payments/{id} ile mutabakat yapın.
Ödeme gönderimi ve iadeler henüz canlı değildir (GET /v1/services, boundaries.livePayouts değerini false olarak bildirir). O zamana kadar ödeme gönderimleri ve ödeme gönderimi grupları transferi yalnızca bakiyenize kaydeder; payout.completed ve refund.completed, fonların çıktığı anlamına gelmez.
Ödeme gönderimi grupları
Bir grup, transfer kayıtlarını bir araya toplar. Grubun onay politikası ve gereken onay sayısı approvalPolicy ve approvalsRequired olarak döndürülür. Birden fazla onaylayıcı varsa, grubu oluşturan kişi kendi grubunu onaylayamaz. Yetkili tek operatör, oturumda kendi oluşturduğu grubu onaylayabilir. Grupları panelde WebAuthn ile onaylayın.
export PROJECT_API_KEY="ncp_test_…"
ncp POST /v1/payout-batches '{
"assetCode":"USDT",
"networkCode":"TRON",
"externalId":"batch-1001",
"items":[{
"destinationAddress":"T…",
"amountMinor":"15000000",
"externalRef":"recipient-1001"
}]
}' -H "idempotency-key: batch-1001"Hedefi, kendi test projenizdeki geçerli bir adresle değiştirin.
Yinelenen faturalandırma
Bir abonelik her faturalandırma döneminde yeni bir fatura oluşturur ve bunu subscription.invoice_created ile bildirir. Müşterinin cüzdanından otomatik olarak ödeme çekmez. Müşteriye yeni ödeme sayfası URL’sini gönderin.
interval: DAY, WEEK, MONTH veya YEAR.
ncp POST /v1/subscriptions '{
"customerRef":"customer-42",
"assetCode":"USDT",
"networkCode":"TRON",
"amountMinor":"9000000",
"interval":"MONTH",
"intervalCount":1
}'API referansındaki yaşam döngüsü işlemlerini kullanarak duraklatın, sürdürün veya iptal edin.
Risk taraması
Ödeme gönderimi ve iade hedefleri, transfer oluşturulmadan önce herkese açık yaptırım listeleriyle karşılaştırılır; bir eşleşme isteği reddeder. Gelen ödemeler taranmaz.
Telegram satıcı botu
@veilnebula_bot aynı anda tek bir projeyle çalışır. Botu, o projenin API anahtarıyla özel bir sohbette bağlayın. Bot mesajınızı silmeye çalışır ve saklanan anahtarı şifreler. Silme başarısız olursa anahtarı iptal edip yenisini oluşturun. Bir anahtarı asla ortak bir sohbete göndermeyin.
Bildirimler, bağlı proje ve etkin anahtarla sınırlıdır. Ödeme gönderimlerini onaylamak için paneli açın.
/link <API_KEY>
/balance
/invoices
/notify on
/unlink