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) {
        /*
        * Build the form for POST-request:
        * <input type="hidden" name="field.getName()" value="field.getValue()">
        * Or create GET-url:
        * ?field.getName()=field.getValue()&...
        */
        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) {
        /*
        * Build the form for POST-request:
        * <input type="hidden" name="name" value="value">
        * Or create GET-url:
        * ?name=value&...
        */
        var name = field.first;
        var value = field.second;
    });
    
    
    <?php
    $form = $formBuilder->generateAddCardParameters();
    
    // read form parameters
    $httpMethod = $form->getMethod();
    $actionUrl = $form->getAction();
    $parameters = $form->getParameters(); 
    
    foreach ($parameters as $key => $value) {
        /*
        * Build the form for POST-request:
        * <input type="hidden" name="$key" value="$value">
        * Or create GET-url:
        * ?$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 'SPH1 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) {
        /*
        * Build the form for POST-request:
        * <input type="hidden" name="field.getName()" value="field.getValue()">
        * Or create GET-url:
        * ?field.getName()=field.getValue()&...
        */
        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) {
        /*
        * Build the form for POST-request:
        * <input type="hidden" name="name" value="value">
        * Or create GET-url:
        * ?name=value&...
        */
        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(); 
    
    foreach ($parameters as $key => $value) {
        /*
        * Build the form for POST-request:
        * <input type="hidden" name="$key" value="$value">
        * Or create GET-url:
        * ?$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 'SPH1 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) {
        /*
        * Build the form for POST-request:
        * <input type="hidden" name="field.getName()" value="field.getValue()">
        * Or create GET-url:
        * ?field.getName()=field.getValue()&...
        */
        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) {
        /*
        * Build the form for POST-request:
        * <input type="hidden" name="name" value="value">
        * Or create GET-url:
        * ?name=value&...
        */
        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(); 
    
    foreach ($parameters as $key => $value) {
        /*
        * Build the form for POST-request:
        * <input type="hidden" name="$key" value="$value">
        * Or create GET-url:
        * ?$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 'SPH1 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) {
        /*
        * Build the form for POST-request:
        * <input type="hidden" name="field.getName()" value="field.getValue()">
        * Or create GET-url:
        * ?field.getName()=field.getValue()&...
        */
        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) {
        /*
        * Build the form for POST-request:
        * <input type="hidden" name="name" value="value">
        * Or create GET-url:
        * ?name=value&...
        */
        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(); 
    
    foreach ($parameters as $key => $value) {
        /*
        * Build the form for POST-request:
        * <input type="hidden" name="$key" value="$value">
        * Or create GET-url:
        * ?$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 'SPH1 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) {
        /*
        * Build the form for POST-request:
        * <input type="hidden" name="field.getName()" value="field.getValue()">
        * Or create GET-url:
        * ?field.getName()=field.getValue()&...
        */
        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) {
        /*
        * Build the form for POST-request:
        * <input type="hidden" name="name" value="value">
        * Or create GET-url:
        * ?name=value&...
        */
        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(); 
    
    foreach ($parameters as $key => $value) {
        /*
        * Build the form for POST-request:
        * <input type="hidden" name="$key" value="$value">
        * Or create GET-url:
        * ?$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 'SPH1 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) {
        /*
        * Build the form for POST-request:
        * <input type="hidden" name="field.getName()" value="field.getValue()">
        * Or create GET-url:
        * ?field.getName()=field.getValue()&...
        */
        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 'SPH1 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 with Siirto

    
    // Generate Siirto form parameters
    
    Long amount = 1999;
    String orderId = "1000123A";
    String description = "A Box of Dreams. 19,90€";
    String phoneNumber = "+358441234567";
    String referenceNumber = "1313";
    
    FormContainer formContainer = formBuilder.siirtoParametersBuilder(
        successUrl,
        failureUrl,
        cancelUrl,
        amount,
        orderId,
        description,
        referenceNumber
    )
        .phoneNumber(phoneNumber)
        .build();
    
    // read form parameters
    String httpMethod = formContainer.getMethod();
    String actionUrl = formContainer.getAction();
    List<NameValuePair> fields = formContainer.getFields();
    
    for (NameValuePair field : fields) {
        /*
        * Build the form for POST-request:
        * <input type="hidden" name="field.getName()" value="field.getValue()">
        * Or create GET-url:
        * ?field.getName()=field.getValue()&...
        */
        field.getName();
        field.getValue();
    }
    
    
    // Generate Siirto form parameters
    
    var amount = 1990;
    var orderId = '1000123A';
    var description = 'A Box of Dreams. 19,90€';
    var phoneNumber = "+358441234567";
    var referenceNumber = "1313";
    
    var formContainer = formBuilder.generateSiirtoParameters(
        successUrl, 
        failureUrl, 
        cancelUrl, 
        language, 
        amount, 
        orderId, 
        description,
        referenceNumber,
        phoneNumber
    );
    
    // read form parameters
    var httpMethod = formContainer.method;
    var actionUrl = formContainer.getAction();
    var fields = formContainer.nameValuePairs;
    
    
    fields.forEach(function(field) {
        /*
        * Build the form for POST-request:
        * <input type="hidden" name="name" value="value">
        * Or create GET-url:
        * ?name=value&...
        */
        var name = field.first;
        var value = field.second;
    });
    
    <?php
    $amount = "1990";
    $currency = "EUR";
    $orderId = "1000123A";
    $description = "A Box of Dreams. 19,90€";
    $phoneNumber = "+358441234567";
    $referenceNumber = "1313";
    
    $form = $formbuilder->generateSiirtoParameters(
                $amount,
                $orderId, 
                $description,
                $phoneNumber,
                $referenceNumber
            );
    
    // read form parameters
    $httpMethod = $form->getMethod();
    $actionUrl = $form->getAction();
    $parameters = $form->getParameters(); 
    
    foreach ($parameters as $key => $value) {
        /*
        * Build the form for POST-request:
        * <input type="hidden" name="$key" value="$value">
        * Or create GET-url:
        * ?$key=$value&...
        */
        echo $key .":". $value;
    }
    

    Siirto is a Finnish real time bank transfer system based on phone numbers and mobile applications.

    HTTP Request

    POST /form/view/siirto

    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. Only “EUR” supported.
    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-reference-number AN M Reference number. In RF-format or in Finnish reference number format.
    sph-phone-number AN O When used, phone number will be prefilled to form. Use international format e.g. "+358441234567"
    signature ANS M Message signature in the format 'SPH1 key-id authentication-string'

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

    Success, Cancel and Failure Responses

    The Success, Cancel and Failure 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 the payment request. Siirto transaction must not be committed.

    Siirto transactions must not be committed. After getting success-response, You should use Siirto transaction result- or Transaction status-query to get info about payment status.

    Payment with Pivo

    
    // Generate Pivo form parameters
    
    Long amount = 1999;
    String orderId = "1000123A";
    String description = "A Box of Dreams. 19,90€";
    String phoneNumber = "+358441234567";
    String referenceNumber = "1313";
    
    FormContainer formContainer = formBuilder.pivoParametersBuilder(
        successUrl,
        failureUrl,
        cancelUrl,
        amount,
        orderId,
        description
    )
        .referenceNumber(referenceNumber)
        .phoneNumber(phoneNumber)
        .build();
    
    // read form parameters
    String httpMethod = formContainer.getMethod();
    String actionUrl = formContainer.getAction();
    List<NameValuePair> fields = formContainer.getFields();
    
    for (NameValuePair field : fields) {
        /*
        * Build the form for POST-request:
        * <input type="hidden" name="field.getName()" value="field.getValue()">
        * Or create GET-url:
        * ?field.getName()=field.getValue()&...
        */
        field.getName();
        field.getValue();
    }
    
    
    // Generate Pivo form parameters
    
    var amount = 1990;
    var orderId = '1000123A';
    var description = 'A Box of Dreams. 19,90€';
    var phoneNumber = "+358441234567";
    var referenceNumber = "1313";
    
    var formContainer = formBuilder.generatePivoParameters(
        successUrl, 
        failureUrl, 
        cancelUrl, 
        language, 
        amount, 
        orderId, 
        description,
        referenceNumber,
        phoneNumber
    );
    
    // read form parameters
    var httpMethod = formContainer.method;
    var actionUrl = formContainer.getAction();
    var fields = formContainer.nameValuePairs;
    
    
    fields.forEach(function(field) {
        /*
        * Build the form for POST-request:
        * <input type="hidden" name="name" value="value">
        * Or create GET-url:
        * ?name=value&...
        */
        var name = field.first;
        var value = field.second;
    });
    
    <?php
    $amount = "1990";
    $currency = "EUR";
    $orderId = "1000123A";
    $description = "A Box of Dreams. 19,90€";
    $phoneNumber = "+358441234567";
    $referenceNumber = "1313";
    
    $form = $formbuilder->generatePivoParameters(
                $amount,
                $orderId, 
                $description,
                $phoneNumber,
                $referenceNumber
            );
    
    // read form parameters
    $httpMethod = $form->getMethod();
    $actionUrl = $form->getAction();
    $parameters = $form->getParameters(); 
    
    foreach ($parameters as $key => $value) {
        /*
        * Build the form for POST-request:
        * <input type="hidden" name="$key" value="$value">
        * Or create GET-url:
        * ?$key=$value&...
        */
        echo $key .":". $value;
    }
    

    Pivo is a Finnish mobile wallet. With different acquiring agreements, Pivo payments can be made with credit card, Siirto or bank transfer.

    HTTP Request

    POST /form/view/pivo

    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. Only “EUR” supported.
    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-reference-number AN O Reference number. In RF-format or in Finnish reference number format. It omitted, random reference number will be generated by PH. Reference number is used when payment type is "siirto" or "account", but not in card payments.
    sph-phone-number AN O When used, phone number will be prefilled to form. Use international format e.g. "+358441234567"
    signature ANS M Message signature in the format 'SPH1 key-id authentication-string'

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

    Success, Cancel and Failure Responses

    The Success, Cancel and Failure 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 the payment request. Pivo transaction must not be committed.

    Pivo transactions must not be committed. After getting success-response, You should use Pivo transaction result- or Transaction status-query to get info about payment status.

    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-Length: 32" \
      -H "Content-Type: application/json" \
      -H "SPH-Account: test" \
      -H "SPH-Api-Version: 20180927" \
      -H "SPH-Merchant: test_merchantId" \
      -H "SPH-Request-Id: 1820d2f1-c001-408e-b842-34bfa6b2758d" \
      -H "SPH-Timestamp: 2018-10-04T10:41:15Z" \
      -H "Signature: SPH1 testKey 1918e69a5dd06fe48844bc3317c9ca257a1fb720bebe25a7da2b3272ee0ff35a" \
      --data '{"currency":"EUR","amount":2500}' \
      https://v1-hub-staging.sph-test-solinor.com/transaction/52ea5beb-343b-4516-ab70-ede2baa058c8/commit
      # Replace the transaction ID with the one retrieved from the Form API sph-transaction-id return parameter.
    
    String transactionId = "52ea5beb-343b-4516-ab70-ede2baa058c8"; // get sph-transaction-id as a GET parameter
    String amount = "2499";
    String currency = "EUR";
    CommitTransactionResponse response = paymentAPI.commitTransaction(transactionId, amount, currency);
    
    response.getResult().getCode(); // 100
    
    transaction_id = "52ea5beb-343b-4516-ab70-ede2baa058c8" # get sph-transaction-id as a GET parameter
    amount = 2499
    currency = "EUR"
    commit_transaction_response = payment_api.commit_transaction(transaction_id, amount, currency)
    
    commit_transaction_response.result.code // 100
    
    var transactionId = '52ea5beb-343b-4516-ab70-ede2baa058c8'; // get sph-transaction-id as a GET parameter
    var amount = 2499;
    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 = "52ea5beb-343b-4516-ab70-ede2baa058c8"; // get sph-transaction-id as a GET parameter
    $amount = 2499;
    $currency = "EUR";
    
    $response = $paymentApi->commitFormTransaction($transactionId, $amount, $currency );
    
    $response->body->result->code; // 100
    

    JSON Response

    {
      "committed": true,
      "committed_amount": 2499,
      "card_token": "77ffbaca-9658-4aef-ac9e-f85da3164bdb",
      "recurring": true,
      "filing_code": "181004705200",
      "cardholder_authentication": "no",
      "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_fingerprint": "da6b0df36efd17c0e7f6967b9e440a0c61b6bd3d96b62f14c90155a1fb883597",
        "pan_fingerprint": "e858e18daac509247f463292641237d6a74ce44e0971ba2de4a14874928a8805"
      },
      "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. cardobject

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

      child fields
    3. customerobject

      child fields
    4. committedmandatoryBOOLEAN

    5. committed_amountmandatoryAMOUNT

      Omitted if "committed" is false

    6. filing_codemandatorystring

    7. resultobject

      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

    {
      "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"
        }
      },
      "customer": {
        "network_address": "83.145.208.186",
        "country_code": "FI"
      },
      "cardholder_authentication": "no",
      "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",
        "card_fingerprint": "0be44c116bfe2070417f5af78ac80e30bdf2d0d600d7a81944f9426e5d7b228a",
        "pan_fingerprint": "139f4f450e1d1e60b50f2f097585f491c3c575dc658b308f48c7b399016896b9"
      },
      "masterpass": {
        "amount": 100,
        "currency": "EUR",
        "checkout_oauth_token": "8dddb475e23bf96ed70082455c7c599596f12986",
        "masterpass_transaction_id": "2468807694572615629",
        "masterpass_wallet_id": "101"
      },
      "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. cardobject

      Present on a successful Masterpass transaction.

      child fields
    2. customerobject

      child fields
    3. cardholder_authenticationstring

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

    4. masterpassconditionalobject

      Masterpass info, mandatory for masterpass transactions

      child fields
    5. profilemandatoryobject

      Masterpass info, mandatory for masterpass transactions

      child fields
    6. resultobject

      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.

    Siirto transaction result

    
    UUID transactionId = UUID.fromString("327c6f29-9b46-40b9-b85b-85e908015d92");
    SiirtoTransactionResultResponse response = paymentAPI.siirtoTransactionResult(transactionId);
    
    
    paymentAPI.siirtoTransactionResult(transactionId).then(function(res) {
        const transactionResult = res;
      });
    
    
    <?php
    $response = $paymentApi->siirtoTransactionResult($transactionId);
    
    

    JSON Response for Siirto transaction

    {
      "current_amount": 100,
      "amount": 100,
      "status": "PAID",
      "customer": {
        "network_address": "127.0.0.1"
      },
      "reference_number": "1313",
      "result": {
        "code": 100,
        "message": "OK"
      }
    }
    

    Used to find out whether or not a Siirto transaction succeeded.

    HTTP Request

    POST /transaction/<:transaction_id>/siirto/result

    Responses

    Siirto transaction response object fields
    1. statusmandatorystring

      Siirto transaction status

    2. customerobject

      child fields
    3. amountmandatoryAMOUNT

      Original transaction amount in the smallest currency unit. E.g. 99.99 € = 9999

    4. current_amountmandatoryAMOUNT

      Amount after possible reversals

    5. reference_numbermandatorystring

      Reference number. In RF-format or in Finnish reference number format.

    6. resultobject

      child fields

    Pivo transaction result

    
    UUID transactionId = UUID.fromString("327c6f29-9b46-40b9-b85b-85e908015d92");
    PivoTransactionResultResponse response = paymentAPI.pivoTransactionResult(transactionId);
    
    
    paymentAPI.pivoTransactionResult(transactionId).then(function(res) {
        const transactionResult = res;
      });
    
    
    <?php
    $response = $paymentApi->pivoTransactionResult($transactionId);
    
    

    JSON Response for Pivo transaction

    {
      "state": "refunded",
      "current_amount": 990,
      "amount": 1000,
      "payment_type": "siirto",
      "archive_id": "20180523593064010087",
      "customer": {
        "network_address": "127.0.0.1"
      },
      "reference_number": "1805231300333",
      "result": {
        "code": 100,
        "message": "OK"
      }
    }
    

    Used to find out whether or not a Pivo transaction succeeded.

    HTTP Request

    POST /transaction/<:transaction_id>/pivo/result

    Responses

    Pivo transaction response object fields
    1. statemandatorystring

      Pivo transaction state (‘pending’, ‘paid’, ‘cancelled’, ‘rejected’ or ‘refunded’)

    2. customerobject

      child fields
    3. amountmandatoryAMOUNT

      Original transaction amount in the smallest currency unit. E.g. 99.99 € = 9999

    4. current_amountAMOUNT

      Amount after possible reversals

    5. reference_numberstring

      Reference number. In RF-format or in Finnish reference number format.

    6. archive_idstring

    7. payment_typestring

      Payment method of the Pivo payment. ‘account’: Payment order paid as Bank account transfer, ‘card’: Payment order paid as Card payment, ‘siirto’ Payment order paid as siirto payment.

    8. resultobject

      child fields

    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-Length: 0" \
      -H "Content-Type: application/json" \
      -H "SPH-Account: test" \
      -H "SPH-Api-Version: 20180927" \
      -H "SPH-Merchant: test_merchantId" \
      -H "SPH-Request-Id: 83d6195d-b2f5-4d65-a5cd-7289dda1811c" \
      -H "SPH-Timestamp: 2018-10-04T10:19:45Z" \
      -H "Signature: SPH1 testKey 6ee85e625fa2bd1fafa6cef6a7f9fe3b7a81e62115f24ece1cff70b8338d928d" \
      --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": "52ea5beb-343b-4516-ab70-ede2baa058c8",
      "result": {
        "code": 100,
        "message": "OK"
      }
    }
    

    HTTP Request

    POST /transaction

    HTTP Response

    Object response fields

    1. idmandatoryUUID4

      The handle for the following requests.

    2. resultobject

      child fields

    Debit transaction

    Charge a card token (debit transaction)

    curl -i \
      -H "Content-Length: 187" \
      -H "Content-Type: application/json" \
      -H "SPH-Account: test" \
      -H "SPH-Api-Version: 20180927" \
      -H "SPH-Merchant: test_merchantId" \
      -H "SPH-Request-Id: 8906778f-c26d-4ea0-a803-23d593d1d1e0" \
      -H "SPH-Timestamp: 2018-10-04T10:19:45Z" \
      -H "Signature: SPH1 testKey a76d67297dbc6b5b3cfb2a02d7f6400dbaa59941771d992924a45d12d12e65a6" \
      --data '{"customer":{},"currency":"EUR","amount":2499,"token":{"id":"77ffbaca-9658-4aef-ac9e-f85da3164bdb"},"splitting":{"amount":1499,"merchant_id":"123456"},"order":"API_TEST_VERSION_20180927"}' \
      https://v1-hub-staging.sph-test-solinor.com/transaction/52ea5beb-343b-4516-ab70-ede2baa058c8/debit
    
    // Debit with Token
    
    Token token = new Token("77ffbaca-9658-4aef-ac9e-f85da3164bdb");
    long amount = 2500L;
    String currency = "EUR";
    
    TransactionRequest transaction = TransactionRequest.Builder(token, amount, currency)
      .setOrder("API_TEST_VERSION_20180927") // Order id
      .build();
    
    String transactionId = "52ea5beb-343b-4516-ab70-ede2baa058c8";
    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 = "52ea5beb-343b-4516-ab70-ede2baa058c8";
    $response = $paymentApi->debitTransaction( transactionId, $transaction);
    
    $response->body->result->code; // 100
    

    JSON Response

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

    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. tokenobject

      Either `card` or `token` must be included

      child fields
    4. cardobject

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

      child fields
    5. commitboolean

      If omitted, true is used

    6. customerobject

      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. resultobject

      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-Length: 0" \
      -H "Content-Type: application/json" \
      -H "SPH-Account: test" \
      -H "SPH-Api-Version: 20180927" \
      -H "SPH-Merchant: test_merchantId" \
      -H "SPH-Request-Id: 83d6195d-b2f5-4d65-a5cd-7289dda1811c" \
      -H "SPH-Timestamp: 2018-10-04T10:19:45Z" \
      -H "Signature: SPH1 testKey 6ee85e625fa2bd1fafa6cef6a7f9fe3b7a81e62115f24ece1cff70b8338d928d" \
      --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": "52ea5beb-343b-4516-ab70-ede2baa058c8",
      "result": {
        "code": 100,
        "message": "OK"
      }
    }
    

    HTTP Request

    POST /transaction

    HTTP Response

    Object response fields

    1. idmandatoryUUID4

      The handle for the following requests.

    2. resultobject

      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_datamandatoryobject

      Apple Pay Top-Level Structure

      child fields
    4. commitboolean

      If omitted, true is used

    5. customerobject

      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. resultobject

      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. resultobject

      child fields

    Order Status

    Get the transactions related to a specific order

    curl -i \
      -H "SPH-Account: test" \
      -H "SPH-Api-Version: 20180927" \
      -H "SPH-Merchant: test_merchantId" \
      -H "SPH-Request-Id: b33696d1-944c-4371-9216-4ba4a910f6c8" \
      -H "SPH-Timestamp: 2018-10-04T10:27:12Z" \
      -H "Signature: SPH1 testKey af890404b04d597f93d7c83198fe470bf007e499a64261401364eb56f5af266e" \
      --data '' \
      https://v1-hub-staging.sph-test-solinor.com/transactions/?order=API_TEST_VERSION_20180927
    
    OrderSearchResponse orderSearchResponse = paymentApi.searchOrders(order);
    
    paymentAPI.searchOrders("API_TEST_VERSION_20180927");
    
    <?php
    $response = paymentApi->searchByOrderId( $orderId );
    

    JSON response

    {
      "transactions": [
        {
          "id": "52ea5beb-343b-4516-ab70-ede2baa058c8",
          "acquirer": {
            "id": "nets",
            "name": "Nets"
          },
          "type": "debit",
          "amount": 2499,
          "current_amount": 1499,
          "currency": "EUR",
          "timestamp": "2018-10-04T10:19:46Z",
          "modified": "2018-10-04T10:31:32Z",
          "filing_code": "181004705200",
          "authorization_code": "436460",
          "token": "77ffbaca-9658-4aef-ac9e-f85da3164bdb",
          "status": {
            "state": "ok",
            "code": 4000
          },
          "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_fingerprint": "da6b0df36efd17c0e7f6967b9e440a0c61b6bd3d96b62f14c90155a1fb883597",
            "pan_fingerprint": "e858e18daac509247f463292641237d6a74ce44e0971ba2de4a14874928a8805"
          },
          "reverts": [
            {
              "type": "cancellation",
              "status": {
                "state": "ok",
                "code": 4000
              },
              "amount": 1000,
              "timestamp": "2018-10-04T10:31:32Z",
              "modified": "2018-10-04T10:31:32Z",
              "filing_code": "181004705200"
            }
          ],
          "cardholder_authentication": "no",
          "order": "API_TEST_VERSION_20180927",
          "committed": true,
          "committed_amount": 2499,
          "recurring": true,
          "splitting": {
            "amount": 1499,
            "merchant_id": "123456"
          }
        }
      ],
      "siirto_transactions": [],
      "pivo_transactions": [
        {
          "id": "177ef24a-d3f2-4514-ad9b-492d3926bb18",
          "type": "debit",
          "amount": 100,
          "current_amount": 100,
          "currency": "EUR",
          "timestamp": "2018-06-15T10:34:31Z",
          "status": {
            "state": "ok",
            "code": 4000
          },
          "reference_number": "1806151034319",
          "customer": {
            "network_address": "93.174.192.154",
            "country_code": "FI"
          },
          "order": "API_TEST_VERSION_20180927",
          "pivo_payment_id": "37b54bcc9f78d04095214f1b8018263082bb3fcb1951520a9e1edeab94af9515",
          "payment_type": "card",
          "archive_id": "180615541764",
          "modified": "2018-06-15T10:54:56Z",
          "refunds": []
        }
      ],
      "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. resultobject

      child fields
    2. transactionsmandatoryarray

      All transactions belonging to the order

      child fields
    3. siirto_transactionsmandatoryarray

      All Siirto transactions belonging to the order

      child fields
    4. pivo_transactionsmandatoryarray

      All Pivo transactions belonging to the order

      child fields

    Revert

    Revert a payment transaction

    curl -i \
      -H "Content-Length: 15" \
      -H "Content-Type: application/json" \
      -H "SPH-Account: test" \
      -H "SPH-Api-Version: 20180927" \
      -H "SPH-Merchant: test_merchantId" \
      -H "SPH-Request-Id: 7399702e-5ae4-4d9f-af57-e78d50937f97" \
      -H "SPH-Timestamp: 2018-10-04T10:31:31Z" \
      -H "Signature: SPH1 testKey d0e8d4cfecdf8db1180057d8a691e1d5af5b7e7d80b5acabfc920e6d0b46f388" \
      --data '{"amount":1000}' \
      https://v1-hub-staging.sph-test-solinor.com/transaction/52ea5beb-343b-4516-ab70-ede2baa058c8/revert
    
    String transactionId = "52ea5beb-343b-4516-ab70-ede2baa058c8";
    TransactionResponse response = paymentAPI.revertTransaction(transactionId);
    
    response.getResult().getCode(); // 100
    
    transaction_id = "52ea5beb-343b-4516-ab70-ede2baa058c8"
    transaction_response = payment_api.revert_transaction(transaction_id)
    transaction_response = payment_api.revert_transaction(transaction_id, 1000)
    
    transaction_response.result.code // 100
    
    var transactionId = "52ea5beb-343b-4516-ab70-ede2baa058c8";
    paymentAPI.revertTransaction(transactionId)
        .then(function(response){
            return response.result.code; // 100
        });
    
    <?php
    $transactionId = "52ea5beb-343b-4516-ab70-ede2baa058c8";
    $response = $paymentApi->revertTransaction($transactionId);
    
    $response->body->result->code; // 100
    

    JSON Response

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

    Reverts an existing debit transaction.

    For Siirto transactions, use Revert Siirto.

    For Pivo transactions, use Revert Pivo.

    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. resultobject

      child fields

    Revert Siirto

    Revert a Siirto transaction

    String transactionId = "f23a9be0-15fe-43df-98ac-92f6a5731c3b";
    String referenceNumber = "1313";
    
    TransactionResponse response = paymentAPI.revertSiirtoTransaction(transactionId, referenceNumber);
    
    response.getResult().getCode(); // 100
    
    const transactionId = "f23a9be0-15fe-43df-98ac-92f6a5731c3b";
    const referenceNumber = "1313";
    const siirtoRevertRequest = new RevertSiirtoTransactionRequest(referenceNumber);
    
    paymentAPI.revertPivoTransaction(transactionId, siirtoRevertRequest)
        .then(function(response){
            response.result.code; // 100
        });
    
    <?php
    $transactionId = "f23a9be0-15fe-43df-98ac-92f6a5731c3b";
    $referenceNumber = "1313";
    $amount = "10";
    
    $response = $paymentApi->revertSiirtoTransaction($transactionId, $referenceNumber, $amount);
    
    $response->body->result->code; // 100
    

    JSON Response

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

    Reverts an existing Siirto transaction.

    For Pivo transactions, use Revert Pivo.

    For other transactions, use Revert.

    HTTP Request

    POST /transaction/<:transaction_id>/siirto/revert

    Object request fields
    1. reference_numbermandatorystring

      Reference number. In RF-format or in Finnish reference number format.

    2. 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. resultobject

      child fields

    Revert Pivo

    Revert a Pivo transaction

    String transactionId = "f23a9be0-15fe-43df-98ac-92f6a5731c3b";
    String referenceNumber = "1313";
    
    TransactionResponse response = paymentAPI.revertPivoTransaction(transactionId, referenceNumber);
    
    response.getResult().getCode(); // 100
    
    const transactionId = "f23a9be0-15fe-43df-98ac-92f6a5731c3b";
    const referenceNumber = "1313";
    const pivoRevertRequest = new RevertPivoTransactionRequest(referenceNumber, pivoRevertRequest);
    
    paymentAPI.revertPivoTransaction(transactionId)
        .then(function(response){
            response.result.code; // 100
        });
    
    <?php
    $transactionId = "f23a9be0-15fe-43df-98ac-92f6a5731c3b";
    $referenceNumber = "1313";
    $amount = "10";
    
    $response = $paymentApi->revertPivoTransaction($transactionId, $referenceNumber, $amount);
    
    $response->body->result->code; // 100
    

    JSON Response

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

    Reverts an existing Pivo transaction.

    For Siirto transactions, use Revert Siirto.

    For other transactions, use Revert.

    HTTP Request

    POST /transaction/<:transaction_id>/pivo/revert

    Object request fields
    1. reference_numberstring

      Reference number. In RF-format or in Finnish reference number format. It omitted, random reference number will be generated by PH

    2. 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. resultobject

      child fields

    Transaction Status

    Transaction status request

    curl -i \
      -H "SPH-Account: test" \
      -H "SPH-Api-Version: 20180927" \
      -H "SPH-Merchant: test_merchantId" \
      -H "SPH-Request-Id: 2c2ffba5-65c3-49aa-8e48-244504892710" \
      -H "SPH-Timestamp: 2018-10-04T10:23:55Z" \
      -H "Signature: SPH1 testKey 7dba83405e7a55973edc8802a60f4fb2315632982cccd48cddc064b4ed623da9" \
      --data '' \
      https://v1-hub-staging.sph-test-solinor.com/transaction/52ea5beb-343b-4516-ab70-ede2baa058c8
    
    String transactionId = "52ea5beb-343b-4516-ab70-ede2baa058c8";
    TransactionStatusResponse statusResponse = paymentAPI.transactionStatus(transactionId);
    
    statusResponse.getResult().getCode(); // 100
    
    transaction_id = "52ea5beb-343b-4516-ab70-ede2baa058c8"
    transaction_status_response = payment_api.transaction_status(transaction_id)
    
    transaction_status_response.result.code; // 100
    
    var transactionId = "52ea5beb-343b-4516-ab70-ede2baa058c8";
    paymentAPI.transactionStatus(transactionId)
        .then(function(response){
            return response.result.code; // 100
        });
    
    <?php
    $transactionId = "52ea5beb-343b-4516-ab70-ede2baa058c8";
    $status = paymentApi->statusTransaction($transactionId);
    
    $status->body->result->code; // 100
    

    JSON Response

    {
      "transaction": {
        "id": "52ea5beb-343b-4516-ab70-ede2baa058c8",
        "acquirer": {
          "id": "nets",
          "name": "Nets"
        },
        "type": "debit",
        "amount": 2499,
        "current_amount": 2499,
        "currency": "EUR",
        "timestamp": "2018-10-04T10:19:46Z",
        "modified": "2018-10-04T10:19:46Z",
        "filing_code": "181004705200",
        "authorization_code": "436460",
        "token": "77ffbaca-9658-4aef-ac9e-f85da3164bdb",
        "status": {
          "state": "ok",
          "code": 4000
        },
        "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_fingerprint": "da6b0df36efd17c0e7f6967b9e440a0c61b6bd3d96b62f14c90155a1fb883597",
          "pan_fingerprint": "e858e18daac509247f463292641237d6a74ce44e0971ba2de4a14874928a8805"
        },
        "reverts": [],
        "cardholder_authentication": "no",
        "order": "API_TEST_VERSION_20180927",
        "committed": true,
        "committed_amount": 2499,
        "recurring": true,
        "splitting": {
          "amount": 1499,
          "merchant_id": "123456"
        }
      },
      "result": {
        "code": 100,
        "message": "OK"
      }
    }
    

    HTTP Request

    GET /transaction/<:transaction_id>

    HTTP Response

    Object response fields
    1. resultobject

      child fields
    2. transactionmandatoryobject

      child fields

    Siirto Transaction Status

    Siirto Transaction status request

    String transactionId = "f23a9be0-15fe-43df-98ac-92f6a5731c3b";
    SiirtoTransactionStatusResponse statusResponse = paymentAPI.siirtoTransactionStatus(transactionId);
    
    statusResponse.getResult().getCode(); // 100
    
    var transactionId = "f23a9be0-15fe-43df-98ac-92f6a5731c3b";
    paymentAPI.siirtoTransactionStatus(transactionId)
        .then(function(response){
            response.result.code; // 100
        });
    
    <?php
    $transactionId = "f23a9be0-15fe-43df-98ac-92f6a5731c3b";
    $status = paymentApi->statusSiirtoTransaction($transactionId);
    
    $status->body->result->code; // 100
    

    JSON Response for Siirto transaction

    {
      "transaction":
      {
        "id": "8c238d8e-4686-4c68-8b0d-beaa861db1a1",
        "type": "debit",
        "amount": 100,
        "current_amount": 99,
        "currency": "EUR",
        "timestamp": "2018-05-02T14:24:52Z",
        "status":
        {
          "state":"reverted",
          "code":5700
        },
        "reference_number": "1313",
        "customer":
          {
            "network_address": "127.0.0.1"
          },
        "refunds":
          [
            {
              "refund_id": "20180502593064010133",
              "amount": 1,
              "reference_number": "1313",
              "message": "",
              "status": "PAID",
              "timestamp": "2018-05-02T14:31:10Z"
            }
          ]
      },
      "result":
      {
       "code":100,
       "message":"OK"
      }
    }
    

    HTTP Request

    GET /transaction/siirto/<:transaction_id>

    HTTP Response

    Siirto transaction response object fields
    1. resultobject

      child fields
    2. transactionmandatoryobject

      child fields

    Pivo Transaction Status

    Pivo Transaction status request

    String transactionId = "f23a9be0-15fe-43df-98ac-92f6a5731c3b";
    TransactionStatusResponse statusResponse = paymentAPI.pivoTransactionStatus(transactionId);
    
    statusResponse.getResult().getCode(); // 100
    
    var transactionId = "f23a9be0-15fe-43df-98ac-92f6a5731c3b";
    paymentAPI.pivoTransactionStatus(transactionId)
        .then(function(response){
            response.result.code; // 100
        });
    
    <?php
    $transactionId = "f23a9be0-15fe-43df-98ac-92f6a5731c3b";
    $status = paymentApi->statusPivoTransaction($transactionId);
    
    $status->body->result->code; // 100
    

    JSON Response for Pivo transaction

    {
      "transaction":
      {
        "id": "e1fd556f-8264-40f2-9bcf-93b5eea979db",
        "type": "debit",
        "amount": 100,
        "current_amount": 99,
        "currency": "EUR",
        "timestamp": "2018-05-04T12:59:35Z",
        "status":
        {
          "state":"reverted",
          "code":5700
        },
        "reference_number": "",
        "customer":
        {
          "network_address": "93.174.192.154",
          "country_code": "FI"
        },
        "order": "pivotus",
        "pivo_payment_id": "35b15797dac97f5233cd54e52611393a82f680bcb235a1b73ff2d8ca23937dfb",
        "phone": "+358444160589",
        "payment_type": "account",
        "archive_id": "20180504593497ZS0013",
        "modified": "2018-05-04T16:04:40Z",
        "refunds":
          [
            {
              "refund_request_id": "5fd7e9d2-7d78-488f-96c8-7ecee999b2f0",
              "amount": 1,
              "timestamp": "2018-05-04T16:04:39Z",
              "reference_number": "",
              "payment_type": "account",
              "archive_id": "20180504593497ZQ0018"
            }
          ]
      },
      "result":
      {
        "code": 100,
        "message": "OK"
       }
    }
    

    HTTP Request

    GET /transaction/pivo/<:transaction_id>

    HTTP Response

    Pivo transaction response object fields
    1. resultobject

      child fields
    2. transactionmandatoryobject

      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 "SPH-Account: test" \
      -H "SPH-Api-Version: 20180927" \
      -H "SPH-Merchant: test_merchantId" \
      -H "SPH-Request-Id: d1f3e1ec-4fc3-4bda-815a-955ff53d0a5d" \
      -H "SPH-Timestamp: 2018-10-04T10:15:46Z" \
      -H "Signature: SPH1 testKey c1777efd75b06c0901c7bcbaa67ea503e66cb7b2a4f8f82516f891e89b2ee353" \
      --data '' \
      https://v1-hub-staging.sph-test-solinor.com/tokenization/1207e5d7-8d15-44d8-b1d0-00f0c434d131
    
    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": "77ffbaca-9658-4aef-ac9e-f85da3164bdb",
      "recurring": true,
      "customer": {
        "network_address": "93.174.192.154",
        "country_code": "FI"
      },
      "cardholder_authentication": "attempted",
      "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_fingerprint": "da6b0df36efd17c0e7f6967b9e440a0c61b6bd3d96b62f14c90155a1fb883597",
        "pan_fingerprint": "e858e18daac509247f463292641237d6a74ce44e0971ba2de4a14874928a8805"
      },
      "result": {
        "code": 100,
        "message": "OK"
      }
    }
    

    HTTP Request

    GET /tokenization/<id>

    HTTP Response

    Object response fields
    1. card_tokenUUID4

      Present if verification was successful

    2. cardobject

      Present if verification was successful

      child fields
    3. customerobject

      child fields
    4. cardholder_authenticationmandatorystring

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

    5. resultobject

      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

    1. resultmandatoryobject

      child fields
    2. settlementsmandatoryarray

      May be empty

      child fields

    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.
    6000 "declined" Payment has been declined e.g. by bank.
    6100 "cancelled" Transaction is cancelled by end user.
    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-09-27

    2018-07-25

    2018-06-08

    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: