Esc
Start typing to search...

API Documentation - Installment Information Belongs to You

There are 2 types of Paynkolay APIs. You can create your own payment form structure with these APIs. #

Merchants use their own payment forms with APIs.

Click to download Postman collection.

You can see example codes in Postman Code snippet.

Paynkolay API (Version 1) #

This is the version to use if you want to get installments from your own installment tables.

  • In this version, all variables are POSTed as form-data in the Body to "https://paynkolaytest.nkolayislem.com.tr/Vpos/v1/Payment" address. (sx, clientRefCode, successUrl, failUrl, amount, installmentNo, cardHolderName, month, year, cvv, cardNumber, use3D, transactionType, rnd, hashData, environment, currencyNumber)
  • Production environment link: https://paynkolay.nkolayislem.com.tr/Vpos/v1/Payment
  • You need to send requests to the production environment from your server. Requests sent from localhost give security errors.
  • Click for hash calculation.
Paynkolay API v1
  • Payment Service test environment link: "https://paynkolaytest.nkolayislem.com.tr/Vpos/v1/Payment" You can see all relevant variables from the Postman collection.
  • If the transaction is not 3D, payment is received and response parameters are returned to your successURL page.
  • If use3D is "true", a 3D form will come. You can run this form on screen as follows.
Paynkolay API v1 Response
example.php
<?php

// 1. Secure your keys (These should ideally be in constants or config)
$merchantSecretKey = "_YckdxUbv4vrnMUZ6VQsr";
$sx = "118591467|bScbGDYCtPf7SS1N6PQ6/+58rFhW1WpsWINqvkJFaJlu6bMH2tgPKDQtjeA5vClpzJP24uA0vx7OX53cP3SgUspa4EvYix+1C3aXe++8glUvu9Oyyj3v300p5NP7ro/9K57Zcw==";

// 2. Prepare variables
$clientRefCode = "APP000000000017|82343"; // Unique reference
$amount = "10.00";
$successUrl = "https://paynkolay.com.tr/biz/success";
$failUrl = "https://paynkolay.com.tr/biz/fail";
$rnd = date("d-m-Y H:i:s");
$customerKey = "";
$merchantCustomerNo = "CUST0001";

// 3. Generate Hash
$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);

/**
*  IP detection
*/
function getClientIpAddress(): string {
    $headers = ['HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'REMOTE_ADDR'];
    foreach ($headers as $header) {
        if (!empty($_SERVER[$header])) {
            $ipList = explode(',', $_SERVER[$header]);
            $ip = trim($ipList[0]);
            if (filter_var($ip, FILTER_VALIDATE_IP)) return $ip;
        }
    }
    return '127.0.0.1';
}

$cardHolderIP = getClientIpAddress();

// 4. API Request
$postData = [
    'sx' => $sx,
    'clientRefCode' => $clientRefCode,
    'successUrl' => $successUrl,
    'failUrl' => $failUrl,
    'amount' => $amount,
    'installmentNo' => '1',
    'cardHolderName' => 'Tuna Cinar',
    'month' => '12',
    'year' => '2026',
    'cvv' => '001',
    'cardNumber' => '4546711234567894',
    'use3D' => 'true',
    'transactionType' => 'SALES',
    'cardHolderIP' => $cardHolderIP,
    'hashDatav2' => $hashDataV2,
    'rnd' => $rnd,
    'environment' => 'API',
    'currencyNumber' => '949',
    'MerchantCustomerNo' => $merchantCustomerNo
];

$curl = curl_init();
curl_setopt_array($curl, [
    CURLOPT_URL => 'https://paynkolaytest.nkolayislem.com.tr/Vpos/v1/Payment',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => http_build_query($postData), // Cleaner than passing raw array
    CURLOPT_TIMEOUT => 30,
]);

$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);

if ($err) {
    echo "cURL Error #:" . htmlspecialchars($err);
} else {
    $data = json_decode($response, true);

    // 5.  BANK_REQUEST_MESSAGE Output
    echo $bankMessage = $data['BANK_REQUEST_MESSAGE'] ?? 'No message returned';

}
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
using System.Net;
using System.Linq;

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

app.MapGet("/", async (HttpContext context) =>
{
    try
    {
        // 1. CONFIGURATION
        string customerKey = "";
        string merchantSecretKey = "_YckdxUbv4vrnMUZ6VQsr";

        string sx = "118591467|bScbGDYCtPf7SS1N6PQ6/+58rFhW1WpsWINqvkJFaJlu6bMH2tgPKDQtjeA5vClpzJP24uA0vx7OX53cP3SgUspa4EvYix+1C3aXe++8glUvu9Oyyj3v300p5NP7ro/9K57Zcw==";
        string clientRefCode = "789456|AB76";
        string amount = "6.00";
        string successUrl = "https://paynkolay.com.tr/test/success";
        string failUrl = "https://paynkolay.com.tr/test/fail";

        // UPDATE: Ensure we use Turkey Time (UTC+3) regardless of Docker's clock
        // If DateTime.Now (UTC) works, you can keep your old line.
        // But this is safer for Turkish banks:
        string rnd = DateTime.UtcNow.AddHours(3).ToString("dd-MM-yyyy HH:mm:ss");

        string merchantCustomerNo = "MS-34345";

        // 2. GET DYNAMIC IP
        string detectedIp = GetClientIpAddress(context);

        // 3. CALCULATE HASH
        string rawData = $"{sx}|{clientRefCode}|{amount}|{successUrl}|{failUrl}|{rnd}|{customerKey}|{merchantSecretKey}";

        string hashDatav2 = "";
        using (var sha512 = SHA512.Create())
        {
            byte[] bytes = sha512.ComputeHash(Encoding.UTF8.GetBytes(rawData));
            hashDatav2 = Convert.ToBase64String(bytes);
        }

        // 4. PREPARE REQUEST
        using var client = new HttpClient();
        using var request = new HttpRequestMessage(HttpMethod.Post, "https://paynkolaytest.nkolayislem.com.tr/Vpos/v1/Payment");

        var content = new MultipartFormDataContent();
        content.Add(new StringContent(sx), "sx");
        content.Add(new StringContent(clientRefCode), "clientRefCode");
        content.Add(new StringContent(successUrl), "successUrl");
        content.Add(new StringContent(failUrl), "failUrl");
        content.Add(new StringContent(amount), "amount");
        content.Add(new StringContent(rnd), "rnd");
        content.Add(new StringContent(hashDatav2), "hashDatav2");
        content.Add(new StringContent(merchantCustomerNo), "MerchantCustomerNo");

        // We add the IP here only once
        content.Add(new StringContent(detectedIp), "cardHolderIP");

        content.Add(new StringContent("2"), "installmentNo");
        content.Add(new StringContent("Tuna Çınar"), "cardHolderName");
        content.Add(new StringContent("12"), "month");
        content.Add(new StringContent("2026"), "year");
        content.Add(new StringContent("001"), "cvv");
        content.Add(new StringContent("4546711234567894"), "cardNumber");
        content.Add(new StringContent("true"), "use3D");
        content.Add(new StringContent("SALES"), "transactionType");
        content.Add(new StringContent("API"), "environment");
        content.Add(new StringContent("949"), "currencyNumber");

        request.Content = content;

        // 5. SEND REQUEST
        var response = await client.SendAsync(request);
        string jsonString = await response.Content.ReadAsStringAsync();

        // 6. EXTRACT AND CLEAN HTML
        using (JsonDocument doc = JsonDocument.Parse(jsonString))
        {
            if (doc.RootElement.TryGetProperty("BANK_REQUEST_MESSAGE", out JsonElement htmlElement))
            {
                string rawHtml = htmlElement.GetString() ?? "";
                string cleanHtml = CleanHtml(rawHtml);
                return Results.Content(cleanHtml, "text/html");
            }
            else
            {
                return Results.Content(jsonString, "application/json");
            }
        }
    }
    catch (Exception ex)
    {
        return Results.Problem($"Error: {ex.Message}");
    }
});

app.Run();

// --- HELPER FUNCTIONS ---
string CleanHtml(string input)
{
    if (string.IsNullOrEmpty(input)) return input;
    return input
        .Replace("\\r", "")
        .Replace("\\n", "")
        .Replace("\r", "")
        .Replace("\n", "")
        .Replace("\\\"", "\"")
        .Trim();
}

