Esc
Start typing to search...

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 #

ParameterDescriptionWhere to Get
apiSecretKeySX valueProvided by Paynkolay
merchantSecretKeyMerchant secret keyProvided by Paynkolay
trxCodeTransaction tracking number (Client Reference Code)You determine
totalTrxAmountTotal transaction amount (Including Taxes + Commission)Transaction amount
trxCurrencyCurrency (e.g.: TRY)Transaction currency
trxTypeTransaction type (e.g.: SALES)SALES

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))

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/+TJA7C81X

Next Steps #

After learning the hash calculation mechanism: