NAV
Java JavaScript PHP

Introduction

This is the API reference and example documentation for Payment Highway. The easy and enjoyable card payment solution for mobile and online.

Payment Highway API consists of two parts:

Client Libraries

Java

https://github.com/PaymentHighway/paymenthighway-java-lib

PHP

https://github.com/PaymentHighway/paymenthighway-php-lib

JavaScript

https://github.com/PaymentHighway/paymenthighway-javascript-lib

Examples

Java

A Simple Java Spring Example using the Client Library @ Github

JavaScript

A simple JavaScript example using the JavaScript client library @ GitHub

Usage

Make a Payment

  1. Show the form with Form API POST /form/view/pay_with_card
    —> returns an sph-transaction-id and signature as a GET parameters to the given success-url
  2. Commit the payment with Payment API POST /transaction/<sph-transaction-id>/commit
    —> returns a result in JSON formatting

Store a Card

  1. Show the form with Form API POST /form/view/add_card
    —> returns an sph-tokenization-id and signature as a GET parameters to the given success-url
  2. Get the card token with Payment API GET /tokenization/<sph-tokenization-id>
    —> returns a card_token and card information in JSON formatting

Pay with a Stored Card

  1. Initialize a transaction with Payment API POST /transaction
    —> returns a transaction id in JSON formatting
  2. Charge the card with Payment API POST /transaction/<id>/debit
    —> returns a result in JSON formatting

Pay with MobilePay

  1. Open MobilePay with Form API POST /form/view/mobilepay
    -> return an sph-transaction-id and signature as a GET parameters to the given success-url
  2. Commit payment with Payment API POST /transaction/<sph-transaction-id>/commit
    —> returns a result in JSON formatting

Development Sandbox

Base URL

The Payment Highway Sandbox environment is accessed on
https://v1-hub-staging.sph-test-solinor.com/

Merchant Account

The Sandbox Merchant Account uses the following credentials:

Parameter Value
sph-account test
sph-merchant test_merchantId
Account key testKey
Account secret testSecret

Take a look at the signature calculation examples in the Form API and in the Payment API.

Sandbox credit cards

There are predefined card numbers that are accepted in the sandbox environment. Each card serves a different purpose in testing the API. For general declines, just input an incorrect CVC or expiry date.

Card abilities Card Number Expiry date CVC Specialties
Tokenization OK
Payment OK
4153013999700024 11/2023 024 Debit card
Tokenization OK
Payment OK
5353299308701770 11/2023 770 Credit card
Tokenization OK
Payment FAIL
4153013999700156 11/2023 156 Insufficient funds in the test bank account
Tokenization FAIL
Payment FAIL
4920101111111113 11/2023 113 Online payments are disabled for the card. A form notification is displayed for the first N submits.
For example Nordea 492010* cards require the card holder to enable online payments in their e-banking services.
Tokenization DEPENDS
Payment DEPENDS
4324643990016048 11/2023 048 Requires CVC, tokenized payments without CVC fail.

Form API

Payment Highway Form API allows merchants to tokenize payment cards and create payments using an HTML form interface.

Request and Response format

// Create a FormBuilder

String method = "POST";
String signatureKeyId = "testKey";
String signatureSecret = "testSecret";
String account = "test";
String merchant = "test_merchantId";
String serviceUrl = "https://v1-hub-staging.sph-test-solinor.com";

FormBuilder formBuilder = new FormBuilder(
  method, signatureKeyId, signatureSecret, account, merchant,
  serviceUrl
);
// Create a FormBuilder

signature_key_id = "testKey"
signature_secret = "testSecret"
account = "test"
merchant = "test_merchantId"
service_url = "https://v1-hub-staging.sph-test-solinor.com"
success_url = "https://www.paymenthighway.fi/"
failure_url = "https://paymenthighway.fi/dev/"
cancel_url = "https://solinor.com/"
language = "EN"

form_builder = PaymentHighway::FormBuilder.new(
  signature_key_id, signature_secret, account, merchant,
  service_url, success_url, failure_url, cancel_url, language)

var paymentHighway = require('paymenthighway-javascript-lib');

var method = 'POST';
var testKey = 'testKey';
var testSecret = 'testSecret';
var account = 'test';
var merchant = 'test_merchantId';
var serviceUrl = 'https://v1-hub-staging.sph-test-solinor.com';

var formBuilder = new paymentHighway.FormBuilder(
        method, 
        testKey, 
        testSecret, 
        account, 
        merchant, 
        serviceUrl
    );
<?php
use \Solinor\PaymentHighway\FormBuilder;

$method = "POST";
$signatureKeyId = "testKey";
$signatureSecret = "testSecret";
$account = "test";
$merchant = "test_merchantId";
$baseUrl = "https://v1-hub-staging.sph-test-solinor.com";
$successUrl = "https://example.com/success";
$failureUrl = "https://example.com/failure";
$cancelUrl = "https://example.com/cancel";
$language = "EN";

$formBuilder = new FormBuilder($method, 
    $signatureKeyId, 
    $signatureSecret, 
    $account,
    $merchant, 
    $baseUrl, 
    $successUrl, 
    $failureUrl,
    $cancelUrl, 
    $language);

Requests

The “sph”-prefixed form fields and the request signature should be calculated server side and set in the html form as hidden fields.

Responses

Responses are delivered to URLs given in the request and signed by using the same key as in the request. Response parameters are added as GET parameters to the URL.

When a user is redirected to the success-url, it means we have successfully completed processing of the request. It does not however mean the card payment or tokenization was accepted by the authorizing parties. You will find out the actual result using the PaymentAPI (server-to-server) commit or tokenization requests.

A user is redirected to the failure-url, if processing of the request failed for example due to missing parameters, authentication issues or connectivity issues to the authorizing parties.

Important! Always validate the form redirection signature parameter to prevent tampering of the values!

Authentication

Authentication is based on a signature calculated from the merchant account information and from the other parameters prefixed with ‘sph’.

Request signature calculation

Original POST data

POST
/form/view/pay_with_card
sph-account=test
sph-merchant=test_merchantId
sph-order=1000123A
sph-request-id=f47ac10b-58cc-4372-a567-0e02b2c3d479
sph-amount=990
sph-currency=EUR
sph-timestamp=2014-09-18T10:32:59Z
sph-success-url=https://merchant.example.com/payment/success
sph-failure-url=https://merchant.example.com/payment/failure
sph-cancel-url=https://merchant.example.com/payment/cancel
language=fi
description=Example payment of 10 balloons á 0,99EUR
signature=SPH1 testKey 960aeec47d172637325b15513b3a526e95c93ba74b5067da766f282573464d58

POST data included in the signature calculation, parameters sorted alphabetically

"POST
/form/view/pay_with_card
sph-account:test
sph-amount:990
sph-cancel-url:https://merchant.example.com/payment/cancel
sph-currency:EUR
sph-failure-url:https://merchant.example.com/payment/failure
sph-merchant:test_merchantId
sph-order:1000123A
sph-request-id:f47ac10b-58cc-4372-a567-0e02b2c3d479
sph-success-url:https://merchant.example.com/payment/success
sph-timestamp:2014-09-18T10:32:59Z
"

Authentication hash using “testSecret” as the keyValue and POST data from above:
HMAC-SHA256(keyValue, data) =>
960aeec47d172637325b15513b3a526e95c93ba74b5067da766f282573464d58

Signature is calculated from the request parameters with HMAC-SHA256 algorithm using one of the merchant secret keys. The signature value contains “SPH1”, the key ID and the calculated authentication hash as a hexadecimal string separated with spaces “ ” (0x20).

The authentication hash value is calculated from the authentication string using the chosen merchant secret key. The authentication string is formed from the request method, URI and the request parameters beginning with “sph-”-prefix. Values are trimmed and the key-value pairs are concatenated in alphabetical order by the key name. The parameter keys must be in lowercase. Each key and value is separated with a colon (“:”) and the different parameters are separated with a new line (“\n”) at the end of each value.

Response redirection signature calculation (success, failure and cancel urls)

Form redirection response example:

http://merchant-example-spring.sph-test-solinor.com/pay_with_card/success?sph-amount=1990&signature=SPH1+testKey+8b9b2eb519e289016ff8b6bb6112901ad64238a8035b6b06a179a1bcb178947e&sph-account=test&sph-currency=EUR&sph-merchant=test_merchantId&sph-transaction-id=24806fe4-c0ed-4baa-9044-14b15457ea6e&sph-order=1000123A&sph-timestamp=2016-05-17T07%3A08%3A27Z&sph-request-id=7475777a-b9f8-4c09-958c-b1ea47bdc0cb&sph-success=OK

"GET

sph-account:test
sph-amount:1990
sph-currency:EUR
sph-merchant:test_merchantId
sph-order:1000123A
sph-request-id:7475777a-b9f8-4c09-958c-b1ea47bdc0cb
sph-success:OK
sph-timestamp:2016-05-17T07:08:27Z
sph-transaction-id:24806fe4-c0ed-4baa-9044-14b15457ea6e
"

Authentication hash using “testSecret” as the keyValue and GET data from above:
HMAC-SHA256(keyValue, data) =>
8b9b2eb519e289016ff8b6bb6112901ad64238a8035b6b06a179a1bcb178947e

// Validate the response signature

SecureSigner secureSigner = new SecureSigner(signatureKeyId, signatureSecret);

if ( ! secureSigner.validateFormRedirect(requestParams)) {
    throw new Exception("Invalid signature!");
}
// Validate the response signature

var secureSigner = new paymentHighway.SecureSigner(testKey, testSecret);

if(!secureSigner.validateFormRedirect(requestParams)) {
    // Handle error
}
<?php
use Solinor\PaymentHighway\Model\Security\SecureSigner;

$secureSigner = new SecureSigner(signatureKeyId, signatureSecret);

try{
    $secureSigner->validateFormRedirect($params)) { 
}
catch(Exception $e) {
    // Validation failed, handle here
}

Response parameters are formatted into a single value and HMAC-SHA256 signature is calculated with the same secret key as in the request. The signature value contains “SPH1”, the key ID and the calculated authentication hash as a hexadecimal string separated with spaces “ ” (0x20).

The authentication hash value is calculated from the authentication string using the chosen merchant secret key. The authentication string is formed from the method “GET”, an empty URI “”, the response parameters beginning with “sph-”-prefix and an empty body “”. Values are trimmed and the key-value pairs are concatenated in alphabetical order (by the key name). The parameter keys must be in lowercase. Each key and value is separated with a colon (“:”) and the different parameters are separated with a new line (“\n”) at the end of each value.

Add Card

curl -i --data-urlencode '
sph-account=test
sph-merchant=test_merchantId
sph-request-id=f47ac10b-58cc-4372-a567-0e02b2c3d479
sph-timestamp=2014-09-18T10:32:59Z
sph-success-url=https://merchant.example.com/payment/success
sph-failure-url=https://merchant.example.com/payment/failure
sph-cancel-url=https://merchant.example.com/payment/cancel
language=fi
signature= SPH1 testKey 4eab87a16e3ee7bd530d778af0cb6c680dcaa52ed1913a9c1bd8ed5a8d689e3e' \
    https://v1-hub-staging.sph-test-solinor.com/form/view/add_card
// Example common parameters for the following form generation functions

String successUrl = "https://www.paymenthighway.fi/";
String failureUrl = "https://paymenthighway.fi/dev/";
String cancelUrl = "https://solinor.com/";
String language = "EN";

// Generate Add Card form parameters

FormContainer formContainer = formBuilder.addCardParameters(successUrl, failureUrl, cancelUrl)
    .language(language)
    .build();

// read form parameters
String httpMethod = formContainer.getMethod();
String actionUrl = formContainer.getAction();
List<NameValuePair> fields = formContainer.getFields();

