Hash Generation

Generating hash for payment request

Each message contains a hash that has been calculated from the fields required in the interface specific descriptions.

Algorithm name

Algorithm

SHA-512

512 bit-length SHA-2

SHA-256

256 bit-length SHA-2

SHA-1

160 bit-length SHA-1

MD5

MD5

When calculating the hash the required fields are concatenated and each field is followed by the & character. The last field is the secret key provided by Svea Payments, followed by the & character. This is the character string used to calculate the hash. The hash algorithm field must contain the algorithm used as named in the table above.

If a field is optional and should be part of hash calculation, but it is not sent, then also the ampersand (&) for that field must be omitted from hash string.

The hash may be transferred in upper or lower case, the response hash is always upper case.

The default character set when calculating the hash is ISO-8859-1, but some other character sets are supported too. The character set used for hash calculation can be sent with the payment parameters as pmt_charset. Currently supported values are: ISO-8859-1, ISO-8859-15 and UTF-8.

In addition, another character set can be defined starting from payment interface version 0004. That parameter, pmt_charsethttp defines the character set used by the web store. This is important, because it defines how Svea Payements payment system will decode the parameters.

If no hash algorithm is specified in the response message received by the web store, the hash of the response is calculated by using the same algorithm as for request.

Example:

The hash should be calculated from the following fields (the example value used is in parenthesis):

  • field1 (123)

  • field2 (ABC)

  • field3 (K)

The secret key is ”testkey” without the quotation marks. The hash is calculated from the following string:
123&ABC&K&testkey&

Following parameters for new payment are presented in the same order as they should be in the hash calculation.

Field

Required

pmt_action

True.

pmt_version

True.

pmt_id

True.

pmt_orderid

True.

pmt_reference

True.

pmt_duedate

True.

pmt_amount

True.

pmt_currency

True.

pmt_okreturn

True.

pmt_errorreturn

True.

pmt_cancelreturn

True.

pmt_delayedpayreturn

True.

pmt_escrow

True.

pmt_escrowchangeallowed

True.

pmt_invoicefromseller

False. Include this field to hash only if it's included in request.

pmt_paymentmethod

False. Include this field to hash only if it's included in request.

pmt_buyeridentificationcode

False. Include this field to hash only if it's included in request.

pmt_buyername

True.

pmt_buyeraddress

True.

pmt_buyerpostalcode

True.

pmt_buyercity

True.

pmt_buyercountry

True.

pmt_deliveryname

True.

pmt_deliveryaddress

True.

pmt_deliverypostalcode

True.

pmt_deliverycity

True.

pmt_deliverycountry

True.

pmt_sellercosts

True.

pmt_token

False. Include this field when you are doing payments with already saved token. See more from Recurring Payments

pmt_marketplacecommission

False. Include this field to hash only if it's included in request.

pmt_marketplacereference

False. Include this field to hash only if it's included in request.

pmt_row_nameN

True.

pmt_row_descN

True.

pmt_row_quantityN

True.

pmt_row_articlenrN

False. Include this field to hash only if it's included in request.

pmt_row_unitN

True.

pmt_row_deliverydateN

True.

pmt_row_price_grossN

False. You should use either gross values or net values in your request. More about this in New Payment .

pmt_row_price_netN

False. You should use either gross values or net values in your request. More about this in New Payment .

pmt_row_vatN

True.

pmt_row_discountpercentageN

True.

pmt_row_typeN

True.

Secret Key

True. This value should always be the last one and end to the character "&"

// Example hash generation for SHA256 using crypto-js

import sha256 from 'crypto-js/sha256';
import Hex from 'crypto-js/enc-hex';

const valuesDictionary = [];

valuesDictionary.push({"pmt_action":"NEW_PAYMENT_EXTENDED"});
valuesDictionary.push({"pmt_version":"0001"});

valuesDictionary.push({"pmt_id": "UNIQUEID123"}); 
valuesDictionary.push({"pmt_orderid": "COULDBEGUIDFOREXAMPLE321"});
valuesDictionary.push({"pmt_reference":"1234567890120"});
valuesDictionary.push({"pmt_duedate":"1.1.2010"});

