DOCS
Panel Giriş Başvurun

Non-3DS

Taksit Bilgisi Size Ait

Kart bilgileriyle tek istekte tahsilat: /Vpos/v1/Payment ucuna use3D=false ile imzalı isteği gönderir, sonucu aynı yanıtın içinde JSON olarak işlersiniz.

Uç Nokta

Test POST https://paynkolaytest.nkolayislem.com.tr/Vpos/v1/Payment

Canlı POST https://paynkolay.nkolayislem.com.tr/Vpos/v1/Payment

Gövde multipart/form-data

Canlı ortama geçerken: canlı uç yalnızca sunucu tarafından yapılan istekleri kabul eder — localhost üzerinden gönderilen istekler güvenlik hatasıyla reddedilir. Bağlantı için en az TLS 1.2 gerekir.

İstek İmzası (hashDatav2)

Alanlar | ile birleştirilir, SHA-512 ile özetlenip Base64'e çevrilir. İmza her zaman sunucu tarafında üretilir:

// customerKey kart saklanmıyorsa boş string olarak hash'e girer
$hashstr = $sx."|".$clientRefCode."|".$amount."|".$successUrl."|".$failUrl."|".$rnd."|".$customerKey."|".$merchantSecretKey;
$hashDatav2 = base64_encode(hash("sha512", $hashstr, true));
const crypto = require('crypto');

// customerKey kart saklanmıyorsa boş string girer — borusu yine de korunur
function hashDatav2(sx, clientRefCode, amount, successUrl, failUrl, rnd, customerKey, merchantSecretKey) {
  const raw = [sx, clientRefCode, amount, successUrl, failUrl, rnd, customerKey, merchantSecretKey].join('|');

  return crypto.createHash('sha512').update(raw, 'utf8').digest('base64');
}

Parametreler

ParametreTipZorunluAçıklama
sxstringSize verilen satış (sx) değeriniz
clientRefCodestringSizin ürettiğiniz referans numarası — her işlem için benzersiz olmalı; 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 = 3DS akışı, false = Non-3DS akışı
cardNumberstringKart numarası
cardHolderNamestringKart üzerindeki isim
month / yearstringSon kullanma ayı (12) ve yılı (2026)
cvvstringKartın güvenlik kodu
installmentNointegerTaksit sayısı; tek çekim için 1
transactionTypestringSALES (satış) veya PRESALES (ön provizyon)
environmentstringAPI gönderilmelidir
currencyNumberstringPara birimi — TL için 949
cardHolderIPstringMüşterinin çıkış IP adresi (IPv4/IPv6)
rndstringİşlem zamanı, Türkiye saatiyle (UTC+3) — ör. 03-09-2026 14:25:11
hashDatav2stringSHA-512 + Base64 istek imzası (yukarıda)
MerchantCustomerNostringTemsilci veya alt üye işyeri numaranız
csCustomerKeystringKart saklanacaksa müşteri anahtarı (TCKN/telefon)
csAutoSavebooleantrue ise ve yetki varsa kart kaydedilir

Örnek İstek

İstek sunucunuzdan tek bir POST ile gider ve sonuç aynı HTTP yanıtında JSON olarak döner. Aşağıdaki form-data isteğinin yanıtı, Yanıt bölümündeki örnektir:

İstek — form-data
# POST https://paynkolaytest.nkolayislem.com.tr/Vpos/v1/Payment (form-data)
sx=118591467|W8a1JLU8A5Cw…FbOO5A==
clientRefCode=SIP-2026-000123
amount=249.90
successUrl=https://magaza.com/odeme/basarili
failUrl=https://magaza.com/odeme/hata
use3D=false
cardNumber=4546711234567894
cardHolderName=Ayşe Yılmaz
month=12  year=2026  cvv=000
installmentNo=1
transactionType=SALES  environment=API  currencyNumber=949
cardHolderIP=85.100.20.15
rnd=03-09-2026 14:25:11
hashDatav2=lunnRyNfDu6pdpNjjlFrlATE4Pj…

Aynı non-3D ödemenin dört dilde çalışır örneği. use3D=false olduğu için sonuç bu yanıtın içinde döner; 3D formu, banka ekranı ve callback yoktur. SX_DEGERINIZ ve SECRET_KEY_DEGERINIZ yerine kendi değerlerinizi yazın.

<?php
// === NON-3D FLOW — Paynkolay V1 ===
// Çalıştırma: php -S localhost:8000 example.php  →  http://localhost:8000
// Not: Canlı uç (https://paynkolay.nkolayislem.com.tr/Vpos/v1/Payment) localhost'tan gelen istekleri reddeder.

date_default_timezone_set('Europe/Istanbul'); // rnd Türkiye saatiyle üretilmeli

$merchantSecretKey = "SECRET_KEY_DEGERINIZ";
$sx                = "SX_DEGERINIZ";
$clientRefCode     = "789456|AB76";                        // her işlemde benzersiz olmalı (ör. "ORDER-" . uniqid())
$amount            = "6.00";
$successUrl        = "https://siteniz.com/payment/success"; // non-3D'de çağrılmaz ama zorunludur ve hash'e girer
$failUrl           = "https://siteniz.com/payment/fail";
$rnd               = date("d-m-Y H:i:s");
$customerKey       = "";                                   // kart saklanmıyorsa boş

// Müşteri IP'si: önce proxy başlıkları, yoksa bağlantı adresi
function getClientIp(): string
{
    foreach (['HTTP_CF_CONNECTING_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_REAL_IP'] as $header) {
        if (!empty($_SERVER[$header])) {
            $ip = trim(explode(',', $_SERVER[$header])[0]);
            if (filter_var($ip, FILTER_VALIDATE_IP)) {
                return $ip;
            }
        }
    }
    return $_SERVER['REMOTE_ADDR'] ?? '127.0.0.1';
}

// Hash: sx|clientRefCode|amount|successUrl|failUrl|rnd|customerKey|secretKey → SHA512 (ham bayt) → Base64
$hashstr    = "$sx|$clientRefCode|$amount|$successUrl|$failUrl|$rnd|$customerKey|$merchantSecretKey";
$hashDataV2 = base64_encode(hash("sha512", $hashstr, true));

$postData = [
    'sx'                 => $sx,
    'clientRefCode'      => $clientRefCode,
    'successUrl'         => $successUrl,
    'failUrl'            => $failUrl,
    'amount'             => $amount,
    'installmentNo'      => '1',
    'cardHolderName'     => 'Tuna Çınar',
    'month'              => '12',
    'year'               => '2026',
    'cvv'                => '001',
    'cardNumber'         => '4546711234567894',
    'use3D'              => 'false',             // ← non-3D'yi belirleyen tek satır
    'transactionType'    => 'SALES',
    'cardHolderIP'       => getClientIp(),
    'hashDatav2'         => $hashDataV2,
    'rnd'                => $rnd,
    'environment'        => 'API',
    'currencyNumber'     => '949',
    'MerchantCustomerNo' => '',                  // opsiyonel: temsilci / alt üye işyeri no
];

// POSTFIELDS dizi olarak verilince istek multipart/form-data gider
$curl = curl_init('https://paynkolaytest.nkolayislem.com.tr/Vpos/v1/Payment');
curl_setopt_array($curl, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_POSTFIELDS     => $postData,
    CURLOPT_TIMEOUT        => 30,
]);
$response = curl_exec($curl);
$error    = curl_error($curl);
curl_close($curl);

header('Content-Type: text/plain; charset=utf-8');

if ($response === false) {
    exit("Bağlantı hatası: " . $error);
}

// === Non-3D'ye özgü kısım: sonuç bu response'ta, form/callback yok ===
$data = json_decode($response, true);

