Security Hash Oluşturma
Servislere iletilen request body ler JWK dosyası ile imzalanıp token üretilerek, securtyHash input alanında gönderilmesi beklenmektedir. Aşağıdaki veriler test ortamındaki bir işyerine göre hesaplanarak gösterilmiştir.
Test/prod ortamında farklı bir işyerinden deneme yapmak istediğinizde hesaplamaları uygun verilerle yaparak ilerleyebilirsiniz.
JWK Dosyası örneği:
{\n \"kty\": \"oct\", // sabit değer kullanılır\n \"use\": \"sig\", // sabit değer kullanılır\n \"kid\": \"kid-value\", //aşağıdaki algoritma ile hesaplanır\n \"k\": \"k-value\", //aşağıdaki algoritma ile hesaplanır\n \"alg\": \"HS512\" //sabit değer kullanılır\n}
Jwk dosyası içerisinde bulunan “kid” ve “k” değerleri unique değerlerdir.
1. Adım:
“Kid” değeri üretilirken işyerlerine sağlanan "secretKey" değeri ve "fixed_kid_value" değeri kullanılır.
Test ve Üretim ortamında kullanılacak olan "Fixed_kid_value" değeri için Soru Sor kısmından Tami Destek ile iletişime geçiniz.
Örnek kod parçası:
private String generateKidValue(String secretKey) {\n byte[] result = null;\n try {\n MessageDigest digest = MessageDigest.getInstance(SHA512);\n String input = secretKey + FIXED_KID_VALUE;\n result = digest.digest(input.getBytes(StandardCharsets.UTF_8));\n } catch (NoSuchAlgorithmException e) {\n log.error(\"Kid cannot be generated\", e);\n }\n return DatatypeConverter.printBase64Binary(result);\n}
2. Adım:
"k" değeri üretilirken merchantNumber - terminalNumber - secretKey - fixed_k_value değeri kullanılır.
Test ve Üretim ortamında kullanılacak olan "Fixed_k_value" değeri için Soru Sor kısmından Tami Destek ile İletişime geçiniz.
Örnek kod parçası:
private String generateKValue(Long merchantNumber, Long terminalNumber, String secretKey) {\n byte[] result = null;\n try {\n MessageDigest digest = MessageDigest.getInstance(SHA512);\n String input = secretKey + FIXED_K_VALUE + merchantNumber + terminalNumber;\n result = digest.digest(input.getBytes(StandardCharsets.UTF_8));\n } catch (NoSuchAlgorithmException e) {\n log.error(\"K cannot be generated\", e);\n }\n return DatatypeConverter.printBase64Binary(result);\n}
3. Adım:
Üretilen “k” ve “kid” değerleri jwk dosyasındaki alanlara setlenir ve request body imzalanırken kullanılır. Yapılmak istenen işlem için uygun request body kullanılmalıdır.
Not: securityHash değeri oluşturulurken body içerisindeki securityHash değeri hesaba katılmamalıdır.
public String generateJWKSignature(\n Long merchantNumber, Long terminalNumber, String secretKey, String input)\n throws ParseException, JOSEException {\n\n JWKResource jwkResource = getJWKResource(merchantNumber, terminalNumber, secretKey);\n JWK jwk = JWK.parse(new Gson().toJson(jwkResource));\n JWSObject jws = new JWSObject(\n new JWSHeader.Builder(JWSAlgorithm.HS512)\n .keyID(jwk.getKeyID())\n .type(JOSEObjectType.JWT)\n .build(),\n new Payload(input));\n jws.sign(new MACSigner(jwk.toOctetSequenceKey()));\n return jws.serialize();\n}\n\nprivate JWKResource getJWKResource(Long merchantNumber, Long terminalNumber, String secretKey) {\n JWKResource jwkResourceTmp = new JWKResource();\n jwkResourceTmp.setKty(\"oct\");\n jwkResourceTmp.setUse(\"sig\");\n jwkResourceTmp.setAlg(\"HS512\");\n jwkResourceTmp.setKid(generateKidValue(secretKey));\n jwkResourceTmp.setK(generateKValue(merchantNumber, terminalNumber, secretKey));\n return jwkResourceTmp;\n}
4. Adım:
Oluşturulan hash servislerin body requestinde istenen securityHash alanında beslenir.
Tüm servislere istek atılırken Headers kısmında;
- "PG-Api-Version" parametresi "v2" değeri ile gönderilmelidir.
- "PG-Auth-Token" parametresi iletilmelidir. Bu parametre "merchantNumber:terminalNumber:hash" değerlerinden oluşur.
- correlationId parametresi her işlem için unique değerle iletilmelidir.
5. Örnek request :
{\n \"amount\": 30,\n \"orderId\": \"tamitest08\",\n \"currency\": \"TRY\",\n \"installmentCount\": 1,\n \"card\": {\n \"holderName\": \"Ad Soyad\",\n \"cvv\": \"\",\n \"expireMonth\": 4,\n \"expireYear\": 2026,\n \"number\": \"4824910501747014\"\n },\n \"buyer\": {\n \"ipAddress\": \"12.55.77.8\",\n \"surName\": \"Soyisim\",\n \"name\": \"Soyisim\",\n \"emailAddress\": \"email@email.com\",\n \"buyerId\": \"78494949\",\n \"phoneNumber\": \"5346484700\"\n },\n \"paymentGroup\": \"PRODUCT\",\n \"securityHash\": \"eyJraWQiOiJuS1dSRTIwZFRYbDc1Uy9PM0tQTFJpR1ZuL0VuQzRtVmw1REhBcU9OR0NUemlVeFVYSzVLcHJRMktWTUlmRlU2RHlzVGpUcEtvbStuZkhpUmxkN01FQT09IiwidHlwIjoiSldUIiwiYWxnIjoiSFM1MTIifQ.ewogICJhbW91bnQiOiAzMCwKICAib3JkZXJJZCI6ICJ0YW1pdGVzdDA4IiwKICAiY3VycmVuY3kiOiAiVFJZIiwKICAiaW5zdGFsbG1lbnRDb3VudCI6IDEsCiAgImNhcmQiOiB7CiAgICAiaG9sZGVyTmFtZSI6ICJBZCBTb3lhZCIsCiAgICAiY3Z2IjogIiIsCiAgICAiZXhwaXJlTW9udGgiOiA0LAogICAgImV4cGlyZVllYXIiOiAyMDI2LAogICAgIm51bWJlciI6ICI0ODI0OTEwNTAxNzQ3MDE0IgogIH0sCiAgImJ1eWVyIjogewogICAgImlwQWRkcmVzcyI6ICIxMi41NS43Ny44IiwKICAgICJzdXJOYW1lIjogIlNveWlzaW0iLAogICAgIm5hbWUiOiAiU295aXNpbSIsCiAgICAiZW1haWxBZGRyZXNzIjogImVtYWlsQGVtYWlsLmNvbSIsCiAgICAiYnV5ZXJJZCI6ICI3ODQ5NDk0OSIsCiAgICAicGhvbmVOdW1iZXIiOiAiNTM0NjQ4NDcwMCIKICB9LAogICJwYXltZW50R3JvdXAiOiAiUFJPRFVDVCIKfQ.z_KRDnDxgFJtafIe9Jk45VA31-6rjTVQtZSfF8Tz3C2HJ5oeNYj6YyHBfq7M7MwkZ_tpEBAVkpQBoCiT6HMSmA\"\n}
Örnek curl komutu:
curl --location 'https://sandbox-paymentapi.tami.com.tr/payment/auth' \\\n--header 'Accept-Language: tr' \\\n--header 'correlationId: correlation0a46293f-44ac-4fdc-984d-0c291772a4a4' \\\n--header 'PG-Auth-Token: 77006866:84006869:ZFBhgSvnJ62QuX1x/siUxeTR9uDwAPdiJNgIiqcV6E4=' \\\n--header 'PG-Api-Version: v2' \\\n--header 'Content-Type: application/json' \\\n--data-raw '{\n\"amount\": 30,\n\"orderId\": \"tamitest08\",\n\"currency\": \"TRY\",\n\"installmentCount\": 1,\n\"card\": {\n\"holderName\": \"Ad Soyad\",\n\"cvv\": \"\",\n\"expireMonth\": 4,\n\"expireYear\": 2026,\n\"number\": \"4824910501747014\"\n},\n\"buyer\": {\n\"ipAddress\": \"12.55.77.8\",\n\"surName\": \"Soyisim\",\n\"name\": \"Soyisim\",\n\"emailAddress\": \"email@email.com\",\n\"buyerId\": \"78494949\",\n\"phoneNumber\": \"5346484700\"\n},\n\"paymentGroup\": \"PRODUCT\",\n\"securityHash\": \"eyJraWQiOiJuS1dSRTIwZFRYbDc1Uy9PM0tQTFJpR1ZuL0VuQzRtVmw1REhBcU9OR0NUemlVeFVYSzVLcHJRMktWTUlmRlU2RHlzVGpUcEtvbStuZkhpUmxkN01FQT09IiwidHlwIjoiSldUIiwiYWxnIjoiSFM1MTIifQ.ewogICJhbW91bnQiOiAzMCwKICAib3JkZXJJZCI6ICJ0YW1pdGVzdDA4IiwKICAiY3VycmVuY3kiOiAiVFJZIiwKICAiaW5zdGFsbG1lbnRDb3VudCI6IDEsCiAgImNhcmQiOiB7CiAgICAiaG9sZGVyTmFtZSI6ICJBZCBTb3lhZCIsCiAgICAiY3Z2IjogIiIsCiAgICAiZXhwaXJlTW9udGgiOiA0LAogICAgImV4cGlyZVllYXIiOiAyMDI2LAogICAgIm51bWJlciI6ICI0ODI0OTEwNTAxNzQ3MDE0IgogIH0sCiAgImJ1eWVyIjogewogICAgImlwQWRkcmVzcyI6ICIxMi41NS43Ny44IiwKICAgICJzdXJOYW1lIjogIlNveWlzaW0iLAogICAgIm5hbWUiOiAiU295aXNpbSIsCiAgICAiZW1haWxBZGRyZXNzIjogImVtYWlsQGVtYWlsLmNvbSIsCiAgICAiYnV5ZXJJZCI6ICI3ODQ5NDk0OSIsCiAgICAicGhvbmVOdW1iZXIiOiAiNTM0NjQ4NDcwMCIKICB9LAogICJwYXltZW50R3JvdXAiOiAiUFJPRFVDVCIKfQ.z_KRDnDxgFJtafIe9Jk45VA31-6rjTVQtZSfF8Tz3C2HJ5oeNYj6YyHBfq7M7MwkZ_tpEBAVkpQBoCiT6HMSmA\"\n}'
Kod Örnekleri
Aşağıda, çeşitli yazılım dilleri kullanılarak yazılmış özel kod örneklerinin linkleri verilmiştir. Tercih ettiğiniz programlama diline ait link üzerinden, önceden belirlenmiş değerlerle yazılmış olan kodları detaylı bir şekilde inceleyebilirsiniz.
Bu örnekler, ilgili işlem tipini içeren kodları içermektedir ve farklı dillerde yazıldığı için çeşitli yaklaşımları ve pratikleri de gözlemleyebilirsiniz. Bu sayede tercih ettiğiniz programlama diline dair daha iyi anlaşılır ve özgün örneklerle çalışma imkanı bulabilirsiniz.
C# Kod Örnekleri için tıklayınız.
VB.Net Kod Örnekleri için tıklayınız.
Java Kod Örnekleri için tıklayınız.
PHP Kod Örnekleri için tıklayınız.
NodeJS Kod Örnekleri için tıklayınız.
Unutmayın ki bu örnekler ön tanımlı değerlerle yazılmıştır ve gerçek projelerde kullanımı için gerekli uyarlama ve güvenlik önlemleri almanız gerekebilir.