DOCS
Panel Giriş Başvurun

Tahsilat Metodu

Form ile Ödeme

Zorunlu alanları hash'leyip Paynkolay ortak ödeme sayfasına POST edersiniz; kart bilgileri Paynkolay tarafında alınır, sonuç adresinize imzalı olarak döner.

Genel Bakış

Form ile Ödeme, çevrimiçi işletmelerin ödeme kabul etmesinin en hızlı ve en güvenli yoludur. Müşteri kart bilgilerini sizin sisteminizde değil, Paynkolay'ın mobil uyumlu ortak ödeme sayfasında girer — böylece PCI DSS yükümlülükleri Paynkolay tarafından karşılanır ve entegrasyon birkaç alanlık bir form göndermeye indirgenir.

Avantajlar

Daha hızlı entegrasyon Kart ekranı, taksit listesi ve 3D akışı hazır — siz yalnızca formu gönderirsiniz.
Güçlü güvenlik güvencesi PCI DSS uyumu Paynkolay'da; 3D Secure ve hash imzası akışın parçasıdır.
Çoklu ödeme seçeneği Visa, Mastercard, Troy, Amex; taksit seçenekleri karta göre otomatik listelenir.

Ödeme Akışı

MüşteriSitenizOrtak Ödeme SayfasıBanka (3D)Ödemeye geç1Form POST(sx · amount · hashDatav2…)2Kart bilgileri Paynkolay sayfasında girilir3SMS / OTP onayı4Sonuç successUrl'e POST5Hash + tutar doğrulaması6Sipariş onayı7

Müşteriniz ödemesini ister tek çekim ister taksitli yapsın, akış dört adımda tamamlanır:

1Müşteri sitenizde "Öde"ye basar; formunuz alanları hash'leyip Paynkolay'a POST eder.

2Ortak ödeme sayfası açılır; müşteri kart bilgilerini girer, taksit seçeneklerini görür.

3Gerekliyse 3D Secure doğrulaması yapılır (SMS / banka şifresi).

4İmzalı sonuç successUrl / failUrl adresinize POST edilir; hash'i doğrulayıp siparişi sonuçlandırırsınız.

Kullanım Seçenekleri

Yönlendirme (varsayılan)
  • Müşteri ortak ödeme sayfasına yönlendirilir
  • En yaygın ve en basit kullanım
iframe içinde
  • Ortak ödeme sayfası kendi sitenizin içinde açılır
  • Müşteri sitenizden hiç ayrılmaz

Örnek Kod

Aşağıdaki örnekler çalışır durumda tam sayfalardır: test bilgileriyle hash'i sunucu tarafında üretir, müşteri IP'sini tespit eder ve ortak ödeme sayfasına gönderen formu basar. Canlıya geçerken form action adresi https://paynkolay.nkolayislem.com.tr/Vpos olur; sx ve merchantSecretKey panelinizdeki canlı değerlerle değiştirilir.

<!doctype html>
<html>
<head>
<title>Sanal POS entegrasyonu örnek PHP sayfamız</title>
<meta charset="utf-8">
</head>
<body>

<?php
// sx değeriniz size verilecektir
$sx="118591467|W8a1JLU8A5Cw+HfadVcO6HiR/GGGxr0NkWr2OGythr8fo0YWdw70cvnI6oKMqvzra3Qu+Wa5u0NRil9gRdJmjocVNd4XciDwfD9+pkVqDErw7/pVZfpcSO+GePg+ZvcqFbOO5A==";
$merchantSecretKey="_viH5wUS4HiBmmw9uGybN"; // size özel - special to you
$successUrl="https://paynkolay.com.tr/test/success";
$failUrl="https://paynkolay.com.tr/test/fail";
$amount="5.00";
$currencyCode="949";
$clientRefCode="2352345";
$use3D="true";
$rnd = date("d-m-Y H:i:s");
$agentCode="1236";
$transactionType="SALES";
$customerKey = "";
$instalments = "";
$hashstr = $sx . "|" . $clientRefCode . "|" . $amount . "|" . $successUrl . "|" . $failUrl . "|" . $rnd . "|" . $customerKey . "|" . $merchantSecretKey;

$hash = mb_convert_encoding($hashstr, 'UTF-8');
$hashedBytes = hash("sha512", $hash, true);
$hashDataV2 = base64_encode($hashedBytes);

