Cüzdan
Son Kullanıcılar
Oluşturma

Son Kullanıcı Oluşturma

Bu uçları kim çağırır?Dış API (s2s)
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_SCOPE alı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:manage ya da wallet:program:manage izni gerekir.
POST /api/v1/wallet/end-users

Son 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

HeaderZorunluKural
İ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.

AlanTipZorunluKural ve anlamı
programIdstring (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.
accountTypestring✅PERSONAL (kişi) ya da BUSINESS (işletme).
phonestring✅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).
externalCustomerIdstring—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.
displayNamestring—Görünen ad, en fazla 120 karakter. Yalnız maskeli hâli saklanır (displayNameMasked).
kycRefstring—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.
kycLevelCachestring—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.
corporateAccountIdstring (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.
defaultCurrencystring—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:

  1. corporateAccountId verildiyse kurumsal hesabın fonlama para birimi. Bu durumda defaultCurrency gönderirseniz fonlama para birimiyle aynı olmalıdır; farklıysa istek 400 WALLET_VALIDATION ile reddedilir.
  2. defaultCurrency verildiyse o para birimi.
  3. 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_CONFLICT döner. Karşılaştırmada programId, accountType, phone, externalCustomerId, corporateAccountId ve defaultCurrency dikkate 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

HTTPKodNe zaman
400VALIDATION_ERRORBody 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
400WALLET_VALIDATIONTelefon 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
403WALLET_KYC_LEVEL_UNVERIFIEDkycLevelCache olarak NONE dışında bir seviye gönderildi
403WALLET_INSUFFICIENT_SCOPEAnahtarda wallet:enduser:manage ya da wallet:program:manage yok
404WALLET_NOT_FOUNDprogramId ya da corporateAccountId size ait bir kayıt değil
409WALLET_ENDUSER_EXISTSProgramda bu telefonla ya da bu externalCustomerId ile bir son kullanıcı zaten var
409WALLET_STATE_INVALIDProgram ACTIVE değil
409WALLET_CURRENCY_NOT_ALLOWEDdefaultCurrency programınızda etkin değil
409WALLET_PROGRAM_CURRENCY_UNDESIGNATEDdefaultCurrency gönderilmedi ve programın ana para birimi tanımlı değil
409WALLET_IDEMPOTENCY_CONFLICTAynı Idempotency-Key farklı bir istekle kullanıldı
409WALLET_IDEMPOTENCY_IN_PROGRESSAynı anahtarla gönderilen ilk istek hâlâ işleniyor; kısa süre sonra aynı anahtarla tekrar deneyin