Son Kullanıcı Oluşturma
- 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
- Aynı işlem merchant panelde de vardır. Bu uç için anahtarınızda
wallet:enduser:manageya dawallet:program:manageizni gerekir.
POST /api/v1/wallet/end-usersSon kullanıcıyı oluşturur ve aynı işlemde varsayılan cüzdanını tek bir hesapla açar. Yanıt, kullanıcıyla birlikte bu cüzdanı ve hesabını döner.
Header'lar
| Header | Zorunlu | Kural |
|---|---|---|
| İmza header'ları | ✅ | Kimlik Doğrulama |
Idempotency-Key | ✅ | Baştaki ve sondaki boşluklar kırpıldıktan sonra 1–128 karakter. Eksik, boş ya da daha uzunsa istek 400 ile reddedilir. |
Body alanları
Body yalnız aşağıdaki alanları içerebilir; listede olmayan bir alan 400 VALIDATION_ERROR ile reddedilir.
| Alan | Tip | Zorunlu | Kural ve anlamı |
|---|---|---|---|
programId | string (UUID) | ✅ | Programınızın kimliği (GET /api/v1/wallet/programs/me). Size ait olmayan bir program 404 WALLET_NOT_FOUND, ACTIVE olmayan bir program 409 WALLET_STATE_INVALID döner. |
accountType | string | ✅ | PERSONAL (kişi) ya da BUSINESS (işletme). |
phone | string | ✅ | 8–20 karakter; yalnız rakam, +, boşluk, (, ) ve - içerebilir. Rakam dışındaki karakterler atılır ve baştaki 00 kaldırılır; kalan rakam sayısı 8–15 olmalıdır, değilse 400 WALLET_VALIDATION. Ülke koduyla uluslararası biçimde gönderin (+905321234567). |
externalCustomerId | string | — | Sizin sisteminizdeki müşteri kimliği, en fazla 128 karakter. Program içinde tekildir; büyük/küçük harfe duyarlıdır, baştaki ve sondaki boşluklar kırpılır. |
displayName | string | — | Görünen ad, en fazla 120 karakter. Yalnız maskeli hâli saklanır (displayNameMasked). |
kycRef | string | — | Kullanıcının KYC kaydına ait referansınız, en fazla 128 karakter. Saklanır ve yanıtta kycRef olarak döner; KYC seviyesini belirlemez. |
kycLevelCache | string | — | En fazla 32 karakter. Göndermeyin ya da NONE gönderin: son kullanıcı her zaman NONE seviyesinde açılır. LOW, SUBSTANTIAL ya da HIGH gönderirseniz istek 403 WALLET_KYC_LEVEL_UNVERIFIED ile reddedilir. Seviye açılıştan sonra yükseltilir: KYC Seviyeleri. |
corporateAccountId | string (UUID) | — | Kullanıcıyı bir işverene (kurumsal hesaba) çalışan olarak bağlar. Kurumsal hesap size ait, ACTIVE ve aynı programda olmalıdır. Bkz. Kurumsal Hesaplar. |
defaultCurrency | string | — | Varsayılan cüzdandaki hesabın para birimi; 3–8 harf, büyük harfe çevrilir. Programınızda etkin olmalıdır, değilse 409 WALLET_CURRENCY_NOT_ALLOWED. |
Telefon nasıl saklanır
Telefon numarası düz metin olarak saklanmaz. Normalize edilmiş rakamlardan tek yönlü bir özet (arama ve tekillik için) ve maskeli bir gösterim üretilir. Maskeli gösterim ilk 4 ve son 2 rakamı açık bırakır: +905321234567 → 9053******67. Yanıtlarda telefon yalnız phoneMasked olarak döner.
Tekillik normalize edilmiş rakamlar üzerinden kurulur. +90 532 123 45 67, 905321234567 ve 00905321234567 aynı numaradır; 05321234567 ise farklı bir numara olarak değerlendirilir. Numarayı her zaman ülke koduyla gönderin.
Görünen ad nasıl saklanır
displayName her kelimenin ilk harfi açık, kalan harfleri * olacak biçimde maskelenir (kelime başına en fazla 8 yıldız, toplam en fazla 64 karakter): Ayşe Yılmaz → A*** Y*****. Açık hâli saklanmaz ve geri okunamaz. Maskeli ad, cüzdan sorgulamada alıcı teyidi için gösterilir; göndermezseniz orada maskeli telefon gösterilir.
Açılış para birimi
Varsayılan cüzdan tek bir hesapla açılır. Para birimi şu sırayla belirlenir:
corporateAccountIdverildiyse kurumsal hesabın fonlama para birimi. Bu durumdadefaultCurrencygönderirseniz fonlama para birimiyle aynı olmalıdır; farklıysa istek400 WALLET_VALIDATIONile reddedilir.defaultCurrencyverildiyse o para birimi.- Hiçbiri yoksa programınızın ana para birimi.
Programınızda ana para birimi tanımlı değilse ve defaultCurrency göndermediyseniz istek 409 WALLET_PROGRAM_CURRENCY_UNDESIGNATED ile reddedilir ve hiçbir kayıt oluşmaz. Programın para birimi listesinden tahmin yapılmaz. Başka para birimleri için sonradan hesap açın: Cüzdan ve Hesap Açma.
Idempotency
Idempotency-Key zorunludur ve isteği bir kez işlenecek şekilde bağlar:
- Aynı anahtarla aynı istek tekrarlanırsa ilk başarılı yanıt aynen döner; ikinci bir kullanıcı oluşmaz.
- Aynı anahtar farklı bir istekle kullanılırsa
409 WALLET_IDEMPOTENCY_CONFLICTdöner. KarşılaştırmadaprogramId,accountType,phone,externalCustomerId,corporateAccountIdvedefaultCurrencydikkate alınır. - İlk istek hata ile sonuçlandıysa anahtar serbest kalır; aynı anahtarla yeniden deneyebilirsiniz.
Tüm senaryolar ve önerilen entegrasyon deseni: Tekrar Oluşturma.
Örnek
curl -X POST "https://api-gateway.lunixi.com/api/v1/wallet/end-users" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: enduser-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ılmaz","defaultCurrency":"TRY"}'{
"status": "success",
"code": "SUCCESS",
"message": "…",
"data": {
"endUser": {
"id": "8d4c2a1f-3b6e-4f7a-9c5d-2e8b1a0f6c34",
"programId": "5b9e2f3a-7c41-4d8e-a6f2-9e1b3c4d5f60",
"accountType": "PERSONAL",
"externalCustomerId": "crm-88213",
"corporateAccountId": null,
"corporateOffboardedAt": null,
"kycRef": null,
"kycLevelCache": null,
"kycLevelRefreshedAt": null,
"phoneMasked": "9053******67",
"displayNameMasked": "A*** Y*****",
"merchantCategory": null,
"status": "ACTIVE",
"createdAt": "2026-10-11T09:15:02.418Z",
"updatedAt": "2026-10-11T09:15:02.418Z"
},
"defaultWallet": {
"id": "1e7f9a3b-5c2d-4a8e-b6f1-3d9c0e2a7b58",
"endUserId": "8d4c2a1f-3b6e-4f7a-9c5d-2e8b1a0f6c34",
"walletNo": "5810763412",
"name": "Cüzdanım",
"isDefault": true,
"status": "ACTIVE",
"accounts": [
{
"id": "c2a5e8f1-9d3b-4c7a-8e6f-5b1d2a9c0e47",
"walletId": "1e7f9a3b-5c2d-4a8e-b6f1-3d9c0e2a7b58",
"currency": "TRY",
"accountCode": 5000,
"fullWalletNo": "58107634125000",
"status": "ACTIVE"
}
],
"createdAt": "2026-10-11T09:15:02.418Z"
}
},
"requestId": "…"
}endUser alanlarının anlamı Detay ve Arama sayfasındadır. Para hareketlerinde kaynak hesap olarak defaultWallet.accounts[].id değerini (walletAccountId) kullanırsınız. Varsayılan cüzdanın adı her zaman Cüzdanım'dır.
Yeni kullanıcının kycLevelCache alanı null döner: kullanıcı NONE seviyesindedir. Bu seviyede hangi işlemlerin açık olduğu KYC Seviyeleri sayfasındadır.
Hatalar
| HTTP | Kod | Ne zaman |
|---|---|---|
| 400 | VALIDATION_ERROR | Body kurallara uymuyor ya da tanımsız bir alan içeriyor (details.errors hangi alanın neden reddedildiğini listeler) |
| 400 | — | Idempotency-Key eksik, boş ya da 128 karakterden uzun |
| 400 | WALLET_VALIDATION | Telefon normalize edildikten sonra 8–15 rakam değil; kurumsal hesap ACTIVE değil ya da başka bir programda; defaultCurrency kurumsal hesabın fonlama para birimiyle çelişiyor |
| 403 | WALLET_KYC_LEVEL_UNVERIFIED | kycLevelCache olarak NONE dışında bir seviye gönderildi |
| 403 | WALLET_INSUFFICIENT_SCOPE | Anahtarda wallet:enduser:manage ya da wallet:program:manage yok |
| 404 | WALLET_NOT_FOUND | programId ya da corporateAccountId size ait bir kayıt değil |
| 409 | WALLET_ENDUSER_EXISTS | Programda bu telefonla ya da bu externalCustomerId ile bir son kullanıcı zaten var |
| 409 | WALLET_STATE_INVALID | Program ACTIVE değil |
| 409 | WALLET_CURRENCY_NOT_ALLOWED | defaultCurrency programınızda etkin değil |
| 409 | WALLET_PROGRAM_CURRENCY_UNDESIGNATED | defaultCurrency gönderilmedi ve programın ana para birimi tanımlı değil |
| 409 | WALLET_IDEMPOTENCY_CONFLICT | Aynı Idempotency-Key farklı bir istekle kullanıldı |
| 409 | WALLET_IDEMPOTENCY_IN_PROGRESS | Aynı anahtarla gönderilen ilk istek hâlâ işleniyor; kısa süre sonra aynı anahtarla tekrar deneyin |