First APIv1

Yatırım ve çekim API’si

Sitenizdeki kullanıcıların yatırım ve çekim taleplerini First Kasa’ya iletmek, ödeme sayfasını göstermek ve sonucu anlık bildirimle almak için gereken her şey.

Taban adres: https://firstapi.duckdns.orgJSON · HTTPSmd5 imza

Genel bakış

  1. 1 · Talep

    Siteniz DepositStart veya WithdrawalStart isteği gönderir.

  2. 2 · Ödeme

    Yatırımda dönen IframeUrl’i müşteriye gösterirsiniz; müşteri tutarı gönderir.

  3. 3 · Onay

    Kasa ekibi hareketi kontrol edip onaylar veya nedeniyle reddeder.

  4. 4 · Bildirim

    Sonuç, callback adresinize imzalı JSON olarak POST edilir.

Kararlar insan onaylıdır: bir talep Pending başlar ve birkaç dakika içinde Successful veya Unsuccessful olur. Bakiyeyi yalnızca başarılı callback geldiğinde güncelleyin.

Başlarken

Panelde API ve anahtarlar sayfasında şu bilgiler bulunur:

AlanTürZorunluAçıklama
Firma kodustring(32)evetİmza anahtarı. Yalnızca sunucunuzda saklayın; tarayıcıya veya mobil uygulamaya koymayın.
MethodKeystring(32)evetHer ödeme yöntemi (Havale/EFT, Papara, Payfix, Kripto…) için ayrı anahtar. İsteğin hangi yöntemle işleneceğini belirler.
Callback adresihttps URLevetSonuçların POST edileceği adresiniz. Panelden kaydedip “Test callback gönder” ile deneyin.
  • Tüm istekler POST, gövde application/json ve UTF-8 olmalıdır.
  • İş hataları HTTP 200 ile döner; sonucu ApiStatus ve ApiCode alanlarından okuyun. Bozuk JSON 400, hız sınırı aşımı 429 döner.
  • Hız sınırı: IP başına saniyede 20 istek (kısa süreli 40’a kadar tolerans).
  • Saatler İstanbul saatidir (UTC+3), biçim YYYY-MM-DD HH:mm:ss.
  • Callback’ler 185.246.188.225 adresinden gelir; güvenlik duvarınızda bu IP’ye izin verin.

İmza (HashCode)

Her istek, sırrı paylaşmadan doğrulanabilmesi için md5 imzası taşır. Değerler araya ayraç koyulmadan, aşağıdaki sırayla birleştirilir:

Formül
Yatırım / çekim / callback:  md5(FirmaKodu + UserId + Reference + Amount)
Durum sorgulama:             md5(FirmaKodu + Reference)

Amount, gönderdiğiniz metnin aynısı olmalı

Tutarı JSON’da metin olarak gönderin ("150.50") ve imzada da aynı metni kullanın. Sayı olarak gönderirseniz JSON 150.50 değerini 150.5 yapar ve imza tutmaz. Ondalık ayracı noktadır, en fazla 2 hane; binlik ayracı kullanılmaz.
İmza
$hash = md5($firmCode . $userId . $reference . $amount);
Örnek
FirmaKodu = 2696c6c22fb5d47a7bfc995075e96bd3
UserId    = 123654789
Reference = FP1730000000
Amount    = 150.50

md5("2696c6c22fb5d47a7bfc995075e96bd3123654789FP1730000000150.50")

Panelde “Hash hesaplayıcı” ile kendi firma kodunuzla ürettiğiniz imzayı karşılaştırabilirsiniz.

Yatırım başlatma

POSThttps://firstapi.duckdns.org/api/deposit-start
AlanTürZorunluAçıklama
ProcessstringevetSabit: DepositStart
MethodKeystring ≤ 64evetÖdeme yönteminin anahtarı.
UserIdstring ≤ 80evetSitenizdeki kullanıcı kimliği.
NameSurnamestring ≤ 120evetKullanıcının adı soyadı. Kasa ekibi gönderen adıyla karşılaştırır.
Amountstring | numberevet0’dan büyük, en fazla 100.000.000, en fazla 2 ondalık. Metin önerilir: "150.50"
Currencystring(3)evetISO para birimi, ör. TRY
Referencestring ≤ 80evetSizin işlem numaranız. Her talepte benzersiz olmalı; tekrar edilirse reddedilir.
ReturnUrlURLhayırSonuç ekranındaki “Siteye dön” düğmesinin adresi (http/https).
HashCodestring(32)evetmd5(FirmaKodu + UserId + Reference + Amount)
İstek
curl -X POST https://firstapi.duckdns.org/api/deposit-start \
  -H "Content-Type: application/json" \
  -d '{
    "Process": "DepositStart",
    "MethodKey": "HAVALE_METHOD_KEY",
    "UserId": "123654789",
    "NameSurname": "JOHN DOE",
    "Amount": "150.50",
    "Currency": "TRY",
    "Reference": "FP1730000000",
    "ReturnUrl": "https://siteniz.com/odeme-sonuc",
    "HashCode": "<md5(FirmaKodu + UserId + Reference + Amount)>"
  }'
Başarılı yanıt
{
  "ApiStatus": "ok",
  "ApiCode": "3001",
  "Message": "The process has been successfully initiated",
  "IframeUrl": "https://firstapi.duckdns.org/pay/8432d583b368881f530742e14796b4a3",
  "Token": "8432d583b368881f530742e14796b4a3"
}
Hatalı yanıt
{
  "ApiStatus": "error",
  "ApiCode": "5010",
  "Message": "Invalid hash"
}

Token ve Reference’ı saklayın. Uygun aktif kasa hesabı yoksa No available account döner; kullanıcıya başka yöntem önerin.

Ödeme sayfası

IframeUrl müşteriye alıcı adı, banka, IBAN/hesap numarası, tutar ve açıklamaya yazılacak referansı gösterir. Müşteri ödemeyi yapıp “Ödemeyi yaptım”a basar; sayfa sonuç gelene kadar kendiliğinden güncellenir. Yönlendirme ya da iframe ile kullanabilirsiniz:

HTML
<iframe
  src="IFRAME_URL"
  style="width:100%;max-width:520px;height:820px;border:0"
  allow="clipboard-write"
></iframe>
  • Sayfa mobil uyumludur; iframe genişliği 360px’ten dar olmamalı.
  • “Siteye dön” bağlantısı iframe’den çıkıp üst pencereyi ReturnUrl’e götürür.
  • Müşterinin sayfayı kapatması işlemi iptal etmez; sonuç yine callback ile gelir.

Çekim başlatma

POSThttps://firstapi.duckdns.org/api/withdrawal-start

Yatırımla aynı alanlar; ReturnUrl yerine müşterinin parasını alacağı AccountNumber gönderilir. Ödeme sayfası yoktur.

AlanTürZorunluAçıklama
ProcessstringevetSabit: WithdrawalStart
AccountNumberstringevetMüşterinin kendi hesabı. Yönteme göre doğrulanır (aşağıda). Boşluklar yok sayılır.
MethodKey · UserId · NameSurname · Amount · Currency · Reference · HashCode—evetYatırımdaki kurallarla aynı.
AlanTürZorunluAçıklama
IBAN (Havale/EFT)TR + 24 rakamevet26 karakter, IBAN kontrol hanesi doğru olmalı. Ör. TR31 0004 6007 0988 8000 2359 26
Cüzdan (Papara, Payfix…)8–20 rakamevetYalnızca rakam.
Kripto20–128 karakterevetHarf ve rakam; ağ/zincir yöntemin tanımına göre.
İstek
curl -X POST https://firstapi.duckdns.org/api/withdrawal-start \
  -H "Content-Type: application/json" \
  -d '{
    "Process": "WithdrawalStart",
    "MethodKey": "HAVALE_METHOD_KEY",
    "UserId": "123654789",
    "NameSurname": "JOHN DOE",
    "AccountNumber": "TR310004600709888000235926",
    "Amount": "1000",
    "Currency": "TRY",
    "Reference": "WD1730000000",
    "HashCode": "<md5(FirmaKodu + UserId + Reference + Amount)>"
  }'
