Documentation

SaltPay, all rights reserved. 2022 ©

Introduction

SaltPay Secure Payment Page enables merchants to sell products securely on the web with minimal integration effort. It enables merchants to accept payments without handling sensitive information since all creditcard information is handled by SaltPay‘s payment page.

The Payment process has two steps, buyer supplies creditcard information on the first webpage

Payment Page

After payment a receipt of the transaction is displayed to the buyer

Payment Page

Technical Information

All communication between the webshop and SaltPay‘s Secure Payment Page is by POST via HTTPS.

The process steps between webshop and SaltPay are as follows:

  1. Process initiation, webshop redirects buyer to SaltPay‘s payment page with cart and payment information
  2. Buyer can take two actions
    1. Push cancel button and be returned to the cancelurl supplied by webshop
    2. Supply creditcard information and finalize payment
  3. As soon as payment is concluded the SaltPay server sends a payment confirmation to the webshop with the success url supplied by webshop
  4. Receipt of transaction the displayed to the buyer
  5. After pressing the „Back to shop“ button the buyer is redirected to the success url supplied by webshop

A secret key, known only to the merchant and the payment page is used to verify that the HTTPS communication is between the correct partners. The key is never sent directly over HTTPS, it is added to a HMAC signature function and thus sent indirectly. Detailed description of how the signature is created is in the Parameters chapter.

An example of a html form is as follows

<html xmlns="http://www.w3.org/1999/xhtml" lang="is" xml:lang="is">
  <head>
    <title>Webshop</title>
  </head>
  <body>
    <form id="form1" action="https://test.borgun.is/SecurePay/default.aspx" method="post">
      Merchantid : <input type="text" name="merchantid" value="9275444" /><br>
      paymentgatewayid : <input type="text" name="paymentgatewayid" value="16" /><br>
      checkhash : <input type="text" size=100 name="checkhash" value="628236a248fc6ca8358924287651273de827d78c3e3ffb281bce4a86d4b17edd" /><br>
      orderid : <input type="text" name="orderid" value="ORDER1230001" /><br>
      currency : <input type="text" name="currency" value="ISK" /><br>
      language : <input type="text" name="language" value="IS" /><br>
      buyername : <input type="text" name="buyername" value="Agnar Agnarsson" /><br>
      buyeremail : <input type="text" name="buyeremail" value="test@borgun.is" /><br>
      returnurlsuccess : <input type="text" size=100 name="returnurlsuccess" value="http://borgun.is/ReturnPageSuccess" /><br>
      returnurlsuccessserver : <input type="text" size=100 name="returnurlsuccessserver" value="http://borgun.is/ReturnPageSuccessServer" /><br>
      returnurlcancel : <input type="text" size=100 name="returnurlcancel" value="http://borgun.is/ReturnPageCancel.aspx" /><br>
      returnurlerror : <input type="text" size=100 name="returnurlerror" value="http://borgun.is/ReturnUrlError.aspx" /><br>
      itemdescription_0 : <input type="text" name="itemdescription_0" value="Dekk" /><br>
      itemcount_0 : <input type="text" name="itemcount_0" value="1" /><br>
      itemunitamount_0 : <input type="text" name="itemunitamount_0" value="800.00" /><br>
      itemamount_0 : <input type="text" name="itemamount_0" value="800.00" /><br>
      amount : <input type="text" name="amount" value="800.00" /><br>
      pagetype : <input type="text" name=" pagetype " value="0" /><br>
      skipreceiptpage : <input type="text" name="skipreceiptpage " value="0" /><br>
      merchantemail : <input type="text" name="merchantemail" value="test@borgun.is" /><br>
      <input type="submit" name="PostButton" />
    </form>
  </body>
</html>

Parameters

Functionality and Constraints

  • SaltPay´s Secure Payment Page can be configured to require the cardholder to insert email, mobile number and home address.
    Cardholder registration

  • If parameter skipreceiptpage is set to 1 then the receipt page is not displayed and the buyer is redirected to the url in parameter returlursuccess upon successful payment. In this setup the merchant must display receipt information.

  • Merchant logo can be displayed by setting a valid url in parameter merchantlogo. The logo will then be displayed in the left corner, above the merchant name. Note that the image needs to be stored under https to avoid browser warning message.

  • The payment page does support boðgreiðslur, e. recurring payments for Icelandic cardholders. The minimum amount for each payment is 500 ISK. The currency must be ISK.

  • SecurePay uses unicode (UTF-8) characters set. If the webshop is in another character set, f.ex. iso8859, then character conversion is needed. A conversion code example in .Net is here

public static string iso8859ToUnicode(string src)
{
  Encoding iso = Encoding.GetEncoding("iso8859-1");
  Encoding unicode = Encoding.UTF8;
  byte[] isoBytes = iso.GetBytes(src);
  byte[] unibytes = Encoding.Convert(iso,unicode,isoBytes);
  char[] unichars = new char[iso.GetCharCount(unibytes,0,unibytes.Length)];
  unicode.GetChars(unibytes,0,unibytes.Length,unichars,0);
  return new string(unichars);
}
  • SecurePay supports Verified By Visa (VbyV) and MasterCard SecureCode, no technical changes are needed are needed to activate enhanced security. Please send request of activation to: greidslusida@borgun.is, stating the website and the merchant id.

  • Decimal numbers can be sent in with either , or . to differentiate between whole numbers and cents.

  • Each pair of MerchantId/PaymentGatewayId can only support one currency. If support is needed for more than one currency then the webshop must be able to change the MerchantId/PaymentGatewayId pair depending on currency. There is no additional charge for multiple MerchantId/PaymentGatewayId´s

From webshop to payment page

Name Value
Merchantid
Required
MerchantId issued by SaltPay that identifies the merchant
paymentgatewayid
Required
Payment Gateway Id issued by SaltPay that identifies the payment method
Orderid
Required
Order number created by webshop, it will be a part of the creditcard transaction. 12 alphanumeric characters, extended characters sets can not be used.
reference
Optional
Reference can be any string, it is returned with the same value as is sent in. It‘s main function is to simplify adaptation to merchant system by containing an external orderid number.
checkhash
Required
Signature that is created by joining together the following parameters with | as separator and using HMAC SHA256 with the merchant secret key to create the checkhash.
MerchantId|ReturnUrlSuccess|ReturnUrlSuccessServer|OrderId|Amount|Currency
(Secret key is issued by SaltPay and known only to merchant and SaltPay)
See HMAC value creation appendix.
amount
Required
Total amount, can be with up to two cent numbers. Examples of legal values, 350 and 54,43 and 12.34
currency
Required
Currency code, allowed values are GBP, USD, EUR, DKK, NOK, SEK, CHF, CAD, HUF, BHD, AUD, RUB, PLN, RON, HRK, CZK and ISK. Default value is ISK.
language
Required
Language on webpages displayed to users. Supported langages are icelandic (IS), english (EN), german (DE), french (FR), russian (RU), spanish (ES) Italian (IT), portuguese (PT), slovenian (SI), hungarian (HU), swedish (SE), dutch (NL), polish (PL), Norwegian (NO), Czech (CZ), Slovak (SK), Hrvatski (HR), Romanian (RO), Danish (DK), Finnish (FI), Faroese (FO), Serbian (SR), Bulgarian (BG) and Lithuanian (LT).
buyername
Optional
Buyers name. If left empty then the buyer can insert it on the payment page.
returnurlsuccess
Required
Buyer will be sent to this page after a successful payment. Note: All provided urls should conform to RFC2396 and contain the protocol used (http, https).
returnurlsuccessserver
Conditional
A notification of successful payment is sent to this URL by the server. *If this parameter is not present, the value of the returnurlsuccess parameter is used instead.**
returnurlcancel
Optional
Buyer will be sent to this page if he pushes the cancel button instead of finalizing the payment.
returnurlerror
Optional
Buyer will be sent to this page if an unexpected error occurs.
payment_type
Optional
 
pagetype
Optional
If set as 1 then cardholder is required to insert email, mobile number and home address. Merchantemail parameter must be set since cardholder information is returned through email to merchant.
merchantlogo
Optional
If merchantlogo contains a url address of an image (100width x 100 height) then it is displayed on left side of the page, above the merchant name. Note that IE displayes warning if image is not stored on SSL.
skipreceiptpage
Optional
If set to 1 then the page displaying the purchase receipt to the cardholder is skipped and browser redirected to the url in returnurlsuccess. Thewebshop must then display a receipt to the cardholder in this setup.
merchantemail
Optional
If present, an e-mail is sent to the merchant upon successful payment. The message contains information about the merchant and buyer, along with the contents of the shopping cart.
buyeremail
Optional
If present, an e-mail is sent to the buyer upon successful payment. The message contains information about the merchang and buyer, along with the contents of the shopping cart.
displaymode
Optional
Can be set as "iframe" to make the payment page use a more compact layout suitable for display in iframes. Minimum supported width is 370px and maximum supported width is 755px.
showadditionalbrands
Optional
Can be set as "false" to hide brand logos other than VISA and MasterCard.
Cart as seen by the payment page consists of one or more items, each type of item creates one line. Each line contains one type of item along with number of items, unit amount and total amount for each line.
Cart is sent by parameters with running number that start with 0 and are sequential. Each set of parameters represent one line in cart.
Required
Itemdescription_x Item description, maximum length is 80 characters
Itemcount_x Number of items of this type
Itemunitamount_x Price of a single unit
Itemamount_x Total prices of this line.

From payment page to webshop

The payment page can end it‘s processing in three different stages:

  • Successful payment, buyer is redirected to the url in the parameter returnurlsuccess
  • Buyer cancels and is redirected to the url in the parameter returnurlcancel
  • Unexpected error occurred, buyer is redirected to the url in the parameter returnurlerror

Successful payment

If payment is successful then the buyer is redirected to the url in parameter returnurlsuccess with the following HTTP POST parameters. It‘s usage is up to the webshop but it is important to verify the orderhash to validate that the success message is from SaltPay.

NOTE: It is strongly recommended that the merchant verifies the orderhash returned in the server-to-server (returnurlsuccessserver) response from SaltPay to avoid fraud attempts.

Name Value
status Contains „Ok“
orderhash Signature that is created by joining together the following parameters with | as separator and using HMAC SHA256 with the merchant secret key to create the checkhash.
orderid|amount|Currency
(Secret key is issued by SaltPay and known only to merchant and SaltPay)
See HMAC value creation appendix
orderid Order number created by webshop and sent to payment page during payment initiation
authorizationcode Payment authorization from SaltPay
creditcardnumber Masked creditcard number (1234-12**-1234)
step Success message is sent on two occations from SaltPay to the webshop.
First time is after buyer has successfully paid and is being shown a receipt by SaltPay. Note that this url request comes from the SaltPay server and is not redirected thorugh the buyer browser, it is thus not in the same active session.
Second time is when the buyer pushes the optional „Back to shop“ button.

The steps are identified by the following values.
„Payment“: Payment has been completed. See section C for more info.
„Confirmation“: Buyer is sent from the payment page back to the webshop.
ticket Included if payment page was accessed using a ticket (See section 4). This parameter will contain the ticket used.
buyername Included if registration was required (pagetype = 1)
buyeraddress Included if registration was required (pagetype = 1)
buyerzip Included if registration was required (pagetype = 1)
buyercity Included if registration was required (pagetype = 1)
buyercountry Included if registration was required (pagetype = 1)
buyerphone Included if registration was required (pagetype = 1)
buyeremail Included if registration was required (pagetype = 1)
buyerreferral Included if registration was required (pagetype = 1)
buyercomment Included if registration was required (pagetype = 1)

Cancel

If buyer pushes the cancel button the he is redirected to the url in the parameter returnurlcancel.

Name Value
Status Contains "Cancel"

Unexpected error

Buyer is redirected to the url in the parameter returnurlerror if unexpected error occurrs.

Name Value
Status Contains „Error“
errordescription Error description suitable for displaying to buyer
errorcode Errorcode

Additional codes are returned from the payment-page test-site

Name Value
errordetailx Details about the error
auditlogx Records from the audit log

Payment notification response

If the step parameter is „Payment“, then the preferred response from the webshop to the server-to-server notification should be an XML document, which indicates that the webshop has successfully received the notification.

The structure of the XML should be as follows:

<PaymentNotification>Accepted</PaymentNotification>

If this response is received from the webshop, an audit log entry is created which states that the payment notification was successfully received by the webshop. Otherwise, the audit log entry will only state that the payment notification was sent to the webshop.

Ticket API

SaltPay SecurePay supplies a secondary interface that creates a token that corresponds to a specific order. The webshop posts order details to the Ticket API that returns a unique string (ticket) referencing the order details. The ticket can be sent to customers in a simple URL that opens a SecurePay page with the pre-made order information. The URL can also be created manually through SaltPay‘s merchant web (B-Online).

The Ticket API supports all the same parameters as the Payment Page (See section 3.b). The parameters below are specific to create and control tickets:

Name Value
TicketExpiryDate Ticket will be valid until this date. If TicketExpiryDate is not supplied Ticket will be valid for two months. Format: „dd.MM.yyyy“.

The ticket API will return a message with the format ticket=ticket&ret=ret&message=message

Name Value
ticket This parameter will contain a ticket if parameter ret is „True“
ret Return code. „True“ if order was successfully processed, „False“ if an error occurred.
Message This parameter will contain a error description if parameter ret is „False“.

The ticket is used by sending it as a GET parameter (?ticket=ticket) to the Ticket API, the API will then redirect the buyer to the payment page.

Test Environment

A test creditcard can be supplied. All transactions created in the test environment are voided. Amounts suitable for testing are within the range of 10-1000 ISK or equivalent in the currency used. Do not use the test creditcard outside of the test environment. Optionally a testcard for testing errorstatus can be supplied.

Contact greidslusida@borgun.is for test URL, MID and all technical inquiries.

Appendix

HMAC value creation

When creating the CheckHash parameter and verifying the OrderHash parameter HMAC_SHA256 should be used. HMAC libraries are available for most programming languages and usually provide a method such as

HMAC_SHA256(secretkey, message)

where message contains the data to be hashed. F.ex.

CheckHashMessage = MerchantId|ReturnUrlSuccess|ReturnUrlSuccessServer|OrderId|Amount|Currency
OrderHashMessage = OrderId|Amount|Currency

Examples

SecretKey = "1234567890abcdef"
CheckHashMessage = "9123456|https://borgun.is/success|https://borgun.is/success_server|TEST00000001|100|ISK"
ExpectedCheckHash = "ef2e66e64df91143e7e98ecc9f94e12988718408b860770b4181e466401f22d0"

OrderHashMessage = "TEST00000001|100|ISK"
ExpectedOrderHash = "d605531aa71c833edb59651652161e7845933d2f7d44d3697bc336e493befd25"

NOTE: If returnurlsuccessserver parameter is not present, the value of the returnurlsuccess parameter is used as returnurlsuccessserver.

A number of online HMAC generators can be used to verify the output of your implementation f.ex. https://www.freeformatter.com/hmac-generator.html.

NOTE: Never use production information when using online HMAC testers.

Following are examples of HMAC implementations in various programming languages:

C# using HMAC_SHA256

Example using the HMACSHA256 class.

string secretKey = "1234567890abcdef";
string message = "9123456|https://borgun.is/success|https://borgun.is/success_server|TEST00000001|100|ISK";

byte[] secretBytes = Encoding.UTF8.GetBytes(secretKey);
HMACSHA256 hasher = new HMACSHA256(secretBytes);
byte[] result = hasher.ComputeHash(Encoding.UTF8.GetBytes(message));
string checkhash = BitConverter.ToString(result).Replace("-", "");

PHP

Example using hash_hmac.

$secretKey = '1234567890abcdef';
$message = utf8_encode('9123456|https://borgun.is/success|https://borgun.is/success_server|TEST00000001|100|ISK');
$checkhash = hash_hmac('sha256', $message, $secretKey);

Python 2.7

Example using hmac

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import hmac
import hashlib

secret_key = '1234567890abcdef'
message = u'9123456|https://borgun.is/success|https://borgun.is/success_server|TEST00000001|100|ISK'.encode('utf-8')
checkhash = hmac.new(secret_key, msg=message, digestmod=hashlib.sha256).hexdigest()

Python 3.4

Example using hmac

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import hmac
import hashlib

secret_key = b'1234567890abcdef'
message = '9123456|https://borgun.is/success|https://borgun.is/success_server|TEST00000001|100|ISK'.encode(encoding='utf-8')
checkhash = hmac.new(secret_key, msg=message, digestmod=hashlib.sha256).hexdigest()

Ruby

Example using OpenSSL::HMAC

# encoding: utf-8

require 'openssl'

secret_key = '1234567890abcdef'
message = '9123456|https://borgun.is/success|https://borgun.is/success_server|TEST00000001|100|ISK'
digest  = OpenSSL::Digest.new('sha256')
checkhash = OpenSSL::HMAC.hexdigest(digest, secret_key, message)

Javascript

Example using crypto-js and Node.

var crypto = require('crypto-js');

var secret_key = '1234567890abcdef';
var message = '9123456|https://borgun.is/success|https://borgun.is/success_server|TEST00000001|100|ISK';

var checkhash_data = crypto.HmacSHA256(message, secret_key);
var checkhash = crypto.enc.Hex.stringify(checkhash_data);

Java

Example using Mac

import java.util.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import javax.xml.bind.DatatypeConverter;

public class hmac {
    public static void main (String[] args) throws Exception {
        String secretKey = "1234567890abcdef";
        String message = "9123456|https://borgun.is/success|https://borgun.is/success_server|TEST00000001|100|ISK";
        byte[] secretKeyBytes = secretKey.getBytes("utf-8");
        byte[] messageBytes = message.getBytes("utf-8");

        SecretKeySpec signingKey = new SecretKeySpec(secretKeyBytes, "HmacSHA256");
        Mac mac = Mac.getInstance("HmacSHA256");
        mac.init(signingKey);
        byte[] checkhashBytes = mac.doFinal(messageBytes);
        String checkhash = DatatypeConverter.printHexBinary(checkhashBytes).toLowerCase();
    }
}