Örnek Form Kullanımı
example.php
<!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|bScbGDYCtPf7SS1N6PQ6/+58rFhW1WpsWINqvkJFaJlu6bMH2tgPKDQtjeA5vClpzJP24uA0vx7OX53cP3SgUspa4EvYix+1C3aXe++8glUvu9Oyyj3v300p5NP7ro/9K57Zcw==";
$merchantSecretKey="_YckdxUbv4vrnMUZ6VQsr"; // size özel - special to you
$successUrl="https://paynkolay.com.tr/test/success";
$failUrl="https://paynkolay.com.tr/test/fail";
$amount="1.00";
$clientRefCode="2352345";
$use3D="true";
$rnd = date("d.m.Y H:i:s");
$agentCode="1236";
$detail="false";
$transactionType="SALES";
$customerKey = "";
$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();
?>
<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="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="submit" value="Gönder" />
</form>
</body>
</html>
using Microsoft.AspNetCore.Mvc.RazorPages;
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;
// Updated Sx value
public string Sx { get; private set; } =
"118591467|bScbGDYCtPf7SS1N6PQ6/+58rFhW1WpsWINqvkJFaJlu6bMH2tgPKDQtjeA5vClpzJP24uA0vx7OX53cP3SgUspa4EvYix+1C3aXe++8glUvu9Oyyj3v300p5NP7ro/9K57Zcw==";
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; } = "1";
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 Rnd { get; private set; } = "";
public string HashDataV2 { get; private set; } = "";
// Renamed property for the client's IP address
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;
// Updated MerchantSecretKey value
var merchantSecretKey = _config["PaynKolay:MerchantSecretKey"] ?? "_YckdxUbv4vrnMUZ6VQsr";
// Call the new, more robust method to get the client's IP address
cardHolderIP = GetClientIpAddress();
Rnd = DateTime.Now.ToString("dd.MM.yyyy H: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>
<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="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" />
<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|bScbGDYCtPf7SS1N6PQ6/+58rFhW1WpsWINqvkJFaJlu6bMH2tgPKDQtjeA5vClpzJP24uA0vx7OX53cP3SgUspa4EvYix+1C3aXe++8glUvu9Oyyj3v300p5NP7ro/9K57Zcw=="
merchant_secret_key = "_YckdxUbv4vrnMUZ6VQsr" # Your unique secret key
success_url = "https://paynkolay.com.tr/test/success"
fail_url = "https://paynkolay.com.tr/test/fail"
amount = "1.00"
client_ref_code = "2352345"
use_3d = "true"
agent_code = "1236"
transaction_type = "SALES"
customer_key = ""
# 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>
<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="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="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 using the new values
const sx = "118591467|bScbGDYCtPf7SS1N6PQ6/+58rFhW1WpsWINqvkJFaJlu6bMH2tgPKDQtjeA5vClpzJP24uA0vx7OX53cP3SgUspa4EvYix+1C3aXe++8glUvu9Oyyj3v300p5NP7ro/9K57Zcw==";
const merchantSecretKey = "_YckdxUbv4vrnMUZ6VQsr"; // Your unique secret key
const successUrl = "https://paynkolay.com.tr/test/success";
const failUrl = "https://paynkolay.com.tr/test/fail";
const amount = "1.00";
const clientRefCode = "2352345";
const use3D = "true";
const agentCode = "1236";
const transactionType = "SALES";
const customerKey = "";
// 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,
cardHolderIP, // Added IP here
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>
<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="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="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`);
});
Test Ortamı #
Entegrasyonunuzu test etmek için aşağıdaki test sayfasını kullanabilirsiniz: