NAV Navbar
Java JavaScript PHP
  • Introduction
  • Development Sandbox
  • Form API
  • Payment API
  • Response and Status Codes
  • Data Types
  • Change log
  • 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

    Object request fields
    1. amountmandatoryAMOUNT

      Amount in the smallest currency unit. E.g. 99.99 € = 9999

    2. currencymandatoryCURRENCY

      ISO 4217 currency code

    HTTP Response

    Object response fields
    1. card_tokenUUID4

      Present on a successful commit. See also card.cvc_required below.

    2. cardhash

      Present on a successful commit. See also card.cvc_required below.

      child fields
    3. customerhash

      child fields
    4. committedmandatoryBOOLEAN

    5. committed_amountmandatoryAMOUNT

      Omitted if "committed" is false

    6. filing_codemandatorystring

    7. resulthash

      child fields

    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

    Object response fields
    1. cardhash

      Present on a successful Masterpass transaction.

      child fields
    2. customerhash

      child fields
    3. cardholder_authenticationstring

      Indicates whether ThreeDS (3ds) card holder authentication was done (authenticated, attempted or no)

    4. masterpassconditionalhash

      Masterpass info, mandatory for masterpass transactions

      child fields
    5. profilemandatoryhash

      Masterpass info, mandatory for masterpass transactions

      child fields
    6. resulthash

      child fields

    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

    Object response fields

    1. idmandatoryUUID4

      The handle for the following requests.

    2. resulthash

      child fields

    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) {
            var resultCode = 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 Request

    POST /transaction/<:transaction_id>/debit

    Create a debit transaction to charge a card.

    Object request fields
    1. amountmandatoryAMOUNT

      Amount in the smallest currency unit. E.g. 99.99 € = 9999

    2. currencymandatoryCURRENCY

      ISO 4217 currency code

    3. tokenhash

      Either `card` or `token` must be included

      child fields
    4. cardhash

      Usage of card is for PCI DSS certified parties only. Typically use token instead.

      child fields
    5. commitboolean

      If omitted, true is used

    6. customerhash

      child fields
    7. orderORDER-ID

      Merchant defined order identifier

    8. splittingobject

      Splits the payment into sub-merchant settlement and the main merchant commission. Requires separate activation. Note: The commission will not be refunded in case of a settled payment (committed transaction after 00:00 UTC). Instead the sub-merchant's account will be used for the money transfer.

      child fields

    HTTP Response

    Object response fields
    1. resulthash

      child fields
    2. filing_codestring

      Omitted on failure

    Apple Pay Debit Transaction

    How to implement Apple Pay

    1. Request a Certificate Signing Request (CSR) from support@paymenthighway.fi for Apple Pay on your site or app.
    2. Sign the CSR in your Apple Developer account and send the Apple Pay Payment Processing Certificate to us.
    3. Implement Apple Pay into your app or web site following Apple's documentation.
    4. Make an Apple Pay debit request to us to charge the card in the Payment Data received from Apple.

    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

    Object response fields

    1. idmandatoryUUID4

      The handle for the following requests.

    2. resulthash

      child fields

    Charge the card with amount

    long amount = 1990L;
    String currency = "EUR";
    
    InitTransactionResponse initResponse = paymentAPI.initTransaction();
    
    PaymentData paymentData = (new JsonParser).mapResponse(jsonFromApplePay, PaymentData.class);
    
    ApplePayTransactionRequest request = ApplePayTransactionRequest
      .Builder(paymentData, amount, currency)
      .build();
    
    TransactionResponse response = paymentAPI.debitApplePayTransaction(initResponse.getId, request);
    
    response.getResult().getCode(); // 100
    
    // Apple Pay Debit with Apple Pay Payment Token
    
    var amount = 1990;
    var currency = 'EUR';
    
    var paymentToken = JSON.parse('...');
    
    paymentAPI.initTransaction()
        .then(function (init) {
            var request = ApplePayTransactionRequest.Builder(paymentToken, amount, currency).build();
    
            return paymentAPI.debitApplePayTransaction(init.id, request);
        })
        .then(function(debit) {
            var resultCode = debit.result.code; // 100
        });
    

    HTTP Request

    POST /transaction/<:transaction_id>/debit_applepay

    Object request fields
    1. amountmandatoryAMOUNT

      Amount in the smallest currency unit. E.g. 99.99 € = 9999

    2. currencymandatoryCURRENCY

      ISO 4217 currency code

    3. payment_datamandatoryhash

      Apple Pay Top-Level Structure

      child fields
    4. commitboolean

      If omitted, true is used

    5. customerhash

      child fields
    6. orderORDER-ID

      Merchant defined order identifier

    HTTP Response

    Same response as Debit transaction

    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 Request

    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.

    Object request fields
    1. amountmandatoryAMOUNT

      Amount in the smallest currency unit. E.g. 99.99 € = 9999

    2. currencymandatoryCURRENCY

      ISO 4217 currency code

    3. commitboolean

      If omitted, true is used

    HTTP Response

    Same response as Debit transaction

    MobilePay app based payment flow

    Using this flow users can be moved directly to MobilePay app without using Form API and browser which will result in smoother user experience.

    It is important to check that user has MobilePay app installed before using payment flow with app.

    Using Payment Highway and MobilePay in Mobile application

    Initialize MobilePay payment with app flow.

    // Initialize MobilePay payment session
    
    long amount = 1990L;
    String currency = "EUR";
    String order = UUID.randomUUID().toString()
    
    MobilePayInitRequest request = MobilePayInitRequest.Builder(amount, currency)
       .setOrder(order)
       .setReturnUri("myapp://paid")
       .setWebhookSuccessUrl("https://backend.myapp.com/success")
       .setWebhookCancelUrl("https://backend.myapp.com/cancel")
       .setWebhookFailureUrl("https://backend.myapp.com/failure")
       .build();
    
    MobilePayInitResponse response = paymentApi.initMobilePaySession(request);
    response.getSessionToken();
    response.getUri(); // start MobilePay app with this uri
    response.getResult().getCode(); // 100
    
    const amount = 1990;
    const currency = 'EUR';
    const orderId = 'orderid';
    
    const request = MobilePayInitRequest.Builder(amount, currency)
      .setOrder(orderId)
      .setReturnUri('myapp://paid')
      .setWebhookSuccessUrl('https://myserver.com/success')
      .setWebhookCancelUrl('https://myserver.com/cancel')
      .setWebhookFailureUrl('https://myserver.com/failure')
      .build()
    
    api.initMobilePaySession(request)
      .then(function (init) {
        const token = init.session_token;
        const uri = init.uri; // start MobilePay app with this uri
        const resultCode = init.result.code; // 100
      });
    

    Json request

    {
      "amount": 1990,
      "currency": "EUR",
      "order": "order",
      "return_uri": "myapp://paid",
      "webhook_success_url": "https://backend.myapp.com/success",
      "webhook_cencel_url": "https://backend.myapp.com/cancel",
      "webhook_failure_url": "https://backend.myapp.com/failure"
    }
    

    Json response

    {
      "session_token": "0001-01-01-00.00.00.000000",
      "uri": "mobilepayonline://online?sessiontoken=0001-01-01-00.00.00.000000&version=2",
      "valid_until": "2018-09-18T10:32:59Z"
      "result": {
        "code":100,
        "message":"OK"
      }
    }
    

    HTTP Requests

    POST /app/mobilepay

    Initialize MobilePay payment flow when using MobilePay app. It is important to check that user has MobilePay app installed before using payment flow with app.

    Object request fields
    1. amountmandatoryAMOUNT

      Amount in the smallest currency unit. E.g. 99.99 € = 9999

    2. currencymandatoryCURRENCY

      ISO 4217 currency code

    3. orderORDER-ID

      Merchant defined order identifier

    4. return_urimandatoryURI

      Where MobilePay app returns. Parameter sessionToken is added to uri.

    5. webhook_success_urlmandatoryURL

      On success, server to server GET request will be made to this url.

    6. webhook_cancel_urlmandatoryURL

      On cancel, server to server GET request will be made to this url.

    7. webhook_failure_urlmandatoryURL

      On failure, server to server GET request will be made to this url.

    8. languageLANG

      Language code. Allowed values are "en", "fi", "da", "no"

    9. sub_merchant_nameANS

    10. sub_merchant_idMERCHANT

    11. shop_nameANS

      Name of the shop/merchant. MobilePay app displays this under the shop logo. If omitted, the merchant name from PH is used.

    12. shop_logo_urlURL

      The logo must be 250x250 pixel in .png format and must be hosted on a HTTPS (secure) server.

    About shop logo in MobilePay

    HTTP Response

    Object response fields
    1. session_tokenmandatoryANS

      MobilePay session token

    2. urimandatoryURI

      MobilePay app uri

    3. valid_untilmandatoryTIMESTAMP

      Session expriration time.

    4. resulthash

      child fields

    MobilePay session status

    Get MobilePay session status

    String sessionToken = "0001-01-01-00.00.00.000000"; // in redirect from MobilePay app, or from init
    
    MobilePayStatusResponse status = paymentAPI.mobilePaySessionStatus(sessionToken);
    
    status.getStatus(); // "ok" when session is finished and transaction can be committed
    status.getTransactionId(); // available when status is "ok"
    status.getValidUntil();
    
    status.getResult().getCode(); // 100
    
    const sessionToken = "0001-01-01-00.00.00.000000"; // in redirect from MobilePay app, or from init
    
    paymentAPI.mobilePaySessionStatus(sessionToken)
      .then(function (response) {
        const status = response.status; // "ok" when session is finished and transaction can be committed
        const transaction_id = response.transaction_id; // available when status is "ok"
        const valid = response.valid_until;
    
        response.result.code; // 100
      });
    
    

    Json response

    {
      "status": "ok",
      "transaction_id": "327c6f29-9b46-40b9-b85b-85e908015d92",
      "result": {
        "code":100,
        "message":"OK"
      }
    }
    

    HTTP Request

    GET /app/mobilepay/<:mobilepay session token>

    HTTP Response

    Object response fields
    1. statusmandatoryTSTATE

      MobilePay session status

    2. valid_untilTIMESTAMP

      Session expriration time.

    3. transaction_idUUID4

      Transaction id. Available if status is "ok"

    4. resulthash

      child fields

    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.

    Object response fields
    1. resulthash

      child fields
    2. transactionsmandatorylist of hash

      All transactions belonging to the order

      child fields

    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

    Object request fields
    1. amountmandatoryAMOUNT

      Amount in the smallest currency unit. E.g. 99.99 € = 9999. Without amount the whole transaction is reverted.

    HTTP Response

    Object response fields
    1. resulthash

      child fields

    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,
        "splitting" : {
          "amount" : 9900,
          "merchant_id" : "123456"
        }
      },
      "result":
      {
        "code":100,
        "message":"OK"
      }
    }
    

    HTTP Request

    GET /transaction/<:transaction_id>

    HTTP Response

    Object response fields
    1. resulthash

      child fields
    2. transactionmandatoryhash

      child fields

    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

    Object response fields
    1. card_tokenUUID4

      Present if verification was successful

    2. cardhash

      Present if verification was successful

      child fields
    3. customerhash

      child fields
    4. cardholder_authenticationmandatorystring

      Indicates whether ThreeDS (3ds) card holder authentication was done (authenticated, attempted or no)

    5. resulthash

      child fields

    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.
    231 "API key is not allowed to access transaction for given account" When using API key with limited access. API key is not allowed to access transaction for given account.
    232 "API key is not allowed to access given merchant" When using API key with limited access. API key is not allowed to access given merchant.
    233 "API key is not allowed to access given card token" When using API key with limited access. API key is not allowed to access given card token.
    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.
    930 Description of invalid transaction state. Transaction was in invalid state for operation.
    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.
    952 "Encryption key not found"
    953 "Decryption failed"
    954 "Invalid cleartext PAN after decryption"
    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
    LANG ^[-\w.]{a-z}$ fi
    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

    2018-04-26

    2018-02-26

    2017-11-27

    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: