While the callback feature is mandatory, we would like to emphasize that it is mainly a fail-safe feature. We strongly advice that it is not your primary mean of checking for payment updates.
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.
Why Is The Callback Important?
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.
Good To Know About Callbacks
- When a change or update from the back-end system is 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. - For unscheduled and recur transactions, no callback will be given for card transactions, only Trustly.
- As it isn’t scaled to be a primary source of updates, no given response time
can be guaranteed, and a callback might fail. It will be retried if that
should happen. Below are the retry timings, in seconds from the initial
transaction time:
- 30 seconds
- 60 seconds
- 360 seconds
- 432 seconds
- 864 seconds
- 1265 seconds
- A callback should return a
200 OK
response.
The callback is sent from either 51.107.183.58
or 91.132.170.1
in both the
test and production environment.
To understand the nature of the callback, the type of transaction, its status,
etc., you need to perform a GET
request on the received URL and inspect the
response. The transaction type or any other information can not and should not
be inferred from the URL. See URL usage for more information.
For paymentOrder
implementations (Digital Payments, Checkout v2 and Payment
Menu v1), it is critical that you do not use the paymentId
or
transactionId
when performing a GET
to retrieve the payment’s status. Use
the paymentOrderId
.
Callback Example
Payment Order Callback
1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"paymentOrder": {
"id": "/psp/paymentorders/7e6cdfc3-1276-44e9-9992-7cf4419750e1",
"instrument": "paymentorders"
},
"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
}
}
Callback Example v3.1
If you have implemented v3.1, the callback will only contain the paymentOrder
node.
This response format will only be triggered if you used version=3.1
in the
original POST
when you created the paymentOrder
.
Payment Order Callback v3.1
1
2
3
4
5
6
7
8
{
"orderReference": "549213",
"paymentOrder": {
"id": "/psp/paymentorders/7e6cdfc3-1276-44e9-9992-7cf4419750e1",
"instrument": "paymentorders"
"number": 12345678
}
}
Field | Type | Description |
---|---|---|
orderReference |
string |
The order reference found in the merchant’s systems. If included in the request, the orderReference will appear in the callback. |
paymentOrder |
object |
The payment order object. |
id |
string |
The relative URL and unique identifier of the paymentorder resource . Please read about URL Usage to understand how this and other URLs should be used in your solution. |
instrument |
string |
The payment method used in the payment. |
number |
string |
The attempt number which triggered the callback. |
GET Response
When performing an HTTP GET
request towards the URL found in the
transaction.id
field of the callback, the response is going to include the
abbreviated example provided below.
The created authorization
resource contains information about the
authorization
transaction made against a paymentorders
payment.
Capture Response
Response
1
2
3
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8; version=3.x/2.0
api-supported-versions: 3.x/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
33
34
35
36
{
"paymentorder": "/psp/paymentorders/7e6cdfc3-1276-44e9-9992-7cf4419750e1",
"authorization": {
"id": "/psp/paymentorders/7e6cdfc3-1276-44e9-9992-7cf4419750e1/currentpayment/ec2a9b09-601a-42ae-8e33-a5737e1cf177",
"itemDescriptions": {
"id": "/psp/paymentorders/7e6cdfc3-1276-44e9-9992-7cf4419750e1/currentpayment/ec2a9b09-601a-42ae-8e33-a5737e1cf177/itemDescriptions"
},
"transaction": {
"id": "/psp/paymentorders/7e6cdfc3-1276-44e9-9992-7cf4419750e1/currentpayment/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": "ABC123",
"isOperational": false,
"problem": {
"type": "https://api.payex.com/psp/errordetail/paymentorders/3DSECUREERROR",
"title": "Error when complete authorization",
"status": 400,
"detail": "Unable to complete 3DSecure verification!",
"problems": [
]
"operations": [
{
"href": "/psp/paymentorders/7e6cdfc3-1276-44e9-9992-7cf4419750e1/currentpayment/ec2a9b09-601a-42ae-8e33-a5737e1cf177",
"rel": "edit-authorization",
"method": "PATCH"
}
]
}
}
}
Field | Type | Description | |
---|---|---|---|
paymentOrder |
string |
The relative URL and unique identifier of the payment resource . Please read about URL Usage to understand how this and other URLs should be used in your solution. |
|
id |
string |
The relative URL and unique identifier of the authorization resource . Please read about URL Usage to understand how this and other URLs should be used in your solution. |
|
itemDescriptions |
object |
The object representation of the itemDescriptions resource. |
|
id |
string |
The relative URL and unique identifier of the itemDescriptions resource . Please read about URL Usage to understand how this and other URLs should be used in your solution. |
|
transaction |
object |
The object representation of the generic transaction resource, containing information about the current transaction. |
|
id |
string |
The relative URL and unique identifier of the transaction resource . Please read about URL Usage to understand how this and other URLs 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 or failed . If a partial authorization has been done and further transactions are possible, the state will be awaitingActivity . |
|
number |
integer |
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. The amount displayed is the final amount the payer paid for their order, including any payment method specific discounts or fees. |
|
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. Set per operation to ensure an exactly-once delivery of a transactional operation. Length and content validation depends on whether the transaction.number or the payeeReference is sent to the acquirer. If Swedbank Pay handles the settlement, the transaction.number is sent and the payeeReference must be in the format of A-Za-z0-9 and string(30) . If you handle the settlement, Swedbank Pay will send the payeeReference and it will be limited to the format of string(12) . All characters must be digits. In Invoice Payments payeeReference is used as an invoice/receipt number, if the receiptReference is not defined. |
|
receiptReference |
string |
A unique reference to the transaction, provided by the merchant. Can be used as an invoice or receipt number as a supplement to payeeReference . |
|
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. |
Sequence Diagram
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 paymentorders payment
deactivate Merchant
note left of Merchant: First API request
SwedbankPay-->>+Merchant: payment resource
deactivate SwedbankPay