function getClientIpAddress(): string
{
    // A list of headers to check in order of priority
    $headers = [
        'HTTP_CLIENT_IP',
        'HTTP_X_FORWARDED_FOR',
        'HTTP_X_FORWARDED',
        'HTTP_X_CLUSTER_CLIENT_IP',
        'HTTP_FORWARDED_FOR',
        'HTTP_FORWARDED',
        'REMOTE_ADDR'
    ];

    foreach ($headers as $header) {
        if (isset($_SERVER[$header])) {
            // HTTP_X_FORWARDED_FOR can contain a comma-separated list of IPs.
            // The first one is the original client IP.
            $ipList = explode(',', $_SERVER[$header]);
            $ip = trim($ipList[0]);

            // Validate the IP address
            if (filter_var($ip, FILTER_VALIDATE_IP)) {
                return $ip;
            }
        }
    }

    return 'UNKNOWN';
}

// How to use the function
$cardHolderIP = getClientIpAddress();

?>

<!-- Canlı ortam için form action linki "https://paynkolay.nkolayislem.com.tr/Vpos" olmalıdır. -->
<form method="post" action="https://paynkolaytest.nkolayislem.com.tr/Vpos">
  <input type="hidden" name="sx" value="<?= $sx ?>">
  <input type="hidden" name="successUrl" value="<?= $successUrl ?>">
  <input type="hidden" name="failUrl" value="<?= $failUrl ?>">
  <input type="hidden" name="amount" value="<?= $amount ?>">
  <input type="hidden" name="currencyCode" value="<?= $currencyCode ?>">
  <input type="hidden" name="clientRefCode" value="<?= $clientRefCode ?>">
  <input type="hidden" name="use3D" value="<?= $use3D ?>">
  <input type="hidden" name="rnd" value="<?= $rnd ?>">
  <input type="hidden" name="agentCode" value="<?= $agentCode ?>">
  <input type="hidden" name="transactionType" value="<?= $transactionType ?>">
  <input type="hidden" name="hashDataV2" value="<?= $hashDataV2 ?>">
  <input type="hidden" name="cardHolderIP" value="<?= $cardHolderIP ?>">
  <input type="hidden" name="instalments" value="<?= $instalments ?>">
  <input type="submit" value="Gönder" />
</form>

</body>
</html>
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Configuration;
using System.Security.Cryptography;
using System.Text;
using System.Globalization;
using System.Linq;
using System.Net;

namespace MyApi.Pages
{
    public class SanalPosModel : PageModel
    {
        private readonly IConfiguration _config;
        public SanalPosModel(IConfiguration config) => _config = config;

        public string Sx { get; private set; } =
            "118591467|W8a1JLU8A5Cw+HfadVcO6HiR/GGGxr0NkWr2OGythr8fo0YWdw70cvnI6oKMqvzra3Qu+Wa5u0NRil9gRdJmjocVNd4XciDwfD9+pkVqDErw7/pVZfpcSO+GePg+ZvcqFbOO5A==";
        public string SuccessUrl { get; private set; } = "https://paynkolay.com.tr/test/success";
        public string FailUrl    { get; private set; } = "https://paynkolay.com.tr/test/fail";
        public string Amount     { get; private set; } = "5";
        public string CurrencyCode { get; private set; } = "949";
        public string ClientRefCode { get; private set; } = "2352345";
        public string Use3D      { get; private set; } = "true";
        public string AgentCode  { get; private set; } = "1236";
        public string Detail     { get; private set; } = "false";
        public string TransactionType { get; private set; } = "SALES";
        public string CustomerKey { get; private set; } = "";
        public string Instalments { get; private set; } = "";
        public string Rnd { get; private set; } = "";
        public string HashDataV2 { get; private set; } = "";

        public string cardHolderIP { get; private set; } = "";

        /// <summary>
        /// Gets the client's IP address by checking various headers, similar to the PHP example.
        /// This is more reliable when the application is behind a proxy or load balancer.
        /// </summary>
        /// <returns>The client's IP address as a string, or "UNKNOWN".</returns>
        private string GetClientIpAddress()
        {
            // A list of headers to check in order of priority.
            // These correspond to the $_SERVER variables in the PHP example.
            var headers = new[]
            {
                "Client-IP",
                "X-Forwarded-For",
                "X-Forwarded",
                "X-Cluster-Client-IP",
                "Forwarded-For",
                "Forwarded"
            };

            foreach (var header in headers)
            {
                // Try to get the value of the header
                var ipHeaderValue = HttpContext.Request.Headers[header].FirstOrDefault();

                if (!string.IsNullOrEmpty(ipHeaderValue))
                {
                    // The "X-Forwarded-For" header can contain a comma-separated list of IPs.
                    // The first IP in the list is the original client's IP.
                    var ipList = ipHeaderValue.Split(',').Select(ip => ip.Trim());
                    var firstIp = ipList.FirstOrDefault();

                    // Validate that the first IP in the list is a valid IP address
                    if (firstIp != null && IPAddress.TryParse(firstIp, out _))
                    {
                        return firstIp;
                    }
                }
            }

            // If no valid IP is found in the headers, fall back to the remote IP address of the connection
            var remoteIp = HttpContext.Connection.RemoteIpAddress;
            if (remoteIp != null)
            {
                // Map to IPv4 if possible to ensure a consistent format, then convert to string
                return remoteIp.MapToIPv4().ToString();
            }

            return "UNKNOWN";
        }


        public void OnGet()
        {
            // optional: override from env/appsettings (safer)
            Sx              = _config["PaynKolay:Sx"] ?? Sx;
            SuccessUrl      = _config["PaynKolay:SuccessUrl"] ?? SuccessUrl;
            FailUrl         = _config["PaynKolay:FailUrl"] ?? FailUrl;
            Amount          = _config["PaynKolay:Amount"] ?? Amount;
            ClientRefCode   = _config["PaynKolay:ClientRefCode"] ?? ClientRefCode;
            Use3D           = _config["PaynKolay:Use3D"] ?? Use3D;
            AgentCode       = _config["PaynKolay:AgentCode"] ?? AgentCode;
            Detail          = _config["PaynKolay:Detail"] ?? Detail;
            TransactionType = _config["PaynKolay:TransactionType"] ?? TransactionType;
            CustomerKey     = _config["PaynKolay:CustomerKey"] ?? CustomerKey;

            var merchantSecretKey = _config["PaynKolay:MerchantSecretKey"] ?? "_viH5wUS4HiBmmw9uGybN";

            // Call the new, more robust method to get the client's IP address
            cardHolderIP = GetClientIpAddress();

            Rnd = DateTime.Now.ToString("dd-MM-yyyy HH:mm:ss", CultureInfo.InvariantCulture);

            var raw = $"{Sx}|{ClientRefCode}|{Amount}|{SuccessUrl}|{FailUrl}|{Rnd}|{CustomerKey}|{merchantSecretKey}";
            using var sha512 = SHA512.Create();
            HashDataV2 = Convert.ToBase64String(sha512.ComputeHash(Encoding.UTF8.GetBytes(raw)));
        }
    }
}
@page "/sanalpos"
@model MyApi.Pages.SanalPosModel
<!doctype html>
<html lang="tr">
<head><meta charset="utf-8" /><title>Sanal POS Örnek</title></head>
<body>
    <!-- Canlı ortam için form action linki "https://paynkolay.nkolayislem.com.tr/Vpos" olmalıdır. -->
    <form method="post" action="https://paynkolaytest.nkolayislem.com.tr/Vpos">
        <input type="hidden" name="sx"              value="@Model.Sx" />
        <input type="hidden" name="successUrl"      value="@Model.SuccessUrl" />
        <input type="hidden" name="failUrl"         value="@Model.FailUrl" />
        <input type="hidden" name="amount"          value="@Model.Amount" />
        <input type="hidden" name="currencyCode"    value="@Model.CurrencyCode" />
        <input type="hidden" name="clientRefCode"   value="@Model.ClientRefCode" />
        <input type="hidden" name="use3D"           value="@Model.Use3D" />
        <input type="hidden" name="rnd"             value="@Model.Rnd" />
        <input type="hidden" name="agentCode"       value="@Model.AgentCode" />
        <input type="hidden" name="detail"          value="@Model.Detail" />
        <input type="hidden" name="transactionType" value="@Model.TransactionType" />
        <input type="hidden" name="hashDataV2"      value="@Model.HashDataV2" />
        <input type="hidden" name="cardHolderIP"    value="@Model.cardHolderIP" />
        <input type="hidden" name="instalments"     value="@Model.Instalments" />
        <button type="submit">Gönder</button>
    </form>
</body>
</html>
import hashlib
import base64
from datetime import datetime
from flask import Flask, request
import ipaddress

app = Flask(__name__)

def get_client_ip():
    """
    Gets the client's IP address by checking various headers,
    replicating the logic from the provided PHP example.
    """
    # A list of headers to check in order of priority.
    # In Flask, these are in the `request.environ` dictionary.
    headers = [
        'HTTP_CLIENT_IP',
        'HTTP_X_FORWARDED_FOR',
        'HTTP_X_FORWARDED',
        'HTTP_X_CLUSTER_CLIENT_IP',
        'HTTP_FORWARDED_FOR',
        'HTTP_FORWARDED',
        'REMOTE_ADDR'
    ]

    for header in headers:
        if header in request.environ:
            # Some headers can contain a comma-separated list of IPs.
            # The client's IP is typically the first one.
            ip_list = request.environ.get(header).split(',')
            ip = ip_list[0].strip()

            # Validate the IP address
            try:
                ipaddress.ip_address(ip)
                return ip
            except ValueError:
                # Not a valid IP, so we continue to the next header
                pass

    return 'UNKNOWN'

@app.route('/')
def generate_payment_form():
    """
    Generates an HTML form for the payment gateway with a calculated hash.
    This function replicates the logic from the original PHP script.
    """
    # Get client IP address using the robust function
    card_holder_ip = get_client_ip()

    # 1. Define your payment parameters
    # This value will be provided to you by the payment gateway
    sx = "118591467|W8a1JLU8A5Cw+HfadVcO6HiR/GGGxr0NkWr2OGythr8fo0YWdw70cvnI6oKMqvzra3Qu+Wa5u0NRil9gRdJmjocVNd4XciDwfD9+pkVqDErw7/pVZfpcSO+GePg+ZvcqFbOO5A=="
    merchant_secret_key = "_viH5wUS4HiBmmw9uGybN"  # Your unique secret key
    success_url = "https://paynkolay.com.tr/test/success"
    fail_url = "https://paynkolay.com.tr/test/fail"
    amount = "5.00"
    currency_code = "949"
    client_ref_code = "2352345"
    use_3d = "true"
    agent_code = "1236"
    transaction_type = "SALES"
    customer_key = ""
    instalments = ""

    # Get the current timestamp in the required format
    rnd = datetime.now().strftime("%d-%m-%Y %H:%M:%S")

    # 2. Create the hash string by concatenating the values
    # The order of concatenation is crucial and must match the payment gateway's documentation.
    hash_str_parts = [
        sx,
        client_ref_code,
        amount,
        success_url,
        fail_url,
        rnd,
        customer_key,
        merchant_secret_key
    ]
    hash_str = "|".join(hash_str_parts)

    # 3. Calculate the SHA-512 hash and then Base64 encode it
    # First, encode the string to bytes using UTF-8
    hash_bytes = hash_str.encode('utf-8')

    # Calculate the SHA-512 hash, getting the raw binary output (digest)
    sha512_hash_digest = hashlib.sha512(hash_bytes).digest()

    # Base64 encode the raw hash digest
    hash_data_v2_bytes = base64.b64encode(sha512_hash_digest)

    # Decode the Base64 bytes into a string to use in the HTML form
    hash_data_v2 = hash_data_v2_bytes.decode('utf-8')

    # 4. Generate the HTML content using an f-string
    html_content = f"""
<!doctype html>
<html>
<head>
<title>Sanal POS entegrasyonu örnek Python sayfamız</title>
<meta charset="utf-8">
</head>
<body>

<h2>Payment Form (Generated by Python)</h2>
<p>Click the button below to proceed to the payment page.</p>

<!-- Canlı ortam için form action linki "https://paynkolay.nkolayislem.com.tr/Vpos" olmalıdır. -->
<form method="post" action="https://paynkolaytest.nkolayislem.com.tr/Vpos">
  <input type="hidden" name="sx" value="{sx}">
  <input type="hidden" name="successUrl" value="{success_url}">
  <input type="hidden" name="failUrl" value="{fail_url}">
  <input type="hidden" name="amount" value="{amount}">
  <input type="hidden" name="currencyCode" value="{currency_code}">
  <input type="hidden" name="clientRefCode" value="{client_ref_code}">
  <input type="hidden" name="use3D" value="{use_3d}">
  <input type="hidden" name="rnd" value="{rnd}">
  <input type="hidden" name="agentCode" value="{agent_code}">
  <input type="hidden" name="transactionType" value="{transaction_type}">
  <input type="hidden" name="hashDataV2" value="{hash_data_v2}">
  <input type="hidden" name="cardHolderIP" value="{card_holder_ip}">
  <input type="hidden" name="instalments" value="{instalments}">
  <input type="submit" value="Gönder" style="padding: 10px 20px; font-size: 16px; cursor: pointer;" />
</form>

</body>
</html>
"""

    # 5. Return the generated HTML content
    return html_content


