Skip to content

Hash Calculation

Hash is a security mechanism used to ensure the security of API requests. It is used to verify that requests have not been modified and come from an authorized source.

In the Marketplace API, you need to calculate hash for two different operations:

  1. ApiKey calculation for Payment Operations
  2. ApiKey calculation for Cancel/Refund Operations
  • CreatePayment
  • GetStoredCardList
  • Payment Profile services (Create, Get, Update, Delete, List)
  • Seller services (Create, Get, Update, Delete, List)
apiKey = Base64(SHA512(apiSecretKey + "|" + merchantSecretKey))
ParameterDescriptionWhere to Get
apiSecretKeySX valueProvided by Pay N Kolay
merchantSecretKeyMerchant secret keyProvided by Pay N Kolay
const crypto = require('crypto');
function calculatePaymentApiKey(apiSecretKey, merchantSecretKey) {
// String concatenation
const hashString = apiSecretKey + '|' + merchantSecretKey;
// SHA512 hash calculation
const hash = crypto.createHash('sha512').update(hashString, 'utf8').digest();
// Base64 encode
const apiKey = hash.toString('base64');
return apiKey;
}
// Usage
const apiSecretKey = "118591467|bScbGDYCtPf7SS1N6PQ6/+58rFhW1WpsWINqvkJFaJl...";
const merchantSecretKey = "_YckdxUbv4vrnMUZ6VQsr";
const apiKey = calculatePaymentApiKey(apiSecretKey, merchantSecretKey);
console.log("ApiKey:", apiKey);
<?php
function calculatePaymentApiKey($apiSecretKey, $merchantSecretKey) {
// String concatenation
$hashString = $apiSecretKey . '|' . $merchantSecretKey;
// SHA512 hash calculation
$hash = hash('sha512', $hashString, true);
// Base64 encode
$apiKey = base64_encode($hash);
return $apiKey;
}
// Usage
$apiSecretKey = "118591467|bScbGDYCtPf7SS1N6PQ6/+58rFhW1WpsWINqvkJFaJl...";
$merchantSecretKey = "_YckdxUbv4vrnMUZ6VQsr";
$apiKey = calculatePaymentApiKey($apiSecretKey, $merchantSecretKey);
echo "ApiKey: " . $apiKey;
?>
import hashlib
import base64
def calculate_payment_api_key(api_secret_key, merchant_secret_key):
# String concatenation
hash_string = api_secret_key + '|' + merchant_secret_key
# SHA512 hash calculation
hash_bytes = hashlib.sha512(hash_string.encode('utf-8')).digest()
# Base64 encode
api_key = base64.b64encode(hash_bytes).decode('utf-8')
return api_key
# Usage
api_secret_key = "118591467|bScbGDYCtPf7SS1N6PQ6/+58rFhW1WpsWINqvkJFaJl..."
merchant_secret_key = "_YckdxUbv4vrnMUZ6VQsr"
api_key = calculate_payment_api_key(api_secret_key, merchant_secret_key)
print(f"ApiKey: {api_key}")
using System;
using System.Security.Cryptography;
using System.Text;
public class HashCalculator
{
public static string CalculatePaymentApiKey(string apiSecretKey, string merchantSecretKey)
{
// String concatenation
string hashString = apiSecretKey + "|" + merchantSecretKey;
// SHA512 hash calculation
using (SHA512 sha512 = SHA512.Create())
{
byte[] hashBytes = sha512.ComputeHash(Encoding.UTF8.GetBytes(hashString));
// Base64 encode
string apiKey = Convert.ToBase64String(hashBytes);
return apiKey;
}
}
// Usage
public static void Main()
{
string apiSecretKey = "118591467|bScbGDYCtPf7SS1N6PQ6/+58rFhW1WpsWINqvkJFaJl...";
string merchantSecretKey = "_YckdxUbv4vrnMUZ6VQsr";
string apiKey = CalculatePaymentApiKey(apiSecretKey, merchantSecretKey);
Console.WriteLine($"ApiKey: {apiKey}");
}
}

ApiKey Calculation for Cancel/Refund Operations

Section titled “ApiKey Calculation for Cancel/Refund Operations”
  • PaymentRefund
  • PaymentCancel

The same formula is used for cancel and refund operations, but a different apiSecretKey value is used.

apiKey = Base64(SHA512(apiSecretKey_iptal + "|" + merchantSecretKey))
function calculateRefundCancelApiKey(apiSecretKey_iptal, merchantSecretKey) {
const hashString = apiSecretKey_iptal + '|' + merchantSecretKey;
const hash = crypto.createHash('sha512').update(hashString, 'utf8').digest();
const apiKey = hash.toString('base64');
return apiKey;
}
// Usage
const apiSecretKey_iptal = "118591467|bScbGDYC...iptal_sx_degeri...";
const merchantSecretKey = "_YckdxUbv4vrnMUZ6VQsr";
const apiKey = calculateRefundCancelApiKey(apiSecretKey_iptal, merchantSecretKey);
console.log("Refund/Cancel ApiKey:", apiKey);

When a payment transaction is completed, you should perform hash verification to check the validity of the data posted to your callbackUrl address.

expectedHash = Base64(SHA512(
timestamp + "|" +
referenceCode + "|" +
trxCode + "|" +
authAmount + "|" +
responseCode + "|" +
apiSecretKey
))
function verifyCallbackHash(callbackData, apiSecretKey) {
const {
timestamp,
referenceCode,
trxCode,
authAmount,
responseCode,
hash
} = callbackData;
// Create hash string
const hashString = [
timestamp,
referenceCode,
trxCode,
authAmount,
responseCode,
apiSecretKey
].join('|');
// Calculate hash
const calculatedHash = crypto
.createHash('sha512')
.update(hashString, 'utf8')
.digest('base64');
// Compare
return calculatedHash === hash;
}
// Usage
app.post('/payment-callback', (req, res) => {
const callbackData = req.body;
const apiSecretKey = process.env.API_SECRET_KEY;
if (verifyCallbackHash(callbackData, apiSecretKey)) {
// Hash verified, accept the transaction
console.log('Payment verified:', callbackData.trxCode);
// Perform your transaction here
} else {
// Hash verification failed, suspicious request
console.error('Hash verification failed!');
return res.status(400).send('Invalid hash');
}
res.status(200).send('OK');
});
// ❌ WRONG - Don't hardcode in code
const apiSecretKey = "118591467|bScbGDYC...";
// ✅ CORRECT - Use environment variables
const apiSecretKey = process.env.API_SECRET_KEY;
const merchantSecretKey = process.env.MERCHANT_SECRET_KEY;
// ❌ WRONG - Don't use HTTP
const url = "http://api.paynkolay.com.tr/marketplace/v1/payment/create";
// ✅ CORRECT - Only use HTTPS
const url = "https://api.paynkolay.com.tr/marketplace/v1/payment/create";
// Don't cache the hash, recalculate for each request
function createPayment(paymentData) {
// Calculate new hash each time
const apiKey = calculatePaymentApiKey(apiSecretKey, merchantSecretKey);
return fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
...paymentData,
apiKey: apiKey,
apiSecretKey: apiSecretKey
})
});
}
// ALWAYS verify the hash in callbacks
app.post('/callback', (req, res) => {
// ❌ WRONG - Continuing without hash verification
// processPayment(req.body);
// ✅ CORRECT - Verify hash first
if (!verifyCallbackHash(req.body, apiSecretKey)) {
return res.status(400).send('Invalid hash');
}
processPayment(req.body);
res.status(200).send('OK');
});

Example values you can use for hash calculation in the test environment:

apiSecretKey (SX): 118591467|bScbGDYCtPf7SS1N6PQ6/+58rFhW1WpsWINqvkJFaJlu6bMH2tgPKDQtjeA5vClpzJP24uA0vx7OX53cP3SgUspa4EvYix+1C3aXe++8glUvu9Oyyj3v300p5NP7ro/9K57Zcw==
merchantSecretKey: _YckdxUbv4vrnMUZ6VQsr
apiSecretKey (Cancel): 118591467|bScbGDYCtPf7SS1N6PQ6/+58rFhW1WpsWINqvkJFaJlu6bMH2tgPKDQtjeA5vClpzJP24uA0vx7OX53cP3SgUspa4EvYix+1C3aXe++8glUvu9Oyyj3v300p5NP7ro/9K57Zcw==|yDUZaCk6rsoHZJWI3d471A/+TJA7C81X

After learning the hash calculation mechanism:

  1. Creating Payment Profile - Create your first profile
  2. Payment Operations - Start accepting payments
  3. Cancel and Refund Operations - Perform cancel/refund