Get Started

Fundamental Principles

Read on to learn about the fundamentals and common architectural principles of the Swedbank Pay API Platform.

Edit "Fundamental Principles" on GitHub

Foundation

The Swedbank Pay API Platform is built using the REST architectural style and the request and responses come in the JSON format. The API has predictable, resource-oriented URLs and use default HTTP features, like HTTP authentication (using OAuth 2), HTTP methods and headers. These techniques are widely used and understood by most HTTP client libraries.

Connection and Protocol

All requests towards Swedbank Pay API Platform are made with HTTP/1.1 over a secure TLS 1.2 (or higher) connection. Older HTTP clients running on older operating systems and frameworks might receive connection errors when connecting to Swedbank Pay’s APIs. This is most likely due to the connection being made from the client with TLS 1.0 or even SSL, which are all insecure and deprecated. If such is the case, ensure that you are able to connect over a TLS 1.2 connection by reading information regarding your programming languages and environments (Java, PHP Curl, PHP Zend, Ruby, Python, Node.js Request).

You can inspect Swedbank Pay’s TLS and cipher suite support at SSL Labs. Support for HTTP/2 in our APIs is being investigated.

Postel’s Robustness Principle

We encourage you to keep Postel’s robustness principle in mind. Build your integration in a way that is resilient to change, wherever it may come. Don’t confine yourself to the limits of our current documentation examples. A string looking like a guid must still be handled and stored like a string, not as a guid, as it could be a URL in the future. The day our transactionNumber ticks past 1,000,000, make sure your integration can handle number 1,000,001. If some fields, operations or headers can’t be understood, you must be able to ignore them. We have built our requests in a way which allows the payeeInfo field to be placed before metadata, or vice versa if you want. We don’t expect a specific order of elements, so we ask that you shouldn’t either.

Headers

All requests against the API Platform should have a few common headers:

HTTP Request

1
2
3
4
5
6
7
POST /some/resource HTTP/1.1
Content-Type: application/json;version=3.1/3.0/2.0  charset=utf-8  // Version optional except for 3.1
Authorization: "Bearer 123456781234123412341234567890AB"
User-Agent: swedbankpay-sdk-dotnet/3.0.1
Accept: application/problem+json; q=1.0, application/json; q=0.9
Session-Id: 779da454399742248f2942bb064c4707
Forwarded: for=82.115.151.177; host=example.com; proto=https
Required Header Description
check Content-Type The content type of the body of the HTTP request. Usually set to application/json.
check Authorization The OAuth 2 Access Token is generated in the Merchant Portal.
  User-Agent The user agent of the HTTP client making the HTTP request. Should be set to identify the system performing requests towards Swedbank Pay. The value submitted here will be returned in the response field initiatingSystemUserAgent.
check Accept The content type accepted by the client. Usually set to application/json and application/problem+json so both regular responses as well as errors can be received properly.
  Session-Id A trace identifier used to trace calls through the API Platform (ref RFC 7329). Each request must mint a new GUID/UUID. If no Session-Id is provided, Swedbank Pay will generate one for the request.
  Forwarded The IP address of the payer as well as the host and protocol of the payer-facing web page. When the header is present, only the for parameter containing the payer’s IP address is required, the other parameters are optional. See RFC 7239 for details.

URL Usage

The base URLs of the API Platform are:

Environment Base URL
Test https://api.externalintegration.payex.com/
Production https://api.payex.com/

An important part of REST is its use of hypermedia. Instead of having to perform complex state management and hard coding URLs and the availability of different operations in the client, this task is moved to the server. The client simply follows links and performs operations provided by the API, given the current state of the resource. The server controls the state and lets the client know through hypermedia what’s possible in the current state of the resource. To get an introduction to hypermedia, please watch this 20 minute video.

warning

Don’t build URLs: It is very important that only the base URLs of Swedbank Pay’s APIs are stored in your system. All other URLs are returned dynamically in the response. Swedbank Pay cannot guarantee that your implementation will remain working if you store any other URLs in your system. When performing requests, please make sure to use the complete URLs that are returned in the response. Do not attempt to parse or build upon the returned data – you should not put any special significance to the information you might glean from an URL. URLs should be treated as opaque identifiers you can use to retrieve the identified resource – nothing more, nothing less. If you don’t follow this advice, your integration most assuredly will break when Swedbank Pay makes updates in the future.

Storing URLs

link

Storing URLs: In general, URLs should be discovered in responses to previous requests, not stored.

However, URLs that are used to create new resources can be stored or hard coded. Also, the URL of the generated resource can be stored on your end to GET it at a later point. Note that the URLs should be stored as opaque identifiers and should not be parsed or interpreted in any way.

warning

Operation URLs: URLs that are returned as part of the operations in each response should not be stored.

See the abbreviated example below where psp/creditcard/payments from the POST header is an example of the URL that can be stored, as it is used to create a new resource. Also, the /psp/creditcard/payments/7e6cdfc3-1276-44e9-9992-7cf4419750e1 URL can be stored in order to retrieve the created payment with an HTTP GET request later.

The URLs found within operations such as the href of update-payment-abort, https://api.externalintegration.payex.com/psp/creditcard/payments/7e6cdfc3-1276-44e9-9992-7cf4419750e1 should not be stored.

In order to find which operations you can perform on a resource and the URL of the operation to perform, you need to retrieve the resource with an HTTP GET request first and then find the operation in question within the operations field.

Request

1
2
3
POST /psp/creditcard/payments HTTP/1.1
Authorization: Bearer <AccessToken>
Content-Type: application/json;version=3.1/3.0/2.0  // Version optional except for 3.1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
    "payment": {
        "operation": "Purchase",
        "intent": "Authorization",
        "currency": "SEK",
        "prices": [{
                "type": "CreditCard",
                "amount": 1500,
                "vatAmount": 0
            }
        ],
        "description": "Test Purchase",
        "generatePaymentToken": false,
        "generateRecurrenceToken": false,
        "userAgent": "Mozilla/5.0...",
        "language": "nb-NO",
     }
 }

Response

1
2
3
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8; version=3.1/3.0/2.0
api-supported-versions: 3.1/3.0/2.0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
{
    "payment": {
        "id": "/psp/creditcard/payments/7e6cdfc3-1276-44e9-9992-7cf4419750e1",
        "number": 1234567890,
        "instrument": "CreditCard",
        "created": "2016-09-14T13:21:29.3182115Z",
        "updated": "2016-09-14T13:21:57.6627579Z",
        "state": "Ready",
        "operation": "Purchase",
        "intent": "Authorization",
        },
    "operations": [
        {
            "rel": "update-payment-abort",
            "href": "https://api.externalintegration.payex.com/psp/creditcard/payments/7e6cdfc3-1276-44e9-9992-7cf4419750e1",
            "method": "PATCH",
            "contentType": "application/json"
        },
        {
            "rel": "redirect-authorization",
            "href": "https://ecom.externalintegration.payex.com/creditcard/payments/authorize/5a17c24e-d459-4567-bbad-aa0f17a76119",
            "method": "GET",
            "contentType": "text/html"
        },
        {
            "rel": "view-authorization",
            "href": "https://ecom.externalintegration.payex.com/creditcard/core/scripts/client/px.creditcard.client.js?token=5a17c24e-d459-4567-bbad-aa0f17a76119",
            "method": "GET",
            "contentType": "application/javascript"
        }
    ]
}

Uniform Responses

When a POST or PATCH request is performed, the whole target resource representation is returned in the response, as when performing a GET request on the resource URL. This is an economic approach that limits the number of necessary GET requests.

Expansion

The payment resource contain the ID of related sub-resources in its response properties. These sub-resources can be expanded inline by using the request parameter expand. The Paid resource would for example be expanded by adding ?$expand=paid after the paymentOrderId. This is an effective way to limit the number of necessary calls to the API, as you return several properties related to a Payment resource in a single request.

Note that the expand parameter is available to all API requests but only applies to the request response. This means that you can use the expand parameter on a POST or PATCH request to get a response containing the target resource including expanded properties.

This example below add the urls and authorizations field inlines to the response, enabling you to access information from these sub-resources.

HTTP Request with expansion

1
2
GET /psp/creditcard/payments/7e6cdfc3-1276-44e9-9992-7cf4419750e1?$expand=urls,authorizations HTTP/1.1
Host: api.externalintegration.payex.com
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
    "payment": {
        "operation": "Purchase",
        "intent": "Authorization",
        "currency": "SEK",
        "prices": [{
                "type": "CreditCard",
                "amount": 1500,
                "vatAmount": 0
            }
        ],
        "description": "Test Purchase",
        "generatePaymentToken": false,
        "generateRecurrenceToken": false,
        "userAgent": "Mozilla/5.0...",
        "language": "nb-NO",
     }
 }

To avoid unnecessary overhead, you should only expand the fields you need info about.

Data Types

Some datatypes, like currency, dates and amounts, are managed in a coherent manner across the entire API Platform.

Currency

All currencies are expressed according to the ISO 4217 standard, e.g SEK, EUR, NOK.

Dates

All dates are expressed according to the ISO 8601 standard that combine dates, time and timezone data into a string, e.g. 2018-09-14T13:21:57.6627579Z.

Locale

When defining locale, we use the combination of language and country codes. Our payment menu UI is currently limited to nb-NO, sv-SE, da-DK fi-FI and en-US.

Monetary Amounts

All monetary amounts are entered in the lowest momentary units of the selected currency. The amount of SEK and NOK are in ören/ører, and EUR is in cents. Another way to put it is that the code amount is expressed as if the true amount is multiplied by 100.

True amount Code amount
NOK 100.00 10000
SEK 50.00 5000
€ 10.00 1000