if __name__ == "__main__":
    # To run this application, you first need to install Flask:
    # pip install Flask
    #
    # After installation, run this script:
    # python sanalpos.py
    #
    # It will start a local web server. You can access the payment form by opening
    # http://127.0.0.1:5000 in your web browser.
    app.run(debug=True)
const express = require('express');
const crypto = require('crypto');
const net = require('net');

const app = express();
const port = 3000;

function getClientIp(req) {
    const headers = [
        'x-client-ip',
        'x-forwarded-for',
        'x-forwarded',
        'x-cluster-client-ip',
        'forwarded-for',
        'forwarded',
    ];

    for (const header of headers) {
        if (req.headers[header]) {
            const ipList = req.headers[header].split(',');
            const ip = ipList[0].trim();
            if (net.isIP(ip)) {
                return ip;
            }
        }
    }

    if (req.socket && req.socket.remoteAddress) {
        const remoteAddress = req.socket.remoteAddress;
        // Handle IPv6-mapped IPv4 addresses
        if (remoteAddress.substr(0, 7) == "::ffff:") {
            const ipv4 = remoteAddress.substr(7)
            if (net.isIP(ipv4)) {
                return ipv4;
            }
        }
        if (net.isIP(remoteAddress)) {
            return remoteAddress;
        }
    }

    return 'UNKNOWN';
}

function generatePaymentForm(cardHolderIP) {
    // 1. Define your payment parameters
    const sx = "118591467|W8a1JLU8A5Cw+HfadVcO6HiR/GGGxr0NkWr2OGythr8fo0YWdw70cvnI6oKMqvzra3Qu+Wa5u0NRil9gRdJmjocVNd4XciDwfD9+pkVqDErw7/pVZfpcSO+GePg+ZvcqFbOO5A==";
    const merchantSecretKey = "_viH5wUS4HiBmmw9uGybN"; // Your unique secret key
    const successUrl = "https://paynkolay.com.tr/test/success";
    const failUrl = "https://paynkolay.com.tr/test/fail";
    const amount = "5.00";
    const currencyCode = "949";
    const clientRefCode = "2352345";
    const use3D = "true";
    const agentCode = "1236";
    const transactionType = "SALES";
    const customerKey = "";
    const instalments = "";

    // Helper function to format the date as "dd.mm.yyyy HH:MM:SS"
    const getFormattedDate = () => {
        const now = new Date();
        const pad = (num) => num.toString().padStart(2, '0');

        const day = pad(now.getDate());
        const month = pad(now.getMonth() + 1); // Months are 0-indexed
        const year = now.getFullYear();

        const hours = pad(now.getHours());
        const minutes = pad(now.getMinutes());
        const seconds = pad(now.getSeconds());

        return `${day}-${month}-${year} ${hours}:${minutes}:${seconds}`;
    };

    const rnd = getFormattedDate();

    // 2. Create the hash string by concatenating the values
    // The order of concatenation is crucial.
    const hashStrParts = [
        sx,
        clientRefCode,
        amount,
        successUrl,
        failUrl,
        rnd,
        customerKey,
        merchantSecretKey
    ];
    const hashStr = hashStrParts.join("|");

    // 3. Calculate the SHA-512 hash and then Base64 encode it
    const hash = crypto.createHash('sha512');
    hash.update(hashStr, 'utf-8');
    const hashDataV2 = hash.digest('base64');

    // 4. Generate the HTML content using a template literal
    const htmlContent = `
<!doctype html>
<html>
<head>
<title>Sanal POS entegrasyonu örnek Node.js sayfamız</title>
<meta charset="utf-8">
</head>
<body>

<h2>Payment Form (Generated by Node.js)</h2>
<p>Your IP address is: ${cardHolderIP}</p>
<p>Click the button below to proceed to the payment page.</p>

<!-- Canlı ortam için form action linki "https://paynkolay.nkolayislem.com.tr/Vpos" olmalıdır. -->
<form method="post" action="https://paynkolaytest.nkolayislem.com.tr/Vpos">
  <input type="hidden" name="sx" value="${sx}">
  <input type="hidden" name="successUrl" value="${successUrl}">
  <input type="hidden" name="failUrl" value="${failUrl}">
  <input type="hidden" name="amount" value="${amount}">
  <input type="hidden" name="currencyCode" value="${currencyCode}">
  <input type="hidden" name="clientRefCode" value="${clientRefCode}">
  <input type="hidden" name="use3D" value="${use3D}">
  <input type="hidden" name="rnd" value="${rnd}">
  <input type="hidden" name="agentCode" value="${agentCode}">
  <input type="hidden" name="transactionType" value="${transactionType}">
  <input type="hidden" name="cardHolderIP" value="${cardHolderIP}">
  <input type="hidden" name="hashDataV2" value="${hashDataV2}">
  <input type="hidden" name="instalments" value="${instalments}">
  <input type="submit" value="Gönder" style="padding: 10px 20px; font-size: 16px; cursor: pointer;" />
</form>

</body>
</html>
`;

    return htmlContent;
}

app.get('/payment', (req, res) => {
  const ip = getClientIp(req);
  const htmlForm = generatePaymentForm(ip);
  res.send(htmlForm);
});

app.listen(port, () => {
  console.log(`Server running on port ${port}`);
  console.log(`Access the payment form at http://localhost:${port}/payment`);
});

hashData, API ile aynı formülle sunucu tarafında üretilir: sx|clientRefCode|amount|successUrl|failUrl|rnd|customerKey|merchantSecretKey → SHA-512 → Base64.

Parametreler

ParametreTipZorunluAçıklama
sxstringSize verilen satış (sx) değeriniz
clientRefCodestringSizin ürettiğiniz referans numarası — her işlem için benzersiz olmalı (aynı kod, sorgulama ve raporlamada işlemleri ayırt edilemez kılar); Türkçe karakter içermemeli, en fazla 1024 karakter
amountdecimalTutar — kuruş ayıracı nokta (ör. 249.90)
successUrlstringBaşarılı sonucun POST edileceği SSL'li adres
failUrlstringBaşarısız sonucun POST edileceği SSL'li adres
use3Dbooleantrue = 3D Secure zorunlu; boş bırakılırsa üye işyeri ayarınız uygulanır
transactionTypestringSALES (satış) veya PRESALES (ön provizyon)
rndstringİşlem zamanı — ör. 03-09-2026 15:04:22
hashDatastringSHA-512 + Base64 istek imzası
instalmentsstringTaksit sayısı; 1 = tek çekim, boş bırakılırsa varsayılan taksit ayarlarınız uygulanır
languagestringOrtak ödeme sayfası dili — boş = Türkçe; en (İngilizce), ru (Rusça)
customerKeystringOrtak ödeme sayfası üzerinden kart saklamak için müşteri anahtarı
currencyCodestringPara birimi — boş = TL; USD için 840, EUR için 978
binstringYalnızca belirli BIN'lerden (kartın ilk 6 hanesi) işlem kabul etmek için
cardcampaignstringKart şeması kampanyası — Visa için 4, Mastercard için 5
detailstringtrue gönderilirse ortak ödeme sayfasında müşteriden ek bilgi alınır
secondstringSepetin kalan süresi (saniye) — ödeme sayfasında geri sayım gösterilir
MerchantCustomerNostringTemsilci veya alt üye işyeri numaranız; panelde bu numarayla arama yapabilirsiniz
agentCodestringAlt temsilcilik üzerinden çalışıyorsanız alt temsilcinizin kodu
ECOMM_PLATFORMstringB2B yazılım geliştiriyorsanız platformunuzun adı

Son güncelleme: 10 Eylül 2026

v8 · Versiyonlar