for (NameValuePair field : fields) {
    field.getName();
    field.getValue();
}
// Generate Add Card form parameters

form_container = form_builder.add_card_parameters

// read form parameters
http_method = form_container.method
action_url = form_container.action
pairs = form_container.pairs // an array of PaymentHighway::NameValuePair

pairs.each do |pair|
    name = pair.name
    value = pair.value
end
// Example common parameters for the following form generation functions

var successUrl = 'https://example.com/success';
var failureUrl = 'https://example.com/failure';
var cancelUrl = 'https://example.com/cancel';
var language = 'EN';

// Generate Add Card form parameters

var formContainer = formBuilder.generateAddCardParameters(
                      successUri, 
                      failureUri, 
                      cancelUri, 
                      language
                    );

// read form parameters
var httpMethod = formContainer.method;
var actionUrl = formContainer.getAction();
var fields = formContainer.nameValuePairs;

fields.forEach(function(field) {
    var name = field.first;
    var value = field.second;
});
<?php
$form = $formBuilder->generateAddCardParameters();

// read form parameters
$httpMethod = $form->getMethod();
$actionUrl = $form->getAction();
$parameters = $form->getParameters(); 

// Header parameters as key => value array
foreach ($parameters as $key => $value) {
    echo $key .":". $value;
}

Adding a new card stores the payment card information to Payment Highway and returns a tokenization id that can be used to fetch a card token for payments.

Simple flow

  1. Show the form with Form API POST /form/view/add_card
    —> returns an sph-tokenization-id and signature as a GET parameters to the given success-url
  2. Get the card token with Payment API GET /tokenization/<sph-tokenization-id>
    —> returns a card_token and card information in JSON formatting

HTTP Request

POST /form/view/add_card

Parameter Data type  M/O Description
sph-account AN M Account identifier
sph-merchant AN M Account merchant identifier
sph-request-id UUID4 M Request identifier
sph-timestamp TIMESTAMP M Request timestamp in ISO 8601
combined date and time in UTC.
E.g. “2025-09-18T10:32:59Z”
sph-success-url URL M Success URL the user is redirected to on success
sph-failure-url URL M Failure URL the user is redirected to on failure
sph-cancel-url  URL  M Cancel URL the user is redirected to on cancel
sph-webhook-success-url URL O On success, server to server GET request will be made to this url with same parameters as success redirect.
sph-webhook-failure-url URL O On failure, server to server GET request will be made to this url with same parameters as failure redirect.
sph-webhook-cancel-url URL O On cancel, server to server GET request will be made to this url with same parameters as cancel redirect.
sph-webhook-delay N O webhook call delay in seconds (MAX. 900). If omitted, default value 0 will be used.
sph-accept-cvc-required BOOLEAN O Allow adding a card even if it requires CVC for payments. Defaults to false.
sph-api-version VERSION O API version number
language A O Two letter language code (ISO 639-1). Supported languages are DE, EN, ES, FI, FR, RU, SV. Defaults to browser language.
sph-skip-form-notifications BOOLEAN O Skip errors displayed on the Payment Highway form and redirect directly to result URL (E.g. “Ecom payments disabled”) . Default false.
sph-exit-iframe-on-result BOOLEAN O Exit from iframe after redirection to result URLs.
sph-exit-iframe-on-three-d-secure BOOLEAN O Exit from iframe when redirecting user to 3DS.
sph-use-three-d-secure BOOLEAN O Force enable/disable 3DS authentication. Omit / null to use default configured parameter. Disable only if permitted by Your acquiring contract!
signature ANS M Message signature in the format key-id:authentication-string

Webhooks have same parameters as success, failure and cancel responses.

Success Response for Add Card

On a successful operation the user is redirected to the given success URL sph-success-url.

When a user is redirected to the success-url, it means we have successfully completed processing of the request. It does not however mean the card payment or tokenization was accepted by the authorizing parties. You will find out the actual result using the PaymentAPI (server-to-server) commit or tokenization requests.

Parameter Data type Description
sph-account AN Account identifier from request
sph-merchant AN Account merchant identifier from request
sph-request-id UUID4 Request identifier from request
sph-tokenization-id UUID4 Generated sph-tokenization-id
sph-timestamp AN Response timestamp in ISO 8601
combined date and time in UTC.
E.g. 2025-09-18T10:33:49Z
sph-success AN Static text “OK”
signature ANS Message signature

Failure Response for Add Card

On failure the user is redirected to the given failure URL sph-failure-url.

A user is redirected to the failure-url, if processing of the request failed for example due to missing parameters, authentication issues or connectivity issues to the authorizing parties.

Parameter Data type Description
sph-account AN Account identifier from request
sph-merchant AN Account merchant identifier from request
sph-request-id UUID4 Request identifier from request
sph-timestamp AN Response timestamp in ISO 8601
combined date and time in UTC.
E.g. 2025-09-18T10:33:49Z
sph-failure AN Failure reason, one of:
  • “UNAUTHORIZED”
  • “INVALID”
  • “FAILURE”
  • “NO_ROUTE” (Equivalent to response code 940)
  • “THREE_D_SECURE” (Technical failure in 3D secure)
signature ANS Message signature

Cancel Response for Add Card

If the user cancels the operation they are redirected to the given cancel URL sph-cancel-url.

Parameter Data type Description
sph-account AN Account identifier from request
sph-merchant AN Account merchant identifier from request
sph-request-id UUID4 Request identifier from request
sph-timestamp AN Response timestamp in ISO 8601
combined date and time in UTC.
E.g. 2025-09-18T10:33:49Z
sph-cancel AN Cancel reason “CANCEL”
signature ANS Message signature

Payment

curl -i --data-urlencode '
sph-account=test
sph-merchant=test_merchantId
sph-order=1000123A
sph-request-id=f47ac10b-58cc-4372-a567-0e02b2c3d479
sph-amount=990
sph-currency=EUR
sph-timestamp=2014-09-18T10:32:59Z
sph-success-url=https://merchant.example.com/payment/success
sph-failure-url=https://merchant.example.com/payment/failure
sph-cancel-url=https://merchant.example.com/payment/cancel
language=fi
description=Example payment of 10 balloons á 0,99EUR
signature= SPH1 testKey 960aeec47d172637325b15513b3a526e95c93ba74b5067da766f282573464d58' \
    https://v1-hub-staging.sph-test-solinor.com/form/view/pay_with_card
// Generate Payment form parameters

String amount = "1990";
String currency = "EUR";
String orderId = "1000123A";
String description = "A Box of Dreams. 19,90€";

FormContainer formContainer = formBuilder.paymentParameters(successUrl, failureUrl, cancelUrl, amount, currency, orderId, description)
        .build();

// read form parameters
String httpMethod = formContainer.getMethod();
String actionUrl = formContainer.getAction();
List<NameValuePair> fields = formContainer.getFields();

for (NameValuePair field : fields) {
    field.getName();
    field.getValue();
}
// Generate Payment form parameters

amount = 1990
currency = "EUR"
order_id = "1000123A"
description = "A Box of Dreams. 19,90€"

form_container = form_builder.pay_with_card_parameters(amount, currency, order_id, description)

// read form parameters
http_method = form_container.method
action_url = form_container.action
pairs = form_container.pairs // an array of PaymentHighway::NameValuePair

pairs.each do |pair|
    name = pair.name
    value = pair.value
end
var amount = 1990;
var currency = 'EUR';
var orderId = '1000123A';
var description = 'A Box of Dreams. 19,90€';

var formContainer = formBuilder.generatePaymentParameters(
        successUri, 
        failureUri, 
        cancelUri, 
        language, 
        amount, 
        currency, 
        orderId, 
        description
    );

// read form parameters
var httpMethod = formContainer.method;
var actionUrl = formContainer.getAction();
var fields = formContainer.nameValuePairs;

fields.forEach(function(field) {
    var name = field.first;
    var value = field.second;
});    
<?php
$amount = "1990";
$currency = "EUR";
$orderId = "1000123A";
$description = "A Box of Dreams. 19,90€";

$form = $formBuilder->generatePaymentParameters($amount, $currency, $orderId, $description);

// read form parameters
$httpMethod = $form->getMethod();
$actionUrl = $form->getAction();
$parameters = $form->getParameters(); 

// Header parameters as key => value array
foreach ($parameters as $key => $value) {
    echo $key .":". $value;
}

The payment card form is shown in the Payment Highway. The response to the success-url contains a sph-transaction-id for committing the transaction through the Payment API.

Simple flow

  1. Show the form with Form API POST /form/view/pay_with_card
    —> returns an sph-transaction-id and signature as a GET parameters to the given success-url
  2. Commit the payment with Payment API POST /transaction/<sph-transaction-id>/commit
    —> returns a result in JSON formatting

HTTP Request

POST /form/view/pay_with_card

Parameter Data type  M/O Description
sph-account AN M Account identifier
sph-merchant AN M Account merchant identifier
sph-order ORDER-ID M Merchant defined order identifier. Should be unique per transaction.
sph-request-id UUID4 M Request identifier
sph-amount N M Amount in the lowest currency unit. E.g. 99,00 € = 9900
sph-currency  A M Currency code “EUR”
sph-timestamp AN M Request timestamp in ISO 8601
combined date and time in UTC.
E.g. “2025-09-18T10:32:59Z”
sph-success-url URL M Success URL user is redirected to on success
sph-failure-url URL M Failure URL user is redirected to on failure
sph-cancel-url  URL  M Cancel URL user is redirected to on cancel
sph-webhook-success-url URL O On success, server to server GET request will be made to this url with same parameters as success redirect.
sph-webhook-failure-url URL O On failure, server to server GET request will be made to this url with same parameters as failure redirect.
sph-webhook-cancel-url URL O On cancel, server to server GET request will be made to this url with same parameters as cancel redirect.
sph-webhook-delay N O Webhook call delay in seconds (MAX. 900). If omitted, default value 0 will be used.
sph-show-payment-method-selector BOOLEAN O Payment method selector is shown and end user can choose either card payment or Masterpass payment.
sph-api-version VERSION O API version number
language A O Language code (ISO 639-1)(FI/EN/SV)
description ANS O The order description shown to the user
sph-skip-form-notifications BOOLEAN O Skip errors displayed on the Payment Highway form and redirect directly to result URL (E.g. “Ecom payments disabled”) . Default false.
sph-exit-iframe-on-result BOOLEAN O Exit from iframe after redirection to result URLs.
sph-exit-iframe-on-three-d-secure BOOLEAN O Exit from iframe when redirecting user to 3DS.
sph-use-three-d-secure BOOLEAN O Force enable/disable 3DS authentication. Omit / null to use default configured parameter. Disable only if permitted by Your acquiring contract!
signature ANS M Message signature in the format key-id:authentication-string

Webhooks have same parameters as success, failure and cancel responses.

Success Response for Payment

On a successful operation the user is redirected to the given success URL sph-success-url.

When a user is redirected to the success-url, it means we have successfully completed processing of the request. It does not however mean the card payment or tokenization was accepted by the authorizing parties. You will find out the actual result using the PaymentAPI (server-to-server) commit or tokenization requests.

Parameter Data type Description
sph-account AN Account identifier
sph-merchant AN Account merchant identifier
sph-order AN Merchant defined order identifier
sph-request-id UUID4 Request identifier
sph-amount N Amount in the lowest currency unit. E.g. 99,00 € = 9900
sph-currency A Currency code “EUR”
sph-transaction-id AN Payment transaction identifier
sph-timestamp AN Request timestamp in ISO 8601
combined date and time in UTC.
E.g. “2025-09-18T10:32:59Z”
sph-success AN Static text “OK”
signature ANS Message signature

Failure Response for Payment

On failure the user is redirected to the given failure URL sph-failure-url.

A user is redirected to the failure-url, if processing of the request failed for example due to missing parameters, authentication issues or connectivity issues to the authorizing parties.

Parameter Data type Description
sph-account AN Account identifier from request
sph-merchant AN Account merchant identifier from request
sph-order AN Merchant defined order identifier
sph-request-id UUID4 Request identifier from request
sph-timestamp AN Response timestamp in ISO 8601
combined date and time in UTC.
E.g. 2025-09-18T10:33:49Z
sph-failure AN Failure reason, one of:
  • “UNAUTHORIZED”
  • “INVALID”
  • “FAILURE”
  • “NO_ROUTE” (Equivalent to response code 940)
  • “MASTERPASS_NOT_SUPPORTED”
  • MASTERPASS
  • “THREE_D_SECURE” (Technical failure in 3D secure)
signature ANS Message signature

Cancel Response for Payment

If the user cancels the operation they are redirected to the given cancel URL sph-cancel-url.

Parameter Data type Description
sph-account AN Account identifier from request
sph-merchant AN Account merchant identifier from request
sph-order AN Merchant defined order identifier
sph-request-id UUID4 Request identifier from request
sph-timestamp AN Response timestamp in ISO 8601
combined date and time in UTC.
E.g. 2025-09-18T10:33:49Z
sph-cancel AN Cancel reason “CANCEL”
signature ANS Message signature

Payment & Add Card

curl -i --data-urlencode '
sph-account=test
sph-merchant=test_merchantId
sph-order=1000123A
sph-request-id=f47ac10b-58cc-4372-a567-0e02b2c3d479
sph-amount=990
sph-currency=EUR
sph-timestamp=2014-09-18T10:32:59Z
sph-success-url=https://merchant.example.com/payment/success
sph-failure-url=https://merchant.example.com/payment/failure
sph-cancel-url=https://merchant.example.com/payment/cancel
language=fi
description=Example payment of 10 balloons á 0,99EUR
signature= SPH1 testKey af9cf1b9a967f6415bb8c4dea8629db0d47edf8ee037c8af1a8bb0eb5aca68e1' \
    https://v1-hub-staging.sph-test-solinor.com/form/view/add_and_pay_with_card
// Generate Add Card And Payment form parameters

String amount = "1990";
String currency = "EUR";
String orderId = "1000123A";
String description = "A Box of Dreams. 19,90€";

FormContainer formContainer = formBuilder.addCardAndPaymentParameters(
            successUrl, 
            failureUrl, 
            cancelUrl, 
            amount, 
            currency, 
            orderId, 
            description
        )
        .build();

// read form parameters
String httpMethod = formContainer.getMethod();
String actionUrl = formContainer.getAction();
List<NameValuePair> fields = formContainer.getFields();

for (NameValuePair field : fields) {
    field.getName();
    field.getValue();
}
// Generate Add Card And Payment form parameters

amount = 1990
currency = "EUR"
order_id = "1000123A"
description = "A Box of Dreams. 19,90€"

form_container = form_builder.add_and_pay_with_card_parameters(amount, currency, order_id, description)

// read form parameters
http_method = form_container.method
action_url = form_container.action
pairs = form_container.pairs // an array of PaymentHighway::NameValuePair

pairs.each do |pair|
    name = pair.name
    value = pair.value
end
// Generate Add Card And Payment form parameters

var amount = 1990;
var currency = 'EUR';
var orderId = '1000123A';
var description = 'A Box of Dreams. 19,90€';

var formContainer = formBuilder.generateAddCardAndPaymentParameters(
        successUri, 
        failureUri, 
        cancelUri, 
        language, 
        amount, 
        currency, 
        orderId, 
        description
    );

// read form parameters
var httpMethod = formContainer.method;
var actionUrl = formContainer.getAction();
var fields = formContainer.nameValuePairs;

fields.forEach(function(field) {
    var name = field.first;
    var value = field.second;
});  
<?php
$amount = "1990";
$currency = "EUR";
$orderId = "1000123A";
$description = "A Box of Dreams. 19,90€";

$form = $formBuilder->generateAddCardAndPaymentParameters($amount, $currency, $orderId, $description);

// read form parameters
$httpMethod = $form->getMethod();
$actionUrl = $form->getAction();
$parameters = $form->getParameters(); 

// Header parameters as key => value array
foreach ($parameters as $key => $value) {
    echo $key .":". $value;
}

This method combines a payment and adding a new card to allow getting the card token after a successful payment with a single request.

HTTP Request

POST /form/view/add_and_pay_with_card

The request and response parameters are exactly the same as in the Payment.

Payment with token and CVC

The CVC Form is shown in the Payment Highway. The response to the success-url contains a sph-transaction-id for committing the transaction through the Payment API.

HTTP Request

POST /form/view/pay_with_token_and_cvc

Parameter Data type  M/O Description
sph-account AN M Account identifier
sph-merchant AN M Account merchant identifier
sph-order AN M Merchant defined order identifier. Should be unique per transaction.
sph-request-id UUID4 M Request identifier
sph-amount N M Amount in the lowest currency unit. E.g. 99,00 € = 9900
sph-currency  A M Currency code “EUR”
sph-timestamp AN M Request timestamp in ISO 8601
combined date and time in UTC.
E.g. “2025-09-18T10:32:59Z”
sph-success-url URL M Success URL user is redirected to on success
sph-failure-url URL M Failure URL user is redirected to on failure
sph-cancel-url  URL  M Cancel URL user is redirected to on cancel
sph-webhook-success-url URL O On success, server to server GET request will be made to this url with same parameters as success redirect.
sph-webhook-failure-url URL O On failure, server to server GET request will be made to this url with same parameters as failure redirect.
sph-webhook-cancel-url URL O On cancel, server to server GET request will be made to this url with same parameters as cancel redirect.
sph-webhook-delay N O webhook call delay in seconds (MAX. 900). If omitted, default value 0 will be used.
sph-show-payment-method-selector BOOLEAN O Payment method selector is shown and end user can choose either card payment or Masterpass payment.
sph-token UUID4 M The card token to charge.
sph-api-version VERSION O API version number
language A O Language code (ISO 639-1)(FI/EN/SV)
description ANS O The order description shown to the user
sph-skip-form-notifications BOOLEAN O Skip errors displayed on the Payment Highway form and redirect directly to result URL (E.g. “Ecom payments disabled”) . Default false.
sph-exit-iframe-on-result BOOLEAN O Exit from iframe after redirection to result URLs.
sph-exit-iframe-on-three-d-secure BOOLEAN O Exit from iframe when redirecting user to 3DS.
sph-use-three-d-secure BOOLEAN O Force enable/disable 3DS authentication. Omit / null to use default configured parameter. Disable only if permitted by Your acquiring contract!
signature ANS M Message signature in the format key-id:authentication-string

Webhooks have same parameters as success, failure and cancel responses.

Failure Response for Payment with token and CVC

On failure the user is redirected to the given failure URL sph-failure-url.

A user is redirected to the failure-url, if processing of the request failed for example due to missing parameters, authentication issues or connectivity issues to the authorizing parties.

Parameter Data type Description
sph-account AN Account identifier from request
sph-merchant AN Account merchant identifier from request
sph-order AN Merchant defined order identifier
sph-request-id UUID4 Request identifier from request
sph-timestamp AN Response timestamp in ISO 8601
combined date and time in UTC.
E.g. 2025-09-18T10:33:49Z
sph-failure AN Failure reason, one of:
  • “UNAUTHORIZED”
  • “INVALID”
  • “FAILURE”
  • “NO_ROUTE” (Equivalent to response code 940)
  • “TOKEN_NOT_FOUND”
  • “THREE_D_SECURE” (Technical failure in 3D secure)
  • “MASTERPASS_NOT_SUPPORTED”
  • MASTERPASS
signature ANS Message signature

Success and Cancel Responses

The Success and Cancel Responses are exactly the same as in the Payment.

When a user is redirected to the success-url, it means we have successfully completed processing of the request. It does not however mean the card payment or tokenization was accepted by the authorizing parties. You will find out the actual result using the PaymentAPI (server-to-server) commit or tokenization requests.

Payment with MobilePay

curl -i --data-urlencode '
sph-account=test
sph-merchant=test_merchantId
sph-order=1000123A
sph-request-id=f47ac10b-58cc-4372-a567-0e02b2c3d479
sph-amount=990
sph-currency=EUR
sph-timestamp=2014-09-18T10:32:59Z
sph-success-url=https://merchant.example.com/payment/success
sph-failure-url=https://merchant.example.com/payment/failure
sph-cancel-url=https://merchant.example.com/payment/cancel
language=fi
description=Example payment of 10 balloons á 0,99EUR
signature= SPH1 testKey af9cf1b9a967f6415bb8c4dea8629db0d47edf8ee037c8af1a8bb0eb5aca68e1' \
    https://v1-hub-staging.sph-test-solinor.com/form/view/mobilepay
// Generate Add Card And Payment form parameters

String amount = "1990";
String currency = "EUR";
String orderId = "1000123A";
String description = "A Box of Dreams. 19,90€";
Boolean exitIframeOnResult = null;
String shopLogoUrl = "https://foo.bar/biz.png";

FormContainer formContainer = formBuilder.mobilePayParametersBuilder(
            successUrl, 
            failureUrl, 
            cancelUrl,
            amount, 
            currency, 
            orderId, 
            description,
            exitIframeOnResult,
            shopLogoUrl
        )
        .build();

// read form parameters
String httpMethod = formContainer.getMethod();
String actionUrl = formContainer.getAction();
List<NameValuePair> fields = formContainer.getFields();

for (NameValuePair field : fields) {
    field.getName();
    field.getValue();
}
// Generate Add Card And Payment form parameters

var amount = 1990;
var currency = 'EUR';
var orderId = '1000123A';
var description = 'A Box of Dreams. 19,90€';
var exitIframeOnResult = undefined;
var shopLogoUrl = 'https://foo.bar/biz.png';

var formContainer = formBuilder.generatePayWithMobilePayParameters(
        successUri, 
        failureUri, 
        cancelUri, 
        language, 
        amount, 
        currency, 
        orderId, 
        description,
        exitIframeOnResult,
        shopLogoUrl
    );


// read form parameters
var httpMethod = formContainer.method;
var actionUrl = formContainer.getAction();
var fields = formContainer.nameValuePairs;

fields.forEach(function(field) {
    var name = field.first;
    var value = field.second;
});  
<?php
$amount = "1990";
$currency = "EUR";
$orderId = "1000123A";
$description = "A Box of Dreams. 19,90€";
$exitIframeOnResult = null;
$shopLogoUrl = "https://foo.bar/biz.png";

$form = $formBuilder->generatePayWithMobilePayParameters(
        $amount, 
        $currency, 
        $orderId, 
        $description,
        $exitIframeOnResult,
        $shopLogoUrl
    );

// read form parameters
$httpMethod = $form->getMethod();
$actionUrl = $form->getAction();
$parameters = $form->getParameters(); 

// Header parameters as key => value array
foreach ($parameters as $key => $value) {
    echo $key .":". $value;
}

This method opens either Danske Bank’s MobilePay page or Danske Bank’s MobilePay application, depending if user is making payment with handheld device or PC.


Your card will not be charged.

Simple flow

  1. Open MobilePay with Form API POST /form/view/mobilepay
    -> return an sph-transaction-id and signature as a GET parameters to the given success-url
  2. Commit payment with Payment API POST /transaction/<sph-transaction-id>/commit
    —> returns a result in JSON formatting

HTTP Request

POST /form/view/mobilepay

Parameter Data type  M/O Description
sph-account AN M Account identifier
sph-merchant AN M Account merchant identifier
sph-order AN M Merchant defined order identifier. Should be unique per transaction.
sph-request-id UUID4 M Request identifier
sph-amount N M Amount in the lowest currency unit. E.g. 99,00 € = 9900
sph-currency  A M Currency code “EUR”
sph-shop-logo-url URL O The logo must be 250x250 pixel in .png format and must be hosted on a HTTPS (secure) server.
sph-mobilepay-phone-number AN O Customer phone number with country code e.q. +358449876543. Makes it easier for the customer to identify himself toward the MPO Website.
sph-mobilepay-shop-name Max 100 AN O Name of the shop/merchant. MobilePay app displays this under the shop logo. If omitted, the merchant name from PH is used.
sph-timestamp AN M Request timestamp in ISO 8601
combined date and time in UTC.
E.g. “2025-09-18T10:32:59Z”
sph-success-url URL M Success URL user is redirected to on success
sph-failure-url URL M Failure URL user is redirected to on failure
sph-webhook-success-url URL O On success, server to server GET request will be made to this url with same parameters as success redirect.
sph-webhook-failure-url URL O On failure, server to server GET request will be made to this url with same parameters as failure redirect.
sph-webhook-cancel-url URL O On cancel, server to server GET request will be made to this url with same parameters as cancel redirect.
sph-webhook-delay N O webhook call delay in seconds (MAX. 900). If omitted, default value 0 will be used.
sph-cancel-url  URL  M Cancel URL user is redirected to on cancel
sph-api-version VERSION O API version number
language A O Language code (ISO 639-1)(FI/EN/SV)
description ANS O The order description shown to the user
signature ANS M Message signature in the format key-id:authentication-string
sph-exit-iframe-on-result BOOLEAN O Exit from iframe after redirection to result URLs.

About shop logo in MobilePay

Webhooks have same parameters as success, failure and cancel responses.

Failure Response for Payment with MobilePay

On failure the user is redirected to the given failure URL sph-failure-url.

A user is redirected to the failure-url, if processing of the request failed for example due to missing parameters, authentication issues or connectivity issues to the authorizing parties.

Parameter Data type Description
sph-account AN Account identifier from request
sph-merchant AN Account merchant identifier from request
sph-order AN Merchant defined order identifier
sph-request-id UUID4 Request identifier from request
sph-timestamp AN Response timestamp in ISO 8601
combined date and time in UTC.
E.g. 2025-09-18T10:33:49Z
sph-failure AN Failure reason, one of:
  • “UNAUTHORIZED”
  • “INVALID”
  • “FAILURE”
  • “NO_ROUTE” (Equivalent to response code 940)
  • “MOBILEPAY_NOT_SUPPORTED”
  • “MOBILEPAY”
signature ANS Message signature

Success and Cancel Responses

The Success and Cancel Responses are exactly the same as in the Payment.

When a user is redirected to the success-url, it means we have successfully completed processing of the request. It does not however mean the card payment or tokenization was accepted by the authorizing parties. You will find out the actual result using the PaymentAPI (server-to-server) commit or tokenization requests.

Using Payment Highway and MobilePay in Mobile application

Payment with Masterpass

// Generate Masterpass form parameters

Long amount = 1990L;
String currency = "EUR";
String orderId = "1000123A";
String description = "A Box of Dreams. 19,90€";

FormContainer formContainer = formBuilder.masterpassParameters(
    successUrl,
    failureUrl,
    cancelUrl,
    amount,
    currency,
    orderId,
    description
)
    .build();

// read form parameters
String httpMethod = formContainer.getMethod();
String actionUrl = formContainer.getAction();
List<NameValuePair> fields = formContainer.getFields();

for (NameValuePair field : fields) {
    field.getName();
    field.getValue();
}
// Generate Masterpass form parameters

var amount = 1990;
var currency = 'EUR';
var orderId = '1000123A';
var description = 'A Box of Dreams. 19,90€';

var formContainer = formBuilder.generateMasterPassParameters(
        successUrl, 
        failureUrl, 
        cancelUrl, 
        language, 
        amount, 
        currency, 
        orderId, 
        description
    );

// read form parameters
var httpMethod = formContainer.method;
var actionUrl = formContainer.getAction();
var fields = formContainer.nameValuePairs;


fields.forEach(function(field) {
    var name = field.first;
    var value = field.second;
});  
<?php
$amount = "1990";
$currency = "EUR";
$orderId = "1000123A";
$description = "A Box of Dreams. 19,90€";

$form = $formbuilder->generateMasterpassParameters(
            $amount, 
            $currency, 
            $orderId, 
            $description
        );

// read form parameters
$httpMethod = $form->getMethod();
$actionUrl = $form->getAction();
$parameters = $form->getParameters(); 

// Header parameters as key => value array
foreach ($parameters as $key => $value) {
    echo $key .":". $value;
}

With sph-show-payment-method-selector-parameter in Payment-method or Payment & Add Card, payment method selector is shown and end user can choose either card payment or Masterpass payment.

HTTP Request

POST /form/view/masterpass

Parameter Data type  M/O Description
sph-account AN M Account identifier
sph-merchant AN M Account merchant identifier
sph-order ORDER-ID M Merchant defined order identifier. Should be unique per transaction.
sph-request-id UUID4 M Request identifier
sph-amount N M Amount in the lowest currency unit. E.g. 99,00 € = 9900
sph-currency  A M Currency code “EUR”
sph-timestamp AN M Request timestamp in ISO 8601
combined date and time in UTC.
E.g. “2025-09-18T10:32:59Z”
sph-success-url URL M Success URL user is redirected to on success
sph-failure-url URL M Failure URL user is redirected to on failure
sph-cancel-url  URL  M Cancel URL user is redirected to on cancel
sph-webhook-success-url URL O On success, server to server GET request will be made to this url with same parameters as success redirect.
sph-webhook-failure-url URL O On failure, server to server GET request will be made to this url with same parameters as failure redirect.
sph-webhook-cancel-url URL O On cancel, server to server GET request will be made to this url with same parameters as cancel redirect.
sph-webhook-delay N O Webhook call delay in seconds (MAX. 900). If omitted, default value 0 will be used.
sph-api-version VERSION O API version number
language A O Language code (ISO 639-1)(FI/EN/SV)
description ANS O The order description shown to the user
sph-exit-iframe-on-result BOOLEAN O Exit from iframe after redirection to result URLs.
sph-exit-iframe-on-three-d-secure BOOLEAN O Exit from iframe when redirecting user to 3DS.
sph-use-three-d-secure BOOLEAN O Force enable/disable 3DS authentication. Omit / null to use default configured parameter. Disable only if permitted by Your acquiring contract!
signature ANS M Message signature in the format key-id:authentication-string

Webhooks have same parameters as success, failure and cancel responses.

Success and Cancel Responses

The Success and Cancel Responses are exactly the same as in the Payment.

Failure Response for Payment with Masterpass

On failure the user is redirected to the given failure URL sph-failure-url.

A user is redirected to the failure-url, if processing of the request failed for example due to missing parameters, authentication issues or connectivity issues to the authorizing parties.

Parameter Data type Description
sph-account AN Account identifier from request
sph-merchant AN Account merchant identifier from request
sph-order AN Merchant defined order identifier
sph-request-id UUID4 Request identifier from request
sph-timestamp AN Response timestamp in ISO 8601
combined date and time in UTC.
E.g. 2025-09-18T10:33:49Z
sph-failure AN Failure reason, one of:
  • “UNAUTHORIZED”
  • “INVALID”
  • “FAILURE”
  • “NO_ROUTE” (Equivalent to response code 940)
  • “MASTERPASS_NOT_SUPPORTED”
  • “MASTERPASS”
signature ANS Message signature

Payment with Masterpass and User Profile

// Generate Masterpass with profile form parameters

Long amount = 2999;
String currency = "EUR";
String orderId = "12345678";
String description = "Example Masterpass payment";

FormContainer formContainer = formBuilder.masterpassWithProfileParameters(
    successUrl,
    failureUrl,
    cancelUrl,
    amount,
    currency,
    orderId,
    description
)
    .requestShippingAddress(true)
    .build();

// read form parameters
String httpMethod = formContainer.getMethod();
String actionUrl = formContainer.getAction();
List<NameValuePair> fields = formContainer.getFields();

for (NameValuePair field : fields) {
    field.getName();
    field.getValue();
}

HTTP Request

POST /form/view/masterpass_with_profile

Parameter Data type  M/O Description
sph-account AN M Account identifier
sph-merchant AN M Account merchant identifier
sph-order ORDER-ID M Merchant defined order identifier. Should be unique per transaction.
sph-request-id UUID4 M Request identifier
sph-amount N M Amount in the lowest currency unit. E.g. 99,00 € = 9900
sph-currency  A M Currency code “EUR”
sph-timestamp AN M Request timestamp in ISO 8601
combined date and time in UTC.
E.g. “2025-09-18T10:32:59Z”
sph-success-url URL M Success URL user is redirected to on success
sph-failure-url URL M Failure URL user is redirected to on failure
sph-cancel-url  URL  M Cancel URL user is redirected to on cancel
sph-webhook-success-url URL O On success, server to server GET request will be made to this url with same parameters as success redirect.
sph-webhook-failure-url URL O On failure, server to server GET request will be made to this url with same parameters as failure redirect.
sph-webhook-cancel-url URL O On cancel, server to server GET request will be made to this url with same parameters as cancel redirect.
sph-webhook-delay N O Webhook call delay in seconds (MAX. 900). If omitted, default value 0 will be used.
sph-api-version VERSION O API version number
language A O Language code (ISO 639-1)(FI/EN/SV)
description ANS O The order description shown to the user
sph-exit-iframe-on-result BOOLEAN O Exit from iframe after redirection to result URLs.
sph-exit-iframe-on-three-d-secure BOOLEAN O Exit from iframe when redirecting user to 3DS.
sph-use-three-d-secure BOOLEAN O Force enable/disable 3DS authentication. Omit / null to use default configured parameter. Disable only if permitted by Your acquiring contract!
sph-request-shipping-address BOOLEAN O Request shipping address from the user via Masterpass Wallet
signature ANS M Message signature in the format key-id:authentication-string

Webhooks have same parameters as success, failure and cancel responses.

Success and Cancel Responses

The Success and Cancel Responses are exactly the same as in the Payment, however instead of calling commit, use the following two API calls to finish the payment:

Failure Response for Payment with Masterpass

On failure the user is redirected to the given failure URL sph-failure-url.

A user is redirected to the failure-url, if processing of the request failed for example due to missing parameters, authentication issues or connectivity issues to the authorizing parties.

Parameter Data type Description
sph-account AN Account identifier from request
sph-merchant AN Account merchant identifier from request
sph-order AN Merchant defined order identifier
sph-request-id UUID4 Request identifier from request
sph-timestamp AN Response timestamp in ISO 8601
combined date and time in UTC.
E.g. 2025-09-18T10:33:49Z
sph-failure AN Failure reason, one of:
  • “UNAUTHORIZED”
  • “INVALID”
  • “FAILURE”
  • “NO_ROUTE” (Equivalent to response code 940)
  • “MASTERPASS_NOT_SUPPORTED”
  • “MASTERPASS”
signature ANS Message signature

Payment API

HTTP Interface

The system consists of different resources accessible via HTTPS protocol using the defined mandatory headers for authentication and UTF-8 JSON body for the POST requests.

HTTP response code is always 200 for successful HTTP calls. Anything else indicates a system or communication level failure.

Mandatory headers for both requests and responses are Content-Type, Content-Length and the Custom Headers. Valid values for Content-Type and Content-Length are “application/json; charset=utf-8” and the correct body byte length using UTF-8 encoding.

Headers

In addition to the standard headers, the following custom headers are used.

All the HTTP requests must contain the following headers:

  1. Signature: ”” = The signature header used for authentication and message consistency, see the following section.
  2. SPH-Account: ”example_account”= (High level) account name associated with the authentication key.
  3. SPH-Merchant: ”example_merchant” = The account’s sub-account, which provides optional merchant level customization.
  4. SPH-Timestamp: “yyyy-MM-dd’T'HH:mm:ss'Z'” = Contains the client’s request time in UTC format. Server will check the timestamp does not differ more than five (5) minutes from the correct global UTC time.
  5. SPH-Request-Id: ”12ade018-c562-40bc-a4e6-7f63c69fd90a” = Unique one-time- use Request ID in UUID4 format.

Optionally the HTTP request may contain the following headers:

  1. Sph-Api-Version: “yyyyMMdd” = The version date of the JSON response schema. Defaults to “20141215”.

All the HTTP responses contain the following headers:

  1. Signature: ”” see the following section.
  2. SPH-Response-Id: ”03c15388-bebc-4872-b3f5-faed0ca65ff6” = Unique one-time- use Response ID in UUID4 format.
  3. SPH-Timestamp: “yyyy-MM-dd’T'HH:mm:ss'Z'” which contains the servers response time in UTC format. When the client receives the response, the timestamp must be checked and it must not differ more than five (5) minutes from the correct global UTC time.
  4. SPH-Request-Id: ”12ade018-c562-40bc-a4e6-7f63c69fd90a” = Same as the request UUID4.

Errors

try {
  // Use Payment Highway's bindings...
} catch (AuthenticationException e) {
  // signals a failure to authenticate Payment Highway response
} catch (HttpResponseException e) {
  // Signals a non 2xx HTTP response.
  // Invalid parameters were supplied to Payment Highway's API
} catch (IOException e) {
  // Signals that an I/O exception of some sort has occurred
} catch (Exception e) {
  // Something else happened
}
begin
  // Use Payment Highway's bindings...
rescue PaymentHighway::Exception::AuthenticationException => e
  // Signals a failure to authenticate Payment Highway response
rescue PaymentHighway::Exception::HttpResponseException => e
  // Signals a non 2xx HTTP response or a 2xx HTTP response not containing the required headers
  // Invalid parameters were supplied to Payment Highway's API
rescue ArgumentError => e
  // A function was called with an argument of invalid type
rescue RuntimeError => e
  // PaymentHighway functioned in an unexpected way
rescue Exception => e
  // Something else happened
PaymentHighwayAPI.initTransaction()
  .then(function(initResponse){
    // handle response
    ...
  })
  .catch(function(error) {
    // handle errors
    ...
  });  
<?php
try {
    // Use Payment Highway's bindings...
} 
catch (Exception $e) {
    // Something else happened
}

Payment Highway clients can raise exceptions for several reasons. Payment Highway authenticates each request and if there is invalid parameters or a signature mismatch, a HttpResponseException is raised.

The Payment Highway clients also authenticate response messages, and in case of signature mismatch an AuthenticationException will be raised.

It is recommended to gracefully handle exceptions from the API.

Authentication

String serviceUrl = "https://v1-hub-staging.sph-test-solinor.com";
String signatureKeyId = "testKey";
String signatureSecret = "testSecret";
String account = "test";
String merchant = "test_merchantId";

try (PaymentAPI paymentAPI = new PaymentAPI(serviceUrl, signatureKeyId, signatureSecret, account, merchant)) {
  // Use paymentAPI to create debit requests etc.
}
service_url = "https://v1-hub-staging.sph-test-solinor.com"
signature_key_id = "testKey"
signature_secret = "testSecret"
account = "test"
merchant = "test_merchantId"

payment_api = PaymentHighway::PaymentApi.new(service_url, signature_key_id, signature_secret, account, merchant)
  // Use payment_api to create debit requests etc.
var serviceUrl = "https://v1-hub-staging.sph-test-solinor.com";
var testKey = 'testKey';
var testSecret = 'testSecret';
var account = 'test';
var merchant = 'test_merchantId';

var paymentAPI = new PaymentAPI(
                serviceUrl, 
                testKey, 
                testSecret, 
                account, 
                merchant
        );
// Use paymentAPI to create debit requests etc.
<?php
use Solinor\PaymentHighway\PaymentApi;

$serviceUrl = "https://v1-hub-staging.sph-test-solinor.com";
$signatureKeyId = "testKey";
$signatureSecret = "testSecret";
$account = "test";
$merchant = "test_merchantId";

$paymentApi = new PaymentApi(
                    $serviceUrl, 
                    $signatureKeyId, 
                    $signatureSecret, 
                    $account, 
                    $merchant
                );

Signatures

Request authentication and the response signatures are calculated by applying the HMAC- SHA256 method (RFC 2104 - Keyed-Hashing for Message Authentication, http://www.ietf.org/rfc/rfc2104.txt) to the defined concatenated string using the secret key provided to the account user.

A signature is transmitted Hex encoded in the ”Signature” HTTP header with the signature value prefixed with the strings “SPH1” and “secretKeyID”, where the secretKeyID is the ID of the key used in the HMAC calculation. The strings are separated with blank spaces (0x20) thus the header would look like: “Signature: SPH1 secretKeyId signature”

The concatenated string consists of the following fields separated with a new line (“\n”):

# Example of a string used for signature calculation
POST
/transaction/859cefdf-41fa-453a-a6a5-beff35e2f3b8/debit
sph-account:test
sph-merchant:test_merchantId
sph-request-id:12ade018-c562-40bc-a4e6-7f63c69fd90a
sph-timestamp:2014-09-18T14:09:25Z
{”some”:”body”{”json”:1}}

The client must check the response signature in order to verify the authenticity of the response.

Message body

The messaging format is standard compliant JSON using UTF-8 encoding. Each request and response has a set of mandatory and optional fields, which values are validated using the included regular expression rules. A GET request does not have a request body whereas a POST request often does, and both of these always receive response body.

Commit Payment

Commit Form Payment

curl -i \
-H "Content-Type: application/json; charset=utf-8" \
-H "SPH-Account: test" \
-H "SPH-Merchant: test_merchantId" \
-H "SPH-Timestamp: 2014-09-18T10:32:59Z" \
-H "SPH-Request-Id: f47ac10b-58cc-4372-a567-0e02b2c3d479" \
-H "Signature: SPH1 testKey 4eab87a16e3ee7bd530d778af0cb6c680dcaa52ed1913a9c1bd8ed5a8d689e3e" \
--data-urlencode '
{
    "amount":1990,
    "currency":"EUR"
} ' \
https://v1-hub-staging.sph-test-solinor.com/transaction/202eee01-a6cb-432a-a725-175c32b887d2/commit
# Replace the transaction ID with the one retrieved from the Form API sph-transaction-id return parameter.
String transactionId = "f23a9be0-15fe-43df-98ac-92f6a5731c3b"; // get sph-transaction-id as a GET parameter
String amount = "1990";
String currency = "EUR";
CommitTransactionResponse response = paymentAPI.commitTransaction(transactionId, amount, currency);

response.getResult().getCode(); // 100
transaction_id = "f23a9be0-15fe-43df-98ac-92f6a5731c3b" // get sph-transaction-id as a GET parameter
amount = 1990
currency = "EUR"
commit_transaction_response = payment_api.commit_transaction(transaction_id, amount, currency)

commit_transaction_response.result.code // 100
var transactionId = 'f23a9be0-15fe-43df-98ac-92f6a5731c3b'; // get sph-transaction-id as a GET parameter
var amount = 1990;
var currency = 'EUR';
var request = new paymentHighway.CommitTransactionRequest(amount, currency);

paymentAPI.commitTransaction(transactionId, request)
    .then(function(response){
        var resultCode = response.result.code; // Should be 100, if OK 
    });
<?php
$transactionId = "f23a9be0-15fe-43df-98ac-92f6a5731c3b"; // get sph-transaction-id as a GET parameter
$amount = 1999;
$currency = "EUR";

$response = $paymentApi->commitFormTransaction($transactionId, $amount, $currency ); 

$response->body->result->code; // 100

JSON Response

{
  "committed": true,
  "committed_amount": 9999,
  "filing_code": "161005089712",
  "card":
  {
    "type":"Visa",
    "partial_pan":"0024",
    "expire_year":"2023",
    "expire_month":"11",
    "cvc_required": "no",
    "bin": "415301",
    "funding": "debit",
    "country_code": "FI",
    "category": "unknown"
  },
  "card_token":"71435029-fbb6-4506-aa86-8529efb640b0",
  "cardholder_authentication" : "no",
  "result":
  {
    "code":100,
    "message":"OK"
  }
}

In order to finalize (capture) a payment performed via Form API (“Payment”, “Payment & Add Card” or “Payment with token and CVC”), the corresponding sph-transaction-id must be committed.

The same applies for a “Charge a card” payment API request when the automatic commit is disabled for auth & capture using the “commit” parameter as “false”. In this case the transaction ID must be committed as well.

The commit amount must be equal or less than the original payment amount. One payment can only be committed once.

Up to 7 days old transactions can be committed.

In order to find out the result of the form payment without committing it, use the “Transaction result” request instead.

HTTP Request

POST /transaction/<:transaction_id>/commit

Field / Object M/O Data type Description
amount M AMOUNT Amount in the smallest currency unit. E.g. 99.99 € = 9999
currency M CURRENCY ISO 4217 currency code

HTTP Response

Field / Object M/O Data type Description
card_token O UUID4 Present on a successful commit. See also card.cvc_required below.
card O Present on a successful commit. See also card.cvc_required below.
card.partial_pan M
card.type M Card type, for example ‘Visa’
card.partial_pan M Last four digits of the card
card.expire_year M Card expiration year
card.expire_month M Card expiration month
card.cvc_required M Whether the CVC is required for paying with this card. Can be one of “yes” or “no”.
card.bin M First 2 or 6 digits of the card number. (6 MC/VISA, 2 Amex/Diners)
card.funding M “credit”, “debit” or “unknown”
card.category M “business”, “prepaid” or “unknown”
card.country_code O ISO 3166-1 alpha-2
customer O
customer.network_address O IP The IP address of the customer for fraud detection purposes
customer.country_code O ISO 3166-1 alpha-2
cardholder_authentication M Indicates whether ThreeDS (3ds) card holder authentication was done (“authenticated”, “attempted” or “no”)
result M
result.code M RCODE
result.message M RMSG
committed M BOOLEAN
committed_amount O AMOUNT Omitted if “committed” is false
filing_code M

User profile

This api is available only for Masterpass transactions. It is is mainly intended for fetching shipping address before calculating shipping cost.

Fetch User Profile for transaction

String transactionId = "327c6f29-9b46-40b9-b85b-85e908015d92"; // get sph-transaction-id as a GET parameter

UserProfileResponse response = paymentAPI.userProfile(transactionId);

response.getResult().getCode(); // 100

JSON Response

{
  "card":
  {
    "type":"MasterCard",
    "partial_pan":"0107",
    "expire_year":"2019",
    "expire_month":"12",
    "cvc_required":"not_tested",
    "bin":"550690",
    "funding":"credit",
    "country_code":"US",
    "category":"unknown"
  },
  "customer":
  {
    "network_address":"83.145.208.186",
    "country_code":"FI"
  },
  "cardholder_authentication":"no",
  "masterpass":
  {
    "amount":100,
    "currency":"EUR",
    "checkout_oauth_token":"8dddb475e23bf96ed70082455c7c599596f12986",
    "masterpass_transaction_id":"2468807694572615629",
    "masterpass_wallet_id":"101"
  },
  "profile":
  {
    "first_name":"Matti",
    "last_name":"Meikäläinen",
    "country":"FI",
    "email_address":"matti.meikalainen@gmail.com",
    "phone_number":"0501234567",
    "billing_address":
    {
      "line1":"Kampinkuja 2",
      "postal_code":"00100",
      "city":"Helsinki",
      "country":"FI"
    },
    "shipping_address":
    {
      "recipient_name":"Matti Meikäläinen",
      "recipient_phone_number":"0501234567",
      "line1":"Kampinkuja 2",
      "postal_code":"00100",
      "city":"Helsinki",
      "country":"FI"
    }
  },
  "result":
  {
    "code":100,
    "message":"OK"
  }
}

After fetching user profile for the transaction, Masterpass debit transaction can be performed.

HTTP Request

GET /transaction/<:transaction_id>/user_profile

HTTP Response

Field / Object M/O Data type Description
card O Present on a successful Masterpass transaction.
card.partial_pan M
card.type M Card type, for example ‘Visa’
card.partial_pan M Last four digits of the card
card.expire_year M Card expiration year
card.expire_month M Card expiration month
card.cvc_required M Whether the CVC is required for paying with this card. Can be one of “yes” or “no”.
card.bin M First 2 or 6 digits of the card number. (6 MC/VISA, 2 Amex/Diners)
card.funding M “credit”, “debit” or “unknown”
card.category M “business”, “prepaid” or “unknown”
card.country_code O ISO 3166-1 alpha-2
customer O
customer.network_address O IP The IP address of the customer for fraud detection purposes
customer.country_code O ISO 3166-1 alpha-2
cardholder_authentication O Indicates whether ThreeDS (3ds) card holder authentication was done (“authenticated”, “attempted” or “no”)
masterpass C Masterpass info, mandatory for masterpass transactions
masterpass.amount M AMOUNT Amount in the smallest currency unit. E.g. 99.99 € = 9999
masterpass.currency M CURRENCY ISO 4217 currency code
masterpass.checkout_oauth_token M AN Checkout token given by Masterpass (for communicating with them)
masterpass.masterpass_transaction_id M AN Transaction id given by Masterpass (for communicating with them)
masterpass.masterpass_wallet_id M N Wallet id, 101 for Masterpass hosted wallets, (for example. 340 for Nordea hosted wallets)
profile M
profile.first_name O
profile.middle_name O
profile.last_name O
profile.gender O AN M or F
profile.date_of_birth O
profile.date_of_birth.year M N Year of birth
profile.date_of_birth.month M N Month of birth
profile.date_of_birth.day M N Day of birth
profile.national_id O
profile.country O AN The cardholder’s country. Defined by ISO 3166-1 alpha-2 digit country codes, for example, US is United States, AU is Australia, CA is Canada, GB is United Kingdom, and so on.
profile.email_address O
profile.phone_number O
profile.billing_address O
profile.billing_address.line1 M
profile.billing_address.line2 O
profile.billing_address.line3 O
profile.billing_address.postal_code O
profile.billing_address.city M
profile.billing_address.country_subdivision O AN the cardholder’s country subdivision. Defined by ISO 3166-1 alpha-2 digit code, for example, US-VA is Virginia, US-OH is Ohio
profile.billing_address.country M AN The cardholder’s country. Defined by ISO 3166-1 alpha-2 digit country codes, for example, US is United States, AU is Australia, CA is Canada, GB is United Kingdom, and so on.
profile.shipping_address O
profile.shipping_address.recipient_name O
profile.shipping_address.recipient_phone_number O
profile.shipping_address.line1 M
profile.shipping_address.line2 O
profile.shipping_address.line3 O
profile.shipping_address.postal_code O
profile.shipping_address.city M
profile.shipping_address.country_subdivision O AN the cardholder’s country subdivision. Defined by ISO 3166-1 alpha-2 digit code, for example, US-VA is Virginia, US-OH is Ohio
profile.shipping_address.country M AN The cardholder’s country. Defined by ISO 3166-1 alpha-2 digit country codes, for example, US is United States, AU is Australia, CA is Canada, GB is United Kingdom, and so on.
result M
result.code M RCODE
result.message M RMSG

Transaction result

Used to find out whether or not an uncommitted transaction succeeded, without actually committing (capturing) it.

HTTP Request

POST /transaction/<:transaction_id>/result

Responses

Responses are exactly the same as in the Commit.

Charge a card

In order to do safe transactions, an execution model is used where the first call to /transaction acquires a financial transaction handle, later referred as “ID”, which ensures the transaction is executed exactly once. Afterwards it is possible to execute a debit transaction by calling /transaction/<:transaction_id>/debit using the received ID handle. If the execution fails, the command can be repeated in order to confirm the transaction with the particular ID has been processed. After executing the command, the status of the transaction can be checked by executing a GET request to the /transaction/<:transaction_id> resource.

Init transaction handle

Init the transaction handle and get the ID for it.

Init transaction handle

curl -i \
-H "Content-Type: application/json; charset=utf-8" \
-H "SPH-Account: test" \
-H "SPH-Merchant: test_merchantId" \
-H "SPH-Timestamp: 2014-09-18T10:32:59Z" \
-H "SPH-Request-Id: f47ac10b-58cc-4372-a567-0e02b2c3d479" \
-H "Signature: SPH1 testKey 4eab87a16e3ee7bd530d778af0cb6c680dcaa52ed1913a9c1bd8ed5a8d689e3e" \
--data "" \
https://v1-hub-staging.sph-test-solinor.com/transaction
InitTransactionResponse initResponse = paymentAPI.initTransaction();

initResponse.getResult().getCode(); // 100
init_response = payment_api.init_transaction_handle

init_response.result.code // 100
paymentAPI.initTransaction()
    .then(function(response){
        var resultCode = response.result.code; // 100
    });
<?php
$response = $paymentApi->initTransaction();

$response->body->result->code; // 100

JSON Response

{
  "id":"ebf19bf4-2ea7-4a29-8a90-f1abec66c57d",
  "result":
  {
    "code":100,
    "message":"OK"
  }
}

HTTP Request

POST /transaction

HTTP Response

Field / Object M/O Data type Description
id M UUID4 The handle for the following requests.
result M
result.code M RCODE
result.message M RMSG

Debit transaction

Charge a card token (debit transaction)

curl -i \
-H "Content-Type: application/json; charset=utf-8" \
-H "SPH-Account: test" \
-H "SPH-Merchant: test_merchantId" \
-H "SPH-Timestamp: 2014-09-18T10:32:59Z" \
-H "SPH-Request-Id: f47ac10b-58cc-4372-a567-0e02b2c3d479" \
-H "Signature: SPH1 testKey 4eab87a16e3ee7bd530d778af0cb6c680dcaa52ed1913a9c1bd8ed5a8d689e3e" \
--data-urlencode '
{
    "amount": 1900,
    "currency": "EUR",
    "token":
    {
        "id": "859aafdf-41fa-453a-a6a5-beff35e2f3b8"
    }
}
' \
https://v1-hub-staging.sph-test-solinor.com/transaction/4d185afe-3ef4-11e4-9d9f-164230d1df67/debit
// Debit with Token

Token token = new Token("859aafdf-41fa-453a-a6a5-beff35e2f3b8");
long amount = 1990L;
String currency = "EUR";

TransactionRequest transaction = TransactionRequest.Builder(token, amount, currency)
  .setOrder("XY123456") // Order id
  .build();

String transactionId = "f23a9be0-15fe-43df-98ac-92f6a5731c3b";
TransactionResponse response = paymentAPI.debitTransaction(transactionId, transaction);

response.getResult().getCode(); // 100
// Debit with Token

amount = 1000
transaction_request = PaymentHighway::Request::TransactionRequest.new("tokenization_id", amount, "currency")
// instead of tokenization_id, you can also give an instance of "Request::Card"

transaction_response = payment_api.debit_transaction("transaction_id", transaction_request)

transaction_response.result.code // 100
// Debit with Token

var token = new paymentHighway.Token('tokenId');
var amount = 1990;
var currency = 'EUR';

var request = new paymentHighway.TransactionRequest(token, amount, currency);
paymentAPI.initTransaction()
    .then(function (init) {
        return paymentAPI.debitTransaction(init.id, request);
    })
    .then(function(debit) {
        debit.result.code; // 100
    });
<?php
use Solinor\PaymentHighway\Model;
use Solinor\PaymentHighway\Model\Request;

$token = new Token( $tokenId );
$transaction = new Transaction( $token, $amount, $currency );

$transactionId = "f23a9be0-15fe-43df-98ac-92f6a5731c3b";
$response = $paymentApi->debitTransaction( transactionId, $transaction);

$response->body->result->code; // 100

JSON Response

{
  "result":
  {
    "code":100,
    "message":"OK"
  },
  "filing_code": "161005089712"
}

HTTP Requests

POST /transaction/<:transaction_id>/debit

Create a debit transaction to charge a card.

Field / Object M/O Data type Description
amount M AMOUNT Amount in the smallest currency unit. E.g. 99.99 € = 9999
currency M CURRENCY ISO 4217 currency code
token M/O Either card or token must be included
token.id M UUID4
token.cvc O
customer O
customer.network_address O IP The IP address of the customer for fraud detection purposes
customer.country_code O ISO 3166-1 alpha-2
order O ORDER-ID Merchant defined order identifier
card M/O Usage of card is for PCI DSS certified parties only. Typically use token instead.
card.pan M
card.expiry_year M
card.expiry_month M
card.cvc O
card.verification O
commit O BOOLEAN If omitted, “true” is used

HTTP Response

Field / Object M/O Data type Description
result M
result.code M RCODE
result.message M RMSG
filing_code O Omitted on failure

Masterpass debit transaction

Charge the card with the final amount.

// Masterpass debit

long amount = 1990L;
String currency = "EUR";

MasterpassTransactionRequest request = MasterpassTransactionRequest.Builder(amount, currency)
  .build();

UUID transactionId = UUID.fromString("327c6f29-9b46-40b9-b85b-85e908015d92");
TransactionResponse response = paymentAPI.debitTransaction(transactionId, transaction);

response.getResult().getCode(); // 100
{
  "filing_code":"170621187700",
  "result":
  {
    "code":100,
    "message":"OK"
  }
}

HTTP Requests

POST /transaction/<:transaction_id>/debit_masterpass

Charge the card with the final amount (for example after calculating shipping costs). Only the originally given amount will be covered by the 3D-secure liability shift.

Field / Object M/O Data type Description
amount M AMOUNT Amount in the smallest currency unit. E.g. 99.99 € = 9999
currency M CURRENCY ISO 4217 currency code
commit O BOOLEAN If omitted, “true” is used

HTTP Response

Same response as Debit transaction

Order Status

Get the transactions related to a specific order

curl -i \
-H "Content-Type: application/json; charset=utf-8" \
-H "SPH-Account: test" \
-H "SPH-Merchant: test_merchantId" \
-H "SPH-Timestamp: 2014-09-18T10:32:59Z" \
-H "SPH-Request-Id: f47ac10b-58cc-4372-a567-0e02b2c3d479" \
-H "Signature: SPH1 testKey 4eab87a16e3ee7bd530d778af0cb6c680dcaa52ed1913a9c1bd8ed5a8d689e3e" \
https://v1-hub-staging.sph-test-solinor.com/transactions/?order=my_order_id_12345
paymentAPI.searchOrders("order");
<?php
$response = paymentApi->searchByOrderId( $orderId );

JSON response

{
  "transactions":
  [
    {
      "id":"f9cc5892-d3e7-486f-9fb3-cf9a42887118",
      "acquirer":
      {
        "id":"nets",
        "name":"Nets"
      },
      "type":"debit",
      "amount":100,
      "current_amount":100,
      "currency":"EUR",
      "timestamp":"2015-07-03T20:16:41Z",
      "modified":"2015-06-27T13:54:05Z",
      "filing_code":"150703000026",
      "status":
      {
        "state":"failed",
        "code":7000
      },
      "card":
      {
        "type":"Visa",
        "partial_pan":"1234",
        "expire_year":"2023",
        "expire_month":"11",
        "cvc_required":"not_tested"
      },
      "reverts":[],
      "cardholder_authentication": "no",
      "committed": false
    },
    {
      "id":"ca02843a-9942-4944-a1b4-59ade8cc3eca",
      "acquirer":
      {
        "id":"nets",
        "name":"Nets"
      },
      "type":"debit",
      "amount":100,
      "current_amount":0,
      "currency":"EUR",
      "timestamp":"2015-07-03T19:22:03Z",
      "modified":"2015-06-27T13:51:27Z",
      "filing_code":"150703000024",
      "authorization_code":"979855",
      "token":"7906486c-beea-4f69-9f55-29f7ab4b6bef",
      "status":
      {
        "state":"reverted",
        "code":5700
      },
      "card":
      {
        "type":"Visa",
        "partial_pan":"0024",
        "expire_year":"2023",
        "expire_month":"11",
        "cvc_required":"no"
      },
      "reverts":
      [
        {
          "type":"cancellation",
          "status":
          {
            "state":"ok",
            "code":4000
          },
          "amount":100,
          "timestamp":"2015-07-03T20:14:03Z",
          "modified":"2015-06-27T13:51:27Z",
          "filing_code":"150703000024"
        }
      ],
      "cardholder_authentication": "no",
      "committed": true,
      "committed_amount": 100
    }
  ],
  "result":
  {
    "code":100,
    "message":"OK"
  }
}

Get the transaction IDs related to the order value given for the payment. This allows to get the payment transaction ID even in a case where the user’s browser does not redirect back to a given URL in the calling service.

HTTP Request

GET /transactions/?order=<order>[&limit=<limit>][&start-date=<start-date>][&end-date=<end-date>][&start-datetime=<start-timestamp>][&end-datetime=<end-timestamp>]

Parameter M/O Data type Description
order M ORDER-ID Merchant defined order identifier
limit O N (1 - 100) Limit the size of the result set. Defaults to 100.
start-date O DATE Start date for the search. Inclusive.
end-date O DATE End date for the search. Inclusive.
start-datetime O TIMESTAMP Start date and time for the search. Inclusive.
end-datetime O TIMESTAMP End date and time for the search. Inclusive.

HTTP Response

The response JSON contains an array of transaction statuses, where the format is the same as in the response of Transaction Status. The array is ordered by timestamp, newest first.

Field / Object M/O Data type Description
result M
result.code M RCODE
result.message M RMSG
transactions[] M JSON Array All transactions belonging to the order
transaction M
transaction.id M UUID4
transaction.acquirer M
transaction.acquirer.id M
transaction.acquirer.name M
transaction.type M Credit or debit
transaction.amount M AMOUNT Original transaction amount in the smallest currency unit. E.g. 99.99 € = 9999
transaction.current_amount O AMOUNT Amount after possible reversals
transaction.currency M CURRENCY ISO 4217 currency code
transaction.timestamp M TIMESTAMP
transaction.modified M TIMESTAMP Latest transaction modification time
transaction.filing_code M
transaction.authorization_code O
transaction.verification_method O
transaction.token O
transaction.status O
transaction.status.state M TSTATE
transaction.status.code M TCODE
transaction.status.messge O TMSG
transaction.card M
transaction.card.partial_pan M
transaction.card.type M
transaction.card.expire_year M
transaction.card.expire_month M
transaction.card.cvc_required M Whether the CVC is required for paying with this card. Can be one of “yes”, “no” or “not_tested”.
transaction.card.bin M First 2 or 6 digits of the card number. (6 MC/VISA, 2 Amex/Diners)
transaction.card.funding M “credit”, “debit” or “unknown”
transaction.card.category M “business”, “prepaid” or “unknown”
transaction.card.country_code O ISO 3166-1 alpha-2
transaction.reverts O JSON Array Present if the transaction is partially or fully reverted
transaction.reverts.type M REVTYPE
transaction.reverts.status M
transaction.reverts.status.state M TSTATE
transaction.reverts.status.code M TCODE
transaction.reverts.status.message M TMSG
transaction.reverts.amount M AMOUNT Amount in the smallest currency unit. E.g. 99.99 € = 9999
transaction.reverts.timestamp M TIMESTAMP
transaction.reverts.modified M TIMESTAMP L
transaction.customer O
transaction.customer.network_address O IP The IP address of the customer for fraud detection purposes
transaction.customer.country_code O ISO 3166-1 alpha-2
transaction.cardholder_authentication M Indicates whether ThreeDS (3ds) card holder authentication was done (“authenticated”, “attempted” or “no”)
transaction.committed M BOOLEAN
transaction.committed_amount O AMOUNT Omitted if “committed” is false

Revert

Revert a payment transaction

curl -i \
-H "Content-Type: application/json; charset=utf-8" \
-H "SPH-Account: test" \
-H "SPH-Merchant: test_merchantId" \
-H "SPH-Timestamp: 2014-09-18T10:32:59Z" \
-H "SPH-Request-Id: f47ac10b-58cc-4372-a567-0e02b2c3d479" \
-H "Signature: SPH1 testKey 4eab87a16e3ee7bd530d778af0cb6c680dcaa52ed1913a9c1bd8ed5a8d689e3e" \
--data-urlencode '
{
    "amount": 1900
}
' \
https://v1-hub-staging.sph-test-solinor.com/transaction/4d185afe-3ef4-11e4-9d9f-164230d1df67/revert
String transactionId = "f23a9be0-15fe-43df-98ac-92f6a5731c3b";
TransactionResponse response = paymentAPI.revertTransaction(transactionId);

response.getResult().getCode(); // 100
transaction_id = "f23a9be0-15fe-43df-98ac-92f6a5731c3b"
transaction_response = payment_api.revert_transaction(transaction_id)
transaction_response = payment_api.revert_transaction(transaction_id, 1000)

transaction_response.result.code // 100
var transactionId = "f23a9be0-15fe-43df-98ac-92f6a5731c3b";
paymentAPI.revertTransaction(transactionId)
    .then(function(response){
        response.result.code; // 100
    });
<?php
$transactionId = "f23a9be0-15fe-43df-98ac-92f6a5731c3b";
$response = $paymentApi->revertTransaction(transactionId);

$response->body->result->code; // 100

JSON Response

{
  "result":
  {
    "code":100,
    "message":"OK"
  }
}

Reverts an existing debit transaction.

HTTP Request

POST /transaction/<:transaction_id>/revert

Field / Object M/O Data type Description
amount O AMOUNT Amount in the smallest currency unit. E.g. 99.99 € = 9999. Without amount the whole transaction is reverted.

HTTP Response

Field / Object M/O Data type Description
result M
result.code M RCODE
result.message M RMSG

Transaction Status

Transaction status request

curl -i \
-H "Content-Type: application/json; charset=utf-8" \
-H "SPH-Account: test" \
-H "SPH-Merchant: test_merchantId" \
-H "SPH-Timestamp: 2014-09-18T10:32:59Z" \
-H "SPH-Request-Id: f47ac10b-58cc-4372-a567-0e02b2c3d479" \
-H "Signature: SPH1 testKey 4eab87a16e3ee7bd530d778af0cb6c680dcaa52ed1913a9c1bd8ed5a8d689e3e" \
https://v1-hub-staging.sph-test-solinor.com/transaction/4d185afe-3ef4-11e4-9d9f-164230d1df67
String transactionId = "f23a9be0-15fe-43df-98ac-92f6a5731c3b";
TransactionStatusResponse statusResponse = paymentAPI.transactionStatus(transactionId);

statusResponse.getResult().getCode(); // 100
transaction_id = "f23a9be0-15fe-43df-98ac-92f6a5731c3b";
transaction_status_response = payment_api.transaction_status(transaction_id)

transaction_status_response.result.code // 100
var transactionId = "f23a9be0-15fe-43df-98ac-92f6a5731c3b";
paymentAPI.transactionStatus(transactionId)
    .then(function(response){
        response.result.code; // 100
    });
<?php
$transactionId = "f23a9be0-15fe-43df-98ac-92f6a5731c3b";
$status = paymentApi->statusTransaction($transactionId);

$status->body->result->code; // 100

JSON Response

{
  "transaction":
  {
    "id":"5a457896-1b74-48e2-a012-0f1016c64900",
    "acquirer":
    {
      "id":"nets",
      "name":"Nets"
    },
    "type":"debit",
    "amount":9999,
    "current_amount":9999,
    "currency":"EUR",
    "timestamp":"2015-04-28T12:11:12Z",
    "modified":"2015-04-28T12:11:12Z",
    "filing_code":"150428011232",
    "authorization_code":"639283",
    "status":
    {
      "state":"ok",
      "code":4000
    },
    "card":
    {
      "type":"Visa",
      "partial_pan":"0024",
      "expire_year":"2023",
      "expire_month":"11"
    },
    "cardholder_authentication": "no",
    "committed": true,
    "committed_amount": 9999
  },
  "result":
  {
    "code":100,
    "message":"OK"
  }
}

HTTP Request

GET /transaction/<:transaction_id>

HTTP Response

Field / Object M/O Data type Description
result M
result.code M RCODE
result.message M RMSG
transaction M
transaction.id M UUID4
transaction.acquirer M
transaction.acquirer.id M
transaction.acquirer.name M
transaction.type M Credit or debit
transaction.amount M AMOUNT Original transaction amount in the smallest currency unit. E.g. 99.99 € = 9999
transaction.current_amount O AMOUNT Amount after possible reversals
transaction.currency M CURRENCY ISO 4217 currency code
transaction.timestamp M TIMESTAMP
transaction.modified M TIMESTAMP Latest transaction modification time
transaction.filing_code M
transaction.authorization_code O
transaction.token O
transaction.status M
transaction.status.state M TSTATE
transaction.status.code M TCODE
transaction.status.messge O TMSG
transaction.card M
transaction.card.partial_pan M
transaction.card.type M
transaction.card.expire_year M
transaction.card.expire_month M
transaction.card.cvc_required M Whether the CVC is required for paying with this card. Can be one of “yes”, “no” or “not_tested”.
transaction.card.bin M First 2 or 6 digits of the card number. (6 MC/VISA, 2 Amex/Diners)
transaction.card.funding M “credit”, “debit” or “unknown”
transaction.card.category M “business”, “prepaid” or “unknown”
transaction.card.country_code O ISO 3166-1 alpha-2
transaction.reverts M JSON Array Present if the transaction is partially or fully reverted
transaction.reverts.type M REVTYPE
transaction.reverts.status M
transaction.reverts.status.state M TSTATE
transaction.reverts.status.code M TCODE
transaction.reverts.status.message M TMSG
transaction.reverts.amount M AMOUNT Amount in the smallest currency unit. E.g. 99.99 € = 9999
transaction.reverts.timestamp M TIMESTAMP
transaction.reverts.modified M TIMESTAMP Latest revert modification time
transaction.reverts.filing_code O
transaction.customer O
transaction.customer.network_address O IP The IP address of the customer for fraud detection purposes
transaction.customer.country_code O ISO 3166-1 alpha-2
transaction.cardholder_authentication M Indicates whether ThreeDS (3ds) card holder authentication was done (“authenticated”, “attempted” or “no”)
transaction.order O
transaction.committed M
transaction.committed_amount O Omitted if “committed” is false

Tokenization

In order to be sure that a tokenized card is valid and is able to process payment transactions the corresponding sph-tokenization-id must be used to get the actual card token.

The card token is fetched by calling the tokenization URI with the sph-tokenization-id.

Technically the tokenization is already done by a Form API call such as /form/view/add_card as processing an authorization requires a valid CVC given by the cardholder. If the card is valid the Tokenization response contains a card token that can be used to make transactions such as charging the card or refunding the card.

Tokenization request

curl -i \
-H "Content-Type: application/json; charset=utf-8" \
-H "SPH-Account: test" \
-H "SPH-Merchant: test_merchantId" \
-H "SPH-Timestamp: 2014-09-18T10:32:59Z" \
-H "SPH-Request-Id: f47ac10b-58cc-4372-a567-0e02b2c3d479" \
-H "Signature: SPH1 testKey 4eab87a16e3ee7bd530d778af0cb6c680dcaa52ed1913a9c1bd8ed5a8d689e3e" \
https://v1-hub-staging.sph-test-solinor.com/tokenization/4d185afe-3ef4-11e4-9d9f-164230d1df67
TokenizationResponse tokenResponse = paymentAPI.tokenize("tokenizationId");

tokenResponse.getResult().getCode(); // 100
token_response = payment_api.tokenize("tokenization_id")

token_response.result.code // 100
paymentAPI.tokenization("tokenizationId")
    .then(function(response){
        response.result.code; // 100
    })
<?php
$response = $paymentApi->tokenize( $tokenizationId );

$response->body->result->code; // 100

JSON Response

{
  "card_token":"71435029-fbb6-4506-aa86-8529efb640b0",
  "card":
  {
    "type":"Visa",
    "partial_pan":"0024",
    "expire_year":"2023",
    "expire_month":"11"
  },
  "cardholder_authentication": "no",
  "result":
  {
    "code":100,
    "message":"OK"
  }
}

HTTP Request

GET /tokenization/<id>

HTTP Response

Field / Object M/O Data type Description
card_token O UUID4 Card Token if verification was successful
card O Card if verification was successful
card.type M Card type, for example ‘Visa’
card.partial_pan M Last four digits of the card
card.expire_year M Card expiration year
card.expire_month M Card expiration month
card.cvc_required M Whether the CVC is required for paying with this card. Can be one of “yes” or “no”.
card.bin M First 2 or 6 digits of the card number. (6 MC/VISA, 2 Amex/Diners)
card.funding M “credit”, “debit” or “unknown”
card.category M “business”, “prepaid” or “unknown”
card.country_code O ISO 3166-1 alpha-2
customer O
customer.network_address O IP The IP address of the customer for fraud detection purposes
customer.country_code O ISO 3166-1 alpha-2
cardholder_authentication M Indicates whether ThreeDS (3ds) card holder authentication was done (“authenticated”, “attempted” or “no”)
result M
result.code M RCODE
result.message M RMSG

Daily Batch Report

Fetch a daily report of the settlements and their transactions for all of the merchants under the account.

Batch Report request

curl -i \
-H "Content-Type: application/json; charset=utf-8" \
-H "SPH-Account: test" \
-H "SPH-Merchant: test_merchantId" \
-H "SPH-Timestamp: 2014-09-18T10:32:59Z" \
-H "SPH-Request-Id: f47ac10b-58cc-4372-a567-0e02b2c3d479" \
-H "Signature: SPH1 testKey 4eab87a16e3ee7bd530d778af0cb6c680dcaa52ed1913a9c1bd8ed5a8d689e3e" \
https://v1-hub-staging.sph-test-solinor.com/report/batch/20150323
ReportResponse report = paymentAPI.fetchDailyReport("20150323");

report.getResult().getCode() // 100
report = payment_api.fetch_daily_report("20150323")

report.result.code // 100
paymentAPI.fetchDailyReport("yyyyMMdd")
    .then(function(response) {
      response.result.code; // 100
    });
<?php
$response = paymentApi->getReport("yyyyMMdd");

$response->body->result->code; // 100

JSON Response

{
  "settlements": [
    {
      "id":"4b961b80-e808-487b-bc89-7cf83ffda4d7",
      "batch":"000017",
      "timestamp":"2015-03-23T22:00:09Z",
      "merchant":
      {
        "id":"test_merchantId",
        "name":"Test user"
      },
      "transaction_count":1,
      "net_amount":620,
      "currency":"EUR",
      "acquirer":
      {
        "id":"nets",
        "name":"Nets"
      },
      "transactions":[
      {
        "id":"bc42307b-1313-4d7d-9a0a-7cdd9d3d190c",
        "timestamp":"2015-03-23T10:59:54Z",
        "type":"debit",
        "partial_pan":"0024",
        "amount":620,
        "currency":"EUR",
        "filing_code":"150323000265",
        "status":
        {
          "state":"ok",
          "code":4000
        },
        "authorization_code":"317020"
      }],
      "status":
      {
        "state":"ok",
        "code":4000
      },
      "reference":"11503231000000174"
    }
  ],
  "result":
  {
    "code":100,
    "message":"OK"
  }
}

HTTP Request

GET /report/batch/<yyyyMMdd>

HTTP Response

Field / Object M/O Data type Description
result M
result.code M RCODE
result.message M RMSG
settlements[] M Array May be empty
settlements[].status M
settlements[].status.state M SSTATE
settlements[].status.code M SCTATE
settlements[].status.message O SMSG
settlements[].id M UUID4
settlements[].batch M String
settlements[].timestamp M TIMESTAMP
settlements[].reference O REFERENCE
settlements[].merchant M
settlements[].merchant.id M String
settlements[].merchant.name M String
settlements[].acquirer M
settlements[].acquirer.id M String
settlements[].acquirer.name M String
settlements[].transaction_count M Integer
settlements[].net_amount M NETAMOUNT Total amount, can be negative
settlements[].currency M CURRENCY
settlements[].transactions[] M Array May be empty
settlements[].transactions[].id M UUID4 Non unique! I.e. related transactions may share an ID. For example a debit transacation may have multiple related credits with the same ID.
settlements[].transactions[].timestamp M TIMESTAMP
settlements[].transactions[].type M String Debit or credit
settlements[].transactions[].partial_pan M String Masked PAN
settlements[].transactions[].amount M AMOUNT
settlements[].transactions[].currency M CURRENCY
settlements[].transactions[].filing_code M String
settlements[].transactions[].authorization_code O String
settlements[].transactions[].verification_method O String Applies to 3D Secure verification
settlements[].transactions[].status M
settlements[].transactions[].status.state M SSTATE
settlements[].transactions[].status.code M SCODE
settlements[].transactions[].status.message O SMSG

Response and Status Codes

RCODE Result Codes

Please note that these codes are different from HTTP response codes

RCODE RMSG Description, actions
100 Description of the succesful request Request successful.
200 Reason for the failure Authorization failed, unable to create a Debit transaction or Revert failed.
For Debit transactions, please initialize a new transaction the next day (in case there was insufficient funds) and/or contact the cardholder.
For transaction reverts, please see the status of the transaction with GET /transaction/<id>
209 Description of the timeout Charge/Revert failed due to acquirer or issuer timeout.
210 Transaction already fully reverted: A full amount revert was performed on an already fully reverted transaction.
211 Insufficient balance for the revert: A partial revert with an amount greater than the amount left was performed on the transaction.
250 “Suspected fraud” The transaction was rejected due to suspected fraud.
300   Transaction in progress. Given when there is already a debit transaction being processed with the ID.
900 Description of the error Could not process the transaction, please try again.
901 Description of the validation error Invalid input. Detailed information is in the message field.
902 Description and ID of the transcation Transaction not found. Error is raised if the transaction iD is not found or when the transaction ID is trying to be used for a wrong type of operation.
910 Description of the operation type error Invalid operation type. Either a credit transaction is performed on a debit ID or vice versa.
920 Description of the erroneous request parameters. Unmatched request parameters. Request parameters do not match the previous parameters with the current transaction ID.
940 Route not found error The transaction did not match any of the merchant’s acquirer routing rules and thus is not allowed.
950 “The desired token already exists” The card is already tokenized with the existing token.
990 Description of the error Permanent failure. Cannot repeat the transaction. Please initialize a new transaction.

TCODE Transaction Status Codes

TCODE TSTATE Description
3000 “in_progress” The transaction is being authorized.
4000 “ok” The transaction has been succesfully processed.
4100 “ok_pending” Pending commit for the transaction.
4200 “ok_estimated_pending” Pending commit for an estimated debit amount.
5700 “reverted” The transaction has been successfully reverted.
5800 “reverting” The revert is being authorized.
7000 “failed” The transaction was failed.
7100 “timeout” The transaction was failed due to timeout from the acquirer or issuer.
7200 “suspected_fraud” The transaction was failed due to suspected fraud.

SCODE Settlement Status Codes

SCODE SSTATE Description
3000 “pending” Settlement has not yet been transmitted to the acquiring bank.
4000 “ok” Settlement is processed OK.

HTTP Status Code Summary

CODE Description
200 - OK Request successful
401 - Unauthorized Authentication HMAC mismatch
404 - Not Found The requested item doesn’t exist
5xx - Server Errors Something went wrong in Payment Highway

Data Types

Type Format Example
N ^[0-9]+$ 1200
ACCOUNT ^[-\w.]{1,500}$
AMOUNT ^\d{1,12}$ 9900 (meaning 99.00 for duodecimal currencies)
AN ^[0-9a-zA-Z]+$ sampleText001
ANS ^[ -~]+$ ~/sample/text! <with@specials>
BOOLEAN ^(true|false)$ true
CURRENCY ^(EUR)$ EUR
DATE ^\d{4}-\d{2}-\d{2}$ 2014-09-18 (year-month-day)
IP Valid IPv4 address 127.0.0.1
MERCHANT ^[-\w.]{1,500}$
MONTH ^[0-9]{2}$ 02
NETAMOUNT ^-?\d{1,12}$ -1590 (meaning -15.90 for duodecimal currencies)
ORDER-ID ^[-a-zA-Z0-9_]{1,254}$ 1000123A
PAN ^[3-6]\d{12,18}$
RCODE ^\d{1,6}$  100
REFERENCE  ^\d{12,20}$
REVTYPE ^(cancellation|refund)$ cancellation
RMSG ^[.,’-=/\w;\s]{0,1023}$
SCODE ^\d{3,4}$ 3000
SMSG ^[.,’-=/\w;\s]{0,1023}$
SSTATE ^[.,’-=/\w;\s]{0,254}$
TCODE ^\d{4}$ 4000
TMSG ^[.,’-=/\w;\s]{0,1023}$
TSTATE ^[.,’-=/\w;\s]{0,254}$ ok
UUID4 ^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$ f47ac10b-58cc-4372-a567-0e02b2c3d479
URL Valid URL with HTTPS scheme https://example.com/success?myparam=abc
TIMESTAMP ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$ 2014-09-18T10:32:59Z
VERSION ^\d{8}$ 20150515
YEAR ^[0-9]{4}$ 2015

Change log

2017-06-27

Masterpass with user profile

2017-05-29

2017-05-23

2016-12-07

2016-11-21

2016-10-17

2016-09-23

2016-06-30

2016-02-12

2015-11-19

2015-10-28

2015-10-01

New Result Codes

2015-09-03

Fraud detection

Changes in the Payment API:

2015-08-05

Get transaction IDs by the “order” value

Introduced the possibility to get the transactions related to a specific order. In cases where the user’s browser does not redirect back to a given URL it is still possible to get the related transaction ID using the order value given for the payment.

Changes in the Payment API:

2015-06-05

New API version: 20150605

The CVC Form

Introduced the new CVC Form to support a wider range of cards and business cases. Added version numbering to the Payment API to allow for incremental changes.

Changes in the Form API:

Changes in the Payment API: