Security Hash Generation
The request bodies transmitted to the services are signed with JWK file, token is generated and expected to be sent in the securtyHash input field. The following data is calculated and shown according to a workplace in the test environment.
When you want to experiment from a different workplace in a test/prod environment, you can proceed by making calculations with appropriate data.
JWK File example:
{\n \"kty\": \"oct\", // fixed value used\n \"use\": \"sig\", // fixed value used\n \"kid\": \"kid-value\", // is calculated with the following algorithm\n \"k\": \"k-value\", // is calculated with the following algorithm\n \"alg\": \"HS512\" // fixed value used\n}
The “kid” and “k” values in the jwk file are unique values.
1. Step:
While generating “Kid” value, “secretKey” value and “fixed_kid_value” value provided to workplaces are used.
Below “fixed_kid_value” value is transmitted as a fixed value for the test environment. In the production environment, you can calculate the "fixed_kid_value" value with the fixed value given below.
Example code fragment:
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}
Sample Kid Value:
Merchant Number |
Terminal Number |
SecretKey |
Caclulated Kid |
77006866 |
84006869 |
8e6883ba-e73b-4de2-b58c-aad37d34bc72 |
nKWRE20dTXl75S/O3KPLRiGVn/EnC4mVl5DHAqONGCTziUxUXK5KprQ2KVMIfFU6DysTjTpKom+nfHiRld7MEA== |
2. Step:
When generating the “k” value, merchantNumber - terminalNumber - secretKey - fixed_k_value is used.
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}
Sample K Value:
Merchant Number |
Terminal Number |
SecretKey |
Caclulated K Value |
77006866 |
84006869 |
8e6883ba-e73b-4de2-b58c-aad37d34bc72 |
TgAzw6MiALsdjAcug8BKL73l/deKBj6+ust4bAAFvAk/16iwhLHfnOQB5DmoUY4xYVKuySXzXjtHQFlSsjYE4w== |
3. Step:
The generated “k” and “kid” values are set to the fields in the jwk file and used when signing the request body. The appropriate request body must be used for the operation to be performed.
Note: When creating the securityHash value, the securityHash value in the body should not be taken into account.
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. Step:
The generated hash is fed in the securityHash field requested in the body request of the services.
In the Headers section when requesting all services;
- The “PG-Api-Version” parameter must be sent with the value “v2”.
- The “PG-Auth-Token” parameter must be passed. This parameter consists of “merchantNumber:terminalNumber:hash” values.
- The correlationId parameter must be passed with a unique value for each transaction.
5. Example 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}
Example curl command:
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}'
Code Examples
Below are links to custom code examples written in various programming languages. You can examine in detail the code written in your preferred programming language with predefined values.
These examples contain code for the relevant type of operation and since they are written in different languages, you can observe various approaches and practices. In this way, you can find the opportunity to work with better understandable and unique examples of your preferred programming language.
Click for C# Code Examples.
Click for VB.Net Code Examples.
Click for Java Code Examples.
Click for PHP Code Examples.
Please note that these examples are written with predefined values and may require adaptation and security measures for use in real projects.