string GetClientIpAddress(HttpContext context)
{
    var headers = new[] { "Client-IP", "X-Forwarded-For", "X-Forwarded", "X-Cluster-Client-IP", "Forwarded-For", "Forwarded" };
    foreach (var header in headers)
    {
        var ipHeaderValue = context.Request.Headers[header].FirstOrDefault();
        if (!string.IsNullOrEmpty(ipHeaderValue))
        {
            var ipList = ipHeaderValue.Split(',').Select(ip => ip.Trim());
            var firstIp = ipList.FirstOrDefault();
            if (firstIp != null && IPAddress.TryParse(firstIp, out _)) return firstIp;
        }
    }
    var remoteIp = context.Connection.RemoteIpAddress;
    return remoteIp != null ? remoteIp.MapToIPv4().ToString() : "UNKNOWN";
}
import http.client
from codecs import encode

conn = http.client.HTTPSConnection("paynkolaytest.nkolayislem.com.tr")
dataList = []
boundary = 'wL36Yn8afVp8Ag7AmP8qZ0SA4n1v9T'
dataList.append(encode('--' + boundary))
dataList.append(encode('Content-Disposition: form-data; name=sx;'))

dataList.append(encode('Content-Type: {}'.format('text/plain')))
dataList.append(encode(''))

dataList.append(encode("118591467|bScbGDYCtPf7SS1N6PQ6/+58rFhW1WpsWINqvkJFaJlu6bMH2tgPKDQtjeA5vClpzJP24uA0vx7OX53cP3SgUspa4EvYix+1C3aXe++8glUvu9Oyyj3v300p5NP7ro/9K57Zcw=="))
dataList.append(encode('--' + boundary))
dataList.append(encode('Content-Disposition: form-data; name=clientRefCode;'))

dataList.append(encode('Content-Type: {}'.format('text/plain')))
dataList.append(encode(''))

dataList.append(encode("789456|AB76"))
dataList.append(encode('--' + boundary))
dataList.append(encode('Content-Disposition: form-data; name=successUrl;'))

dataList.append(encode('Content-Type: {}'.format('text/plain')))
dataList.append(encode(''))

dataList.append(encode("https://paynkolay.com.tr/test/success"))
dataList.append(encode('--' + boundary))
dataList.append(encode('Content-Disposition: form-data; name=failUrl;'))

dataList.append(encode('Content-Type: {}'.format('text/plain')))
dataList.append(encode(''))

dataList.append(encode("https://paynkolay.com.tr/test/fail"))
dataList.append(encode('--' + boundary))
dataList.append(encode('Content-Disposition: form-data; name=amount;'))

dataList.append(encode('Content-Type: {}'.format('text/plain')))
dataList.append(encode(''))

dataList.append(encode("6.00"))
dataList.append(encode('--' + boundary))
dataList.append(encode('Content-Disposition: form-data; name=installmentNo;'))

dataList.append(encode('Content-Type: {}'.format('text/plain')))
dataList.append(encode(''))

dataList.append(encode("2"))
dataList.append(encode('--' + boundary))
dataList.append(encode('Content-Disposition: form-data; name=cardHolderName;'))

dataList.append(encode('Content-Type: {}'.format('text/plain')))
dataList.append(encode(''))

dataList.append(encode("Tuna Çınar"))
dataList.append(encode('--' + boundary))
dataList.append(encode('Content-Disposition: form-data; name=month;'))

dataList.append(encode('Content-Type: {}'.format('text/plain')))
dataList.append(encode(''))

dataList.append(encode("12"))
dataList.append(encode('--' + boundary))
dataList.append(encode('Content-Disposition: form-data; name=year;'))

dataList.append(encode('Content-Type: {}'.format('text/plain')))
dataList.append(encode(''))

dataList.append(encode("2026"))
dataList.append(encode('--' + boundary))
dataList.append(encode('Content-Disposition: form-data; name=cvv;'))

dataList.append(encode('Content-Type: {}'.format('text/plain')))
dataList.append(encode(''))

dataList.append(encode("001"))
dataList.append(encode('--' + boundary))
dataList.append(encode('Content-Disposition: form-data; name=cardNumber;'))

dataList.append(encode('Content-Type: {}'.format('text/plain')))
dataList.append(encode(''))

dataList.append(encode("4546711234567894"))
dataList.append(encode('--' + boundary))
dataList.append(encode('Content-Disposition: form-data; name=use3D;'))

dataList.append(encode('Content-Type: {}'.format('text/plain')))
dataList.append(encode(''))

dataList.append(encode("true"))
dataList.append(encode('--' + boundary))
dataList.append(encode('Content-Disposition: form-data; name=transactionType;'))

dataList.append(encode('Content-Type: {}'.format('text/plain')))
dataList.append(encode(''))

dataList.append(encode("SALES"))
dataList.append(encode('--' + boundary))
dataList.append(encode('Content-Disposition: form-data; name=cardHolderIP;'))

dataList.append(encode('Content-Type: {}'.format('text/plain')))
dataList.append(encode(''))

dataList.append(encode("185.125.190.58"))
dataList.append(encode('--' + boundary))
dataList.append(encode('Content-Disposition: form-data; name=rnd;'))

dataList.append(encode('Content-Type: {}'.format('text/plain')))
dataList.append(encode(''))

dataList.append(encode("09-10-2025 15:24:22"))
dataList.append(encode('--' + boundary))
dataList.append(encode('Content-Disposition: form-data; name=hashDatav2;'))

dataList.append(encode('Content-Type: {}'.format('text/plain')))
dataList.append(encode(''))

dataList.append(encode("VM9LfJtJTjUesvqq9HQqCkuD6fYn+mhrn0WV5UCPU30VcI4BYRPzbhOs3EBDTCuwvndVsAEsqLFEClqZ3SbbIw=="))
dataList.append(encode('--' + boundary))
dataList.append(encode('Content-Disposition: form-data; name=environment;'))

dataList.append(encode('Content-Type: {}'.format('text/plain')))
dataList.append(encode(''))

dataList.append(encode("API"))
dataList.append(encode('--' + boundary))
dataList.append(encode('Content-Disposition: form-data; name=currencyNumber;'))

dataList.append(encode('Content-Type: {}'.format('text/plain')))
dataList.append(encode(''))

dataList.append(encode("949"))
dataList.append(encode('--'+boundary+'--'))
dataList.append(encode(''))
body = b'\r\n'.join(dataList)
payload = body
headers = {
   'Content-type': 'multipart/form-data; boundary={}'.format(boundary)
}
conn.request("POST", "/Vpos/v1/Payment", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
const axios = require('axios');
const FormData = require('form-data');
let data = new FormData();
data.append('sx', '118591467|bScbGDYCtPf7SS1N6PQ6/+58rFhW1WpsWINqvkJFaJlu6bMH2tgPKDQtjeA5vClpzJP24uA0vx7OX53cP3SgUspa4EvYix+1C3aXe++8glUvu9Oyyj3v300p5NP7ro/9K57Zcw==');
data.append('clientRefCode', '789456|AB76');
data.append('successUrl', 'https://paynkolay.com.tr/test/success');
data.append('failUrl', 'https://paynkolay.com.tr/test/fail');
data.append('amount', '6.00');
data.append('installmentNo', '2');
data.append('cardHolderName', 'Tuna Çınar');
data.append('month', '12');
data.append('year', '2026');
data.append('cvv', '001');
data.append('cardNumber', '4546711234567894');
data.append('use3D', 'true');
data.append('transactionType', 'SALES');
data.append('cardHolderIP', '185.125.190.58');
data.append('rnd', '09-10-2025 15:24:22');
data.append('hashDatav2', 'VM9LfJtJTjUesvqq9HQqCkuD6fYn+mhrn0WV5UCPU30VcI4BYRPzbhOs3EBDTCuwvndVsAEsqLFEClqZ3SbbIw==');
data.append('environment', 'API');
data.append('currencyNumber', '949');
let config = {
  method: 'post',
  maxBodyLength: Infinity,
  url: 'https://paynkolaytest.nkolayislem.com.tr/Vpos/v1/Payment',
  headers: {
    ...data.getHeaders()
  },
  data : data
};
axios.request(config)
.then((response) => {
  console.log(JSON.stringify(response.data));
})
.catch((error) => {
  console.log(error);
});

When the incoming 3D form is printed on the screen, the relevant bank's 3D secure window opens and it is expected to enter the 3D secure password here.

3D Secure Window