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