Hash Calculation
What is Hash? #
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:
- ApiKey for Payment Operations calculation
- ApiKey for Cancel/Refund Operations calculation
ApiKey Calculation for Payment Operations #
Used Services #
- CreatePayment
- GetStoredCardList
- Payment Profile servisleri (Create, Get, Update, Delete, List)
- Seller servisleri (Create, Get, Update, Delete, List)
Hash Calculation Formula #
apiKey = Base64(SHA512(apiSecretKey + "|" + merchantSecretKey + "|" + trxCode + "|" + totalTrxAmount + "|" + trxCurrency + "|" + trxType))Parameters #
| Parameter | Description | Where to Get |
|---|---|---|
| apiSecretKey | SX value | Provided by Paynkolay |
| merchantSecretKey | Merchant secret key | Provided by Paynkolay |
| trxCode | Transaction tracking number (Client Reference Code) | You determine |
| totalTrxAmount | Total transaction amount (Including Taxes + Commission) | Transaction amount |
| trxCurrency | Currency (e.g.: TRY) | Transaction currency |
| trxType | Transaction type (e.g.: SALES) | SALES |
warning
Example Codes #
const crypto = require('crypto');
function calculatePaymentApiKey(apiSecretKey, merchantSecretKey, trxCode, totalTrxAmount, trxCurrency, trxType) {
// String birleştirme
const hashString = apiSecretKey + '|' + merchantSecretKey + '|' + trxCode + '|' + totalTrxAmount + '|' + trxCurrency + '|' + trxType;
// SHA512 hash hesaplama
const hash = crypto.createHash('sha512').update(hashString, 'utf8').digest();
// Base64 encode
const apiKey = hash.toString('base64');
return apiKey;
}
// Kullanım
const apiSecretKey = "118591467|bScbGDYCtPf7SS1N6PQ6/+58rFhW1WpsWINqvkJFaJl...";
const merchantSecretKey = "_YckdxUbv4vrnMUZ6VQsr";
const apiKey = calculatePaymentApiKey(apiSecretKey, merchantSecretKey);
console.log("ApiKey:", apiKey);<?php
function calculatePaymentApiKey($apiSecretKey, $merchantSecretKey, $trxCode, $totalTrxAmount, $trxCurrency, $trxType) {
// String birleştirme
$hashString = $apiSecretKey . '|' . $merchantSecretKey . '|' . $trxCode . '|' . $totalTrxAmount . '|' . $trxCurrency . '|' . $trxType;
// SHA512 hash hesaplama
$hash = hash('sha512', $hashString, true);
// Base64 encode
$apiKey = base64_encode($hash);
return $apiKey;
}
// Kullanım
$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, trx_code, total_trx_amount, trx_currency, trx_type):
# String birleştirme
hash_string = api_secret_key + '|' + merchant_secret_key + '|' + trx_code + '|' + total_trx_amount + '|' + trx_currency + '|' + trx_type
# SHA512 hash hesaplama
hash_bytes = hashlib.sha512(hash_string.encode('utf-8')).digest()
# Base64 encode
api_key = base64.b64encode(hash_bytes).decode('utf-8')
return api_key
# Kullanım
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 trxCode, string totalTrxAmount, string trxCurrency, string trxType)
{
// String birleştirme
string hashString = apiSecretKey + "|" + merchantSecretKey + "|" + trxCode + "|" + totalTrxAmount + "|" + trxCurrency + "|" + trxType;
// SHA512 hash hesaplama
using (SHA512 sha512 = SHA512.Create())
{
byte[] hashBytes = sha512.ComputeHash(Encoding.UTF8.GetBytes(hashString));
// Base64 encode
string apiKey = Convert.ToBase64String(hashBytes);
return apiKey;
}
}
// Kullanım
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 #
Used Services #
- PaymentRefund
- PaymentCancel
Hash Calculation Formula #
The same formula is used for cancel and refund operations, but a different apiSecretKey value is used.
apiKey = Base64(SHA512(apiSecretKey_iptal + "|" + merchantSecretKey + "|" + trxType + "|" + trxDate + "|" + amount + "|" + trxCurrency + "|" + referenceCode))warning
Example Code (JavaScript) #
function calculateRefundCancelApiKey(apiSecretKey_iptal, merchantSecretKey, trxType, trxDate, amount, trxCurrency, referenceCode) {
const hashString = apiSecretKey_iptal + '|' + merchantSecretKey + '|' + trxType + '|' + trxDate + '|' + amount + '|' + trxCurrency + '|' + referenceCode;
const hash = crypto.createHash('sha512').update(hashString, 'utf8').digest();
const apiKey = hash.toString('base64');
return apiKey;
}
// Kullanım
const apiSecretKey_iptal = "118591467|bScbGDYC...iptal_sx_degeri...";
const merchantSecretKey = "_YckdxUbv4vrnMUZ6VQsr";
const apiKey = calculateRefundCancelApiKey(apiSecretKey_iptal, merchantSecretKey);
console.log("Refund/Cancel ApiKey:", apiKey);Hash Verification (in Callbacks) #
When a payment transaction is completed, you should perform hash verification to check the validity of the data posted to your callbackUrl address.
Callback Hash Formula #
expectedHash = Base64(SHA512(
apiSecretKey + "|" +
statusCode + "|" +
refCode + "|" +
authCode + "|" +
trxCode + "|" +
commissionRate + "|" +
commissionAmount + "|" +
installment + "|" +
trxAmount + "|" +
authAmount + "|" +
timestamp + "|" +
currencyCode + "|" +
cardType + "|" +
issuerBankCode + "|" +
installmentFeeRate + "|" +
installmentFeeAmount + "|" +
paymentSystem
))Callback Hash Verification Example #
function verifyCallbackHash(callbackData, apiSecretKey) {
const {
statusCode,
refCode,
authCode,
trxCode,
commissionRate,
commissionAmount,
installment,
trxAmount,
authAmount,
timestamp,
currencyCode,
cardType,
issuerBankCode,
installmentFeeRate,
installmentFeeAmount,
paymentSystem,
hash
} = callbackData;
// Hash string oluştur
const hashString = [
apiSecretKey,
statusCode,
refCode,
authCode,
trxCode,
commissionRate,
commissionAmount,
installment,
trxAmount,
authAmount,
timestamp,
currencyCode,
cardType,
issuerBankCode,
installmentFeeRate,
installmentFeeAmount,
paymentSystem
].join('|');
// Hash hesapla
const calculatedHash = crypto
.createHash('sha512')
.update(hashString, 'utf8')
.digest('base64');
// Karşılaştır
return calculatedHash === hash;
}
// Kullanım
app.post('/payment-callback', (req, res) => {
const callbackData = req.body;
const apiSecretKey = process.env.API_SECRET_KEY;
if (verifyCallbackHash(callbackData, apiSecretKey)) {
// Hash doğrulandı, işlemi kabul et
console.log('Ödeme doğrulandı:', callbackData.trxCode);
// İşleminizi burada gerçekleştirin
} else {
// Hash doğrulanamadı, şüpheli istek
console.error('Hash doğrulama başarısız!');
return res.status(400).send('Invalid hash');
}
res.status(200).send('OK');
});Security Best Practices #
1. Store Keys Securely #
// ❌ YANLIŞ - Koda hardcode etmeyin
const apiSecretKey = "118591467|bScbGDYC...";
// ✅ DOĞRU - Environment variables kullanın
const apiSecretKey = process.env.API_SECRET_KEY;
const merchantSecretKey = process.env.MERCHANT_SECRET_KEY;2. Use HTTPS #
// ❌ YANLIŞ - HTTP kullanmayın
const url = "http://api.paynkolay.com.tr/marketplace/v1/payment/create";
// ✅ DOĞRU - Sadece HTTPS kullanın
const url = "https://api.paynkolay.com.tr/marketplace/v1/payment/create";3. Recalculate Hash for Each Request #
// Hash'i cache'lemeyin, her istek için yeniden hesaplayın
function createPayment(paymentData) {
// Her seferinde yeni hash hesapla
const apiKey = calculatePaymentApiKey(apiSecretKey, merchantSecretKey);
return fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
...paymentData,
apiKey: apiKey,
apiSecretKey: apiSecretKey
})
});
}4. Always Verify Callback Hash #
// Callback'lerde gelen hash'i MUTLAKA doğrulayın
app.post('/callback', (req, res) => {
// ❌ YANLIŞ - Hash kontrolü yapmadan işleme devam etmek
// processPayment(req.body);
// ✅ DOĞRU - Önce hash'i doğrula
if (!verifyCallbackHash(req.body, apiSecretKey)) {
return res.status(400).send('Invalid hash');
}
processPayment(req.body);
res.status(200).send('OK');
});Test Environment Values #
Example values you can use for hash calculation in the test environment:
apiSecretKey (SX): 118591467|bScbGDYCtPf7SS1N6PQ6/+58rFhW1WpsWINqvkJFaJlu6bMH2tgPKDQtjeA5vClpzJP24uA0vx7OX53cP3SgUspa4EvYix+1C3aXe++8glUvu9Oyyj3v300p5NP7ro/9K57Zcw==
merchantSecretKey: _YckdxUbv4vrnMUZ6VQsr
apiSecretKey (İptal): 118591467|bScbGDYCtPf7SS1N6PQ6/+58rFhW1WpsWINqvkJFaJlu6bMH2tgPKDQtjeA5vClpzJP24uA0vx7OX53cP3SgUspa4EvYix+1C3aXe++8glUvu9Oyyj3v300p5NP7ro/9K57Zcw==|yDUZaCk6rsoHZJWI3d471A/+TJA7C81XYour specific keys for the production environment will be provided by Paynkolay.
Next Steps #
After learning the hash calculation mechanism:
- 1. Create Payment Profile - Create your first profile
- 2. Payment Operations - Start accepting payments
- 3. Cancel and Refund Operations - Perform cancel/refund