Hızlı Başlangıç
- Taban yol
/api/v1/wallet- Kimlik
- Ed25519 istek imzası —
X-Key-Id,X-Date,X-Nonce,Digest(body varsa),X-Signature. Zaman penceresi ±5 dk, nonce tek kullanımlık, anahtarda IP allow-list olabilir. - Yetki
- Anahtarınız cüzdan ürününü ve çağrının gerektirdiği cüzdan iznini taşımalıdır; izni olmayan çağrı
403 WALLET_INSUFFICIENT_SCOPEalır. Uç başına izinler: Anahtar izinleri. - Çapraz yüzey
- Bu uçlar zaten s2s yüzeyindedir — kendi sunucunuzdan imzalı olarak çağırabilirsiniz.
Bu rehber sizi sıfırdan çalışan bir cüzdan akışına götürür: kullanıcı oluşturma → bakiye yükleme → transfer → sonucu doğrulama. Tamamı bugün üretimde çalışan yollardan geçer; bağlı sağlayıcı gerektiren hiçbir adım yoktur.
Tüm tutarlar minor-unit string'dir: "amount": "10050" = ₺100,50. Tüm istekler Ed25519 imzalıdır — aşağıdaki örneklerde imza header'ları … ile kısaltılmıştır. İstek body'lerini boşluksuz JSON olarak (satır sonu ve fazladan boşluk olmadan) gönderin ve Digest değerini tam olarak bu metin üzerinden hesaplayın; aşağıdaki body'ler yalnız okunabilirlik için birkaç satıra yayılmıştır.
İmzalamayı doğrulayın
Para hareketine geçmeden önce imzanızın çalıştığını en basit uçla kanıtlayın:
curl "https://api-gateway.lunixi.com/api/v1/wallet/ping" \
-H "X-Key-Id: $LUNIXI_KEY_ID" \
-H "X-Date: $DATE" -H "X-Nonce: $NONCE" -H "X-Signature: $SIG"Bu çağrı için anahtarınızda bir kurulum izni (wallet:program:manage veya wallet:enduser:manage) bulunmalıdır. 200 almadan devam etmeyin. Sorun varsa Kimlik Doğrulama → Hata kodları.
Programınızı öğrenin
curl "https://api-gateway.lunixi.com/api/v1/wallet/programs/me" \
-H "X-Key-Id: …" -H "X-Date: …" -H "X-Nonce: …" -H "X-Signature: …"Programınızın id değerini not edin: son kullanıcı oluştururken ve program alan diğer çağrılarda bu değeri programId olarak gönderirsiniz.
Son kullanıcı oluşturun
Kullanıcı program içinde telefonla tekildir — aynı telefonla yeni bir anahtarla gönderilen ikinci çağrı yeni kullanıcı üretmez, 409 WALLET_ENDUSER_EXISTS döner; aynı Idempotency-Key ile tekrar ise ilk yanıtı döndürür. Tüm alanlar ve kurallar: Son Kullanıcı Oluşturma.
curl -X POST "https://api-gateway.lunixi.com/api/v1/wallet/end-users" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: signup-crm-88213" \
-H "X-Key-Id: …" -H "X-Date: …" -H "X-Nonce: …" -H "Digest: …" -H "X-Signature: …" \
-d '{
"programId": "5b9e2f3a-7c41-4d8e-a6f2-9e1b3c4d5f60",
"accountType": "PERSONAL",
"phone": "+905321234567",
"externalCustomerId": "crm-88213",
"displayName": "Ayşe Y."
}'Yanıt, kullanıcıyla birlikte varsayılan cüzdanı ve hesaplarını da döner:
{
"status": "success",
"code": "SUCCESS",
"data": {
"endUser": { "id": "8d4c2a1f-3b6e-4f7a-9c5d-2e8b1a0f6c34", "accountType": "PERSONAL", "status": "ACTIVE" },
"defaultWallet": {
"id": "1e7f9a3b-5c2d-4a8e-b6f1-3d9c0e2a7b58",
"walletNo": "5810763412",
"name": "Cüzdanım",
"isDefault": true,
"accounts": [
{ "id": "c2a5e8f1-9d3b-4c7a-8e6f-5b1d2a9c0e47", "currency": "TRY", "fullWalletNo": "58107634125000", "status": "ACTIVE" }
]
}
}
}externalCustomerId sizin kimliğinizdir. Bizim id'lerimizi saklamak istemiyorsanız kullanıcıya GET /wallet/end-users/by-external/crm-88213?programId=… ile ulaşabilirsiniz.
Gerekiyorsa ek hesap açın
Varsayılan cüzdan tek bir hesapla, programınızın ana para biriminde (ya da istekte defaultCurrency ile verdiğiniz para biriminde) açılır. Farklı bir para birimi gerekiyorsa:
curl -X POST "https://api-gateway.lunixi.com/api/v1/wallet/wallets/1e7f9a3b-5c2d-4a8e-b6f1-3d9c0e2a7b58/accounts" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: acct-crm-88213-usd" \
-H "X-Key-Id: …" -H "X-Signature: …" \
-d '{ "currency": "USD" }'Kartla bakiye yükleyin
Kart yüklemesi ödeme altyapısına delege edilir: yanıt size ya hosted checkout içeriği ya da 3D Secure yönlendirmesi verir.
curl -X POST "https://api-gateway.lunixi.com/api/v1/wallet/topups/card" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: topup-crm-88213-1" \
-H "X-Key-Id: …" -H "X-Signature: …" \
-d '{
"creditWalletAccountId": "c2a5e8f1-9d3b-4c7a-8e6f-5b1d2a9c0e47",
"amount": "25000",
"currency": "TRY",
"returnUrl": "https://app.acme.com/wallet/topup/result"
}'{
"status": "success",
"code": "SUCCESS",
"data": {
"operationId": "4f1b8d2e-6a9c-4b3e-8f7d-1c5e9a2b6d08",
"paymentId": "9c6f2b1a-4e8d-4a3f-b5e6-2d7c1a9b8e30",
"status": "INITIALIZED",
"checkoutFormContent": "<script …>",
"redirectUrl": ""
}
}checkoutFormContent'i kullanıcının tarayıcısında mount edin; kart bilgisi sizin sunucunuza hiç uğramaz. Kullanıcı ödemeyi tamamladığında operasyon COMPLETED olur ve wallet.topup.completed webhook'u düşer.
Yükleme sonucunu returnUrl'e dönen kullanıcıdan öğrenmeyin. Tarayıcı geri dönmeyebilir. Doğru kaynak webhook'tur; teyit için GET /wallet/topups/{operationId}.
Bakiyeyi kontrol edin
curl "https://api-gateway.lunixi.com/api/v1/wallet/end-users/8d4c2a1f-3b6e-4f7a-9c5d-2e8b1a0f6c34/balances" \
-H "X-Key-Id: …" -H "X-Signature: …"{
"status": "success",
"code": "SUCCESS",
"data": {
"balances": [
{
"walletAccountId": "c2a5e8f1-9d3b-4c7a-8e6f-5b1d2a9c0e47",
"currency": "TRY",
"balance": "25000",
"fullWalletNo": "58107634125000"
}
]
}
}Transferi önce fiyatlandırın
Para çıkaran işlemlerde önce quote çağırın — kullanıcıya ücreti hesaptan düşülmeden önce göstermek zorundasınız.
curl -X POST "https://api-gateway.lunixi.com/api/v1/wallet/transfers/w2w/quote" \
-H "Content-Type: application/json" \
-H "X-Key-Id: …" -H "X-Signature: …" \
-d '{
"endUserId": "8d4c2a1f-3b6e-4f7a-9c5d-2e8b1a0f6c34",
"sourceWalletAccountId": "c2a5e8f1-9d3b-4c7a-8e6f-5b1d2a9c0e47",
"destinationPhone": "+905339876543",
"amount": "10050",
"currency": "TRY"
}'{
"status": "success",
"code": "SUCCESS",
"data": {
"feeTotal": "250",
"taxTotal": "125",
"totalCharge": "10425",
"requiredAmount": "10425",
"maskedDestinationName": "Meh*** Ö***",
"sourceBalance": "25000",
"sufficientBalance": true,
"limitBlocked": false,
"scheduleVersionId": "2d8b5e1c-7f4a-4c9e-a3b6-8e1f5c2d9a74"
}
}sufficientBalance: false ya da limitBlocked: true ise transferi başlatmayın — kullanıcıya nedeni gösterin. maskedDestinationName alıcının doğru kişi olduğunu teyit ettirmek içindir.
Transferi başlatın
curl -X POST "https://api-gateway.lunixi.com/api/v1/wallet/transfers/w2w" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: p2p-crm-88213-1" \
-H "X-Key-Id: …" -H "X-Signature: …" \
-d '{
"endUserId": "8d4c2a1f-3b6e-4f7a-9c5d-2e8b1a0f6c34",
"sourceWalletAccountId": "c2a5e8f1-9d3b-4c7a-8e6f-5b1d2a9c0e47",
"destinationPhone": "+905339876543",
"amount": "10050",
"currency": "TRY",
"scheduleVersionId": "2d8b5e1c-7f4a-4c9e-a3b6-8e1f5c2d9a74",
"otpDestination": "+905321234567",
"otpChannel": "SMS"
}'{
"status": "success",
"code": "SUCCESS",
"data": {
"operationId": "7a3e9c1d-2b4f-4e8a-9d6c-0f5b8e2a1c93",
"status": "CHALLENGED",
"otpRequired": true,
"otpChannel": "SMS",
"integrityHash": "9c1f…",
"nonce": "4b82…"
}
}Fon rezerve edildi, para henüz taşınmadı. otpRequired: true ise kullanıcıya kod soruyorsunuz.
Transferi tamamlayın
curl -X POST "https://api-gateway.lunixi.com/api/v1/wallet/transfers/w2w/7a3e9c1d-2b4f-4e8a-9d6c-0f5b8e2a1c93/complete" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: p2p-crm-88213-1-complete" \
-H "X-Key-Id: …" -H "X-Signature: …" \
-d '{
"endUserId": "8d4c2a1f-3b6e-4f7a-9c5d-2e8b1a0f6c34",
"operationId": "7a3e9c1d-2b4f-4e8a-9d6c-0f5b8e2a1c93",
"integrityHash": "9c1f…",
"nonce": "4b82…",
"otpCode": "482913"
}'{
"status": "success",
"code": "SUCCESS",
"data": {
"operationId": "7a3e9c1d-2b4f-4e8a-9d6c-0f5b8e2a1c93",
"status": "COMPLETED",
"ledgerTxnRef": "ltx_01J8ZU…",
"receiptUrl": "https://api-gateway.lunixi.com/api/v1/wallet/operations/7a3e9c1d-2b4f-4e8a-9d6c-0f5b8e2a1c93/receipt"
}
}integrityHash ve nonce bir önceki adımdan birebir taşınmalıdır. nonce tek kullanımlıktır; complete hata verirse aynı nonce ile tekrar denemeyin, operasyonu sorgulayın.
Webhook'u bağlayın
Asenkron sonuçları polling ile değil webhook ile öğrenin. Panelden endpoint'inizi tanımlayın ve şu olayları dinleyin:
| Olay | Ne zaman |
|---|---|
wallet.topup.completed | Kart/havale yüklemesi bakiyeye yansıdı |
wallet.topup.failed | Yükleme başarısız |
wallet.transfer.completed | Transfer tamamlandı |
wallet.transfer.failed | Transfer başarısız, rezervasyon çözüldü |
Zarf ve imza doğrulaması: Webhook'lar.
Sonraki adımlar
- Temel Kavramlar — program, hesap, operasyon sözlüğü
- Limitler ve Ücretler — reddedilme sebeplerini anlamak için
- Portal & SDK — son kullanıcı uygulaması yazacaksanız
- Yol Haritası — banka entegrasyonu, fatura, ATM gibi yeteneklerin durumu