valuesDictionary.push({"pmt_amount":"10,00"});
valuesDictionary.push({"pmt_currency":"EUR"});
valuesDictionary.push({"pmt_okreturn":"https://testsite.com/OK"});
valuesDictionary.push({"pmt_errorreturn":"https://testsite.com/ERROR"});
valuesDictionary.push({"pmt_cancelreturn":"https://testsite.com/CANCEL"});
valuesDictionary.push({"pmt_delayedpayreturn":"https://testsite.com/DELAYED_RETURN"});

valuesDictionary.push({"pmt_buyername":"Teemu Testaaja"});
valuesDictionary.push({"pmt_buyeraddress":"Atomitie 2 C"});
valuesDictionary.push({"pmt_buyerpostalcode":"00370"});
valuesDictionary.push({"pmt_buyercity":"Helsinki"});
valuesDictionary.push({"pmt_buyercountry":"FI"});

valuesDictionary.push({"pmt_deliveryname":"Teemu Testaaja"});
valuesDictionary.push({"pmt_deliveryaddress":"Atomitie 2 C"});
valuesDictionary.push({"pmt_deliverypostalcode":"00370"});
valuesDictionary.push({"pmt_deliverycity":"Helsinki"});
valuesDictionary.push({"pmt_deliverycountry":"FI"});

valuesDictionary.push({"pmt_sellercosts":"0,00"});

// Order rows are included in hash. Loop over one row at a time and replace N
// with the row number "pmt_row_name1"
valuesDictionary.push({"pmt_row_nameN":"tuote 1"});
valuesDictionary.push({"pmt_row_descN":"tuotteen 1 pitkä kuvausteksti blaa blaa"});
valuesDictionary.push({"pmt_row_quantityN":"2"});
valuesDictionary.push({"pmt_row_deliverydateN":"01.01.2012"});
valuesDictionary.push({"pmt_row_price_netN":"5,00"});
valuesDictionary.push({"pmt_row_vatN":"0,00"});
valuesDictionary.push({"pmt_row_discountpercentageN":"0,00"});
valuesDictionary.push({"pmt_row_typeN":""});

valuesDictionary.push({"secret":"TestSecret123!"});

// Loop over the values and create hash string from the dictionary
// field1&field2&fieldN&secret&

const hashMessage = valuesDictionary
.map(pair => Object.values(pair))
.join("&") + "&";
  
const hash = sha256(hashMessage).toString(Hex).toUpperCase();

// Append hash into the form data.
const dataToSend = new FormData();
dataToSend.append('pmt_hash', hash);

Tips for hash calculation

It is highly recommended to copy and paste e.g. the secret key through for example Notepad or some other plain text editor. It is common problem that the hash calculation fails simply because there are invisible whitespaces or line feeds / carriage returns in the value when it has been copied from rich text editors (e.g. MS Word) or email clients (e.g. MS Outlook).

At first, test your hash calculation with messages that have NO special characters, umlauts or other than US-ASCII character set, for that matter. That is, first try with an order without any special or control characters and without European national letters like ÄÖÅ. If hash mismatches with messages that contain any of the aforementioned characters, it is obvious there is something wrong with characters set (something else is used for calculation than told in the message):

  • Hash calculation character encoding / pmt_charset:

    • This field tells the character set that has been used to calculate the hash value for input data. Currently supported values are: ISO-8859-1, ISO-8859-15 and UTF-8. Hash calculation is always done from binary data, which is not obvious in some programming languages. You must handle the transformation from character based data to binary data before hash calculation correctly. If it’s not possible to define the character set for hash calculation function, you must find out which character set is used internally by the hash algorithm. For example character "Ä" have different hash values for UTF-8 and Latin-1 character sets.

  • Character encoding of input data (and of webstore) / pmt_charsethttp:

    • This field tells the character encoding of the input data. The Svea Payments payment interface handles HTTP request parameters according to this character encoding. Practically this is the character set reported by the browser, when you’re browsing the checkout pages in the webstore.

Please make sure that the string to be hashed does not contain two consecutive & chars (ampersands). Each field in hash string should be followed by exactly one ampersand. Empty or null fields are never put in hash string. The last character of the hash string should also be &.

Please check the parameter list again from the interface definition document. It is different from the list of parameters to be passed as all the parameters are not mandatory and some are not necessary to be “signed” by hash calculation.