LiderHavale · Partner API Dokümantasyonu LiderHavale · Partner API Documentation
Geliştirici kılavuzuDeveloper guide

LiderHavale Partner API LiderHavale Partner API

Yatırım ve çekim işlemlerini kendi platformunuza bağlayın. Yalnızca HTTPS, JSON gövde; kimlik doğrulama gövdedeki apiKey + secKey ikilisiyle yapılır. Integrate deposit and withdraw operations into your own platform. HTTPS only, JSON body; authentication uses the apiKey + secKey pair in the request body.

Taban adres
Base URL
https://api.liderhavale.com
Taşıma
Transport
HTTPS zorunluHTTPS required
Yöntemler
Methods
GET · POST
Kimlik
Authentication
auth.apiKey + auth.secKey
◧

GirişIntroduction

Beş dakikada ilk yatırımı açın. Open your first deposit in five minutes.

⚡ Hızlı başlangıçQuickstart

  1. Yatırım isteği açınCreate a deposit request
    POST /api/payment/deposit/with-partner
  2. Cevaptaki token değerini alın Take the token from the response
  3. Müşteriyi ödeme sayfasına yönlendirin Redirect the customer to the payment page
    https://payment.liderhavale.com/?token=${token}
  4. Bildirimi bekleyinWait for the callback
    İşlem onaylanınca sunucunuza POST atarız. We POST to your server once the transaction is confirmed.

🔒 GüvenlikSecurity

  • apiKey ve secKey değerlerini ortam değişkeninde tutun — kaynak koda yazmayın. Keep apiKey and secKey in environment variables — never hard-code them.
  • Gelen her bildirimin hash alanını SHA1 ile doğrulayın. Verify the hash field of every callback with SHA1.
  • Bildirim ucunuzu aynı işlemi iki kez işlemeyecek biçimde yazın (idempotent). Write your callback endpoint so the same transaction is never processed twice (idempotent).
  • İsteğe bağlı: bize IP listesi bildirin, yalnız o adreslerden gelen istekleri kabul ederiz. Optional: give us an IP allowlist and we will only accept requests from those addresses.
≡

Uç noktalarEndpoints overview

Üç iş ucu, dekont bağlantısı ve size attığımız bildirim. Three business endpoints, the receipt link and the callback we send you.

İşlevFeature YöntemMethod YolPath KimlikAuth
YatırımDeposit POST /api/payment/deposit/with-partner apiKey + secKey
ÇekimWithdraw POST /api/payment/withdraw/with-partner apiKey + secKey
Banka listesiBank list GET /api/bank GerekmezNone
Çekim dekontuWithdraw receipt GET /api/dekont/:token Bağlantıdaki jetonToken in link
Bildirim (biz size)Callback (us → you) POST SİZİN_ADRESİNİZYOUR_URL SHA1 hash
◆

Durum kodlarıStatus types

Yatırım ve çekimin alabileceği bütün değerler. Every value a deposit or withdraw can take.

DurumStatus AnlamıMeaning NotNote
PENDING Müşteri ya da yönetici onayı bekleniyor Awaiting customer action or admin approval Ara durumInterim
PROCESSING İstek alındı, ödeme akışı sürüyor Request accepted, payment flow in progress İlk durumInitial state
CONFIRMED Tamamlandı, bildirim gönderildi Completed, callback sent Yalnızca bu durum bildirim üretir Only this state fires a callback
REJECTED Yönetici ya da müşteri reddetti Rejected by admin or customer Sonradan onaylanabilir — aşağıya bakın May be confirmed later — see below
TIMEOUT_REJECTED Süre aşımıyla otomatik reddedildi Auto-rejected after timeout Sonradan onaylanabilir — aşağıya bakın May be confirmed later — see below
SUSPICIOUS Bizde onaylı, ama bildirim ≈1 saat (12 deneme) iletilemedi Confirmed on our side, but the callback failed for ≈1 hour (12 attempts) Kurtarılabilir — akışa bakın Recoverable — see the flow
FAILED İşlem sırasında hata Processing error Kesin durumFinal
CANCELLED Müşteri ya da sistem iptali Cancelled by customer or system Kesin durumFinal
ÖnemliImportant Bildirim CONFIRMED, REJECTED ve TIMEOUT_REJECTED durumları için gönderilir. SUSPICIOUS bir işlem, adresiniz yeniden erişilebilir olduğunda kurtarılır ve size CONFIRMED bildirilir. Callbacks are sent for CONFIRMED, REJECTED and TIMEOUT_REJECTED. A SUSPICIOUS transaction is recovered once your URL is reachable again and you receive CONFIRMED.
Reddedilen yatırım sonradan onaylanabilirA rejected deposit can be confirmed later Müşteri havaleyi süre dolduktan sonra yaparsa ödeme ekibimiz kaydı tekrar onaylayabilir. Bu durumda aynı transactionId için önce REJECTED/TIMEOUT_REJECTED, sonra CONFIRMED bildirimi alırsınız. CONFIRMED geldiğinde — önceki red bildirimine bakmadan — müşterinin bakiyesini yükleyin. Tek kural: aynı işlem için CONFIRMED'ı iki kez işlemeyin. If the customer pays after the window closed, our payment team can re-approve the record. You then receive REJECTED/TIMEOUT_REJECTED followed by CONFIRMED for the same transactionId. When CONFIRMED arrives, credit the customer regardless of the earlier rejection. The only rule: never process CONFIRMED twice for the same transaction.
Onaylanan tutar farklı olabilirThe confirmed amount can differ Müşteri istenenden farklı tutar gönderirse kayıt gelen tutarla onaylanır. Bildirimdeki amount alanı her zaman onaylanan (gerçekten gelen) tutardır — bakiyeyi bu değere göre yükleyin, ilk istediğiniz tutara göre değil. If the customer sends a different amount, the record is confirmed with the amount actually received. The amount in the callback is always the confirmed amount — credit that value, not the amount you originally requested.
⌂

Ortam ve kimlik doğrulamaEnvironment & authentication

Adresler, istek biçimi ve anahtarların nasıl gönderildiği. Addresses, request format and how the keys are sent.

ServisServiceAdresAddress KullanımUsage
APIhttps://api.liderhavale.com Sunucunuzdan çağırdığınız tüm uçlarEvery endpoint you call from your server
Ödeme sayfasıPayment pagehttps://payment.liderhavale.com Müşteriyi ?token= ile yönlendirdiğiniz sayfaWhere you redirect the customer with ?token=
DokümantasyonDocshttps://docs.liderhavale.com Bu sayfaThis page

İstek biçimiRequest format

  • Gövde JSON, başlık Content-Type: application/json. En fazla 1 MB. Body is JSON with Content-Type: application/json. Up to 1 MB.
  • Yalnız HTTPS. Tutarlar Türk lirası, tam sayı ya da iki haneli ondalık. HTTPS only. Amounts are in Turkish lira, integer or two decimals.
  • Zamanlar ISO 8601, UTC (2026-01-01T08:08:26.340Z). Timestamps are ISO 8601, UTC (2026-01-01T08:08:26.340Z).
  • İş kuralı hataları HTTP 200 + "status": false ile döner; önce status alanına bakın. Business errors return HTTP 200 + "status": false; always check status first.

AnahtarlarKeys

  • apiKey ve secKey her istekte gövdedeki auth nesnesiyle gönderilir. apiKey and secKey go in the body's auth object on every request.
  • secKey aynı zamanda bildirim imzasının sırrıdır; tarayıcıya ya da mobil uygulamaya asla koymayın. secKey is also the callback signing secret; never ship it to a browser or mobile app.
  • Anahtarlar sızdıysa hesap yöneticiniz panelden yeniler; eskiler anında geçersiz olur. If keys leak, your account manager rotates them in the panel; the old ones stop working immediately.
  • IP kısıtı: sunucu IP'lerinizi bildirirseniz hesabınız yalnız o adreslerden istek kabul eder; listede olmayan adres 402 Unauthorized Access. alır. IP allowlist: send us your server IPs and your account only accepts requests from them; other addresses get 402 Unauthorized Access.
1

YatırımDeposit

Müşteriniz adına yatırım isteği açar. Creates a deposit request on behalf of your customer.

POST https://api.liderhavale.com/api/payment/deposit/with-partner

İstek gövdesiRequest body

{
  "auth": {
    "apiKey": "API_ANAHTARINIZ",
    "secKey": "GIZLI_ANAHTARINIZ"
  },
  "customer": {
    "id":       "123123",       // sizdeki müşteri no
    "username": "testmusteri",
    "fullName": "Ahmet Yılmaz"   // banka hesabındaki ad
  },
  "transactionId": "456785",      // sizde tekil olmalı
  "returnUrl":     "https://siteniz.com/hesabim",
  "amount":        1000
}

Başarılı cevapSuccess response

HTTP 200
{
  "status": true,
  "deposit": {
    "customer": {
      "fullName": "Ahmet Yılmaz",
      "username": "testmusteri",
      "id": "123123"
    },
    "transactionId": "456785",
    "amount": 1000,
    "partner": "6453f2b3c4b1361de57edf90",
    "status": "PROCESSING",
    "_id": "64c76bfacfe287ddf963ce49",
    "created_at": "2026-01-01T08:08:26.340Z"
  },
  "token": "pZk3_9vQxT2Lm8Rd...",
  "paymentUrl": "https://payment.liderhavale.com/?token=pZk3_9vQxT2Lm8Rd..."
}

Müşteriyi yönlendirinRedirect the customer

Cevaptaki token ile ödeme sayfasına gönderin. Bağlantı 10 dakika geçerlidir. Send them to the payment page with the token from the response. The link is valid for 10 minutes.

https://payment.liderhavale.com/?token=${token}

Adresi kendiniz kurmak istemiyorsanız cevaptaki paymentUrl alanını olduğu gibi kullanabilirsiniz — aynı şey. If you would rather not build the URL yourself, use the paymentUrl field from the response as is — it is the same thing.

Kapalı yatırım hatalarıDeposit disabled errors Yatırım işlemleri şu anda kapalıdır ya da Bu site için yatırım işlemleri kapalıdır cevabı alıyorsanız, yatırım ya sistem geneline ya da yalnız sizin hesabınıza kapatılmıştır. Bu cevap HTTP 200 ile gelir — gövdedeki status alanına bakın. If you get Yatırım işlemleri şu anda kapalıdır or Bu site için yatırım işlemleri kapalıdır, deposits are off either globally or for your account only. This response arrives with HTTP 200 — check the status field in the body.
2

ÇekimWithdraw

Müşterinin banka hesabına ödeme talebi açar. Submits a payout to the customer's bank account.

POST https://api.liderhavale.com/api/payment/withdraw/with-partner

İstek gövdesiRequest body

{
  "auth": {
    "apiKey": "API_ANAHTARINIZ",
    "secKey": "GIZLI_ANAHTARINIZ"
  },
  "customer": {
    "id": "123456",
    "username": "testmusteri",
    "fullName": "Ahmet Yılmaz"
  },
  "transactionId": "123123",
  "iban":          "TR760009901234567800100001",
  "bank":          "65c6525532c59fcd5af4a4b3",  // /api/bank içindeki _id
  "amount":        1000
}

Başarılı cevapSuccess response

HTTP 200
{
  "status": true,
  "withdraw": {
    "customer": { "fullName": "Ahmet Yılmaz",
                   "username": "testmusteri",
                   "id": "123456" },
    "bank": "65c6525532c59fcd5af4a4b3",
    "iban": "TR760009901234567800100001",
    "transactionId": "123123",
    "amount": 1000,
    "partner": "6453f2b3c4b1361de57edf90",
    "status": "PROCESSING",
    "_id": "64c769013f547212cdb46415",
    "created_at": "2026-01-01T07:55:45.150Z"
  }
}
Yatırım ve çekim ayrı anahtarlardırDeposit and withdraw toggle separately Bu site için çekim işlemleri kapalıdır cevabı alsanız bile yatırım çalışıyor olabilir; tersi de geçerlidir. IBAN kontrol basamağı bizde doğrulanır — geçersiz IBAN iş kuralı hatası döner. Getting Bu site için çekim işlemleri kapalıdır does not mean deposits are off — and vice versa. We validate the IBAN checksum; an invalid IBAN comes back as a business-logic error.
3

Banka listesiBank list

Çekim isteğinde kullanacağınız banka kimliklerini verir. Returns the bank ids you use in withdraw requests.

GET https://api.liderhavale.com/api/bank
Kimlik gerekmezNo auth
{
  "status": true,
  "data": [
    {
      "_id": "6453f2c8c4b1361de57edfc2",
      "name": "GARANTİ BANKASI",
      "code": "0062",
      "enabled": true,
      "created_at": "2026-01-01T18:00:40.003Z",
      "updated_at": "2026-01-01T18:00:40.003Z"
    },
    {
      "_id": "64c852d8f7fa26fc12daabb2",
      "name": "HALKBANK",
      "code": "0012",
      "enabled": true,
      "created_at": "2026-01-02T00:33:28.724Z",
      "updated_at": "2026-01-02T00:33:28.724Z"
    }
  ]
}
İpucuTip Çekim isteğindeki bank alanına _id değerini yazın; banka adını değil. Liste değişebilir, günde bir kez tazelemeniz yeter. Put the _id value in the withdraw request's bank field, not the bank name. The list can change; refreshing once a day is enough.
4

BildirimCallbacks

İşlem sonuçlanınca sizin sunucunuza POST atarız. We POST to your server when a transaction is settled.