Başarılı yanıt
{
  "ApiStatus": "ok",
  "ApiCode": "3001",
  "Message": "The process has been successfully initiated",
  "Token": "c32b1a64e5449bd5c57a1e66f2a37963"
}

Hatalı hesap numarası 5011 · Account number is incorrect döner. Para kullanıcıya gönderilince başarılı callback gelir; çekim tutarını o ana kadar kullanıcının bakiyesinde bloke tutun.

Durum sorgulama

POSThttps://firstapi.duckdns.org/api/transaction-status

Callback’i kaçırdığınızda veya gün sonu mutabakatında bir talebin güncel durumunu sorgulayın. Bayinize ait herhangi bir MethodKey kullanılabilir.

AlanTürZorunluAçıklama
ProcessstringevetSabit: StatusQuery
MethodKeystringevetBayinize ait herhangi bir yöntem anahtarı.
TypestringevetDeposit veya Withdrawal
ReferencestringevetTalepte gönderdiğiniz referans.
HashCodestring(32)evetmd5(FirmaKodu + Reference)
İstek
curl -X POST https://firstapi.duckdns.org/api/transaction-status \
  -H "Content-Type: application/json" \
  -d '{
    "Process": "StatusQuery",
    "MethodKey": "HERHANGI_BIR_METHOD_KEY",
    "Type": "Deposit",
    "Reference": "FP1730000000",
    "HashCode": "<md5(FirmaKodu + Reference)>"
  }'
Yanıt
{
  "ApiStatus": "ok",
  "ApiCode": "3001",
  "Type": "Deposit",
  "Reference": "FP1730000000",
  "UserId": "123654789",
  "Amount": "150.50",
  "Currency": "TRY",
  "Status": "Successful",
  "Message": "Deposit successful",
  "CreatedAt": "2026-10-25 12:00:00",
  "DecidedAt": "2026-10-25 12:04:31",
  "Token": "8432d583b368881f530742e14796b4a3"
}

Status: Pending, Successful veya Unsuccessful. Bulunamazsa 5010 · Transaction not found.

Callback (bildirim)

Kasa ekibi karar verdiği anda kayıtlı callback adresinize POST isteği gönderilir. Gövde JSON’dur ve aynı imza kuralıyla imzalanır.

AlanTürZorunluAçıklama
ProcessstringevetDepositReturn veya WithdrawalReturn
MethodKeystringevetTalepteki yöntem anahtarı.
UserId · NameSurname · Reference · CurrencystringevetTalepte gönderdiğiniz değerler.
Amountnumber | stringevetYatırımda sayı (150.5), çekimde metin ("1000").
StatusstringevetSuccessful veya Unsuccessful
MessagestringevetRed nedeni veya bilgi notu. Reddedilen işlemde kullanıcıya gösterebilirsiniz.
DatestringevetKarar zamanı, İstanbul saati.
Tokenstring(32)evetTalepte dönen token.
HashCodestring(32)evetmd5(FirmaKodu + UserId + Reference + Amount) — Amount, talepte gönderdiğiniz metin.
TestbooleanhayırYalnızca panelden gönderilen test bildiriminde true. Bu durumda işlem yapmadan 200 dönün.
Örnek gövde
{
  "Process": "DepositReturn",
  "MethodKey": "254f499a2cb2f83f87f0728b0e8353c4",
  "UserId": "123654789",
  "NameSurname": "JOHN DOE",
  "Amount": 150.5,
  "Currency": "TRY",
  "Reference": "FP1730000000",
  "Status": "Successful",
  "Message": "Deposit successful",
  "Date": "2026-10-25 12:04:31",
  "Token": "8432d583b368881f530742e14796b4a3",
  "HashCode": "…"
}
  • 10 saniye içinde herhangi bir 2xx yanıt verin; aksi halde gönderim “ulaşmadı” sayılır. Ağır işleri yanıttan sonra yapın.
  • Otomatik yeniden deneme yoktur. Ulaşmayan bildirimleri kasa ekibi panelden yeniden gönderebilir; siz de durum sorgulama ile mutabakat yapın.
  • Aynı bildirim birden fazla gelebilir: işlemi Reference ile bir kez uygulayın (idempotent).
  • İmzayı doğrularken tutarı callback’ten değil, talepte gönderdiğiniz metinden alın.
