Esc
Aramaya başlamak için yazın...

API Dokümanı - Taksit Bilgisi Paynkolay'a Ait

Bu API'nin kullanımında önce taksitler çağırılır. Taksitleri çağırmak için sx, amount, cardNumber, hosturl, iscardvalid değişkenleri "https://paynkolaytest.nkolayislem.com.tr/Vpos/Payment/PaymentInstallments" adresine Body'de form-data olarak POST edilir.

Sadece BIN numarası ile (kartın ilk 8 hanesi ile) taksit sorgulamak için iscardvalid parametresi "false" olarak gönderilmeli, ya da hiç gönderilmemelidir.

image

PaymentInstallments servisinden gelen EncodedValue tutar bilgisi AUTHORIZATION_AMOUNT ve taksit bilgisi INSTALLMENT diğer değişkenlerle birlikte Payment Servis'ine Body'de form-data olarak POST edilir. (EncodedValue, installmentNo, amount, sx, clientRefCode, successUrl, failUrl, amount, installmentNo, cardHolderName, month, year, cvv, cardNumber, EncodedValue, use3D, transactionType, hosturl, rnd, hashData, environment).

  • Payment Servis linki: "https://paynkolaytest.nkolayislem.com.tr/Vpos/Payment/Payment" İlgili tüm değişkenleri Postman collection'ından görebilirsiniz.
image
  • İşlem 3D değilse bu aşamada ödeme alınır. İşlem sonlanır.

Response Dönüş Parametreleri Payment servisine POST edildiğinde, 3D true ise 3D formu gelecektir. Bu formu şu şekilde ekranda çalıştırabilirsiniz:

example.php
<?php

// --- Helper Function ---
function getClientIpAddress(): string
{
    $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])) {
            $ipList = explode(',', $_SERVER[$header]);
            $ip = trim($ipList[0]);
            if (filter_var($ip, FILTER_VALIDATE_IP)) {
                return $ip;
            }
        }
    }
    return 'UNKNOWN';
}

// --- Configuration & Data Preparation ---

// 1. Credentials & URLs
$sx = "118591467|bScbGDYCtPf7SS1N6PQ6/+58rFhW1WpsWINqvkJFaJlu6bMH2tgPKDQtjeA5vClpzJP24uA0vx7OX53cP3SgUspa4EvYix+1C3aXe++8glUvu9Oyyj3v300p5NP7ro/9K57Zcw==";
$merchantSecretKey = "_YckdxUbv4vrnMUZ6VQsr";
$customerKey = "";
$successUrl = "https://paynkolay.com.tr/test/success";
$failUrl = "https://paynkolay.com.tr/test/fail";

// 2. Transaction Data
$amount = "6.00";
$clientRefCode = "789456|AB76";
$rnd = date("d-m-Y H:i:s");
$cardHolderIP = getClientIpAddress();
$merchantCustomerNo="1234567890";

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

// --- Step 1: Query Installments ---

$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => 'https://paynkolaytest.nkolayislem.com.tr/Vpos/Payment/PaymentInstallments',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => '',
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 0,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_POSTFIELDS => array(
        'sx' => $sx,
        'amount' => $amount,
        'cardNumber' => '4546711234567894',
        'hosturl' => 'https://yoursite.com',
        'iscardvalid' => 'false'
    ),
));

$response = curl_exec($curl);
$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);

$encodedValue = null;
$selectedInstallmentCount = null;

if ($httpCode == 200) {
    $installmentData = json_decode($response, true);

    // CHANGED: Access the first item in the PAYMENT_BANK_LIST array
    // We use [0] to get the first installment option ("Tek Çekim" / Installment: 1)
    $firstOption = $installmentData['PAYMENT_BANK_LIST'][0] ?? null;

    if ($firstOption) {
        $encodedValue = $firstOption['EncodedValue'] ?? null;
        $selectedInstallmentCount = $firstOption['INSTALLMENT'] ?? '1'; // Default to 1 if missing
    } else {
        echo "Error: PAYMENT_BANK_LIST is empty or invalid.\n";
    }

} else {
    echo "Error retrieving installments. HTTP Code: $httpCode. Response: " . htmlspecialchars($response) . "\n";
}

// --- Step 2: Make Payment ---

if (isset($encodedValue)) {
    $paymentCurl = curl_init();

    curl_setopt_array($paymentCurl, array(
        CURLOPT_URL => 'https://paynkolaytest.nkolayislem.com.tr/Vpos/Payment/Payment',
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_ENCODING => '',
        CURLOPT_MAXREDIRS => 10,
        CURLOPT_TIMEOUT => 0,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
        CURLOPT_CUSTOMREQUEST => 'POST',
        CURLOPT_POSTFIELDS => array(
            'EncodedValue' => $encodedValue,
            'installmentNo' => $selectedInstallmentCount, // Dynamically set from the selected option
            'amount' => $amount,
            'sx' => $sx,
            'clientRefCode' => $clientRefCode,
            'successUrl' => $successUrl,
            'failUrl' => $failUrl,
            'cardHolderName' => 'John Doe',
            'month' => '12',
            'year' => '2026',
            'cvv' => '123',
            'cardNumber' => '4546711234567894',
            'use3D' => 'true',
            'transactionType' => 'SALES',
            'cardHolderIP' => $cardHolderIP,
            'rnd' => $rnd,
            'hashDatav2' => $hashDataV2,
            'environment' => 'API',
            'merchantCustomerNo' => $merchantCustomerNo
        ),
    ));

    $paymentResponse = curl_exec($paymentCurl);
    $paymentHttpCode = curl_getinfo($paymentCurl, CURLINFO_HTTP_CODE);
    curl_close($paymentCurl);

    if ($paymentHttpCode == 200) {
        // Decode JSON response
        $json = json_decode($paymentResponse, true);
        if (isset($json['BANK_REQUEST_MESSAGE'])) {
            echo $json['BANK_REQUEST_MESSAGE'];
        } else {
            echo "BANK_REQUEST_MESSAGE not found in response.\n";
        }
    } else {
        echo "Error in payment. HTTP Code: $paymentHttpCode. Response: " . htmlspecialchars($paymentResponse) . "\n";
    }
}
?>
using Microsoft.AspNetCore.Mvc;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Net; // Required for IPAddress

namespace dotNET_apiv0.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class PaymentController : ControllerBase
    {
        private readonly IHttpClientFactory _httpClientFactory;

        public PaymentController(IHttpClientFactory httpClientFactory)
        {
            _httpClientFactory = httpClientFactory;
        }

        [HttpGet("process")]
        public async Task<IActionResult> ProcessPayment()
        {
            // --- Helper: Get IP Address using your custom method ---
            string clientIp = GetClientIpAddress();

            // --- Configuration ---
            string sx = "118591467|bScbGDYCtPf7SS1N6PQ6/+58rFhW1WpsWINqvkJFaJlu6bMH2tgPKDQtjeA5vClpzJP24uA0vx7OX53cP3SgUspa4EvYix+1C3aXe++8glUvu9Oyyj3v300p5NP7ro/9K57Zcw==";
            string merchantSecretKey = "_YckdxUbv4vrnMUZ6VQsr";
            string customerKey = "";
            string successUrl = "https://paynkolay.com.tr/test/success";
            string failUrl = "https://paynkolay.com.tr/test/fail";

            // --- Transaction Data ---
            string amount = "6.00";
            string clientRefCode = "789456|AB76";
            string rnd = DateTime.Now.ToString("dd-MM-yyyy HH:mm:ss");
            string merchantCustomerNo = "1234567890";

            // --- Hash Calculation ---
            string hashStr = $"{sx}|{clientRefCode}|{amount}|{successUrl}|{failUrl}|{rnd}|{customerKey}|{merchantSecretKey}";
            string hashDataV2;

            using (SHA512 sha512 = SHA512.Create())
            {
                byte[] bytes = Encoding.UTF8.GetBytes(hashStr);
                byte[] hashBytes = sha512.ComputeHash(bytes);
                hashDataV2 = Convert.ToBase64String(hashBytes);
            }

            // Create HTTP Client
            var client = _httpClientFactory.CreateClient();

            // --- Step 1: Query Installments ---
            var installmentContent = new MultipartFormDataContent
            {
                { new StringContent(sx), "sx" },
                { new StringContent(amount), "amount" },
                { new StringContent("4546711234567894"), "cardNumber" },
                { new StringContent("https://yoursite.com"), "hosturl" },
                { new StringContent("false"), "iscardvalid" }
            };

            var installmentRes = await client.PostAsync("https://paynkolaytest.nkolayislem.com.tr/Vpos/Payment/PaymentInstallments", installmentContent);
            string installmentBody = await installmentRes.Content.ReadAsStringAsync();

            string? encodedValue = null;
            string selectedInstallmentCount = "1";

            if (installmentRes.IsSuccessStatusCode)
            {
                var jsonNode = JsonNode.Parse(installmentBody);
                var paymentBankList = jsonNode?["PAYMENT_BANK_LIST"]?.AsArray();
                var firstOption = paymentBankList?.FirstOrDefault();

                if (firstOption != null)
                {
                    var encodedNode = firstOption["EncodedValue"];
                    if (encodedNode != null && encodedNode.GetValueKind() != JsonValueKind.Null)
                    {
                        encodedValue = encodedNode.GetValue<string>();
                    }

                    var installmentNode = firstOption["INSTALLMENT"];
                    if (installmentNode != null && installmentNode.GetValueKind() != JsonValueKind.Null)
                    {
                        selectedInstallmentCount = installmentNode.ToString();
                    }
                }
                else
                {
                    return Content("Error: PAYMENT_BANK_LIST is empty or invalid.", "text/plain");
                }
            }
            else
            {
                return Content($"Error retrieving installments. HTTP Code: {installmentRes.StatusCode}. Response: {installmentBody}", "text/plain");
            }

            // --- Step 2: Make Payment ---
            if (!string.IsNullOrEmpty(encodedValue))
            {
                var paymentContent = new MultipartFormDataContent
                {
                    { new StringContent(encodedValue), "EncodedValue" },
                    { new StringContent(selectedInstallmentCount), "installmentNo" },
                    { new StringContent(amount), "amount" },
                    { new StringContent(sx), "sx" },
                    { new StringContent(clientRefCode), "clientRefCode" },
                    { new StringContent(successUrl), "successUrl" },
                    { new StringContent(failUrl), "failUrl" },
                    { new StringContent("Tuna Çınar"), "cardHolderName" },
                    { new StringContent("12"), "month" },
                    { new StringContent("2026"), "year" },
                    { new StringContent("000"), "cvv" },
                    { new StringContent("4546711234567894"), "cardNumber" },
                    { new StringContent("true"), "use3D" },
                    { new StringContent("SALES"), "transactionType" },
                    { new StringContent(clientIp), "cardHolderIP" }, // Uses the new helper method result
                    { new StringContent(rnd), "rnd" },
                    { new StringContent(hashDataV2), "hashDatav2" },
                    { new StringContent("API"), "environment" },
                    { new StringContent(merchantCustomerNo), "merchantCustomerNo" }
                };

                var paymentRes = await client.PostAsync("https://paynkolaytest.nkolayislem.com.tr/Vpos/Payment/Payment", paymentContent);
                string paymentBody = await paymentRes.Content.ReadAsStringAsync();

                if (paymentRes.IsSuccessStatusCode)
                {
                    var paymentJson = JsonNode.Parse(paymentBody);
                    string? bankMessage = paymentJson?["BANK_REQUEST_MESSAGE"]?.ToString();

                    if (!string.IsNullOrEmpty(bankMessage))
                    {
                        return Content(bankMessage, "text/html", Encoding.UTF8);
                    }

                    return Content($"BANK_REQUEST_MESSAGE not found. Full Response: {paymentBody}", "text/plain");
                }

                return Content($"Error in payment. HTTP Code: {paymentRes.StatusCode}. Response: {paymentBody}", "text/plain");
            }

            return Content("EncodedValue could not be retrieved from the bank (it was null). Payment step skipped.", "text/plain");
        }

        /// <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()
        {
            var headers = new[]
            {
                "Client-IP",
                "X-Forwarded-For",
                "X-Forwarded",
                "X-Cluster-Client-IP",
                "Forwarded-For",
                "Forwarded"
            };

            foreach (var header in headers)
            {
                var ipHeaderValue = HttpContext.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 = HttpContext.Connection.RemoteIpAddress;
            if (remoteIp != null)
            {
                // Map to IPv4 to ensure format like 127.0.0.1 instead of ::ffff:127.0.0.1
                return remoteIp.MapToIPv4().ToString();
            }

            return "UNKNOWN";
        }
    }
}
import requests
import json
import time

def main():
    # Step 1: Query Installments
    installment_url = "https://paynkolaytest.nkolayislem.com.tr/Vpos/Payment/PaymentInstallments"

    installment_data = {
        'sx': '118591467|bScbGDYCtPf7SS1N6PQ6/+58rFhW1WpsWINqvkJFaJlu6bMH2tgPKDQtjeA5vClpzJP24uA0vx7OX53cP3SgUspa4EvYix+1C3aXe++8glUvu9Oyyj3v300p5NP7ro/9K57Zcw==',
        'amount': '6.00',
        'cardNumber': '4546711234567894',
        'hosturl': 'https://yoursite.com',
        'iscardvalid': 'false'  # Use false to query with BIN only
    }

    try:
        installment_response = requests.post(installment_url, data=installment_data)

        if installment_response.status_code == 200:
            installment_result = installment_response.json()
            encoded_value = installment_result['EncodedValue']
            print("Installments retrieved successfully")
            print(f"EncodedValue: {encoded_value}")

            # Step 2: Make Payment with EncodedValue
            payment_url = "https://paynkolaytest.nkolayislem.com.tr/Vpos/Payment/Payment"

            payment_data = {
                'EncodedValue': encoded_value,
                'installmentNo': '2',
                'amount': '6.00',
                'sx': '118591467|bScbGDYCtPf7SS1N6PQ6/+58rFhW1WpsWINqvkJFaJlu6bMH2tgPKDQtjeA5vClpzJP24uA0vx7OX53cP3SgUspa4EvYix+1C3aXe++8glUvu9Oyyj3v300p5NP7ro/9K57Zcw==',
                'clientRefCode': '789456|AB76',
                'successUrl': 'https://paynkolay.com.tr/test/success',
                'failUrl': 'https://paynkolay.com.tr/test/fail',
                'cardHolderName': 'John Doe',
                'month': '12',
                'year': '2026',
                'cvv': '123',
                'cardNumber': '4546711234567894',
                'use3D': 'true',
                'transactionType': 'SALES',
                'cardHolderIP': '185.125.190.58',
                'rnd': str(int(time.time())),  # Random value for security
                'hashDatav2': 'VM9LfJtJTjUesvqq9HQqCkuD6fYn+mhrn0WV5UCPU30VcI4BYRPzbhOs3EBDTCuwvndVsAEsqLFEClqZ3SbbIw==',
                'environment': 'TEST'
            }

            payment_response = requests.post(payment_url, data=payment_data)

            if payment_response.status_code == 200:
                print("Payment request sent successfully")
                print(f"Response: {payment_response.text}")

                # If use3D is true, the response will contain HTML form for 3D secure
                if '<form' in payment_response.text:
                    print("3D Secure form received. Display this form to user:")
                    with open('3d_form.html', 'w', encoding='utf-8') as f:
                        f.write(payment_response.text)
            else:
                print(f"Error in payment: {payment_response.text}")

        else:
            print(f"Error retrieving installments: {installment_response.text}")

    except requests.exceptions.RequestException as e:
        print(f"Request exception: {e}")
    except json.JSONDecodeError as e:
        print(f"JSON decode error: {e}")
    except Exception as e:
        print(f"Exception: {e}")

if __name__ == "__main__":
    main()
const axios = require('axios');
const qs = require('querystring');
const fs = require('fs');

async function main() {
    try {
        // Step 1: Query Installments
        const installmentUrl = 'https://paynkolaytest.nkolayislem.com.tr/Vpos/Payment/PaymentInstallments';

        const installmentData = {
            'sx': '118591467|bScbGDYCtPf7SS1N6PQ6/+58rFhW1WpsWINqvkJFaJlu6bMH2tgPKDQtjeA5vClpzJP24uA0vx7OX53cP3SgUspa4EvYix+1C3aXe++8glUvu9Oyyj3v300p5NP7ro/9K57Zcw==',
            'amount': '6.00',
            'cardNumber': '4546711234567894',
            'hosturl': 'https://yoursite.com',
            'iscardvalid': 'false' // Use false to query with BIN only
        };

        const installmentResponse = await axios.post(installmentUrl, qs.stringify(installmentData), {
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded'
            }
        });

        if (installmentResponse.status === 200) {
            const installmentResult = installmentResponse.data;
            const encodedValue = installmentResult.EncodedValue;
            console.log('Installments retrieved successfully');
            console.log(`EncodedValue: ${encodedValue}`);

            // Step 2: Make Payment with EncodedValue
            const paymentUrl = 'https://paynkolaytest.nkolayislem.com.tr/Vpos/Payment/Payment';

            const paymentData = {
                'EncodedValue': encodedValue,
                'installmentNo': '2',
                'amount': '6.00',
                'sx': '118591467|bScbGDYCtPf7SS1N6PQ6/+58rFhW1WpsWINqvkJFaJlu6bMH2tgPKDQtjeA5vClpzJP24uA0vx7OX53cP3SgUspa4EvYix+1C3aXe++8glUvu9Oyyj3v300p5NP7ro/9K57Zcw==',
                'clientRefCode': '789456|AB76',
                'successUrl': 'https://paynkolay.com.tr/test/success',
                'failUrl': 'https://paynkolay.com.tr/test/fail',
                'cardHolderName': 'John Doe',
                'month': '12',
                'year': '2026',
                'cvv': '123',
                'cardNumber': '4546711234567894',
                'use3D': 'true',
                'transactionType': 'SALES',
                'cardHolderIP': '185.125.190.58',
                'rnd': Math.floor(Date.now() / 1000).toString(), // Random value for security
                'hashDatav2': 'VM9LfJtJTjUesvqq9HQqCkuD6fYn+mhrn0WV5UCPU30VcI4BYRPzbhOs3EBDTCuwvndVsAEsqLFEClqZ3SbbIw==',
                'environment': 'TEST'
            };

            const paymentResponse = await axios.post(paymentUrl, qs.stringify(paymentData), {
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded'
                }
            });

            if (paymentResponse.status === 200) {
                console.log('Payment request sent successfully');
                console.log(`Response: ${paymentResponse.data}`);

                // If use3D is true, the response will contain HTML form for 3D secure
                if (paymentResponse.data.includes('<form')) {
                    console.log('3D Secure form received. Display this form to user:');
                    fs.writeFileSync('3d_form.html', paymentResponse.data);
                }
            } else {
                console.log(`Error in payment: ${paymentResponse.data}`);
            }

        } else {
            console.log(`Error retrieving installments: ${installmentResponse.data}`);
        }

    } catch (error) {
        if (error.response) {
            console.log(`HTTP Error ${error.response.status}: ${error.response.data}`);
        } else {
            console.log(`Exception: ${error.message}`);
        }
    }
}

main();
image
  • Gelen 3D formu ekrana basıldığında ilgili bankanın 3D secure penceresi açılır ve burada 3D secure şifresi girilmesi beklenir.
3D Secure Window