• Tami Sanal POS

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.

Aşağıda "fixed_kid_value" değeri test ortamı için sabit bir değer iletilmiştir. Üretim ortamında da "fixed_kid_value" değeri için aşağıda iletilen sabit değer ile hesaplama yapabilirsiniz.

Örnek kod parçası:

String FIXED_KID_VALUE = \"00ff6ea8-3511-4d04-946c-ba569208306f\";\n\nprivate 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}

Örnek Kid Değeri:

Merchant Number Terminal Number SecretKey Hesaplanan Kid
77006866 84006869 8e6883ba-e73b-4de2-b58c-aad37d34bc72  nKWRE20dTXl75S/O3KPLRiGVn/EnC4mVl5DHAqONGCTziUxUXK5KprQ2KVMIfFU6DysTjTpKom+nfHiRld7MEA==

2. Adım:

"k" değeri üretilirken merchantNumber - terminalNumber - secretKey - fixed_k_value değeri kullanılır.

String FIXED_K_VALUE = \"87919a8f-957b-427b-ae12-167622ab52b5\";\n\nprivate 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}

Örnek K Değeri:

Merchant Number Terminal Number SecretKey Hesaplanan K Değeri
77006866 84006869  8e6883ba-e73b-4de2-b58c-aad37d34bc72  TgAzw6MiALsdjAcug8BKL73l/deKBj6+ust4bAAFvAk/16iwhLHfnOQB5DmoUY4xYVKuySXzXjtHQFlSsjYE4w==

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}'

Tüm soru ve destek taleplerinde yanındayız.

Soru Sor Soru Sor