if (isset($data['RESPONSE_CODE']) && $data['RESPONSE_CODE'] == '2') {
    echo "Ödeme başarılı. Referans: " . ($data['REFERENCE_CODE'] ?? '-');
    // Siparişi burada COMPLETED yap — callback bekleme
} else {
    echo "Ödeme başarısız: " . ($data['RESPONSE_DATA'] ?? $response);
}
// Paynkolay Sanal POS V1 — NON-3D ödeme örneği (.NET minimal API)
// Kurulum: dotnet new web -n PaynkolayNon3D → bu dosyayı Program.cs ile değiştirin → dotnet run
// Test: tarayıcıda http://localhost:<port>/odeme (port konsolda yazar)
// Not: Canlı uç localhost'tan gelen istekleri reddeder; canlıda sunucunuzdan çalıştırın.
using System.Globalization;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpClient();
var app = builder.Build();

// Kimlik bilgileri (size verilen değerler)
const string Sx = "SX_DEGERINIZ";
const string MerchantSecretKey = "SECRET_KEY_DEGERINIZ";

// Test ucu — canlı: https://paynkolay.nkolayislem.com.tr/Vpos/v1/Payment
const string ApiUrl = "https://paynkolaytest.nkolayislem.com.tr/Vpos/v1/Payment";

app.MapGet("/odeme", async (HttpContext ctx, IHttpClientFactory httpFactory) =>
{
    // Sipariş ve kart bilgileri (gerçekte ödeme formunuzdan gelir)
    var clientRefCode = "789456|AB76";                     // her işlemde benzersiz olmalı (ör. "ORDER-" + Guid)
    var amount = "6.00";
    var successUrl = "https://siteniz.com/payment/success"; // non-3D'de çağrılmaz ama zorunludur ve hash'e girer
    var failUrl = "https://siteniz.com/payment/fail";
    var customerKey = "";                                  // kart saklanmıyorsa boş

    // rnd: Türkiye saatiyle (UTC+3) dd-MM-yyyy HH:mm:ss
    var rnd = DateTime.UtcNow.AddHours(3).ToString("dd-MM-yyyy HH:mm:ss", CultureInfo.InvariantCulture);

    // hashDatav2: alanlar | ile birleşir → SHA512 (ham bayt) → Base64
    var hashStr = string.Join("|", Sx, clientRefCode, amount, successUrl, failUrl, rnd, customerKey, MerchantSecretKey);
    var hashDatav2 = Convert.ToBase64String(SHA512.HashData(Encoding.UTF8.GetBytes(hashStr)));

    var fields = new Dictionary<string, string>
    {
        ["sx"] = Sx,
        ["clientRefCode"] = clientRefCode,
        ["successUrl"] = successUrl,
        ["failUrl"] = failUrl,
        ["amount"] = amount,
        ["installmentNo"] = "1",
        ["cardHolderName"] = "Tuna Çınar",
        ["month"] = "12",
        ["year"] = "2026",
        ["cvv"] = "001",
        ["cardNumber"] = "4546711234567894",
        ["use3D"] = "false",                 // ← non-3D'yi belirleyen tek satır
        ["transactionType"] = "SALES",
        ["cardHolderIP"] = GetClientIp(ctx),
        ["rnd"] = rnd,
        ["hashDatav2"] = hashDatav2,
        ["environment"] = "API",
        ["currencyNumber"] = "949",
        ["MerchantCustomerNo"] = "",         // opsiyonel: temsilci / alt üye işyeri no
    };

    // Body: multipart/form-data
    using var form = new MultipartFormDataContent();
    foreach (var (key, value) in fields)
    {
        form.Add(new StringContent(value), key);
    }

    var http = httpFactory.CreateClient();
    http.Timeout = TimeSpan.FromSeconds(30);

    string body;
    try
    {
        using var response = await http.PostAsync(ApiUrl, form);
        body = await response.Content.ReadAsStringAsync();
    }
    catch (Exception ex) when (ex is HttpRequestException or TaskCanceledException)
    {
        return Results.Text($"Bağlantı hatası: {ex.Message}", "text/plain; charset=utf-8", statusCode: 502);
    }

    // Non-3D'ye özgü kısım: sonuç bu yanıtta, form/callback yok
    try
    {
        using var json = JsonDocument.Parse(body);
        var root = json.RootElement;

        if (root.TryGetProperty("RESPONSE_CODE", out var code) && code.ToString() == "2")
        {
            // Siparişi burada COMPLETED yap — callback bekleme
            var reference = root.TryGetProperty("REFERENCE_CODE", out var refCode) ? refCode.ToString() : "-";
            return Results.Text($"Ödeme başarılı. Referans: {reference}", "text/plain; charset=utf-8");
        }

        var message = root.TryGetProperty("RESPONSE_DATA", out var data) ? data.ToString() : body;
        return Results.Text($"Ödeme başarısız: {message}", "text/plain; charset=utf-8", statusCode: 400);
    }
    catch (JsonException)
    {
        return Results.Text($"Ödeme başarısız: {body}", "text/plain; charset=utf-8", statusCode: 400);
    }
});

app.Run();

// Müşteri IP'si: önce proxy başlıkları, yoksa bağlantı adresi
static string GetClientIp(HttpContext ctx)
{
    foreach (var header in new[] { "CF-Connecting-IP", "X-Forwarded-For", "X-Real-IP" })
    {
        var value = ctx.Request.Headers[header].ToString();
        if (string.IsNullOrWhiteSpace(value)) continue;

        var ip = value.Split(',')[0].Trim();
        if (IPAddress.TryParse(ip, out _)) return ip;
    }

    var remote = ctx.Connection.RemoteIpAddress;
    if (remote is null) return "127.0.0.1";
    return (remote.IsIPv4MappedToIPv6 ? remote.MapToIPv4() : remote).ToString();
}
# Paynkolay Sanal POS V1 — NON-3D ödeme örneği (Python + requests)
# Kurulum: pip install requests
# Çalıştırma: python3 example.py  →  http://localhost:8000/odeme
# Not: Canlı uç localhost'tan gelen istekleri reddeder; canlıda sunucunuzdan çalıştırın.
import base64
import hashlib
import ipaddress
from datetime import datetime, timedelta, timezone
from http.server import BaseHTTPRequestHandler, HTTPServer

import requests

# Kimlik bilgileri (size verilen değerler)
SX = "SX_DEGERINIZ"
MERCHANT_SECRET_KEY = "SECRET_KEY_DEGERINIZ"

# Test ucu — canlı: https://paynkolay.nkolayislem.com.tr/Vpos/v1/Payment
API_URL = "https://paynkolaytest.nkolayislem.com.tr/Vpos/v1/Payment"


def client_ip(handler):
    """Müşteri IP'si: önce proxy başlıkları, yoksa bağlantı adresi."""
    for header in ("CF-Connecting-IP", "X-Forwarded-For", "X-Real-IP"):
        value = handler.headers.get(header)
        if value:
            ip = value.split(",")[0].strip()
            try:
                ipaddress.ip_address(ip)
                return ip
            except ValueError:
                pass
    return handler.client_address[0]


def pay(card_holder_ip):
    # Sipariş ve kart bilgileri (gerçekte ödeme formunuzdan gelir)
    client_ref_code = "789456|AB76"  # her işlemde benzersiz olmalı (ör. "ORDER-" + uuid)
    amount = "6.00"
    success_url = "https://siteniz.com/payment/success"  # non-3D'de çağrılmaz ama zorunludur ve hash'e girer
    fail_url = "https://siteniz.com/payment/fail"
    customer_key = ""  # kart saklanmıyorsa boş

    # rnd: Türkiye saatiyle (UTC+3) dd-MM-yyyy HH:mm:ss
    rnd = datetime.now(timezone(timedelta(hours=3))).strftime("%d-%m-%Y %H:%M:%S")

    # hashDatav2: alanlar | ile birleşir → SHA512 (ham bayt) → Base64
    hash_str = "|".join([SX, client_ref_code, amount, success_url, fail_url, rnd, customer_key, MERCHANT_SECRET_KEY])
    hash_datav2 = base64.b64encode(hashlib.sha512(hash_str.encode("utf-8")).digest()).decode("ascii")

    fields = {
        "sx": SX,
        "clientRefCode": client_ref_code,
        "successUrl": success_url,
        "failUrl": fail_url,
        "amount": amount,
        "installmentNo": "1",
        "cardHolderName": "Tuna Çınar",
        "month": "12",
        "year": "2026",
        "cvv": "001",
        "cardNumber": "4546711234567894",
        "use3D": "false",  # ← non-3D'yi belirleyen tek satır
        "transactionType": "SALES",
        "cardHolderIP": card_holder_ip,
        "rnd": rnd,
        "hashDatav2": hash_datav2,
        "environment": "API",
        "currencyNumber": "949",
        "MerchantCustomerNo": "",  # opsiyonel: temsilci / alt üye işyeri no
    }

    # files=(None, değer) biçimi isteği multipart/form-data gönderir
    response = requests.post(API_URL, files={k: (None, v) for k, v in fields.items()}, timeout=30)

    # Non-3D'ye özgü kısım: sonuç bu yanıtta, form/callback yok
    try:
        data = response.json()
    except ValueError:
        return False, "Ödeme başarısız: " + response.text

    if str(data.get("RESPONSE_CODE")) == "2":
        # Siparişi burada COMPLETED yap — callback bekleme
        return True, "Ödeme başarılı. Referans: {}".format(data.get("REFERENCE_CODE", "-"))
    return False, "Ödeme başarısız: {}".format(data.get("RESPONSE_DATA") or response.text)


class Handler(BaseHTTPRequestHandler):
    def do_GET(self):
        if self.path != "/odeme":
            return self.reply(404, "Ödeme için /odeme adresini açın.")
        try:
            ok, message = pay(client_ip(self))
            self.reply(200 if ok else 400, message)
        except requests.RequestException as exc:
            self.reply(502, "Bağlantı hatası: {}".format(exc))

    def reply(self, status, text):
        body = text.encode("utf-8")
        self.send_response(status)
        self.send_header("Content-Type", "text/plain; charset=utf-8")
        self.send_header("Content-Length", str(len(body)))
        self.end_headers()
        self.wfile.write(body)


if __name__ == "__main__":
    print("http://localhost:8000/odeme")
    HTTPServer(("0.0.0.0", 8000), Handler).serve_forever()
// Paynkolay Sanal POS V1 — NON-3D ödeme örneği (Node.js + axios + form-data)
// Kurulum: npm install axios form-data
// Çalıştırma: node example.js  →  http://localhost:8000/odeme
// Not: Canlı uç localhost'tan gelen istekleri reddeder; canlıda sunucunuzdan çalıştırın.
const http = require('http');
const net = require('net');
const crypto = require('crypto');
const axios = require('axios');
const FormData = require('form-data');

// Kimlik bilgileri (size verilen değerler)
const SX = 'SX_DEGERINIZ';
const MERCHANT_SECRET_KEY = 'SECRET_KEY_DEGERINIZ';

// Test ucu — canlı: https://paynkolay.nkolayislem.com.tr/Vpos/v1/Payment
const API_URL = 'https://paynkolaytest.nkolayislem.com.tr/Vpos/v1/Payment';

// Müşteri IP'si: önce proxy başlıkları, yoksa bağlantı adresi
function clientIp(req) {
  for (const header of ['cf-connecting-ip', 'x-forwarded-for', 'x-real-ip']) {
    const value = req.headers[header];
    if (value) {
      const ip = String(value).split(',')[0].trim();
      if (net.isIP(ip)) return ip;
    }
  }
  return (req.socket.remoteAddress || '127.0.0.1').replace(/^::ffff:/, '');
}

// rnd: Türkiye saatiyle (UTC+3) dd-MM-yyyy HH:mm:ss
function turkeyTime() {
  const d = new Date(Date.now() + 3 * 60 * 60 * 1000);
  const p = (n) => String(n).padStart(2, '0');
  return `${p(d.getUTCDate())}-${p(d.getUTCMonth() + 1)}-${d.getUTCFullYear()} ` +
    `${p(d.getUTCHours())}:${p(d.getUTCMinutes())}:${p(d.getUTCSeconds())}`;
}

async function pay(cardHolderIP) {
  // Sipariş ve kart bilgileri (gerçekte ödeme formunuzdan gelir)
  const clientRefCode = '789456|AB76';                     // her işlemde benzersiz olmalı (ör. 'ORDER-' + Date.now())
  const amount = '6.00';
  const successUrl = 'https://siteniz.com/payment/success'; // non-3D'de çağrılmaz ama zorunludur ve hash'e girer
  const failUrl = 'https://siteniz.com/payment/fail';
  const customerKey = '';                                  // kart saklanmıyorsa boş
  const rnd = turkeyTime();

  // hashDatav2: alanlar | ile birleşir → SHA512 (ham bayt) → Base64
  const hashStr = [SX, clientRefCode, amount, successUrl, failUrl, rnd, customerKey, MERCHANT_SECRET_KEY].join('|');
  const hashDatav2 = crypto.createHash('sha512').update(hashStr, 'utf8').digest('base64');

  const fields = {
    sx: SX,
    clientRefCode,
    successUrl,
    failUrl,
    amount,
    installmentNo: '1',
    cardHolderName: 'Tuna Çınar',
    month: '12',
    year: '2026',
    cvv: '001',
    cardNumber: '4546711234567894',
    use3D: 'false',              // ← non-3D'yi belirleyen tek satır
    transactionType: 'SALES',
    cardHolderIP,
    rnd,
    hashDatav2,
    environment: 'API',
    currencyNumber: '949',
    MerchantCustomerNo: '',      // opsiyonel: temsilci / alt üye işyeri no
  };

  // Body: multipart/form-data
  const form = new FormData();
  for (const [key, value] of Object.entries(fields)) form.append(key, value);

  const response = await axios.post(API_URL, form, {
    headers: form.getHeaders(),
    timeout: 30000,
    responseType: 'text',
    validateStatus: () => true, // HTTP durum kodundan bağımsız gövdeyi okuyalım
  });
  const body = response.data;

  // Non-3D'ye özgü kısım: sonuç bu yanıtta, form/callback yok
  let data;
  try {
    data = JSON.parse(body);
  } catch {
    return { ok: false, message: `Ödeme başarısız: ${body}` };
  }

  if (String(data.RESPONSE_CODE) === '2') {
    // Siparişi burada COMPLETED yap — callback bekleme
    return { ok: true, message: `Ödeme başarılı. Referans: ${data.REFERENCE_CODE ?? '-'}` };
  }
  return { ok: false, message: `Ödeme başarısız: ${data.RESPONSE_DATA || body}` };
}

http.createServer(async (req, res) => {
  const reply = (status, text) => {
    res.writeHead(status, { 'Content-Type': 'text/plain; charset=utf-8' });
    res.end(text);
  };

  if (req.url !== '/odeme') return reply(404, 'Ödeme için /odeme adresini açın.');

  try {
    const { ok, message } = await pay(clientIp(req));
    reply(ok ? 200 : 400, message);
  } catch (err) {
    reply(502, `Bağlantı hatası: ${err.message}`);
  }
}).listen(8000, () => console.log('http://localhost:8000/odeme'));

Yanıt

Yanıttaki hashDataV2 imzasını doğrulamadan siparişi onaylamayın; başarı kuralları için Altın Kural'a bakın.

Başarılı Yanıt — 200
{
  "RESPONSE_CODE": 2,
  "RESPONSE_DATA": "İşlem Başarılı.",
  "REFERENCE_CODE": "IKSIRPF142277040",
  "CLIENT_REFERENCE_CODE": "SIP-2026-000123",
  "AUTH_CODE": "345344",
  "USE_3D": false,
  "TRANSACTION_AMOUNT": 249.90,
  "INSTALLMENT": 1,
  "RND": "1645700316156",
  "hashDataV2": "lunnRyNfDu6pdpNjjlFrlATE…"
}
Hatalı Yanıt — örnek
{
  "RESPONSE_CODE": 0,
  "RESPONSE_DATA": "Girdiğiniz bilgileri kontrol ediniz."
}

Son güncelleme: 15 Eylül 2026

v1 · Versiyonlar