AdresDestination SİZİN_ADRESİNİZYOUR_URL — bize bildirdiğiniz uç — the endpoint you gave us
YöntemMethod POST application/json
Beklenen cevapExpected response HTTP 200
Zaman aşımıTimeout 15 saniye15 seconds
DenemeAttempts 5 dakikada bir, en fazla 12 kez (≈1 saat) · sonra SUSPICIOUS Every 5 minutes, up to 12 times (≈1 hour) · then SUSPICIOUS
DekontReceipt Hesabınızda çekim dekontu açıksa çekim bildirimine receipt_url eklenir — ödeme makbuzunun kimlik istemeyen bağlantısı (60 gün). İmzaya dahil değildir. If withdraw receipts are enabled for your account, the withdraw callback carries receipt_url — an unauthenticated link to the payout receipt (60 days). It is not part of the signature.
Test bildirimiTest callback Kurulumda adresinize "status": "TEST" ve transactionId'si TEST- ile başlayan imzalı bir bildirim gönderebiliriz. Bakiye yüklemeyin, yalnız imzayı doğrulayıp HTTP 200 dönün. During setup we may send a signed callback with "status": "TEST" and a transactionId starting with TEST-. Do not credit anything — just verify the signature and return HTTP 200.
DoğrulamaVerification Gövdedeki hash — SHA1 hash in the body — SHA1

İmza (SHA1)Signature (SHA1)

İmzalanan metnin sırası sözleşmenin parçasıdır — alanları başka sırayla dizerseniz hash tutmaz. The order of the signed text is part of the contract — a different field order produces a different hash.

// Node.js
const crypto = require("crypto");

const hashRequestSignature = (secret, text) =>
  crypto.createHash("sha1").update(`${secret}${text}`).digest("hex");

// Gelen bildirimi doğrulama
function bildirimGecerli(govde, secKey) {
  const metin = `transactionId=${govde.transactionId}&amount=${govde.amount}&status=${govde.status}`;
  return hashRequestSignature(secKey, metin) === govde.hash;
}

↓ Yatırım bildirimiDeposit callback

{
  "transactionId": "456785",
  "status": "CONFIRMED",
  "amount": 1000,
  "hash": "bb2299ae42…",
  "type": "deposit"
}

↑ Çekim bildirimiWithdraw callback

{
  "transactionId": "123123",
  "status": "REJECTED",
  "amount": 1000,
  "hash": "4f1ac07b93…",
  "type": "withdraw",
  "receipt_url": "https://api.liderhavale.com/api/dekont/…"  // yalnız dekont açıksa
}
⚙

Bildirim akışı ve kurtarmaCallback flow & recovery

Deneme sayacı ve SUSPICIOUS durumu nasıl çalışır. How the retry counter and the SUSPICIOUS state work.

1
İşlem bizde onaylanırTransaction is confirmed on our side Yönetici elle onaylar ya da otomatik eşleşme tamamlanır. An admin approves it, or auto-matching completes.
2
Adresinize POST atılırWe POST to your URL Gövde: transactionId, status, amount, hash, type. Body: transactionId, status, amount, hash, type.
✓
HTTP 200 dönerse iş biterHTTP 200 ends it İşlem CONFIRMED kalır, tekrar denemeyiz. The transaction stays CONFIRMED; we do not retry.
!
200 dışı cevap ya da zaman aşımıNon-200 or timeout Deneme sayacı artar; 15 saniye içinde cevap gelmezse başarısız sayılır. 5 dakika sonra otomatik olarak yeniden deneriz. The attempt counter increases; no answer within 15 seconds counts as failed. We retry automatically after 5 minutes.
3
12. başarısız denemede (≈1 saat) SUSPICIOUS The 12th failure (≈1 hour) moves it to SUSPICIOUS Otomatik denemeyi bırakırız; işlem panelde şüpheli kuyruğuna düşer ve ekibimize haber gider. We stop retrying automatically; it lands in the suspicious queue and our team is alerted.
4
Panelden elle tekrar gönderilirManual retry from the panel Denemeler arasında 60 saniye bekleme vardır. There is a 60-second cooldown between attempts.
✓
Başarılı olursa CONFIRMED'a döner On success it returns to CONFIRMED Kayda kim kurtardığı ve ne zaman düşülür. Who recovered it and when is written to the audit log.
Çift işleme riski yokNo duplicate risk Sizin tarafınızdan bakıldığında her işlem için tek başarılı bildirim alırsınız — ilk denemede ya da kurtarmada. Yine de bildirim ucunuzu transactionId'ye bakıp iki kez işlemeyecek biçimde yazın. From your side you receive exactly one successful callback per transaction — either on the first attempt or on recovery. Even so, write your handler to check transactionId and never process it twice.
▣

Dekont bağlantısıReceipt link

Çekim ödendiğinde ödeme makbuzunu müşterinize gösterebilmeniz için. So you can show the payout receipt to your customer once a withdraw is paid.

GET https://api.liderhavale.com/api/dekont/:token
  • Adres, çekim bildirimindeki receipt_url alanıdır; kendiniz kurmayın. The address is the receipt_url field of the withdraw callback; do not build it yourself.
  • Kimlik istemez; jeton tahmin edilemez uzunluktadır. Bağlantıyı yalnız ilgili müşteriyle paylaşın. No auth needed; the token is unguessable. Share the link only with that customer.
  • Cevap dosyanın kendisidir: image/jpeg, image/png, image/webp ya da application/pdf (en fazla 5 MB). The response is the file itself: image/jpeg, image/png, image/webp or application/pdf (up to 5 MB).
  • Dekontlar 60 gün saklanır; sonra bağlantı 404 döner. Kalıcı saklamanız gerekiyorsa dosyayı indirip kendinizde tutun. Receipts are kept for 60 days; after that the link returns 404. Download and store the file if you need it longer.
  • receipt_url imzaya dahil değildir; imzayı yine transactionId, amount, status ile doğrulayın. receipt_url is not signed; still verify with transactionId, amount, status.
5

HatalarErrors

İki ayrı hata sınıfı var — karıştırmak en sık yapılan entegrasyon hatası. There are two distinct error classes — confusing them is the most common integration mistake.

Yalnızca HTTP koduna bakmayınDo not look at the HTTP code alone İş kuralı hataları HTTP 200 ile ve gövdede "status": false olarak döner. Sadece response.ok kontrolü yapan entegrasyonlar bunları başarılı sanıp müşteriye bakiye yükler. Her zaman gövdedeki status alanını okuyun. Business-logic errors come back with HTTP 200 and "status": false in the body. Integrations that only check response.ok read these as success and credit the customer. Always read the status field in the body.

HTTP seviyesi hatalarHTTP-level errors

KodCode AnlamıMeaning Örnek cevapExample response
401 Parametre eksikMissing parameters {"status":false,"message":"Missing parameters apikey or secKey","code":401}
402 Yetkisiz erişim — anahtar hatalı Unauthorized — wrong key {"status":false,"message":"Unauthorized Access.","code":402}
403 Hesap kapalı ya da IP listede değil Account disabled or IP not allowlisted {"status":false,"message":"Unauthorized Access.","code":403}

İş kuralı hatalarıBusiness-logic errors

HTTP 200 · status:false
MesajMessage SebepReason
Sistem geçici bir süreliğine bakım durumundadır Sistem geneli kapalı. Bekleyip tekrar deneyin. System-wide switch is off. Wait and retry.
Yatırım işlemleri şu anda kapalıdır Yatırım sistem geneline kapatılmış. Deposits disabled globally.
Bu site için yatırım işlemleri kapalıdır Yatırım yalnız sizin hesabınızda kapalı. Deposits disabled for your account only.
Çekim işlemleri şu anda kapalıdır Çekim sistem geneline kapatılmış. Withdraws disabled globally.
Bu site için çekim işlemleri kapalıdır Çekim yalnız sizin hesabınızda kapalı. Withdraws disabled for your account only.
Minimum yatırım tutarı X TL'dir Tutar alt sınırın altında. Amount below the minimum.
Maksimum yatırım tutarı X TL'dir Tutar üst sınırın üstünde. Amount above the maximum.
Aynı transactionId ile bir işlem zaten mevcut transactionId sizde tekil olmalı. transactionId must be unique on your side.
Şu anda bu tutar için uygun yatırım hesabı bulunmuyor, lütfen daha sonra tekrar deneyin Bu tutarı alabilecek yatırım hesabı şu an yok (limitler dolu ya da bakımda). Talep açılmaz; müşteriye mesajı gösterip birazdan ya da farklı tutarla denetin. No receiving account can take this amount right now (limits full or maintenance). Nothing is created; show the message and let the customer retry later or with another amount.
Geçersiz IBAN TR + 24 rakam ve kontrol basamağı doğrulanır. TR + 24 digits; the checksum is validated.
Müşteri bilgileri eksik (id, username, fullName) Üç alanın üçü de zorunlu. All three fields are required.
Tamamlanmamış yatırım talepleriniz var. Lütfen önce onları sonuçlandırın Aynı müşterinin (username) aynı anda en fazla 3 açık yatırımı olabilir. Önceki talep sonuçlanınca ya da süresi dolunca yenisi açılır. A customer (username) may hold at most 3 open deposits at once. A new one opens once an earlier one settles or expires.
Ödeme yöntemine erişiminiz kısıtlanmıştır… Müşteri risk nedeniyle engellenmiş. Müşteriye bu mesajı gösterebilirsiniz. The customer is blocked for risk reasons. You may show this message to the customer.
Seçilen banka şu anda kullanılamıyor Çekimdeki banka kapalı; /api/bank listesini tazeleyin. The withdraw bank is disabled; refresh the /api/bank list.

Doğru kontrolThe correct check

const cevap = await fetch(url, { method: "POST", headers, body });
const govde = await cevap.json();

// YANLIŞ: iş kuralı hatası da 200 döner
// if (cevap.ok) { bakiyeYukle(); }

// DOĞRU
if (!cevap.ok)      throw new Error(`HTTP ${cevap.status}: ${govde.message}`);
if (!govde.status)  throw new Error(govde.message);  // iş kuralı

// buraya geldiyseniz işlem gerçekten açıldı
musteriyiYonlendir(govde.token);
⏱

Hız sınırlarıRate limits

Sınırlar istemci IP'si başına, dakikalık pencereyle sayılır. Limits are counted per client IP over a one-minute window.

UçlarEndpointsDakikadaPer minute AşılıncaWhen exceeded
/api/payment/*, /api/bank60 HTTP 429 · {"status":false,"message":"Too many requests.","code":429}
Tüm /api (toplam)All of /api (total)600 HTTP 429
429 aldığınızdaWhen you get 429 Cevaptaki RateLimit ve Retry-After başlıkları ne kadar beklemeniz gerektiğini söyler. İsteği aynı transactionId ile birkaç saniye sonra tekrarlayın; ilk istek işlendiyse ikincisi mükerrer olarak reddedilir, çift işlem oluşmaz. Banka listesini her istekte değil, saatte bir çekip önbellekte tutun. The RateLimit and Retry-After headers tell you how long to wait. Retry with the same transactionId after a few seconds; if the first request went through the second is rejected as a duplicate, so nothing is created twice. Cache the bank list hourly instead of fetching it per request.
{}

Kod örnekleriCode samples

Yatırım açma ve bildirimi doğrulama — kopyalayıp anahtarlarınızı ortam değişkeninden verin. Creating a deposit and verifying the callback — copy and feed your keys from environment variables.

Yatırım açmaCreate a deposit

<?php
$govde = [
  'auth' => ['apiKey' => getenv('LH_API_KEY'), 'secKey' => getenv('LH_SEC_KEY')],
  'customer' => ['id' => '123123', 'username' => 'testmusteri', 'fullName' => 'Ahmet Yılmaz'],
  'transactionId' => 'DEP-' . $siparisNo,        // sizde tekil
  'returnUrl' => 'https://siteniz.com/hesabim',
  'amount' => 1000,
];
$ch = curl_init('https://api.liderhavale.com/api/payment/deposit/with-partner');
curl_setopt_array($ch, [
  CURLOPT_POST => true,
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_TIMEOUT => 20,
  CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
  CURLOPT_POSTFIELDS => json_encode($govde, JSON_UNESCAPED_UNICODE),
]);
$cevap = json_decode(curl_exec($ch), true);
$http = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($http === 200 && !empty($cevap['status'])) {
  header('Location: ' . $cevap['paymentUrl']);   // müşteriyi ödeme sayfasına gönder
  exit;
}
// status:false → $cevap['message'] müşteriye gösterilebilir (limit, kapalı yatırım…)
error_log('LiderHavale: ' . ($cevap['message'] ?? "HTTP $http"));

Bildirimi karşılamaHandling the callback

<?php
$b = json_decode(file_get_contents('php://input'), true) ?: [];
$metin = "transactionId={$b['transactionId']}&amount={$b['amount']}&status={$b['status']}";
$beklenen = sha1(getenv('LH_SEC_KEY') . $metin);

if (!hash_equals($beklenen, (string)($b['hash'] ?? ''))) {
  http_response_code(401); exit('imza hatali');     // 200 dönmeyin: sahte istek
}
if ($b['status'] === 'TEST') { http_response_code(200); exit('ok'); }

// Aynı bildirim birden çok kez gelebilir: işlemi yalnız BİR kez uygulayın.
$db->beginTransaction();
$islem = $db->kilitleVeGetir($b['transactionId']);          // SELECT … FOR UPDATE
if ($islem && $islem['durum'] !== $b['status']) {
  if ($b['type'] === 'deposit' && $b['status'] === 'CONFIRMED') {
    $db->bakiyeEkle($islem['musteri'], $b['amount']);          // DİKKAT: istenen değil, gelen tutar
  }
  if ($b['type'] === 'withdraw' && $b['status'] === 'REJECTED') {
    $db->bakiyeIadeEt($islem['musteri'], $islem['tutar']);
  }
  $db->durumYaz($b['transactionId'], $b['status']);
}
$db->commit();
http_response_code(200);
echo 'ok';
✓

Canlıya geçiş kontrol listesiGo-live checklist

Canlı trafiği açmadan önce her maddeyi deneyerek işaretleyin. Tick every item by actually trying it before opening live traffic.

  • Anahtarlar ortam değişkeninde; kaynak kodda ve istemci tarafında yok.Keys live in environment variables; not in source code or client side.
  • Bildirim adresiniz HTTPS, herkese açık ve 15 saniye içinde HTTP 200 dönüyor.Your callback URL is HTTPS, publicly reachable and returns HTTP 200 within 15 seconds.
  • Hesap yöneticinizden test bildirimi istediniz; imza doğrulandı ve 200 döndünüz.You asked your account manager for a test callback; the signature verified and you returned 200.
  • Yanlış imzalı bildirimi reddediyorsunuz (200 dönmüyorsunuz).You reject a wrongly signed callback (you do not return 200).
  • Aynı bildirimi iki kez gönderince bakiye bir kez değişiyor.Sending the same callback twice changes the balance once.
  • Yatırımda bildirimdeki amount ile bakiye yüklüyorsunuz (istenen tutarla değil).For deposits you credit the callback's amount (not the requested amount).
  • Önce REJECTED gelip sonra CONFIRMED gelen yatırımı yüklüyorsunuz (tekrar onay).A deposit that first comes REJECTED and later CONFIRMED is credited (re-approval).
  • Çekimde bakiyeyi talep anında düşüyor, REJECTED gelince iade ediyorsunuz.For withdraws you hold the balance on request and refund on REJECTED.
  • "status": false cevaplarını (limit, kapalı yatırım, mükerrer no…) müşteriye anlaşılır gösteriyorsunuz.You show "status": false answers (limit, deposits off, duplicate id…) to the customer clearly.
  • Banka listesini önbellekte tutuyor, çekim formunda yalnız açık bankaları gösteriyorsunuz.You cache the bank list and only offer enabled banks on the withdraw form.
  • Sunucu IP'lerinizi IP kısıtı için hesap yöneticinize ilettiniz (önerilir).You sent your server IPs to your account manager for the allowlist (recommended).
?

Sık sorulanlarFAQ

Müşteri ödeme yaptı ama bildirim gelmedi.The customer paid but no callback arrived.

Onay ekibimiz ödemeyi hesapta görünce onaylar; bildirim o anda gider. Sunucunuz 200 dönmezse 5 dakikada bir, 12 kez (≈1 saat) yeniden denenir, sonra işlem SUSPICIOUS olur ve ekibimiz elle yeniden gönderir. İşlem numarasıyla destek isteyin; panelde her denemenin HTTP kodunu görürüz. Our team confirms once the payment shows in the account; the callback is sent then. If your server does not return 200 we retry every 5 minutes, 12 times (≈1 hour), then the transaction turns SUSPICIOUS and our team resends manually. Ask support with the transaction id; we see the HTTP code of every attempt.

Müşteri istenenden farklı tutar gönderdi.The customer sent a different amount.

Ekibimiz tutarı gelen havaleye göre düzeltip onaylar; bildirimdeki amount gerçekte yatan tutardır. Her zaman o değeri yükleyin. Our team corrects the amount to the actual transfer and confirms; the callback's amount is what was really paid. Always credit that value.

Reddedilen yatırım sonradan onaylanabilir mi?Can a rejected deposit be confirmed later?

Evet. Havale geç düşerse ekibimiz işlemi tekrar onaylar ve aynı transactionId ile CONFIRMED bildirimi gider. Kodunuz bu geçişi kabul etmeli. Yes. If the transfer lands late our team re-approves it and a CONFIRMED callback is sent with the same transactionId. Your code must accept that transition.

Ödeme bağlantısının süresi doldu.The payment link expired.

Bağlantı 10 dakika geçerlidir; ödeme yapılmamışsa işlem 10 dakika sonunda TIMEOUT_REJECTED olur ve bildirilir. Müşteri için yeni bir transactionId ile yeni yatırım açın. The link is valid for 10 minutes; if unpaid after 10 minutes the transaction becomes TIMEOUT_REJECTED and you are notified. Open a new deposit with a new transactionId.

Aynı müşteri için kaç açık yatırım olabilir?How many open deposits can one customer have?

Sınırlı sayıda: aynı müşterinin (customer.username) sonuçlanmamış yatırımı 3 olunca yenisi Tamamlanmamış yatırım talepleriniz var… hatasıyla reddedilir (HTTP 200, status:false). Önceki işlemler sonuçlanınca yeniden deneyin. A limited number: once the same customer (customer.username) has 3 unsettled deposits, a new one is rejected with Tamamlanmamış yatırım talepleriniz var… (HTTP 200, status:false). Retry once earlier ones settle.

Test ortamı var mı?Is there a sandbox?

Ayrı bir sandbox yoktur; bunun yerine payment.liderhavale.com adresi bir test alanıdır: API anahtarlarınızı bir kez girin (yalnız tarayıcınızda saklanır), tutarı yazın, "Yatırım talebi oluştur" deyin — istek bu dokümandaki uca gider ve aynı sayfada ödeme ekranı açılır. Çekim talebi de oradan açılır. Callback'inizi denemek için hesap yöneticiniz panelden imzalı TEST bildirimi gönderebilir. There is no separate sandbox; instead payment.liderhavale.com is a test playground: enter your API keys once (kept only in your browser), type an amount and hit "create deposit" — the request goes to the endpoint documented here and the payment screen opens on the same page. Withdraw requests can be opened there too. To test your callback, your account manager can send a signed TEST callback from the panel.

◷

NotlarNotes

  • transactionId sizde tekil olmalı; aynı numarayla ikinci istek reddedilir. Bizde (partner, transactionId) ikilisi üzerinde benzersiz indeks var — eşzamanlı iki istek bile geçemez. transactionId must be unique on your side; a second request with the same number is rejected. We keep a unique index on (partner, transactionId), so even two concurrent requests cannot pass.
  • returnUrl müşterinin ödemeden sonra döneceği adrestir. Boş bırakırsanız ödeme sayfasında "geri dön" düğmesi çıkmaz. returnUrl is where the customer goes after paying. Leave it empty and the payment page shows no "back" button.
  • Komisyon yatırım ve çekim için ayrı ayrı, hesap bazında tanımlanır. Değişiklik için hesap yöneticinizle görüşün. Commission is set per account, separately for deposits and withdraws. Contact your account manager to change it.
  • Limitler sistem geneli varsayılanlardan gelir; hesabınız için ezilebilir. Boş bırakılan limit sistem değerine düşer. Limits come from system-wide defaults and can be overridden per account. An unset limit falls back to the system value.
  • Çekim akışı: talep PROCESSING olarak açılır; ödeme ekibi üstlenince PENDING olur, ödeme yapılınca CONFIRMED ya da REJECTED bildirilir. Çekimlerde süre aşımı yoktur. Withdraw flow: the request opens as PROCESSING; it becomes PENDING once a payment team takes it, and you receive CONFIRMED or REJECTED after payout. Withdraws do not time out.
  • Ödeme bağlantısı 10 dakika geçerlidir. Süresi dolan bağlantı için yeni bir yatırım isteği açın. The payment link is valid for 10 minutes. Open a new deposit request for an expired link.
  • Destek için işlem numarasını iletin; panelde o işlemin bize gelen isteği, verdiğimiz cevap ve bildirim denemeleri birlikte görünüyor. For support, quote the transaction id; the panel shows that transaction's incoming request, our response and every callback attempt together.
↻

Sürüm geçmişiChangelog

  • v1.2 2026-09
    Ortam ve kimlik, dekont bağlantısı, hız sınırları, PHP/Node/cURL örnekleri, canlıya geçiş listesi ve SSS eklendi. Sözleşmede değişiklik yok. Added environment & auth, receipt link, rate limits, PHP/Node/cURL samples, go-live checklist and FAQ. No contract changes.
  • v1.1 2026-09
    Bildirimde 5 dk arayla 12 deneme; receipt_url; TEST bildirimi; tekrar onay ve düzeltilmiş tutar notları; yeni iş kuralı hataları. Callback retried 12 times every 5 minutes; receipt_url; TEST callback; re-approval and corrected amount notes; new business errors.
  • v1.0 2026-08
    Yatırım, çekim, banka listesi ve SHA1 imzalı bildirim. Deposit, withdraw, bank list and SHA1-signed callback.