Callback karşılayıcı
<?php
$body = json_decode(file_get_contents('php://input'), true);
if (!empty($body['Test'])) { http_response_code(200); exit('OK'); }   // panelden test

$order = find_order_by_reference($body['Reference']);                 // kendi kaydınız
if (!$order) { http_response_code(404); exit('unknown'); }

// Tutarı callback'ten değil, istekte gönderdiğiniz metinden alın
$expected = md5($firmCode . $body['UserId'] . $body['Reference'] . $order['amount_text']);
if (!hash_equals($expected, strtolower($body['HashCode']))) { http_response_code(400); exit('bad hash'); }

if ($order['status'] === 'pending') {           // aynı bildirim iki kez gelebilir
    if ($body['Status'] === 'Successful') {
        credit_user($order);                     // bakiyeyi ekle / çekimi tamamla
    } else {
        fail_order($order, $body['Message']);
    }
}
http_response_code(200);
echo 'OK';

Yanıt kodları

ApiCodeMessageNe yapmalı
3001The process has been successfully initiatedTalep alındı.
5010Operation failedZorunlu alan eksik/hatalı, Process yanlış veya tutar biçimi geçersiz.
5010Unknown methodMethodKey yanlış ya da yöntem kapatılmış. Paneldeki anahtarı kontrol edin.
5010Invalid hashİmza tutmuyor. Birleştirme sırasını ve Amount metnini kontrol edin.
5010Duplicate referenceBu Reference daha önce kullanıldı. Yeni bir referans üretin.
5010No available accountTutara/limite uygun aktif kasa yok. Daha sonra veya başka yöntemle deneyin.
5010Transaction not foundDurum sorgulamada referans bulunamadı.
5011Account number is incorrectÇekimde alıcı hesap biçimi geçersiz.

Canlıya geçiş listesi

  • Firma kodu yalnızca sunucuda, ortam değişkeninde saklanıyor.
  • Her talepte benzersiz Reference üretiliyor ve Amount metniyle birlikte kaydediliyor.
  • Amount JSON’da metin olarak gönderiliyor ve imzadaki metinle birebir aynı.
  • Callback adresi panelde kayıtlı, HTTPS ve “Test callback gönder” 200 dönüyor.
  • Callback imzası doğrulanıyor, Test bildirimleri yok sayılıyor, aynı Reference iki kez uygulanmıyor.
  • Bakiye yalnızca Successful callback ile güncelleniyor; çekim tutarı karar gelene kadar bloke.
  • Gün sonunda Pending kalan talepler durum sorgulama ile kontrol ediliyor.

Sık sorulanlar

Talep ne kadar sürede sonuçlanır?

Kasa ekibi hareketi gördüğü anda karar verir; genellikle birkaç dakika. Müşterinin “Ödemeyi yaptım”a basması süreci hızlandırır.

Müşteri farklı tutar gönderirse?

Talep reddedilebilir (Message: Tutar uyuşmuyor). Doğru tutarla yeni bir talep açtırın.

Test ortamı var mı?

Canlı ortamda küçük tutarlarla deneyin; callback’inizi panelden “Test callback gönder” ile test edin. Test bildirimi Test: true içerir.

Anahtarım sızdıysa?

Kasa yöneticisinden MethodKey’i yenilemesini isteyin; eski anahtar anında geçersiz olur. Firma kodu değişikliği için de yöneticiye başvurun.

Callback’im ulaşmadı, ne olur?

İşlem sonucu değişmez. Panelde gönderim “ulaşmadı” görünür; kasa ekibi yeniden gönderebilir. Siz de durum sorgulamayla sonucu alabilirsiniz.

Sürüm notları

  • v1.1 · İşlem durumu sorgulama (/api/transaction-status) eklendi. Ödeme sayfası “Siteye dön” bağlantısı iframe dışına çıkar.
  • v1.0 · DepositStart, WithdrawalStart, ödeme sayfası ve imzalı callback.