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:
- Form API - for displaying a secure card information input form
- Payment API - for charging and refunding a card and for reporting
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
Live example. Try it out here!
JavaScript
A simple JavaScript example using the JavaScript client library @ GitHub
Usage
Make a Payment
- Show the form with Form API
POST /form/view/pay_with_card
—> returns ansph-transaction-id
andsignature
as a GET parameters to the givensuccess-url
- Commit the payment with Payment API
POST /transaction/<sph-transaction-id>/commit
—> returns a result in JSON formatting
Store a Card
- Show the form with Form API
POST /form/view/add_card
—> returns ansph-tokenization-id
andsignature
as a GET parameters to the givensuccess-url
- Get the card token with Payment API
GET /tokenization/<sph-tokenization-id>
—> returns acard_token
and card information in JSON formatting
Pay with a Stored Card
- Initialize a transaction with Payment API
POST /transaction
—> returns a transactionid
in JSON formatting - Charge the card with Payment API
POST /transaction/<id>/debit
—> returns a result in JSON formatting
Pay with MobilePay
- Open MobilePay with Form API
POST /form/view/mobilepay
-> return ansph-transaction-id
andsignature
as a GET parameters to the givensuccess-url
- 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 |
4153013999700313 | 11/2026 | 313 | Successful 3D Secure. 3DS form password "secret". |
Tokenization OK Payment OK |
4153013999700321 | 11/2026 | 321 | Successful 3D Secure. 3DS form will be automatically completed. |
Tokenization OK Payment OK |
4153013999700339 | 11/2026 | 339 | 3D Secure attempt. 3DS will be automatically attempted. |
Tokenization (OK) Payment (OK) |
4153013999700347 | 11/2026 | 347 | 3D Secure fails. The "cardholder_authentication" response parameter will be "no". It is at discretion of the merchant to accept or reject unauthentication transactions. If the merchant decides to decline the payment, the transaction should be reverted. |
Tokenization OK Payment FAIL |
4153013999700354 | 11/2026 | 354 | Successful 3D Secure. 3DS form password "secret". Insufficient funds in the test bank account. |
Tokenization OK Payment OK with 3DS |
4153013999701162 | 11/2026 | 162 | Soft decline when charging saved card using Customer Initiated Transaction (requires 3DS). 3DS form password "secret". |
Tokenization OK Payment OK with 3DS |
4153013999701170 | 11/2026 | 170 | Soft decline when charging saved card using Customer Initiated Transaction (requires 3DS). 3DS form will be automatically completed. |
Tokenization OK Payment OK |
4153013999700024 | 11/2026 | 024 | Non-EU - "one leg out" card, not enrolled to 3DS. The "cardholder_authentication" response parameter will be "attempted". |
Tokenization OK Payment FAIL |
4153013999700156 | 11/2026 | 156 | Non-EU - "one leg out" card, not enrolled to 3DS. Insufficient funds in the test bank account. |
Tokenization OK Payment OK |
4153013999703002 | Any month and year | Any CVC | Partial approval on amount greater than 2. Returns partial approval of half the amount. Only for AFD customers. |
Tokenization OK Payment OK |
4153013999704000 | Any month and year | Any CVC | Provides a network token, if enabled for the test merchant. |
Tokenization OK Payment FAIL |
4153013999704018 | Any month and year | Any CVC | Provides a network token, if enabled for the test merchant. Insufficient funds in the test bank account for payments. |
Tokenization OK Payment OK with 3DS |
4153013999704026 | Any month and year | Any CVC | Provides a network token, if enabled for the test merchant. Soft decline when charging saved card using Customer Initiated Transaction (requires 3DS). 3DS form password "secret". |
Tokenization OK Payment OK with 3DS |
4153013999704034 | Any month and year | Any CVC | Provides a network token, if enabled for the test merchant. Soft decline when charging saved card or network token using Customer Initiated Transaction (requires 3DS). 3DS form password "secret". |
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
- Show the form with Form API
POST /form/view/add_card
—> returns ansph-tokenization-id
andsignature
as a GET parameters to the givensuccess-url
- Get the card token with Payment API
GET /tokenization/<sph-tokenization-id>
—> returns acard_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, IT, NL, PT, PL, 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-api-version | VERSION | API version number used in the request |
sph-session-id | UUID4 | Reference to the form session |
sph-tokenization-id | UUID4 | Generated sph-tokenization-id |
sph-timestamp | TIMESTAMP | 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-api-version | VERSION | API version number used in the request |
sph-session-id | UUID4 | Reference to the form session |
sph-timestamp | TIMESTAMP | 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:
|
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-api-version | VERSION | API version number used in the request |
sph-session-id | UUID4 | Reference to the form session |
sph-timestamp | TIMESTAMP | 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
- Show the form with Form API
POST /form/view/pay_with_card
—> returns ansph-transaction-id
andsignature
as a GET parameters to the givensuccess-url
- 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 | 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 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). Supported languages are DE, EN, ES, FI, FR, IT, NL, PT, PL, RU, SV. Defaults to browser language. |
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! |
sph-reference-number | AN | O | Reference number. In RF-format or in Finnish reference number format. Used only when transactions are configured to be settled one by one. |
sph-splitting-merchant-id | N | O | Sub-merchant ID from the settlements provider. Not to be confused with the sph-merchant value. |
sph-splitting-amount | N | O | The amount settled to the sub-merchant's account. The rest will be considered as the main merchant's commission. In the smallest currency unit. E.g. 99.99 € = 9999. |
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 | ORDER-ID | Merchant defined order identifier |
sph-request-id | UUID4 | Request identifier |
sph-api-version | VERSION | API version number used in the request |
sph-session-id | UUID4 | Reference to the form session |
sph-amount | N | Amount in the lowest currency unit. E.g. 99,00 € = 9900 |
sph-currency | A | Currency code "EUR" |
sph-transaction-id | UUID4 | Payment transaction identifier |
sph-timestamp | TIMESTAMP | 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 | ORDER-ID | Merchant defined order identifier |
sph-request-id | UUID4 | Request identifier from request |
sph-api-version | VERSION | API version number used in the request |
sph-session-id | UUID4 | Reference to the form session |
sph-timestamp | TIMESTAMP | 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:
|
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 | ORDER-ID | Merchant defined order identifier |
sph-request-id | UUID4 | Request identifier from request |
sph-api-version | VERSION | API version number used in the request |
sph-session-id | UUID4 | Reference to the form session |
sph-timestamp | TIMESTAMP | 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 | 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 | 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 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-token | UUID4 | M | The card token to charge. |
sph-api-version | VERSION | O | API version number |
language | A | O | Language code (ISO 639-1). Supported languages are DE, EN, ES, FI, FR, IT, NL, PT, PL, RU, SV. Defaults to browser language. |
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! |
sph-reference-number | AN | O | Reference number. In RF-format or in Finnish reference number format. Used only when transactions are configured to be settled one by one. |
sph-splitting-merchant-id | N | O | Sub-merchant ID from the settlements provider. Not to be confused with the sph-merchant value. |
sph-splitting-amount | N | O | The amount settled to the sub-merchant's account. The rest will be considered as the main merchant's commission. In the smallest currency unit. E.g. 99.99 € = 9999. |
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 | ORDER-ID | Merchant defined order identifier |
sph-request-id | UUID4 | Request identifier from request |
sph-api-version | VERSION | API version number used in the request |
sph-session-id | UUID4 | Reference to the form session |
sph-timestamp | TIMESTAMP | 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:
|
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
- Open MobilePay with Form API
POST /form/view/mobilepay
-> return ansph-transaction-id
andsignature
as a GET parameters to the givensuccess-url
- 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 | 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-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 | 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 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). Supported languages are DE, EN, ES, FI, FR, IT, NL, PT, PL, RU, SV. Defaults to browser language. |
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. Used only when transactions are configured to be settled one by one. |
sph-splitting-merchant-id | N | O | Sub-merchant ID from the settlements provider. Not to be confused with the sph-merchant value. |
sph-splitting-amount | N | O | The amount settled to the sub-merchant's account. The rest will be considered as the main merchant's commission. In the smallest currency unit. E.g. 99.99 € = 9999. |
signature | ANS | M | Message signature in the format 'SPH1 key-id authentication-string' |
About shop logo in MobilePay
- The logo must be 250x250 pixel in .png format.
- MPO will show a default logo in the app if this is empty or the image location doesn’t exist.
- Once a ShopLogoURL has been sent to MPOnline the .png-file on that URL must never be changed. If the shop wants a new (or more than one) logo, a new ShopLogoURL must be used.
- The logo must be hosted on a HTTPS (secure) server.
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 | ORDER-ID | Merchant defined order identifier |
sph-request-id | UUID4 | Request identifier from request |
sph-api-version | VERSION | API version number used in the request |
sph-session-id | UUID4 | Reference to the form session |
sph-timestamp | TIMESTAMP | 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:
|
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 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 | 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 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 |
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. If omitted, random reference number will be generated by us. Reference number is used when payment type is "siirto" or "account", but not in card payments. With contract where transactions are configured to be settled one by one, reference number is used in every payment method. |
sph-phone-number | AN | O | When used, phone number will be prefilled to form. Use international format e.g. "+358441234567" |
sph-splitting-merchant-id | N | O | Sub-merchant ID from the settlements provider. Not to be confused with the sph-merchant value. |
sph-splitting-amount | N | O | The amount settled to the sub-merchant's account. The rest will be considered as the main merchant's commission. In the smallest currency unit. E.g. 99.99 € = 9999. |
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:
Signature
: ”” = The signature header used for authentication and message consistency, see the following section.SPH-Account
: ”example_account”= (High level) account name associated with the authentication key.SPH-Merchant
: ”example_merchant” = The account’s sub-account, which provides optional merchant level customization.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.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:
Sph-Api-Version
: “yyyyMMdd” = The version date of the JSON response schema. Defaults to “20141215”.
All the HTTP responses contain the following headers:
Signature
: ”” see the following section.SPH-Response-Id
: ”03c15388-bebc-4872-b3f5-faed0ca65ff6” = Unique one-time- use Response ID in UUID4 format.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.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}}
- HTTP method (e.g. “POST” or “GET”)
- HTTP URI without server URL (e.g. ““/transaction/859cefdf-41fa-453a-a6a5- beff35e2f3b8/debit”).
- All the SPH- headers’ trimmed key value pairs concatenated in alphabetic order (by the header name). The header keys must be in lowercase. Each header’s key and value are separated with a colon (“:”) and the different headers are separated with a new line (“\n”).
- HTTP body if exists, empty string if not.
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.
Initialize Add Card Form via Backend
Initialize a new Add Card form via Payment API (backend-to-backend).
The Add Card form allows the end user to submit their payment card information, which is then securely stored to Payment Highway. The merchant receives tokenization ID via the given redirection success url and optionally the webhook. The tokenization ID is used to fetch the actual card token, used to charge the card.
Technically this is the same as add card via Form API, but the URL for the Add Card form is immediately returned in the response of this request, instead of requiring the end user's browser to POST the details via an HTML page, in order to initialize the Add Card form.
when using API version "20210412" or above, sph-session-id
and sph-api-version
query parameter are included in the success, cancel and failure redirections and webhook calls.
HTTP Request
POST /form/init/add_card
Object request fields
return_urlsmandatoryobject
The URLs where to redirect the user and send the webhook requests to, upon completion of the form.
child fields
strong_customer_authenticationmandatoryobject
Information used in transaction risk analysis (TRA) and can increase the likelihood of the transaction being considered low risk, possibly skipping the requirements of strong customer authentication.
child fields
languageANS
Two letter language code (ISO 639-1). Supported languages are DE, EN, ES, FI, FR, IT, NL, PT, PL, RU, SV. Defaults to browser language.
customerobject
child fields
skip_form_notificationsBOOLEAN
Skip errors displayed on the Payment Highway form and redirect directly to result URL (E.g. "Ecom payments disabled") . Default false.
HTTP Response
Object response fields
urlmandatoryURL
The form URL where the user is redirected to. After submitting the form the user will be sent to one of the specified return URLs.
valid_untilmandatoryTIMESTAMP
Session expriration time.
session_idmandatoryUUID4
Session ID used to fetch the state and details of the form session.
resultobject
child fields
Initialize Click to Pay Form via Backend
Initialize a new Click to Pay form via Payment API (backend-to-backend). The URL for the Click to Pay form is immediately returned in the response of this request, instead of requiring the customer's browser to POST the details via an HTML page, like it is with the Form API calls.
The Click to Pay form allows the customer to pay with Click to Pay.
Click to Pay detects a returning customer device via a cookie. Supplying the customer.email
and/or customer.phone_number
allows Click to Pay to look for the customer's account in their registry if the device is unknown.
When the form has been completed by the customer the merchant receives a sph-transaction-id
via the given redirection sph-success-url
and optionally the sph-webhook-success-url
. The transaction ID is used to commit the payment.
When using API version "20210412" or above, sph-session-id
and sph-api-version
query parameter are included in the success, cancel and failure redirections and webhook calls.
HTTP Request
POST /form/init/pay_with_click_to_pay
Object request fields
amountmandatoryAMOUNT
Amount in the smallest currency unit. E.g. 99.99 € = 9999
currencymandatoryCURRENCY
ISO 4217 currency code
ordermandatoryORDER-ID
Merchant defined order identifier. Should be unique per order. See also Order Status search.
return_urlsmandatoryobject
The URLs where to redirect the user and send the webhook requests to, upon completion of the form.
child fields
strong_customer_authenticationmandatoryobject
Information used in transaction risk analysis (TRA) and can increase the likelihood of the transaction being considered low risk, possibly skipping the requirements of strong customer authentication.
child fields
languageANS
Two letter language code (ISO 639-1). Supported languages are DE, EN, ES, FI, FR, IT, NL, PT, PL, RU, SV. Defaults to browser language.
customerobject
child fields
skip_form_notificationsBOOLEAN
Skip errors displayed on the Payment Highway form and redirect directly to result URL (E.g. "Ecom payments disabled") . Default false.
HTTP Response
Object response fields
urlmandatoryURL
The form URL where the user is redirected to. After submitting the form the user will be sent to one of the specified return URLs.
valid_untilmandatoryTIMESTAMP
Session expriration time.
session_idmandatoryUUID4
Session ID used to fetch the state and details of the form session.
resultobject
child fields
Commit Payment
Commit Form Payment
curl -i \
-H "Content-Length: 32" \
-H "Content-Type: application/json" \
-H "SPH-Account: test" \
-H "SPH-Api-Version: 20191204" \
-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
amountmandatoryAMOUNT
Amount in the smallest currency unit. E.g. 99.99 € = 9999
currencymandatoryCURRENCY
ISO 4217 currency code
HTTP Response
Object response fields
card_tokenUUID4
Present on a successful commit. See also card.cvc_required below.
cardobject
Present on a successful commit. See also card.cvc_required below.
child fields
customerobject
child fields
committedmandatoryBOOLEAN
committed_amountmandatoryAMOUNT
Omitted if "committed" is false
filing_codeAN
approved_amountmandatoryAMOUNT
Approved amount that covers only automated fuel dispenser case when supports_partial_approval is used in the request.
reference_numberAN
Reference number. In RF-format or in Finnish reference number format.
resultobject
child fields
acquirerobject
child fields
acquirer_response_codeAN
Acquirer specific response code
authorizerAN
The card issuer or scheme network which gave the authorization response (acquirer_response_code)
Transaction result
Used to find out whether or not an uncommitted transaction succeeded, without actually committing (capturing) it.
For Pivo payments, check Pivo transaction result
HTTP Request
GET /transaction/<:transaction_id>/result
Responses
Responses are exactly the same as in the Commit.
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
GET /transaction/<:transaction_id>/pivo/result
Responses
Pivo transaction response object fields
statemandatoryA
Pivo transaction state (‘pending’, ‘paid’, ‘cancelled’, ‘rejected’ or ‘refunded’)
customerobject
child fields
amountmandatoryAMOUNT
Amount in the smallest currency unit. E.g. 99.99 € = 9999
current_amountAMOUNT
Amount after possible reversals
reference_numberAN
Reference number. In RF-format or in Finnish reference number format.
archive_idAN
payment_typeA
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.
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 transactions 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: 20191204" \
-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
idmandatoryUUID4
The handle for the following requests.
resultobject
child fields
Charging a card token
After the introduction of the European PSD2 directive, the electronic payment transactions are categorised in so called customer initiated transactions (CIT) and merchant initiated transactions (MIT).
Customer initiated transactions are scenarios, where the customer actively takes part in the payment process. This also includes token, or "one-click" purchases, where the transaction uses a previously saved payment method.
Merchant initiated transactions are payments triggered without the customer's participation. This kind of transactions can be used for example in scenarios where the final price is not known at the time of the purchase or the customer is not present when the charge is made. A prior agreement, or "mandate" between the customer and the merchant is required.
Charging a customer initiated transaction (CIT)
Urls returnUrls = Urls.Builder(
"https://example.com/success/12345",
"https://example.com/failure/12345",
"https://example.com/cancel/12345"
)
.setWebhookSuccessUrl("https://example.com/success/12345/?webhook=1")
.setWebhookCancelUrl("https://example.com/failure/12345/?webhook=1")
.setWebhookFailureUrl("https://example.com/webhook/failure/?webhook=1")
.build();
CustomerDetails customerDetails = CustomerDetails.Builder()
.setShippingAddressMatchesBillingAddress(true)
.setName("Eric Example")
.setEmail("eric.example@example.com")
// ...
.build();
StrongCustomerAuthentication strongCustomerAuthentication = new StrongCustomerAuthentication.Builder(returnUrls)
.setCustomerDetails(customerDetails)
// ...
.build();
Token cardToken = new Token("49026753-ff50-4c35-aff0-0335a26ea0ff");
ChargeCitRequest request = new ChargeCitRequest.Builder(
cardToken,
123L,
"EUR",
"order-123456",
strongCustomerAuthentication
).build();
String requestId = request.getRequestId();
UUID transactionId = paymentAPI.initTransaction().getId();
ChargeCitResponse citResponse = paymentAPI.chargeCustomerInitiatedTransaction(transactionId, request);
const token = new paymentHighway.Token('tokenId');
const amount = 1990;
const currency = 'EUR';
const returnUrls = ReturnUrls.Builder(
"https://example.com/success", // URL the user is redirected after succesful 3D-Secure authentication if strong customer authentication is required
"https://example.com/cancel", // URL the user is redirected after cancelled 3D-Secure authentication if strong customer authentication is required
"https://example.com/failure" // URL the user is redirected after failed 3D-Secure authentication if strong customer authentication is required
)
.setWebhookSuccessUrl("https://example.com/success/12345/?webhook=1")
.setWebhookCancelUrl("https://example.com/failure/12345/?webhook=1")
.setWebhookFailureUrl("https://example.com/webhook/failure/?webhook=1")
.build();
const customerDetails = CustomerDetails.Builder()
.setShippingAddressMatchesBillingAddress(true)
.setName('Eric Example')
.setEmail('eric.example@example.com')
// ...
.build();
const sca = StrongCustomerAuthentication.Builder(returnUrls)
.setCustomerDetails(customerDetails)
// Optionally other information about the customer and purchase to help in transaction risk analysis (TRA)
.build();
return paymentAPI.chargeCustomerInitiatedTransaction(transactionId, new ChargeCitRequest(token, amount, currency, sca));
<?php
$token = new \Solinor\PaymentHighway\Model\Token( $tokenId );
$strongCustomerAuthentication = new \Solinor\PaymentHighway\Model\Sca\StrongCustomerAuthentication(
new \Solinor\PaymentHighway\Model\Sca\ReturnUrls(
"https://example.com/success", // URL the user is redirected after succesful 3D-Secure authentication if strong customer authentication is required
"https://example.com/cancel", // URL the user is redirected after cancelled 3D-Secure authentication if strong customer authentication is required
"https://example.com/failure" // URL the user is redirected after failed 3D-Secure authentication if strong customer authentication is required
)
// Optinally other information about the customer and purchase to help in transaction risk analysis (TRA)
);
$transaction = new \Solinor\PaymentHighway\Model\Request\CustomerInitiatedTransaction( $token, $amount, $currency, $strongCustomerAuthentication );
$response = $paymentApi->chargeCustomerInitiatedTransaction( $transactionId, $transaction);
When charging a token using customer initiated transaction, applicable exemptions are attempted in order to avoid the need for strong customer authentication, 3D Secure. These exemptions may include but are not limited to: low-value (under 30 EUR) or transaction risk analysis.
Regardless, there is always a possibility the card issuer requires strong customer authentication by requesting a step-up. In this case, the response will contain "soft decline" result code 400 and an URL, where the customer needs to be redirected to, in order to perform the authentication. The merchant's URLs where the customer will be redirected back to - after completing the authentication - need to be defined in the return_urls
parameter in strong_customer_authentication
.
When the customer is redirected back to the success URL, after completing the payment using strong customer authentication, the payment needs to be committed exactly as in the normal FormAPI payment flow.
The merchant supplied "order", the request ID, or custom merchant parameters specified in the return URLs, can be used to connect the returning customer to the specific payment.
In addition to the return urls, the strong_customer_authentication
object contains many optional fields for information about the customer and the transaction. This information is used in transaction risk analysis (TRA) and may increase the likelihood of transaction being considered as low-risk, thus avoiding the need for strong authentication.
HTTP Request
POST /transaction/<:transaction_id>/card/charge/customer_initiated
Object request fields
amountmandatoryAMOUNT
Amount in the smallest currency unit. E.g. 99.99 € = 9999
currencymandatoryCURRENCY
ISO 4217 currency code
tokenobject
Either `card` or `token` must be included
child fields
cardobject
Usage of card is for PCI DSS certified parties only. Typically use token instead.
child fields
ordermandatoryORDER-ID
Merchant defined order identifier
customerobject
child fields
commitBOOLEAN
If omitted,
true
is usedsplittingobject
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 22:00 UTC). Instead the sub-merchant's account will be used for the money transfer.
child fields
strong_customer_authenticationmandatoryobject
Information used in transaction risk analysis (TRA) and can increase the likelihood of the transaction being considered low risk, possibly skipping the requirements of strong customer authentication. Includes return URLs object with webhooks for receiving the results.
child fields
supports_partial_approvalBOOLEAN
Support partial approval for this transaction. Only available for Automated Fuel Dispensers.
is_estimated_amountBOOLEAN
Flag to set to `true` if the amount is estimated and will likely be changed. Should be set to `true` for Automated Fuel Dispensers.
HTTP Response
Object response fields
resultobject
child fields
three_d_secure_urlURL
Populated in case of soft decline result code "400" (Issuer requests 3DS step-up). The URL to redirect the cardholder to, for strong customer authentication.
acquirerobject
child fields
acquirer_response_codeAN
Acquirer specific response code
authorizerAN
The card issuer or scheme network which gave the authorization response (acquirer_response_code)
approved_amountAMOUNT
Approved amount that covers only automated fuel dispenser case when supports_partial_approval is used in the request.
Charging a CIT for Automated Fuel Dispenser (AFD)
The general CIT flow is partially modified for the Automated Fuel Dispenser use case.
When making a charge request, the following fields should be set to appropriate values:
is_estimated_amount
must be set totrue
commit
must be set tofalse
- In case partial approval is supported the flag
supports_partial_approval
should be set totrue
If partial approval is supported, the approved_amount
in the response must be observed for the actual amount that is available for the transaction.
After the final amount of the transaction is known an advice message with the full amount should be sent.
This will adjust the reserved amount of the transaction in real-time.
The advice message must be sent within 20 minutes of creating an original charge request.
Please note that amount
parameter in the advice message is the final amount as opposed to amount
in the revert message where amount
parameter is the cancelled amount.
After the amount was adjusted to the final amount a commit message with the final amount can be sent.
In case the transaction is aborted a revert should be sent instead of the advice message.
Charging a merchant initiated transaction (MIT)
Token cardToken = new Token("49026753-ff50-4c35-aff0-0335a26ea0ff");
ChargeMitRequest request = ChargeMitRequest.Builder(cardToken, 99L, "EUR", "order-123456").build();
String requestId = request.getRequestId();
UUID transactionId = paymentAPI.initTransaction().getId();
ChargeMitResponse chargeMitResponse = paymentAPI.chargeMerchantInitiatedTransaction(transactionId, request);
var token = new paymentHighway.Token('tokenId');
var amount = 1990;
var currency = 'EUR';
return paymentAPI.chargeMerchantInitiatedTransaction(transactionId, new ChargeMitRequest(token, amount, currency));
<?php
$token = new \Solinor\PaymentHighway\Model\Token( $tokenId );
$transaction = new \Solinor\PaymentHighway\Model\Request\Transaction( $token, $amount, $currency );
$response = $paymentApi->chargeMerchantInitiatedTransaction( $transactionId, $transaction);
This method should be used when charging the customer's card in a context, where the customer is not actively participating in the transaction.
The MIT transactions are exempt from the strong customer authentication requirements of PSD2, thus the payment cannot receive the "soft decline" response (code 400), unlike in the case of customer initiated transactions.
HTTP Request
POST /transaction/<:transaction_id>/card/charge/merchant_initiated
Object request fields
amountmandatoryAMOUNT
Amount in the smallest currency unit. E.g. 99.99 € = 9999
currencymandatoryCURRENCY
ISO 4217 currency code
tokenobject
Either `card` or `token` must be included
child fields
cardobject
Usage of card is for PCI DSS certified parties only. Typically use token instead.
child fields
ordermandatoryORDER-ID
Merchant defined order identifier
customerobject
child fields
commitBOOLEAN
If omitted,
true
is usedsplittingobject
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 22:00 UTC). Instead the sub-merchant's account will be used for the money transfer.
child fields
HTTP Response
Object response fields
resultobject
child fields
filing_codeAN
approved_amountAMOUNT
Approved amount that covers only automated fuel dispenser case when supports_partial_approval is used in the request. Omitted on failure
acquirerobject
child fields
acquirer_response_codeAN
Acquirer specific response code
authorizerAN
The card issuer or scheme network which gave the authorization response (acquirer_response_code)
Apple Pay Debit Transaction
How to implement Apple Pay
- Request a Certificate Signing Request (CSR) from support@paymenthighway.fi for Apple Pay on your site or app.
- Sign the CSR in your Apple Developer account and send the Apple Pay Payment Processing Certificate to us.
- Implement Apple Pay into your app or web site following Apple's documentation.
- 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: 20191204" \
-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
idmandatoryUUID4
The handle for the following requests.
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
});
Create Apple Pay debit request
HTTP Request
POST /transaction/<:transaction_id>/debit_applepay
Object request fields
amountmandatoryAMOUNT
Amount in the smallest currency unit. E.g. 99.99 € = 9999
currencymandatoryCURRENCY
ISO 4217 currency code
payment_datamandatoryobject
child fields
commitBOOLEAN
If omitted,
true
is usedcustomerobject
child fields
orderORDER-ID
Merchant defined order identifier
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 22:00 UTC). Instead the sub-merchant's account will be used for the money transfer.
child fields
HTTP Response
Same response as Merchant initiated transaction (MIT)
Google Pay™ Debit Transaction
Enrolling with Google Pay
To support Google Pay as a payment method, please refer to Google Pay Web developer documentation, Google Pay Web integration checklist and Google Pay Web Brand Guidelines.
Create Google Pay debit request
In your requests for payments towards the Google Pay API, please use nexirelay
as a gatewayId
and merchant reference used in sph-merchant
as gatewayMerchantId
.
We support both PAN_ONLY
and CRYPTOGRAM_3DS
authentication methods. When a token from Google Pay is PAN_ONLY
the customer will be required to complete the 3DS step-up flow. For details on 3DS step up, please refer to Customer initiated transaction (CIT).
The following card networks are supported by our platform:
AMEX
MASTERCARD
VISA
HTTP Request
POST /transaction/<:transaction_id>/debit_googlepay
Object request fields
amountmandatoryAMOUNT
Amount in the smallest currency unit. E.g. 99.99 € = 9999
currencymandatoryCURRENCY
ISO 4217 currency code
google_pay_tokenmandatorystring
A token string received from Google Pay that contains the encrypted details required for payment. The token should be provided as unparsed string from the Google Pay API response
paymentData.paymentMethodData.tokenizationData.token
.commitBOOLEAN
If omitted,
true
is usedcustomerobject
child fields
orderORDER-ID
Merchant defined order identifier
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 22:00 UTC). Instead the sub-merchant's account will be used for the money transfer.
child fields
HTTP Response
Same response as Customer initiated transaction (CIT)
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
amountmandatoryAMOUNT
Amount in the smallest currency unit. E.g. 99.99 € = 9999
currencymandatoryCURRENCY
ISO 4217 currency code
orderORDER-ID
Merchant defined order identifier
return_urimandatoryURI
Where MobilePay app returns. Parameter sessionToken is added to uri.
webhook_success_urlmandatoryURL
On success, server to server GET request will be made to this url.
webhook_cancel_urlmandatoryURL
On cancel, server to server GET request will be made to this url.
webhook_failure_urlmandatoryURL
On failure, server to server GET request will be made to this url.
languageLANG
Language code. Allowed values are "en", "fi", "da", "no"
shop_nameANS
Name of the shop/merchant. MobilePay app displays this under the shop logo. If omitted, the merchant name from PH is used.
shop_logo_urlURL
The logo must be 250x250 pixel in .png format and must be hosted on a HTTPS (secure) server.
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 22:00 UTC). Instead the sub-merchant's account will be used for the money transfer.
child fields
About shop logo in MobilePay
- The logo must be 250x250 pixel in .png format.
- MPO will show a default logo in the app if this is empty or the image location doesn’t exist.
- Once a ShopLogoURL has been sent to MPOnline the .png-file on that URL must never be changed. If the shop wants a new (or more than one) logo, a new ShopLogoURL must be used.
- The logo must be hosted on a HTTPS (secure) server.
HTTP Response
Object response fields
session_tokenmandatoryANS
MobilePay session token
urimandatoryURI
MobilePay app uri
valid_untilTIMESTAMP
Session expriration time.
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
statusmandatoryTSTATE
MobilePay session status
valid_untilmandatoryTIMESTAMP
Session expriration time.
transaction_idUUID4
Transaction id. Available if status is "ok"
resultobject
child fields
Pivo app based payment flow
Open Pivo app without external browsers, resulting in a smoother user experience.
Please remember to first verify the user has Pivo app installed!
Using Payment Highway and Pivo in Mobile application
Initialize Pivo payment with app flow.
// Initialize Pivo payment session
long amount = 1990L;
String currency = "EUR";
String order = UUID.randomUUID().toString()
PivoInitRequest request = PaymentRequestBuilder.pivoInitRequest(amount, currency)
.setOrder(order)
.setAppUrl("myapp://paid")
.setWebhookSuccessUrl("https://backend.myapp.com/success")
.setWebhookCancelUrl("https://backend.myapp.com/cancel")
.setWebhookFailureUrl("https://backend.myapp.com/failure")
.setDescription("3 oranges");
PivoInitResponse response = paymentAPI.initPivoTransaction(request);
response.getTransactionId();
response.getUri(); // start Pivo app with this uri
response.getResult().getCode(); // 100
const amount = 1990;
const currency = 'EUR';
const orderId = 'orderid';
const request = PivoInitRequest.Builder(amount, currency)
.setOrder(orderId)
.setDescription('3 oranges')
.setAppUrl('myapp://paid')
.setWebhookSuccessUrl('https://myserver.com/success')
.setWebhookCancelUrl('https://myserver.com/cancel')
.setWebhookFailureUrl('https://myserver.com/failure')
.build()
api.initPivoTransaction(request)
.then(function (init) {
const transaction_id = init.transaction_id;
const uri = init.uri; // start Pivo app with this uri
const resultCode = init.result.code; // 100
});
Json request
{
"amount": 1990,
"currency": "EUR",
"order": "order",
"description": "3 oranges",
"app_url": "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
{
"transaction_id": "52ea5beb-343b-4516-ab70-ede2baa058c8",
"uri": "pivo://api/v1/payment_button?payment_id=9942a5fa5e872a7cde823ec7b1443519506e99cd31e89ad7d63b4ea793c85843",
"valid_until": "2018-09-18T10:32:59Z",
"result": {
"code":100,
"message":"OK"
}
}
HTTP Requests
POST /app/pivo
Initialize Pivo payment flow when using Pivo app. It is important to check that user has Pivo app installed before using payment flow with app.
Object request fields
amountmandatoryAMOUNT
Amount in the smallest currency unit. E.g. 99.99 € = 9999
currencymandatoryCURRENCY
ISO 4217 currency code
orderORDER-ID
Merchant defined order identifier
reference_numberAN
Reference number. In RF-format or in Finnish reference number format.
phone_numberPHONE
descriptionANS
The order description shown to the user
app_urlmandatoryURL
Where the user is returned to, after a finished Pivo payment.
webhook_success_urlmandatoryURL
On success, server to server GET request will be made to this url.
webhook_cancel_urlmandatoryURL
On cancel, server to server GET request will be made to this url.
webhook_failure_urlmandatoryURL
On failure, server to server GET request will be made to this url.
languageLANG
Language code.
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 22:00 UTC). Instead the sub-merchant's account will be used for the money transfer.
child fields
HTTP Response
Object response fields
transaction_idmandatoryUUID4
Transaction ID
urimandatoryURI
Pivo app uri
valid_untilmandatoryTIMESTAMP
Session expriration time.
resultobject
child fields
Retrying Failed Payments
If a payment transaction fails with RCODE 200
there are two possible retry scenarios:
- retrying is forbidden or
- retrying is allowed only a certain number of times.
For a failed transaction you need to inspect the acquirer_response_code
to know how to proceed.
A transaction is considered a retry when after an initially failed transaction:
- the card number or the token used to pay is the same and
- the amount is the same and
- the acquiring agreement is the same.
The most common scenario is retrying a failed MIT transaction. Pay attention to the automatic retry logic for MITs. A retry can also easily occur with Customer Initiated Transactions using token, for example during a commute ticket purchase via an app. Even a one-time purchase in a web shop may lead to a retry if the cardholder inputs the same card details again after an initial failed payment.
Case 1 - Retrying is forbidden
When the acquirer_response_code
is:
Nets | Bambora | Concardis | Amex |
---|---|---|---|
111, 119, 165, 200, 207, 208, 209, 902, 908, 909 | 04, 07, 12, 14, 15, 41, 43, 46, 57, R0, R1, R3 | 04, 12, 14, 43, 57 | 181, 183, 187, 189, 200 |
Never retry such a transaction. The cardholder needs to give a new card number to proceed.
Case 2 - Retrying is allowed
When the acquirer_response_code
is any other than above for a specific acquirer, you may retry the transaction up to 15 times in the next 30 days.
Order Status
Get the transactions related to a specific order
curl -i \
-H "SPH-Account: test" \
-H "SPH-Api-Version: 20191204" \
-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_20191204
OrderSearchResponse orderSearchResponse = paymentApi.searchOrders(order);
paymentAPI.searchOrders("API_TEST_VERSION_20191204");
<?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_20191204",
"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_20191204",
"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
resultobject
child fields
transactionsmandatoryarray
All transactions belonging to the order
child fields
siirto_transactionsarray
Deprecated empty array
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: 20191204" \
-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 Pivo transactions, use Revert Pivo.
HTTP Request
POST /transaction/<:transaction_id>/revert
Object request fields
amountmandatoryAMOUNT
Amount in the smallest currency unit. E.g. 99.99 € = 9999. Without amount the whole transaction is reverted.
HTTP Response
Object response fields
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 other transactions, use Revert.
HTTP Request
POST /transaction/<:transaction_id>/pivo/revert
Object request fields
reference_numberAN
Reference number. In RF-format or in Finnish reference number format. It omitted, random reference number will be generated by PH
amountmandatoryAMOUNT
Amount in the smallest currency unit. E.g. 99.99 € = 9999. Without amount the whole transaction is reverted.
HTTP Response
Object response fields
resultobject
child fields
Advice for Automated Fuel Dispensers
Adjust amount of a payment transaction
curl -i \
-H "Content-Length: 15" \
-H "Content-Type: application/json" \
-H "SPH-Account: test" \
-H "SPH-Api-Version: 20191204" \
-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/advice
JSON Response
{
"result": {
"code": 100,
"message":" OK"
}
}
Adjusts the amount of the initial authorization with the final amount of the transaction at the Automated Fuel Dispenser. If the user cancelled the fuelling, use Revert instead.
The advice message should be retried at most once.
HTTP Request
POST /transaction/<:transaction_id>/advice
Object advice fields
amountmandatoryAMOUNT
Amount in the smallest currency unit. E.g. 99.99 € = 9999.
HTTP Response
Object advice fields
resultobject
child fields
Transaction Status
Transaction status request
curl -i \
-H "SPH-Account: test" \
-H "SPH-Api-Version: 20191204" \
-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_20191204",
"committed": true,
"committed_amount": 2499,
"recurring": true,
"splitting": {
"amount": 1499,
"merchant_id": "123456"
}
},
"result": {
"code": 100,
"message": "OK"
}
}
HTTP Request
For Pivo payments, check Pivo transaction status
GET /transaction/<:transaction_id>
HTTP Response
Object response fields
resultobject
child fields
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
resultobject
child fields
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: 20191204" \
-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": false,
"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/<sph-tokenization-id>
HTTP Response
Object response fields
card_tokenUUID4
Present if verification was successful
cardobject
Present if verification was successful
child fields
customerobject
child fields
cardholder_authenticationmandatoryA
Indicates whether ThreeDS (3ds) card holder authentication was done (
authenticated
,attempted
orno
)resultobject
child fields
acquirerobject
child fields
acquirer_response_codeAN
Acquirer specific response code
authorizerAN
The card issuer or scheme network which gave the authorization response (acquirer_response_code)
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
resultmandatoryobject
child fields
settlementsmandatoryarray
May be empty
child fields
Form Session Status
Form session status
JSON Response
{
"status": {
"code": 2000,
"message": "started"
}
"transaction_id": null,
"operation": "pay-and-tokenize"
"created": "2022-07-14T15:00:00Z",
"valid_until": "2022-07-14T17:59:59Z",
"result": {
"code":100,
"message":"OK"
}
}
Get form session current status.
HTTP Request
GET /form/<:session_id>/status
HTTP Response
Object response fields
statusmandatoryobject
Form session status.
child fields
transaction_idUUID4
Transaction id.
operationmandatoryAN
Operation (tokenize, pay-and-tokenize, pay-single, pay-mobilepay, pay-pivo, pay-with-token-and-cvc, pay-three-d-secure-step-up).
createdmandatoryTIMESTAMP
Session creation time.
valid_untilmandatoryTIMESTAMP
Session expriration time.
resultobject
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. |
101 | Description of partial approval success | Request for partial approval is 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. | |
400 | Soft Decline: Issuer requests step-up | Customer Initiated Transaction is soft declined and the issuer requests a step-up 3D Secure transaction. |
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. |
931 | Token temporarily unusable. | The payment with token failed due to network token error. |
932 | Token unusable. | The token provided can no longer be used as the associated network token is invalid and the associated card changed. |
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. |
999 | Deprecated API has been removed |
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. |
7020 | "soft_declined" | Issuer requests 3DS step-up |
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. |
FSCODE Form Session Status Codes
FCODE | FSTATE | Description |
---|---|---|
3000 | "in_progress" | The form has been initialized but not submitted. |
4000 | "ok" | The form has been successfully processed. |
4100 | "ok_pending" | The form has been initialized but waiting for user. |
4300 | "failed_recoverable" | Processing of the form input has failed, but can be re-processed. |
6100 | "cancelled" | The form has been cancelled by the user. |
7000 | "failed" | Processing the form session has permanently failed. |
7030 | "failed_no_route" | No acquiring route was found for the submitted payment details. |
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 |
---|---|---|
A | ^[a-zA-Z]+$ | Hello |
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 |
PHONE | ^+[\d]{1,14}$ | +358441234567 |
HEX | ^[A-Fa-f0-9]+$ | |
FSTATE | ^[.,'-=/\w;\s]{0,254}$ | |
FCODE | ^\d{4}$ | 2000 |
Change log
2024-05-22
Click to Pay added - New Payment API endpoint for initializing a Click to Pay form
2022-11-30
- New API version 20220825, adding
approved_amount
to commit, transaction result, CIT and MIT responses - Add section for CIT for Automated Fuel Dispenser
- Add
is_estimated_amount
parameter for customer initiated transaction (CIT)
2022-10-20
- Add sandbox test cards that issue a network token.
2022-08-19
- Support Partial Approval for AFD.
2022-08-15
- Addition of advice messages.
2022-08-11
- Instructions for retrying failed payments
2022-07-15
- New endpoint for fetching form session current status
2021-04-12
- New API version 20210412
- when using API version "20210412" or above in Form and Payment APIs, the
sph-session-id
andsph-api-version
query parameters are included in the success, cancel and failure redirections and webhook calls.
2020-04-27
- Masterpass removed
sph-show-payment-method-selector
parameter removed
2020-04-20
- New API version 20200401
- Acquirer info, acquirer response code and authorizer info for card based transactions (CIT, MIT, Apple Pay, Order status, Transaction status, Tokenization)
2020-02-24
- New result code (RCODE): 999 - "API endpoint is no longer available.".
- Removed Siirto payments
- Form redirects to failure url
- Api requests return new 999 result code
2019-12-11
- New API version 20191204
- Reference number field for transaction info in: Commit, Order status, Transaction status, Transaction result
2019-09-26
- New failure URL reason parameter (sph-failure) value: "SESSION_EXPIRED". Used when a payment or tokenization form session has expired before the user has completed it. Currently the forms are active for 3 hours.
2019-09-13
- Deprecated the old Charge Card (/debit) API in favor of the new PSD2 compliant APIs.
- PSD2 compliant APIs for charging cards: Customer Initiated Transaction and Merchant Initiated Transaction.
- New result code (RCODE): 400 - "Soft Decline: Issuer requests step-up". Used when a Customer Initiated Transaction request is soft declined and the issuer requests step-up 3D Secure transaction.
- New transaction status (TCODE): 7020 - "soft_declined". Used for a soft declined transaction.
- New 3DS enabled test cards and ones that will soft decline Customer Initiated Transactions.
- Labeled the old test cards as Non-EU one-leg-out cards, which are not enrolled into 3D Secure.
2019-06-14
2018-09-27
- ApiVersion 20180927
- Card objects have pan and card fingerprints
2018-07-25
- ApiVersion 20180725
- Update Pivo and Siirto response fields from camelCase to snake_case. Order status Order status.
2018-06-08
- ApiVersion 20180608
- Siirto payments
- Pivo payments
- New Pivo and Siirto response fields for order status Order status.
2018-04-26
- Payment splitting parameters to debit request and transaction status
2018-02-26
- Apple Pay support was added
2017-11-27
- ApiVersion 20171127
- Backend returns
recurring
information with transactions, boolean value informs if transaction is recurring
2017-06-27
Masterpass with user profile
- Form API
- Payment with Masterpass and User Profile added for requesting user profile before authorization
sph-request-shipping-address
optional boolean parameter added to Masterpass requests
- Payment API
- User profile for fetching user profile
- Masterpass debit transaction card charging after fetching user profile
2017-05-29
- Masterpass form function
- New failure reasons: THREE_D_SECURE, MOBILEPAY_NOT_SUPPORTED, MOBILEPAY, MASTERPASS_NOT_SUPPORTED, MASTERPASS
- New form parameter for Payment and Payment & Add Card:
sph-show-payment-method-selector
2017-05-23
- Webhook form parameters added
sph-webhook-success-url
,sph-webhook-failure-url
,sph-webhook-cancel-url
andsph-webhook-delay
2016-12-07
- Java lib examples with new builder pattern.
- New parameters for MobilePay: sph-mobilepay-phone-number, sph-mobilepay-shop-name
2016-11-21
- Shop logo url for MobilePay
2016-10-17
- Diners and Amex card bin lengths are set to 2 first digits. This applies to all previous ApiVersion versions.
2016-09-23
- MobilePay form functions just as the regular Pay with Card form.
2016-06-30
- ApiVersion 20160630
- Allow committing smaller amounts than was authorized and showing committed status and amount in transaction info
- Less than 7 days old transactions can be committed
- Transaction/<:transaction_id>/result - added
- committed and committed_amount added for result, commit, transaction status and order-search responses
- "committed_amount" is omitted if "committed" is false
2016-02-12
- Added optional sph-use-three-d-secure parameter for form entry api, possible values are true or false. When missing default behavior is used for contract, but when when true is used then Three D Secure is turned on and when false is used then it is turned off despite default options for contract.
- Added new fields sph-skip-form-notifications, sph-exit-iframe-on-result, sph-exit-iframe-on-three-d-secure, sph-use-three-d-secure
2015-11-19
- New field "filing_code" to successful commit and debit responses
2015-10-28
- ApiVersion 20151028
- New fields to card object in responses (bin, funding, category, country_code)
- New fields to Transaction Status, Commit, Tokenization Order Search responses if customer details available (Transaction done using form, or customer.network_address given in Payment API debit request)
- New field to Transaction Status, Commit, Tokenization and Order Search responses, which indicates whether ThreeDS (3ds) card holder authentication was done
2015-10-01
New Result Codes
- Added results codes 209 "Authorization timeout", 902 "Transaction not found" and 950 "Token already exists"
2015-09-03
Fraud detection
Changes in the Payment API:
- Added a new parameter
customer.network_address
to the debit request - Added a new response code 250 for a transaction rejected by fraud detection
- Added a new transaction status 7200 when a transaction is automatically reverted due to rejection by fraud detection
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:
- Added a new method GET /transactions
- Added the parameter "order" to Payment API debit request JSON
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:
- Added an optional parameter
sph-accept-cvc-required
to Add Card request to allow adding a card even if it requires the CVC for payments. See below for the related changes in the Payment API.
Changes in the Payment API:
- Renamed the optional version parameter in the header from
Schema-Version
toSph-Api-Version
- Added
card.cvc_required
to the tokenization response with the possible values of "yes" or "no".- Previously you would have received a failure response for a card requiring the CVC for payments.
- With the new API version you always receive a success response with the
cvc_required
field.
- Added
card.cvc_required
to the commit form payment response with the possible values of "yes" or "no".- Previously you would have not received a
card_token
for a card requiring the CVC for payments. - With the new API version you always receive a
card_token
in a success response. You must check the value of thecvc_required
field to know whether the card requires the CVC for payments.
- Previously you would have not received a
- Added
transaction.card.cvc_required
to the transaction status response with the possible values of "yes", "no" or "not_tested".- For transactions created using the old API version the
cvc_required
field may contain the value "not_tested".
- For transactions created using the old API version the