Security

Every data modification request sent by merchant to Klix and every Klix widget order parameters should be signed by merchant private key and validated on Klix side by merchant public key.

Transport-Level Security

All communication is going via HTTPS TLS 1.2 protocol.

Certificates

Private and public key pairs are issued by Klix PKI (Public Key Infrastructure) server. It is possible to generate a new RSA 2048 key pair in Merchant Console -> Certificates page. When clicking “GENERATE NEW CERTIFICATE” private key is downloaded to user machine, and public key is kept in Klix database.

alt_text

Merchant RSA Key Pair generation guidelines:

  • Each key pair is assigned a unique identifier in Klix database.
  • Merchant private key is not stored in Klix and its responsibility of merchant to keep it secure.
  • Key could be revoked by the merchant or Klix admin at any time.
  • Multiple keys could be active at the same time. Widget attribute certificate-name helps to identify which key is used to sign particular order.
  • Default Key expiration time is 2 calendar years. This is defined on PKI policies level.
  • Notifications about key status changes (as well as expiration reminders) is sent to merchant email address.

Requests sent from Klix to merchant defined callback URL are also signed digitally using Klix private key and validated using public key, which is available in Merchant Console.

Storing private key

Do not share your private key with anyone.

Signing order

In order for Klix server to be able to verify a payment request origin Klix widget order parameters must be signed by merchant. Note that if your webshop is written in PHP you can use Klix PHP library to sign orders therefore following section can be skipped.

Signature generation

Order signature is generated by concatenating order fields into single string and applying SHA256 hash function and RSA encryption to it. Order signature = Base64Encode(SHA256withRSA(signature-input)), where signature-input is calculated in a following way. Generate signature Note that all blank fields should be replaced with empty strings, all amount fields should be formatted with 2 decimals using dot as a decimal point and without thousand separator (e.g. if amount is 1025 then it should be formatted as 1025.00), count field should be formatted with 3 decimals (e.g. 2 should be formatted as 2.000).

Examples

Following private key is used in all examples. Note that you can obtain your merchant private key in Klix Merchant Console.

Expand to see a private key
-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDAom+89QBxPCJz
lQP+PtVsJrdl7wJq2Nj2crBDyNyZjIZcCaf7CCLRD43VCwsFjGSGoWhYDwbWAWzy
ryi6bwcaXdWg8p/pHoWTP3sHluVaHQx6fh3xHsb2qgSE320JtvEYJC3k0RwQyt7j
MEhN79Dizxj2fsMl9nv2fe1/8WwEudtaJl2o+iEQvhz9p2XR106AOU8+DesOt/1X
9wGmQKpxffOLbq0WpYzXw7U5R41Zk9atusRi+CP5FAhKvdRQu9zv18vU2Mv2CdHl
Dxe/Z+dpm3iFbBFKVPRMFHzBE4tYQ49YfHrxTob6rHbv1MoyGW01FgVhW989Caq2
Sa60iV4XAgMBAAECggEAYG7w0P81gXpBJOtsXFLINKQNG5JS+3oi4vz3EHf1N0kJ
2flbhmfERjQrJIOquNRXXq5etfaPzYJZMARPt0TtoV1oHHJZazJEXDpjNKFtn3b7
UDbidlqZ79GdAYd35m0WtKcn8mxcSGvGuKTrDVkIkQJr1LoQp2iFFhhkVLBfCt3A
W13MeCq4fcu5CHj7ZHExpgTkyO+o4cKCU+XqBMiN0xl2yt8BeFVpyuK0bxMs8yjb
budT5mhA+pQYYLblS/S+ONYFhQZdvwyCUDcpmDwQc5oUCyJISPvT618cAL9/WfWU
YhDjPZ1LDkiGcP6KWyEp4TCupMOCDQ6KoKdbfEdHAQKBgQD13sE1E5327ZnuqmYD
4c+zD4c3duXi9ZqoD/ZYV9XwiER2XnMKMbDDztaPiBZVd5gy60I7uLXs/7elQ02D
zla+vIew44ZgZUFuNnVCooT5MEGIrI6lyZEy7wOiMSSQsw60wbsDAqWqNZm63wbf
fizIpvc3ELxXXDfqfgBpM1GJJwKBgQDIkjG4/E2dXhlUDxKozwi+5y/61Ir1jBKg
c7KF5BbO61o/J7GxUcUDtf4Rw9wqaYWrcIycyIB0wGQKuWomadi1uM3m63x44cqQ
RzcwUZckiQv465rpct/exXoq5xy8JdLMi9pVjGaAKtvDy1moVVMqf44704JTYBjK
pqLRPkc5kQKBgFBh3SSvHyvFjlfa2bNXNgJCh2B4vLuwtDlRzqYfQVB8HHXedxnU
GQhLLRaL1VFn4hhzlZnUz5WGHNIo6MS4xt9g37PTDvGg6P1RTJDWdUbKogI+9/v3
pELUpYl3K48rGxm5ZJydVvAIyhOwKp0SsS2AeL5F+G1PNvCw9Q1vu65tAoGAGeNc
zZ6rOfOqW0Iyy10lqNZYSAzk/rqcsN8eHNAK7ZxNIrex5MxEHK2B5LMeGM9T9IPr
clUi1275urSh8eFZmmMHGJYuk7+5EJRQmEj/tDSIOhHXBejQ4oUktqLr/5D2O3aV
sNMVa9ecVBJMOUECIgsixbAQM0jFCmslutJKCTECgYA+SCrepQmwfQF47I+wVHDf
81Hvh3/WqeFaaXt12kvEk2DDdG9PYvEuqtEFalvH/5LcsWDiknA1zdo9pXLIg95N
SY5hDphsXnZLaYS9V9uaW7RCC4VpWELxoVG13mtGDnteAIgoxwWIQ6TfhidFpVtM
2KcJhf0hnLkFQW0qEMn0vg==
-----END PRIVATE KEY-----

Example No 1: Klix Pay widget with single order item

Consider Klix widget for following order should be placed in merchant webshop:

<klix-checkout widget-id="21ca7904-ff16-48b5-918d-c2d80af81f05"  
    amount="5.45"  
    currency="EUR"  
    order-id="12345678"  
    label="Order No 12345678"  
    language="lv"
    back-to-merchant-url="https://example.com/shopping-cart"
    signature="n0b7Sj0qEVlU52kNctEHR9zUZ9pRtPjA/5/avPSQamx7HiI3q6qijgstBw6KhOKZqcCIL3RULbWNu6xoSGnNtW/nx+RcSd12I0st21Los9MXXPakEIjIto+2Zx0+ZiVoa97dxO8/iGF5A1U4qW9GFhPJGPqQecmZSp7rYaiO+VRq5D9KqKqRpBQEYN9YJgDgWMn36KVYkTdlOYAhJslwkVeKKZ+/ifUqHhiXbPKD3VKAXwx7/MqSiRlfU8Qsm7Vcv/zV05X9trZiaSYOL6yd9aWO/KE2so2hAswY58i6dR218/XD6ab5xTpCSXrfjYbfhInchukvlH7CrbE1T3RcWw==">
</klix-checkout>

Steps to calculate a signature:

  1. Calculate signature input string. Input string = CONCAT(widget ID, language, back to merchant URL, amount, currency, label) = 21ca7904-ff16-48b5-918d-c2d80af81f05lvhttps://example.com/shopping-cart123456785.45EUROrder No 12345678. Note that fields without a value e.g. certificate name, success URL, unit, count are not included in signature input string.

  2. Calculate signature using private key previously downloaded from Klix Merchant Console and applying SHA256withRSA and Base64Encode functions to calculated input string. Signature = Base64Encode(SHA256withRSA(signature-input)) = Base64Encode(SHA256withRSA("21ca7904-ff16-48b5-918d-c2d80af81f05lvhttps://example.com/shopping-cart123456785.45EUROrder No 12345678")).

Calculated signature which should be passed to Klix widget as a signature attribute value in this example: ebSnfsTOV2v0zwXxk8YVYjH6iYTfkYA+tn+ove9I+0Zi3lgQ+Mhc6sNJJlhqaSa6hqODZJKGGOCy/d2sqB86dIcJd2M3wB1MqHtVTNadCR+V3gHi+ORTcAQmX/c7crU0lLiKwfHSvaE7FlZUG9cU8ErcZfWDAJEtOMWncMl/yIeec1kPwb302mFzZUsXkVi8/VPp70k9oIh+vPvew/vVTGhoS2ClnFx4heezp1BNXYxZZsFoSgYFP555tNsHYi4GY6DOIx0qrUtmRrWCrt8HjWV7hBFPDNOQnQ05vALLcWtzWdDtGIo5a46HrlW2biCXW3R6K9jW/FxhsEVvwT7fDQ==.

Example No 2: Klix Checkout widget with multiple order items and order delivery

Consider Klix widget for following order should be placed in merchant webshop:

<klix-checkout widget-id="8c597447-5234-4de1-ab85-b54e252098ce" 
    language="lv"
    order="{&quot;items&quot;: [{&quot;orderItemId&quot;: &quot;12345&quot;, &quot;amount&quot;: 88, &quot;taxRate&quot;: 0.21, &quot;currency&quot;: &quot;EUR&quot;, &quot;label&quot;: &quot;Vacuum cleaner TP-3&quot;}, {&quot;amount&quot;: 9.39, &quot;currency&quot;: &quot;EUR&quot;, &quot;label&quot;: &quot;TP-3 HEPA filter&quot;,&quot;count&quot;: 2, &quot;unit&quot;: &quot;PIECE&quot;}], &quot;shippingOptions&quot;: [{&quot;id&quot;:&quot;omniva&quot;,&quot;amount&quot;:2,&quot;currency&quot;:&quot;EUR&quot;,&quot;taxRate&quot;: 0.21},  {&quot;id&quot;:&quot;courier&quot;,&quot;amount&quot;:0}]}"
    signature="DJNg/BEiWk6+9CR/wD6P2gbK1+LtAtB0wuqZEelc3tj22/8uVgiTLJ1bj6/H5AhMIiIzI7mIDAFTSc5l+BHZPM7Z/BAXU6mLrbqQUQ6apKmNcjDIDL+NQnZEVb3PCcLRO+IR5tRJLnTcJXVYBDwLlYfvK7INFLwz/4pvklGQOa/ZSHdMLsR5aHLpvfgm6gTlMszV63k8NxCgFghN6B6xdftcdQPskzEYXdpqn+++40bbYv3hReA1zaOCDupjrJirYcNP3P+f6V7t1MLkQqX2pqh3TJEkorrJH/0e1WMbHUdQY6NiJcsMN56qEntdQI6GiUQVNtwOj8sH9kMMdgdjbg==">
</klix-checkout>

Note that character " values are escaped in a JSON document passed as order attribute value.

Expand to see an unescaped and formatted order attribute value
{
    "items":[
        {
            "orderItemId":"12345",
            "amount":88,
            "taxRate":0.21,
            "currency":"EUR",
            "label":"Vacuum cleaner TP-3",
        },
        {
            "amount":9.39,
            "currency":"EUR",
            "label":"TP-3 HEPA filter",
            "count":2,
            "unit":"PIECE"
        }
    ],
    "shippingOptions":[
        {
            "id":"omniva",
            "amount":2,
            "currency":"EUR",
            "taxRate":0.21
        },
        {
            "id":"courier",
            "amount":0
        }
    ]
}

Steps to calculate a signature:

  1. Calculate signature input string. Input string = CONCAT(widget ID, language, first order item amount, first order item currency, first order item label, first order item tax rate, first order item id, second order item amount, second order item currency, second order item label, second order item count, second order item unit, first shipping option id, first shipping option amount, first shipping option currency, second shipping option id, second shipping option amount) = 8c597447-5234-4de1-ab85-b54e252098celv88.00EURVacuum cleaner TP-30.21123459.39EURTP-3 HEPA filter2PIECEomniva2.00EURcourier0.00. Note that fields without a value are not included in signature input string.

  2. Calculate signature using private key previously downloaded from Klix Merchant Console and applying SHA256withRSA and Base64Encode functions to calculated input string. Signature = Base64Encode(SHA256withRSA(signature-input)) = Base64Encode(SHA256withRSA("8c597447-5234-4de1-ab85-b54e252098celv88.00EURVacuum cleaner TP-30.21123459.39EURTP-3 HEPA filter2PIECEomniva2.00EURcourier0.00")).

Calculated signature which should be passed to Klix widget as a signature attribute value in this example: DJNg/BEiWk6+9CR/wD6P2gbK1+LtAtB0wuqZEelc3tj22/8uVgiTLJ1bj6/H5AhMIiIzI7mIDAFTSc5l+BHZPM7Z/BAXU6mLrbqQUQ6apKmNcjDIDL+NQnZEVb3PCcLRO+IR5tRJLnTcJXVYBDwLlYfvK7INFLwz/4pvklGQOa/ZSHdMLsR5aHLpvfgm6gTlMszV63k8NxCgFghN6B6xdftcdQPskzEYXdpqn+++40bbYv3hReA1zaOCDupjrJirYcNP3P+f6V7t1MLkQqX2pqh3TJEkorrJH/0e1WMbHUdQY6NiJcsMN56qEntdQI6GiUQVNtwOj8sH9kMMdgdjbg==.