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 URIs 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 a 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.
Headers
All requests against the API Platform should have a few common headers:
HTTP request
1
2
3
4
5
6
POST /some/resource HTTP/1.1
Content-Type: application/json; charset=utf-8
Accept: application/problem+json; q=1.0, application/json; q=0.9
Authorization: "Bearer 123456781234123412341234567890AB"
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︎ | 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. |
check︎ | Authorization |
The OAuth 2 Access Token is generated in Swedbank Pay Admin. |
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. |
URI Usage
The base URIs 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 URIs 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.
Don’t build URIs
It is very important that only the base URIs of Swedbank Pay’s APIs are stored in your system. All other URIs are returned dynamically in the response. Swedbank Pay cannot guarantee that your implementation will remain working if you store any other URIs in your system. When performing requests, please make sure to use the complete URIs 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 URI. URIs 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 URIs
Storing URIs
In general, URIs should be discovered in responses to previous requets, not stored.
However, URIs that are used to create new resources can be stored or hard coded.
Also, the URI of the generated resource can be stored on your end to GET
it at a
later point. Note that the URIs should be stored as opaque identifiers and
should not be parsed or interpreted in any way.
Operation URIs
URIs 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 URI that can be stored, as it is used to
create a new resource. Also, the /psp/creditcard/payments/7e6cdfc3-1276-44e9-9992-7cf4419750e1
URI can be stored in order to retrieve the created payment with an HTTP GET
request later.
The URIs 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 URI 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
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
POST /psp/creditcard/payments HTTP/1.1
Authorization: Bearer <AccessToken>
Content-Type: application/json
{
"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
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
33
34
35
HTTP/1.1 200 OK
Content-Type: application/json
{
"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 URI. 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
. 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
To avoid unnecessary overhead, you should only expand the nodes 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, e.g. nb-NO
, sv-SE
, 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 |
Operations
When a resource is created and during its lifetime, it will have a set of operations that can be performed on it. Which operations that are available in a given state varies depending on payment instrument used, what the access token is authorized to do, etc. A subset of possible operations are described below. Visit the technical reference page of a payment instrument for instrument specific operations.
JSON with Operations
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
{
"payment": {},
"operations": [
{
"href": "http://api.externalintegration.payex.com/psp/creditcard/payments/7e6cdfc3-1276-44e9-9992-7cf4419750e1",
"rel": "update-payment-abort",
"method": "PATCH"
},
{
"href": "https://ecom.externalintegration.payex.com/creditcard/payments/authorize/5a17c24e-d459-4567-bbad-aa0f17a76119",
"rel": "redirect-authorization",
"method": "GET"
},
{
"href": "https://ecom.externalintegration.payex.com/swish/core/scripts/client/px.swish.client.js?token=5a17c24e-d459-4567-bbad-aa0f17a76119",
"rel": "view-payment",
"method": "GET",
"contentType": "application/javascript"
},
{
"href": "https://api.externalintegration.payex.com/psp/creditcard/payments/7e6cdfc3-1276-44e9-9992-7cf4419750e1/captures",
"rel": "create-capture",
"method": "POST"
}
]
}
Field | Description |
---|---|
href |
The target URI to perform the operation against. |
rel |
The name of the relation the operation has to the current resource. |
method |
The HTTP method to use when performing the operation. |
The operations should be performed as described in each response and not as
described here in the documentation. Always use the href
and method
as
specified in the response by finding the appropriate operation based on its
rel
value.
Payee Reference
The payeeReference
given when creating transactions and payments has some
specific processing rules depending on specifications in the contract.
- It must be unique for every operation, used to ensure exactly-once delivery of a transactional operation from the merchant system.
- Its length and content validation is dependent on whether the
transaction.number
or thepayeeReference
is sent to the acquirer.- If you select Option A in the settlement process (Swedbank Pay will
handle the settlement), Swedbank Pay will send the
transaction.number
to the acquirer and thepayeeReference
must be in the format of charactersA-Za-z0-9
(including-
) andstring(30)
. - If you select Option B in the settlement process (you will handle the
settlement yourself), Swedbank Pay will send the
payeeReference
to the acquirer and it will be limited to the format ofstring(12)
and all characters must be digits.
- If you select Option A in the settlement process (Swedbank Pay will
handle the settlement), Swedbank Pay will send the
Read more about the settlement process here.
Callback
When a change or update from the back-end system are made on a payment or transaction, Swedbank Pay will perform a callback to inform the payee (merchant) about this update.
Providing a callbackUrl
in POST
requests is mandatory. Below we provide
three example scenarios of why this is important:
- If the payer closes the payment window, the merchant will never know what
happened to the payment if
callbackUrl
is not implemented. - If the payer stops up in a payment app such as Vipps or Swish, the payer
will never come back to the merchant. This means that the merchant won’t
know what happened to the payment unless
callbackUrl
is implemented. - If a payer experiences a network error or something else happens that
prevents the payer from being redirected from Swedbank Pay back to the
merchant website, the
callbackUrl
is what ensures that you receive the information about what happened with the payment.
- When a change or update from the back-end system are made on a payment or transaction, Swedbank Pay will perform an asynchronous server-to-server callback to inform the payee (merchant) about this update.
- It is important to know that the callback is asynchronous, and not real-time. As we can’t guarantee when you get the callback, there could be a delay between when the payer is returned back to the merchant and when the callback arrives. If the merchant chooses to wait for the callback, the payer might be left at the merchant’s page until the response comes.
- Swedbank Pay will make an HTTP
POST
to thecallbackUrl
that was specified when the payee (merchant) created the payment. - When the
callbackUrl
receives such a callback, an HTTPGET
request must be made on the payment or on the transaction. The retrieved payment or transaction resource will give you the necessary information about the recent change/update. - The callback will be retried if it fails. Below are the retry timings, in
seconds from the initial transaction time:
- 30 seconds
- 60 seconds
- 360 seconds
- 432 seconds
- 864 seconds
- 1265 seconds
- The callback is sent from the following IP address:
82.115.146.1
- A callback should return a
200 OK
response.
To understand the nature of the callback, the type of transaction, its status, etc.,
you need to perform a GET
request on the received URI and inspect the response.
The transaction type or any other information can not and should not be inferred
from the URI. See URI usage for more information.
Payment Instrument Callback
1
2
3
4
5
6
7
8
9
10
{
"payment": {
"id": "/psp/creditcard/payments/7e6cdfc3-1276-44e9-9992-7cf4419750e1",
"number": 222222222
},
"transaction": {
"id": "/psp/creditcard/payments/7e6cdfc3-1276-44e9-9992-7cf4419750e1/authorizations/ec2a9b09-601a-42ae-8e33-a5737e1cf177",
"number": 333333333
}
}
When performing an HTTP GET
request towards the URI found in the
transaction.id
field of the callback, the response is going to look
something like the abbreviated example provided below.
The created authorization
resource contains information about the
authorization
transaction made against a creditcard
payment.
Response
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
HTTP/1.1 200 OK
Content-Type: application/json
{
"payment": "/psp/creditcard/payments/7e6cdfc3-1276-44e9-9992-7cf4419750e1",
"authorization": {
"id": "/psp/creditcard/payments/7e6cdfc3-1276-44e9-9992-7cf4419750e1/authorizations/ec2a9b09-601a-42ae-8e33-a5737e1cf177",
"paymentToken": "5a17c24e-d459-4567-bbad-aa0f17a76119",
"maskedPan": "123456xxxxxx1234",
"expireDate": "mm/yyyy",
"panToken": "ec2a9b09-601a-42ae-8e33-a5737e1cf177",
"cardBrand": "Visa",
"cardType": "Credit Card",
"issuingBank": "UTL MAESTRO",
"countryCode": "999",
"acquirerTransactionType": "3DSECURE",
"acquirerStan": "39736",
"acquirerTerminalId": "39",
"acquirerTransactionTime": "2017-08-29T13:42:18Z",
"authenticationStatus": "Y",
"itemDescriptions": {
"id": "/psp/creditcard/payments/7e6cdfc3-1276-44e9-9992-7cf4419750e1/transactions/ec2a9b09-601a-42ae-8e33-a5737e1cf177/itemDescriptions"
},
"transaction": {
"id": "/psp/creditcard/payments/7e6cdfc3-1276-44e9-9992-7cf4419750e1/transactions/ec2a9b09-601a-42ae-8e33-a5737e1cf177",
"created": "2016-09-14T01:01:01.01Z",
"updated": "2016-09-14T01:01:01.03Z",
"type": "Authorization",
"state": "Completed",
"number": 1234567890,
"amount": 1000,
"vatAmount": 250,
"description": "Test transaction",
"payeeReference": "AH123456",
"isOperational": false,
"problem": {
"type": "https://api.payex.com/psp/errordetail/creditcard/3DSECUREERROR",
"title": "Error when complete authorization",
"status": 400,
"detail": "Unable to complete 3DSecure verification!",
"problems": [
]
"operations": [
{
"href": "/psp/creditcard/payments/7e6cdfc3-1276-44e9-9992-7cf4419750e1/transactions/ec2a9b09-601a-42ae-8e33-a5737e1cf177",
"rel": "edit-authorization",
"method": "PATCH"
}
]
}
}
}
Field | Type | Description | |
---|---|---|---|
payment |
string |
The relative URI and unique identifier of the payment resource this authorization belongs to.. Please read about URI Usage to understand how this and other URIs should be used in your solution. |
|
authorization |
string |
The current authorization transaction resource. |
|
└➔ id
|
string |
The relative URI and unique identifier of the authorization resource this authorization belongs to.. Please read about URI Usage to understand how this and other URIs should be used in your solution. |
|
└➔ paymentToken
|
string |
The payment token created for the card used in the authorization. | |
└➔ maskedPan
|
string |
The masked PAN number of the card. | |
└➔ expireDate
|
string |
The month and year of when the card expires. | |
└➔ panToken
|
string |
The token representing the specific PAN of the card. | |
└➔ cardBrand
|
string |
Visa , MC , etc. The brand of the card. |
|
└➔ cardType
|
string |
Credit Card or Debit Card . Indicates the type of card used for the authorization. |
|
└➔ issuingBank
|
string |
The name of the bank that issued the card used for the authorization. | |
└➔ countryCode
|
string |
The country the card is issued in. | |
└➔ acquirerTransactionType
|
string |
3DSECURE or SSL . Indicates the transaction type of the acquirer. |
|
└➔ acquirerStan
|
string |
The System Trace Audit Number assigned by the acquirer to uniquely identify the transaction. | |
└➔ acquirerTerminalId
|
string |
The ID of the acquirer terminal. | |
└➔ acquirerTransactionTime
|
string |
The ISO-8601 date and time of the acquirer transaction. | |
└➔ authenticationStatus
|
string |
Y , A , U or N . Indicates the status of the authentication. |
|
└➔ itemDescriptions
|
object |
The object representation of the itemDescriptions resource. |
|
└─➔ id
|
string |
The relative URI and unique identifier of the itemDescriptions resource this authorization belongs to.. Please read about URI Usage to understand how this and other URIs should be used in your solution. |
|
└➔ transaction
|
object |
The object representation of the generic transaction resource. | |
└─➔ id
|
string |
The relative URI and unique identifier of the transaction resource this authorization belongs to.. Please read about URI Usage to understand how this and other URIs should be used in your solution. |
|
└─➔ created
|
string |
The ISO-8601 date and time of when the transaction was created. | |
└─➔ updated
|
string |
The ISO-8601 date and time of when the transaction was updated. | |
└─➔ type
|
string |
Indicates the transaction type. | |
└─➔ state
|
string |
Indicates the state of the transaction, usually initialized , completed orfailed . If a partial authorization has been done and further transactionsare possible, the state will be awaitingActivity . |
|
└─➔ number
|
string |
The transaction number , useful when there’s need to reference the transaction in human communication. Not usable for programmatic identification of the transaction, where id should be used instead. |
|
└─➔ amount
|
integer |
The transaction amount (including VAT, if any) entered in the lowest monetary unit of the selected currency. E.g.: 10000 = 100.00 SEK, 5000 = 50.00 SEK. |
|
└─➔ vatAmount
|
integer |
The payment’s VAT (Value Added Tax) amount , entered in the lowest monetary unit of the selected currency. E.g.: 10000 = 100.00 SEK, 5000 = 50.00 SEK. The vatAmount entered will not affect the amount shown on the payment page, which only shows the total amount . This field is used to specify how much of the total amount the VAT will be. Set to 0 (zero) if there is no VAT amount charged. |
|
└─➔ description
|
string |
A 40 character length textual description of the purchase. | |
└─➔ payeeReference
|
string |
A unique reference from the merchant system. It is set per operation to ensure an exactly-once delivery of a transactional operation. See payeeReference for details. In Invoice Payments payeeReference is used as an invoice/receipt number, if the receiptReference is not defined. |
|
└─➔ receiptReference
|
string |
A unique reference for the transaction. This reference is used as an invoice/receipt number. | |
└─➔ failedReason
|
string |
The human readable explanation of why the payment failed. | |
└─➔ isOperational
|
bool |
true if the transaction is operational; otherwise false . |
|
└─➔ operations
|
array |
The array of operations that are possible to perform on the transaction in its current state. |
The sequence diagram below shows the HTTP POST
you will receive from Swedbank
Pay, and the two GET
requests that you make to get the updated status.
sequenceDiagram
Participant Merchant
Participant SwedbankPay as Swedbank Pay
activate SwedbankPay
SwedbankPay->>+Merchant: POST <callbackUrl>
deactivate SwedbankPay
note left of Merchant: Callback by Swedbank Pay
Merchant-->>+SwedbankPay: HTTP response
Merchant->>+SwedbankPay: GET creditcard payment
deactivate Merchant
note left of Merchant: First API request
SwedbankPay-->>+Merchant: payment resource
deactivate SwedbankPay
Problems
When performing operations against a resource in the Swedbank Pay API Platform, it will respond with a problem message that contain details of the error type if the request could not be successfully performed. Regardless of why the error occurred, the problem message will follow the same structure as specified in the Problem Details for HTTP APIs (RFC 7807) specification.
We generally use the problem message type
and status
code to identify the
nature of the problem. The problems
array contains objects with name
and
description
that will often help narrow down the specifics of the problem,
usually to the field in the request that was missing or contained invalid data.
The structure of a problem message will look like this:
Problem Example
1
2
3
4
5
6
7
8
9
10
11
12
{
"type": "https://api.payex.com/psp/errordetail/<resource>/inputerror",
"title": "There was an input error",
"detail": "Please correct the errors and retry the request",
"instance": "ec2a9b09-601a-42ae-8e33-a5737e1cf177",
"status": 400,
"action": "RetryNewData",
"problems": [{
"name": "CreditCardParameters.Issuer",
"description": "minimum one issuer must be enabled"
}]
}
Field | Type | Description |
---|---|---|
type |
string |
The URI that identifies the error type. This is the only field usable for programmatic identification of the type of error! When dereferenced, it might lead you to a human readable description of the error and how it can be recovered from. |
title |
string |
The title contains a human readable description of the error. |
detail |
string |
A detailed, human readable description of the error and how you can recover from it. |
instance |
string |
The identifier of the error instance. This might be of use to Swedbank Pay support personnel in order to find the exact error and the context it occurred in. |
status |
integer |
The HTTP status code that the problem was served with. |
action |
string |
The action indicates how the error can be recovered from. |
problems |
array |
The array of problem detail objects. |
└➔ name
|
string |
The name of the field, header, object, entity or likewise that was erroneous. |
└➔ description
|
string |
The human readable description of what was wrong with the field, header, object, entity or likewise identified by name . |
Common Problems
All common problem types will have a URI in the format
https://api.payex.com/psp/errordetail/<error-type>
. The URI is an
identifier that you can hard-code and implement logic around. It is currently
not not possible to dereference this URI, although that might be possible in the
future.
Type | Status | Description |
---|---|---|
inputerror |
400 |
The server cannot or will not process the request due to an apparent client error (e.g. malformed request syntax, size to large, invalid request). |
forbidden |
403 |
The request was valid, but the server is refusing the action. The necessary permissions to access the resource might be lacking. |
notfound |
404 |
The requested resource could not be found, but may be available in the future. Subsequent requests are permissible. |
systemerror |
500 |
A generic error message. |
configurationerror |
500 |
A error relating to configuration issues. |
Payment Instrument Specific Problems
Problem types for a specific payment instrument will have a URI in the format
https://api.payex.com/psp/errordetail/<payment-instrument>/<error-type>
. You
can read more about the payment instrument specific problem messages below: