In order to initialize the Payment Menu, you need to create a Payment Order.
The paymentorders
resource and how you interact with it is described below.
{% include payment-order-get.md show_status_operations=true %}
To create a payment order, you perform a POST
request towards the
paymentorders
resource:
{% include payment-order-purchase.md %}
{% include description.md %}
The response given when creating a payment order is equivalent to a GET
request towards the paymentorders
resource, as displayed above.
When creating a Payment Order, the urls
field of the paymentOrder
contains the related URIs, including where the consumer gets redirected when
going forward with or cancelling a payment session, as well as the callback URI
that is used to inform the payee (merchant) of changes or updates made to
underlying payments or transaction.
{:.table .table-striped}
Required | Field | Type | Description |
---|---|---|---|
{% icon check %} ︎︎︎︎︎ | hostUrls |
array |
The array of URIs valid for embedding of Swedbank Pay Hosted Views. |
{% icon check %} | completeUrl |
string |
The URL that Swedbank Pay will redirect back to when the payer has completed his or her interactions with the payment. This does not indicate a successful payment, only that it has reached a final (complete) state. A GET request needs to be performed on the payment order to inspect it further. |
{% icon check %} | termsOfServiceUrl |
string |
{% include field-description-termsofserviceurl.md %} |
cancelUrl |
string |
The URI to redirect the payer to if the payment is canceled, either by the payer or by the merchant trough an abort request of the payment or paymentorder . |
|
paymentUrl |
string |
The URI that Swedbank Pay will redirect back to when the payment menu needs to be loaded, to inspect and act on the current status of the payment. | |
callbackUrl |
string |
The URI to the API endpoint receiving POST requests on transaction activity related to the payment order. |
|
logoUrl |
string |
The URI to the logo that will be displayed on redirect pages. HTTPS is a requirement. |
{% include payment-url.md api_resource="paymentorders" documentation_section="payment-menu" when="selecting the payment instrument Vipps or in the 3-D Secure verification for Credit Card Payments" full_reference=true %}
It is possible to perform a GET
request on the urls
resource to retrieve its
contents.
{:.code-header} Request
GET /psp/paymentorders/{{ page.payment_order_id }}/urls/ HTTP/1.1
Host: {{ page.api_host }}
Authorization: Bearer <AccessToken>
Content-Type: application/json
{:.code-header} Response
HTTP/1.1 200 OK
Content-Type: application/json
{
"paymentorder": "/psp/payments/{{ page.payment_order_id }}",
"urls": {
"id": "/psp/payments/{{ page.payment_order_id }}/urls",
"hostUrls": [ "https://example.com", "https://example.net" ],
"completeUrl": "https://example.com/payment-complete",
"cancelUrl": "https://example.com/payment-canceled",
"paymentUrl": "https://example.com/perform-payment",
"callbackUrl": "http://api.example.com/payment-callback",
"logoUrl": "http://merchant.com/path/to/logo.png",
"termsOfServiceUrl": "http://merchant.com/path/to/tems"
}
}
{:.table .table-striped}
Field | Type | Description |
---|---|---|
paymentorder |
string |
{% include field-description-id.md sub_resource="urls" %} |
urls |
object |
The URLs object. |
└➔ id |
string |
{% include field-description-id.md resource="urls" %} |
└➔ hostsUrl |
string |
An array of the whitelisted URIs that are allowed as parents to a Hosted View, typically the URI of the web shop or similar that will embed a Hosted View within it. |
└➔ completeUrl |
string |
The URL that Swedbank Pay will redirect back to when the payer has completed his or her interactions with the payment. This does not indicate a successful payment, only that it has reached a final (complete) state. A GET request needs to be performed on the payment order to inspect it further. |
└➔ cancelUrl |
string |
The URI to redirect the payer to if the payment is canceled, either by the payer or by the merchant trough an abort request of the payment or paymentorder . |
└➔ paymentUrl |
string |
The URI that Swedbank Pay will redirect back to when the payment menu needs to be loaded, to inspect and act on the current status of the payment. |
└➔ callbackUrl |
string |
The URI that Swedbank Pay will perform an HTTP POST against every time a transaction is created on the payment. See callback for details. |
└➔ logoUrl |
string |
The URI that will be used for showing the customer logo. Must be a picture with at most 50px height and 400px width. |
└➔ termsOfServiceUrl |
string |
{% include field-description-termsofserviceurl.md %} |
The orderItems
field of the paymentOrder
is an array containing the items being purchased with the order. Used to print on invoices if the payer chooses to pay with invoice, among other things. orderItems
is required in all requests. It should be specified on both payment order creation as well as on Capture.
{:.table .table-striped}
Required | Field | Type | Description |
---|---|---|---|
{% icon check %} | reference |
string |
A reference that identifies the order item. |
{% icon check %} | name |
string |
The name of the order item. |
{% icon check %} | type |
enum |
PRODUCT , SERVICE , SHIPPING_FEE , DISCOUNT , VALUE_CODE , or OTHER . The type of the order item. |
{% icon check %} | class |
string |
The classification of the order item. Can be used for assigning the order item to a specific product category, such as MobilePhone . Note that class cannot contain spaces and must follow the regex pattern [\w]* (a-zA-Z0-9_) . Swedbank Pay may use this field for statistics. |
itemUrl |
string |
The URL to a page that can display the purchased item, such as a product page | |
imageUrl |
string |
The URL to an image of the order item. | |
description |
string |
The human readable description of the order item. | |
discountDescription |
string |
The human readable description of the possible discount. | |
{% icon check %} | quantity |
decimal |
The 4 decimal precision quantity of order items being purchased. |
{% icon check %} | quantityUnit |
string |
The unit of the quantity, such as pcs , grams , or similar. |
{% icon check %} | unitPrice |
integer |
The price per unit of order item, including VAT. |
discountPrice |
integer |
If the order item is purchased at a discounted price. This field should contain that price, including VAT. | |
{% icon check %} | vatPercent |
integer |
The percent value of the VAT multiplied by 100, so 25% becomes 2500 . |
{% icon check %} | amount |
integer |
{% include field-description-amount.md %} |
{% icon check %} | vatAmount |
integer |
{% include field-description-vatamount.md %} |
The items
field of the paymentOrder
is an array containing items that will affect how the payment is performed.
{:.table .table-striped}
Required | Field | Type | Description |
---|---|---|---|
creditCard |
object |
The credit card object. | |
└➔ rejectDebitCards |
bool |
true if debit cards should be declined; otherwise false per default. Default value is set by Swedbank Pay and can be changed at your request. |
|
└➔ rejectDebitCards |
bool |
true if debit cards should be declined; otherwise false per default. Default value is set by Swedbank Pay and can be changed at your request. |
|
└➔ rejectCreditCards |
bool |
true if credit cards should be declined; otherwise false per default. Default value is set by Swedbank Pay and can be changed at your request. |
|
└➔ rejectConsumerCards |
bool |
true if consumer cards should be declined; otherwise false per default. Default value is set by Swedbank Pay and can be changed at your request. |
|
└➔ rejectCorporateCards |
bool |
true if corporate cards should be declined; otherwise false per default. Default value is set by Swedbank Pay and can be changed at your request. |
|
invoice |
object |
The invoice object. | |
└➔ feeAmount |
integer |
The fee amount in the lowest monetary unit to apply if the consumer chooses to pay with invoice. | |
swish |
object |
The swish object. | |
└➔ enableEcomOnly |
bool |
true to only enable Swish on ecommerce transactions. |
The paymentOrders
resource utilize several sub-resources, relating to
underlying payments,
the current payment active,
payers and urls.
Common sub-resources like payeeinfo, that are
structurally identical for both payments and payments orders, are described in
the Payment Resources section.
When a payment order resource is created and during its lifetime, it will have a set of operations that can be performed on it. The state of the payment order resource, what the access token is authorized to do, the chosen payment instrument and its transactional states, etc. determine the available operations before the initial purchase. A list of possible operations and their explanation is given below.
{:.code-header} Operations
{
"paymentOrder": {
"id": "/psp/paymentorders/{{ page.payment_order_id }}",
}
"operations": [
{
"method": "PATCH",
"href": "{{ page.api_url }}/psp/paymentorders/{{ page.payment_order_id }}",
"rel": "update-paymentorder-abort",
"contentType": "application/json"
},
{
"method": "PATCH",
"href": "{{ page.api_url }}/psp/paymentorders/{{ page.payment_order_id }}",
"rel": "update-paymentorder-updateorder",
"contentType": "application/json"
},
{
"method": "GET",
"href": "{{ page.front_end_url }}/paymentmenu/{{ page.payment_token }}",
"rel": "redirect-paymentorder",
"contentType": "text/html"
},
{
"method": "GET",
"href": "{{ page.front_end_url }}/paymentmenu/core/scripts/client/px.paymentmenu.client.js?token={{ page.payment_token }}&culture=nb-NO",
"rel": "view-paymentorder",
"contentType": "application/javascript"
},
{
"method": "POST",
"href": "{{ page.api_url }}/psp/paymentorders/{{ page.payment_order_id }}/captures",
"rel": "create-paymentorder-capture",
"contentType": "application/json"
},
{
"method": "POST",
"href": "{{ page.api_url }}/psp/paymentorders/{{ page.payment_order_id }}/cancellations",
"rel": "create-paymentorder-cancel",
"contentType": "application/json"
},
{
"method": "POST",
"href": "{{ page.api_url }}/psp/paymentorders/{{ page.payment_order_id }}/reversals",
"rel": "create-paymentorder-reversal",
"contentType": "application/json"
},
{
"method": "GET",
"href": "{{ page.api_url }}/psp/paymentorders/{{ page.payment_order_id }}/paid",
"rel": "paid-paymentorder",
"contentType": "application/json"
},
{
"method": "GET",
"href": "{{ page.api_url }}/psp/paymentorders/{{ page.payment_order_id }}/failed",
"rel": "failed-paymentorder",
"contentType": "application/problem+json"
}
]
}
{:.table .table-striped}
Field | Type | Description |
---|---|---|
href |
string |
The target URI to perform the operation against. |
rel |
string |
The name of the relation the operation has to the current resource. |
method |
string |
GET , PATCH , POST , etc. The HTTP method to use when performing the operation. |
contentType |
string |
The HTTP content type of the resource referenced in the href field. |
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. The only thing that should be hard coded in the client is the value
of the rel
and the request that will be sent in the HTTP body of the request
for the given operation.
{:.table .table-striped}
Operation | Description |
---|---|
update-paymentorder-abort |
Aborts the payment order before any financial transactions are performed. |
update-paymentorder-updateorder |
Updates the order with a change in the amount and/or vatAmount . |
redirect-paymentorder |
Contains the URI that is used to redirect the consumer to the Swedbank Pay Payments containing the Payment Menu. |
view-paymentorder |
Contains the JavaScript href that is used to embed the Payment Menu UI directly on the webshop/merchant site. |
create-paymentorder-capture |
The second part of a two-phase transaction where the authorized amount is sent from the payer to the payee. It is possible to do a part-capture on a subset of the authorized amount. Several captures on the same payment are possible, up to the total authorization amount. |
create-paymentorder-cancel |
Used to cancel authorized and not yet captured transactions. If a cancellation is performed after doing a part-capture, it will only affect the not yet captured authorization amount. |
create-paymentorder-reversal |
Used to reverse a payment. It is only possible to reverse a payment that has been captured and not yet reversed. |
paid-paymentorder |
Returns the information about a paymentorder that has the status paid . |
failed-paymentorder |
Returns the information about a paymentorder that has the status failed . |
{% include complete-url.md %}
The view-paymentorder
operation contains the URI of the JavaScript that needs to be set as a script
element's src
attribute, either client-side through JavaScript or server-side in HTML as shown below.
<!DOCTYPE html>
<html>
<head>
<title>Swedbank Pay Checkout is Awesome!</title>
</head>
<body>
<div id="checkout"></div>
<script src="{{ page.front_end_url }}/paymentmenu/core/scripts/client/px.paymentmenu.client.js?token={{ page.payment_token }}&culture=nb-NO"></script>
<script language="javascript">
payex.hostedView.paymentMenu({
container: 'checkout',
culture: 'nb-NO',
onPaymentCompleted: function(paymentCompletedEvent) {
console.log(paymentCompletedEvent);
},
onPaymentFailed: function(paymentFailedEvent) {
console.log(paymentFailedEvent);
},
onPaymentCreated: function(paymentCreatedEvent) {
console.log(paymentCreatedEvent);
},
onPaymentToS: function(paymentToSEvent) {
console.log(paymentToSEvent);
},
onPaymentMenuInstrumentSelected: function(paymentMenuInstrumentSelectedEvent) {
console.log(paymentMenuInstrumentSelectedEvent);
},
onError: function(error) {
console.error(error);
},
}).open();
</script>
</body>
</html>
Change amount and vat amount on a payment order. If you implement UpdateOrder
you need to refresh()
the Payment Menu front end so the
new amount is shown to the end customer.
{:.code-header} Request
PATCH /psp/paymentorders/{{ page.payment_order_id }} HTTP/1.1
Authorization: Bearer <AccessToken>
Content-Type: application/json
{
"paymentorder": {
"operation": "UpdateOrder",
"amount": 1500,
"vatAmount": 375,
"orderItems": [
{
"reference": "P1",
"name": "Product1",
"type": "PRODUCT",
"class": "ProductGroup1",
"itemUrl": "https://example.com/shop/products/1234",
"imageUrl": "https://example.com/products/product1.jpg",
"description": "Product description",
"discountDescription": "Volume discount",
"quantity": 351.3514,
"quantityUnit": "pcs",
"unitPrice": 300,
"discountPrice": 200,
"vatPercent": 2500,
"amount": 1000,
"vatAmount": 250
},
{
"reference": "P2",
"name": "Product2",
"type": "PRODUCT",
"class": "ProductGroup1",
"description": "Product description",
"quantity": 9876.1531,
"quantityUnit": "pcs",
"unitPrice": 500,
"vatPercent": 2500,
"amount": 500,
"vatAmount": 125
}
]
}
}
{:.code-header} Response
HTTP/1.1 200 OK
Content-Type: application/json
{
"paymentorder": {
"id": "/psp/paymentorders/{{ page.payment_order_id }}",
"created": "2018-09-14T13:21:29.3182115Z",
"updated": "2018-09-14T13:21:57.6627579Z",
"operation": "Purchase",
"state": "Ready",
"currency": "SEK",
"amount": 1500,
"vatAmount": 0,
"remainingCaptureAmount": 1500,
"remainingCancellationAmount": 1500,
"remainingReversalAmount": 0,
"description": "Test Purchase",
"initiatingSystemUserAgent": "PostmanRuntime/3.0.1",
"userAgent": "Mozilla/5.0...",
"language": "nb-NO",
"urls" : { "id": "/psp/paymentorders/{{ page.payment_order_id }}/urls" },
"payeeInfo" : { "id": "/psp/paymentorders/{{ page.payment_order_id }}/payeeinfo" },
"settings": { "id": "/psp/paymentorders/{{ page.payment_order_id }}/settings" },
"payers": { "id": "/psp/paymentorders/{{ page.payment_order_id }}/payers" },
"orderItems" : { "id": "/psp/paymentorders/{{ page.payment_order_id }}/orderItems" },
"metadata": { "id": "/psp/paymentorders/{{ page.payment_order_id }}/metadata" },
"payments": { "id": "/psp/paymentorders/{{ page.payment_order_id }}/payments" },
"currentPayment": { "id": "/psp/paymentorders/{{ page.payment_order_id }}/currentpayment" }
},
"operations": [
{
"method": "PATCH",
"href": "{{ page.api_url }}/psp/paymentorders/{{ page.payment_order_id }}",
"rel": "update-paymentorder-abort",
"contentType": "application/json"
},
{
"method": "GET",
"href": "{{ page.front_end_url }}/paymentmenu/{{ page.payment_token }}",
"rel": "redirect-paymentorder",
"contentType": "text/html"
},
{
"method": "GET",
"href": "{{ page.front_end_url }}/paymentmenu/core/scripts/client/px.paymentmenu.client.js?token={{ page.payment_token }}&culture=nb-NO",
"rel": "view-paymentorder",
"contentType": "application/javascript"
}
]
}
The response given when changing a payment order is equivalent to a GET
request towards the paymentorders
resource,
as displayed above.
{% include alert.html type="informative" icon="info" body="
After updating the Payment Order, remember to call .refresh()
on the Payment
Menu in JavaScript." %}
To abort a payment order, perform the update-paymentorder-abort
operation that
is returned in the payment order response. You need to include the following
in the request body:
{:.code-header} Request
PATCH /psp/paymentorders/{{ page.payment_order_id }} HTTP/1.1
Host: {{ page.api_host }}
Authorization: Bearer <AccessToken>
Content-Type: application/json
{
"paymentorder": {
"operation": "Abort",
"abortReason": "CancelledByConsumer"
}
}
{:.code-header} Response
HTTP/1.1 200 OK
Content-Type: application/json
{
"paymentorder": {
"id": "/psp/paymentorders/{{ page.payment_order_id }}",
"created": "2018-09-14T13:21:29.3182115Z",
"updated": "2018-09-14T13:21:57.6627579Z",
"operation": "Purchase",
"state": "Ready",
"currency": "SEK",
"amount": 1500,
"vatAmount": 0,
"remainingCaptureAmount": 1500,
"remainingCancellationAmount": 1500,
"remainingReversalAmount": 0,
"description": "Test Purchase",
"initiatingSystemUserAgent": "PostmanRuntime/3.0.1",
"userAgent": "Mozilla/5.0...",
"language": "nb-NO",
"urls" : { "id": "/psp/paymentorders/{{ page.payment_order_id }}/urls" },
"payeeInfo" : { "id": "/psp/paymentorders/{{ page.payment_order_id }}/payeeinfo" },
"settings": { "id": "/psp/paymentorders/{{ page.payment_order_id }}/settings" },
"payers": { "id": "/psp/paymentorders/{{ page.payment_order_id }}/payers" },
"orderItems" : { "id": "/psp/paymentorders/{{ page.payment_order_id }}/orderItems" },
"metadata": { "id": "/psp/paymentorders/{{ page.payment_order_id }}/metadata" },
"payments": { "id": "/psp/paymentorders/{{ page.payment_order_id }}/payments" },
"currentPayment": { "id": "/psp/paymentorders/{{ page.payment_order_id }}/currentpayment" }
},
"operations": [
{
"method": "PATCH",
"href": "{{ page.api_url }}/psp/paymentorders/{{ page.payment_order_id }}",
"rel": "update-paymentorder-abort",
"contentType": "application/json"
},
{
"method": "GET",
"href": "{{ page.front_end_url }}/paymentmenu/{{ page.payment_token }}",
"rel": "redirect-paymentorder",
"contentType": "text/html"
},
{
"method": "GET",
"href": "{{ page.front_end_url }}/paymentmenu/core/scripts/client/px.paymentmenu.client.js?token={{ page.payment_token }}&culture=nb-NO",
"rel": "view-paymentorder",
"contentType": "application/javascript"
}
]
}
The response given when aborting a payment order is equivalent to a GET
request towards the paymentorders
resource, as displayed above.
with its state
set to Aborted
.
{% include payment-order-cancel.md %}
{% include payment-order-reversal.md %}
{% include transactions.md api_resource="paymentorders" documentation_section="checkout" %}
{% include transaction.md api_resource="paymentorders" documentation_section="checkout" %}
If you want to enable subsequent recurring – server-to-server – payments, you need to create a recurrence token. This token will be utilized after the initial payment order. Recurring payments must be activated on the contract with Swedbank Pay in order to work.
- When initiating a
Purchase
payment order, you need to make sure that the fieldgenerateRecurrenceToken
is set totrue
. This recurrence token will stored in the authorization transaction sub-resource on the underlying payment resource. - When initiating a
Verify
payment order, a recurrence token will be generated automatically. This recurrence token is stored in the verification sub-resource on the underlying payment resource.
You can view the current payment resource, containg the recurrence token and
other payment instrument properties, by expanding the sub-resource
currentpayment
when doing a GET
request on the
paymentorders
resource.
{:.code-header} Request
GET /psp/paymentorders/{{ page.payment_order_id }}?$expand=currentpayment HTTP/1.1
Host: {{ page.api_host }}
When you have a recurrenceToken
token safely tucked away, you can use this
token in a subsequent Recur
payment order. This will be a server-to-server
affair, as we have tied all necessary payment instrument details related to the
recurrence token during the initial payment order.
{:.code-header} Request
POST /psp/paymentorders HTTP/1.1
Host: {{ page.api_host }}
Authorization: Bearer <AccessToken>
Content-Type: application/json
{
"paymentorder": {
"operation": "Recur",
"recurrenceToken": "{{ page.payment_order_id }}",
"currency": "SEK",
"amount": 1000,
"vatAmount": 250,
"description": "Test Purchase",
"userAgent": "Mozilla/5.0...",
"language": "sv-SE",
"urls": {
"callbackUrl": "https://example.com/callback"
},
"payeeInfo": {
"payeeId": "{{ page.merchant_id }}"
"payeeReference": "CD1234",
"payeeName": "Merchant1",
"productCategory": "A123",
"orderReference": "or-12456",
"subsite": "Subsite1"
},
"orderItems": [
{
"reference": "P1",
"name": "Product1",
"type": "PRODUCT",
"class": "ProductGroup1",
"itemUrl": "https://example.com/shop/id=123",
"imageUrl": "https://example.com/product1.jpg",
"description": "Product 1 description",
"discountDescription": "Volume discount",
"quantity": 4,
"quantityUnit": "pcs",
"unitPrice": 300,
"discountPrice": 200,
"vatPercent": 2500,
"amount": 1000,
"vatAmount": 250
}
],
"metadata": {
"key1": "value1",
"key2": 2,
"key3": 3.1,
"key4": false
}
}
}
sequenceDiagram
participant Payer
participant ConsumerSubscription
participant Merchant
participant SwedbankPay as Swedbank Pay
rect rgba(81,43,43,0.1)
note left of Payer: Checkin
activate Payer
Payer ->>+ SwedbankPay: Checkin procedure
deactivate Payer
end
rect rgba(55, 91, 134,0.1)
activate Payer
note left of Payer: Payment Menu
Payer ->>+ Merchant: Initiate Purchase
deactivate Payer
Merchant ->>+ SwedbankPay: POST/psp/paymentorders (generateRecurrenceToken = True)
deactivate Merchant
SwedbankPay -->>+ Merchant: rel:view-paymentorder
deactivate SwedbankPay
Merchant -->>- Payer: Display Payment Menu on Merchant Page
activate Payer
Payer ->> Payer: Initiate Payment Menu Hosted View (open iframe)
Payer -->>+ SwedbankPay: Show Payment UI page in iframe
deactivate Payer
SwedbankPay ->>+ Payer: Do payment logic
deactivate SwedbankPay
SwedbankPay -->>+ Merchant: POST Payment Callback
SwedbankPay -->>- Payer: Payment Status
Payer -->>+ Merchant: Redirect to Payment Complete URL
Merchant ->>+ SwedbankPay: GET/psp/paymentorders/<paymentOrderId>
SwedbankPay -->>+ Merchant: Payment Order Status
end
rect rgba(63, 204, 164,0.1)
note left of Payer: Capture
activate Merchant
Merchant ->>+ SwedbankPay: POST/psp/paymentorders/<paymentOrderId>/captures
deactivate Merchant
SwedbankPay -->>- Merchant: Capture status
note right of Merchant: Capture here only if the purchased<br/>goods don't require shipping.<br/>If shipping is required, perform capture<br/>after the goods have shipped.<br>Should only be used for <br>PaymentInstruments that support <br>Authorizations.
end
rect rgba(94, 108, 23,0.1)
note left of Payer: Recurring payment
activate ConsumerSubscription
ConsumerSubscription ->>+ Merchant: Start recurring payment
deactivate ConsumerSubscription
note left of Merchant: Server-to-Server request at a later date
activate Merchant
Merchant ->>+ SwedbankPay: POST Card Payments (operation=RECUR) (reccurenceToken included)
deactivate Merchant
SwedbankPay -->>- Merchant: Payment resource
opt [Intent=Authorization]
Merchant ->>+ SwedbankPay: Create-capture
SwedbankPay -->>- Merchant: Transaction resource
end
activate Merchant
Merchant -->>- ConsumerSubscription: display purchase result
end
The Purchase
operation is used in all common purchase scenarios.
{:.code-header} Purchase
{
"paymentorder": {
"operation": "Purchase"
{
}
The Verify
operation lets you post verifications to confirm the validity of
credit card information, without reserving or charging any amount. This
option is mainly used to initiate a recurring payment scenario where the card
will be charged at a later date. The request body is equivalent to a Purchase
order with credit card as the selected item.
A recurrence token will be generated automatically,
rendering the parameter generateRecurrenceToken
unnecessary for this
operation.
{:.code-header} Verify
{
"paymentorder": {
"operation": "Verify"
{
}
A payment order is able to hold more than one payment object, even though a successful payment order only harbour one successful payment. This is necessary as the consumer might select and initiate a payment option that is not followed through successfully. I.e. if the consumer cancels an invoice payment, a cancel transaction will still be tied to that particular invoice payment resource. This payment resource will continue to exist, even if the consumer successfully should finish the purchase with a credit card payment instead.
{:.code-header} Request
GET /psp/paymentorders/{{ page.payment_order_id }}/payments HTTP/1.1
Host: {{ page.api_host }}
Authorization: Bearer <AccessToken>
Content-Type: application/json
{
"paymentorder": "/psp/paymentorders/{{ page.payment_order_id }}",
"payments": {
"id": "/psp/paymentorders/{{ page.payment_order_id }}/payments",
"paymentList" : [
{
"id": "/psp/creditcard/payments/{{ page.transaction_id }}",
"instrument" : "CreditCard",
"created": "2016-09-14T13:21:29.3182115Z"
},
{
"id": "/psp/invoice/payments/{{ page.payment_id }}",
"instrument" : "Invoice",
"created": "2016-09-14T13:21:29.3182115Z"
}
]
}
}
{:.table .table-striped}
Field | Type | Description |
---|---|---|
paymentorder |
object |
The payment order object. |
payments |
object |
The payments object. |
└➔ id |
string |
{% include field-description-id.md resource="payments" %} |
└➔ paymentList |
array |
The array of payment objects. |
└─➔ id |
string |
{% include field-description-id.md %} |
└─➔ instrument |
string |
The name of the payment instrument. |
└─➔ created |
string |
The ISO-8601 date and time of when the payment was created. |
The currentpayment
resource displays the payment that are active within the
payment order container.
{:.code-header} Request
GET /psp/paymentorders/{{ page.payment_order_id }}/currentpayment HTTP/1.1
Host: {{ page.api_host }}
Authorization: Bearer <AccessToken>
Content-Type: application/json
{:.code-header} Response
HTTP/1.1 200 OK
Content-Type: application/json
{
"paymentorder": "/psp/paymentorders/{{ page.payment_order_id }}",
"menuElementName": "paymentorders",
"payment": {
"recurrenceToken": "{{ page.payment_order_id }}",
"id": "/psp/paymentorders/payments/{{ page.payment_order_id }}",
"number": 1234567890,
"instrument": "CreditCard",
"created": "2016-09-14T13:21:29.3182115Z",
"updated": "2016-09-14T13:21:57.6627579Z",
"operation": "Purchase",
"intent": "Authorization",
"state": "Ready",
"currency": "NOK",
"amount": 1500,
"remainingCaptureAmount": 1500,
"remainingCancellationAmount": 1500,
"remainingReversalAmount": 0,
"description": "Test Purchase",
"payerReference": "AB1234",
"userAgent": "Mozilla/5.0...",
"language": "nb-NO",
"prices": { "id": "/psp/paymentorders/payments/{{ page.payment_order_id }}/prices" },
"transactions": { "id": "/psp/paymentorders/payments/{{ page.payment_order_id }}/transactions" },
"authorizations": { "id": "/psp/paymentorderspayments/{{ page.payment_order_id }}/authorizations" },
"captures": { "id": "/psp/paymentorders/payments/{{ page.payment_order_id }}/captures" },
"cancellations": { "id": "/psp/paymentorders/payments/{{ page.payment_order_id }}/cancellations" },
"reversals": { "id": "/psp/paymentorders/payments/{{ page.payment_order_id }}/reversals" },
"verifications": { "id": "/psp/paymentorders/payments/{{ page.payment_order_id }}/verifications" },
"urls" : { "id": "/psp/paymentorderspayments/{{ page.payment_order_id }}/urls" },
"payeeInfo" : { "id": "/psp/paymentorders/payments/{{ page.payment_order_id }}/payeeInfo" },
"metadata" : { "id": "/psp/paymentorders/payments/{{ page.payment_order_id }}/metadata" },
"settings": { "id": "/psp/paymentorders/payments/{{ page.payment_order_id }}/settings" }
},
"operations": []
}
{:.table .table-striped}
Field | Type | Description |
---|---|---|
paymentorder |
string |
{% include field-description-id.md resource="paymentorder" sub_resource="payment" %} |
menuElementName |
string |
creditcard , invoice , etc. The name of the selected menu element. |
payment |
object |
The payment object. |
└➔ recurrenceToken |
string |
The created recurrenceToken, if operation: Verify or generateRecurrenceToken: true was used. |
└➔ id |
string |
{% include field-description-id.md %} |
└➔ number |
integer |
The payment number , useful when there's need to reference the payment in human communication. Not usable for programmatic identification of the payment, for that id should be used instead. |
└➔ instrument |
string |
The payment instrument used. |
└➔ created |
string |
The ISO-8601 date of when the payment was created. |
└➔ updated |
string |
The ISO-8601 date of when the payment was updated. |
└➔ operation |
string |
Purchase , payout , Verify or recur. The type of the initiated payment. |
└➔ intent |
string |
The intent of the payment. |
└➔ state |
string |
Ready , Pending , Failed or Aborted . Indicates the state of the payment. This field is only for status display purposes. |
└➔ currency |
string |
The currency of the payment. |
└➔ prices |
object |
The prices object. |
└─➔ amount |
integer |
{% include field-description-amount.md %} |
└─➔ remainingCaptureAmount |
integer |
The available amount to capture. |
└─➔ remainingCancelAmount |
integer |
The available amount to cancel. |
└─➔ remainingReversalAmount |
integer |
The available amount to reverse. |
└➔ description |
string(40) |
{% include field-description-description.md documentation_section="checkout" %} |
└➔ payerReference |
string |
The reference to the consumer from the merchant system, like mobile number, customer number etc. |
└➔ userAgent |
string |
The user agent string of the consumer's browser. |
└➔ language |
string |
{% include field-description-language.md api_resource="paymentorders" %} |
{% include prices.md api_resource="paymentorders" %}
The payer
resource contains payer information related to the payment order.
The information is retrieved via a consumer profile token
(consumerProfileRef
), from the Consumers resource
during login/checkin.
{:.code-header} Request
GET /psp/paymentorders/{{ page.payment_order_id }}/payers/ HTTP/1.1
Host: {{ page.api_host }}
Authorization: Bearer <AccessToken>
Content-Type: application/json
{:.code-header} Response
HTTP/1.1 200 OK
Content-Type: application/json
{
"paymentorder": "/psp/paymentorders/{{ page.payment_order_id }}",
"payer" : {
"id": "/psp/paymentorders/{{ page.payment_order_id }}/payer",
"reference": "reference to payer",
"email": "email",
"msisdn": "msisdn",
"shippingAddress": {
"addressee": "firstName + lastName",
"coAddress": "coAddress",
"streetAddress": "streetAddress",
"zipCode": "zipCode",
"city": "city",
"countryCode": "countryCode"
}
}
}
{:.table .table-striped}
Field | Type | Description |
---|---|---|
paymentorder |
string |
{% include field-description-id.md resource="paymentorder" sub_resource="payer" %} |
payer |
object |
The payer object. |
└➔ id |
string |
{% include field-description-id.md resource="payer" %} |
└➔ email |
string |
Payer's registered email address. |
└➔ msisdn |
string |
Payer's registered mobile phone number. |
└➔ shippingAddress |
object |
The shipping address object related to the payer . |
└─➔ addresse |
object |
The shipping address object related to the payer . |
└─➔ coAddress |
string |
Payer' s c/o address, if applicable. |
└─➔ streetAddress |
string |
Payer's street address |
└─➔ zipCode |
string |
Payer's zip code |
└─➔ city |
string |
Payer's city of residence |
└─➔ countryCode |
string |
Country Code for country of residence. |
It is possible to disable the payment menu when only one instrument exist by
setting the disablePaymentMenu
field to true
. The default value is
false
, exemplified below.
{:.code-header} Request
{
"paymentorder": {
"disablePaymentMenu": false
{
}
{:.text-center} {:width="450" :height="850"}
Setting disablePaymentMenu
field to true
removes all other payment
instruments but the one that is available.
This feature is only valuable to set to true
if you have only one payment
instrument available. By setting it to true
will remove the frame around the
menu and show only the instrument.
{:.code-header} Request
{
"paymentorder": {
"disablePaymentMenu": true
{
}
{:.text-center} {:width="463" :height="553"}
During operation in the Payment Menu, several events can occur. They are described below.
This event triggers when a user actively changes payment instrument in the
Payment Menu. The onPaymentMenuInstrumentSelected
event is raised with the
following event argument object:
{:.code-header}
onPaymentMenuInstrumentSelected
event object
{
"name": "menu identifier",
"instrument": "creditcard | vipps | swish | invoice",
}
{:.table .table-striped}
Field | Type | Description |
---|---|---|
name |
string |
The name and identifier of specific instrument instances - i.e. if you deploy more than one type of credit card payments, they would be distinguished by name . |
instrument |
string |
Creditcard , vipps , swish , invoice . The instrument selected by the user. |
This event triggers when a user has selected a payment instrument and actively
attempts to perform a payment. The onPaymentCreate
event is raised with the
following event argument object:
{:.code-header}
onPaymentCreated
event object
{
"id": "/psp/paymentorders/payments/{{ page.payment_id }}",
"instrument": "creditcard | vipps | swish | invoice",
}
{:.table .table-striped}
Field | Type | Description |
---|---|---|
id |
string |
{% include field-description-id.md %} |
instrument |
string |
Creditcard , vipps , swish , invoice . The instrument selected when initiating the payment. |
This event triggers when a payment has completed successfully.
The onPaymentCompleted
event is raised with the following event argument
object:
{:.code-header}
onPaymentCompleted
event object
{
"id": "/psp/paymentorders/payments/{{ page.payment_id }}",
"redirectUrl": "https://en.wikipedia.org/wiki/Success"
}
{:.table .table-striped}
Field | Type | Description |
---|---|---|
id |
string |
{% include field-description-id.md %} |
redirectUrl |
string |
The URI the user will be redirect to after a completed payment. |
This event triggers when the user cancels the payment.
The onPaymentCanceled
event is raised with the following event argument
object:
{:.code-header}
onPaymentCanceled
event object
{
"id": "/psp/paymentorders/payments/{{ page.payment_id }}",
"redirectUrl": "https://en.wikipedia.org/wiki/Canceled"
}
{:.table .table-striped}
Field | Type | Description |
---|---|---|
id |
string |
{% include field-description-id.md %} |
redirectUrl |
string |
The URI the user will be redirect to after a canceled payment. |
This event triggers when a payment attempt fails, further attempts can be made
for the payment. An error message will appear in the payment UI, and the
consumer will be able to try again or choose another payment instrument. The
onPaymentTransactionFailed
event is raised with the following event argument
object:
{:.code-header}
onPaymentTransactionFailed
event object
{
"id": "/psp/paymentorders/payments/{{ page.payment_id }}",
"details": "[HttpCode ProblemTitle]"
}
{:.table .table-striped}
Field | Type | Description |
---|---|---|
id |
string |
{% include field-description-id.md %} |
details |
string |
A human readable and descriptive text of the error. |
This event triggers when a payment has failed, disabling further attempts to
perform a payment. The onPaymentFailed
event is raised with the following
event argument object:
{:.code-header}
onPaymentFailed
event object
{
"id": "/psp/paymentorders/payments/{{ page.payment_id }}",
"redirectUrl": "https://en.wikipedia.org/wiki/Failed"
}
{:.table .table-striped}
Field | Type | Description |
---|---|---|
id |
string |
{% include field-description-id.md %} |
redirectUrl |
string |
The URI the user will be redirect to after a failed payment. |
This event triggers when the user clicks on the "Display terms and conditions"
link. The onPaymentTermsOfService
event is raised with the following event
argument object:
{:.code-header}
onPaymentTermsOfService
event object
{
"origin": "owner | merchant",
"openUrl": "https://example.org/terms.html"
}
{:.table .table-striped}
Field | Type | Description |
---|---|---|
origin |
string |
owner , merchant . The value is always merchant unless Swedbank Pay hosts the view. |
openUrl |
string |
The URI containing Terms of Service and conditions. |
This event triggers during terminal errors or if the configuration fails
validation. The onError
event will be raised with the following event argument
object:
{:.code-header}
onError
event object
{
"origin": "consumer | paymentmenu | creditcard | invoice | ...",
"messageId": "<unique message ID>",
"details": "Descriptive text of the error"
}
{:.table .table-striped}
Field | Type | Description |
---|---|---|
origin |
string |
consumer , paymentmenu , creditcard , identifies the system that originated the error. |
messageId |
string |
A unique identifier for the message. |
details |
string |
A human readable and descriptive text of the error. |
- Setting a
callbackUrl
in the HTTPPOST
API is optional, but highly recommended. If a payer closes the browser window, a network error or something else happens that prevents the payer from being redirect from Swedbank Pay back to the merchant website, the callback is what ensures that you receive 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.
- 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
.
{:.code-header} Payment Order Callback
{
"orderReference": "OR-123456",
"paymentOrder":{
"id": "/psp/paymentorders/{{ page.payment_order_id }}",
"instrument": "<payment instrument>"
},
"payment":{
"id": "/psp/<payment instrument>/payments/{{ page.payment_id }}",
"number": 222222222
},
"transaction":{
"id": "/psp/<payment instrument>/payments/{{ page.payment_id }}/<transaction type>/{{ page.transaction_id }}",
"number": 333333333
}
}
{:.table .table-striped}
Parameter | Description |
---|---|
orderReference |
The orderReference sent in on create paymentOrder |
Payment Instrument |
CreditCard , Invoice , Swish , Vipps , DirectDebit , MobilePay |
Transaction Type |
Authorization , Capture , Cancellation , Reversal |
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 Merchant
activate SwedbankPay
SwedbankPay->Merchant: POST <callbackUrl>
note left of Merchant: Callback by Swedbank Pay
Merchant-->SwedbankPay: HTTP response
deactivate SwedbankPay
deactivate Merchant
activate Merchant
Merchant->SwedbankPay: GET <payment instrument> payment
activate SwedbankPay
note left of Merchant: First API request
SwedbankPay-->Merchant: payment resource
deactivate SwedbankPay
deactivate Merchant
When performing operations against the API, 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] specification.
The structure of a problem message will look like this:
{
"type": "https://api.payex.com/psp/errordetail/paymentorders/inputerror",
"title": "There was an input error",
"detail": "Please correct the errors and retry the request",
"instance": "{{ page.transaction_id }}",
"status": 400,
"action": "RetryNewData",
"problems": [{
"name": "CreditCardParameters.Issuer",
"description": "minimum one issuer must be enabled "
}]
}
{:.table .table-striped}
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. |
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 description of what was wrong with the field, header, object, entity or likewise identified by name . |
{% include common-problem-types.md %}
{% include expand-parameter.md api_resource="paymentorders" %}
{% include payee-info.md api_resource="paymentorders" %}
{% include merchant-authenticated-consumer.md %}
{% include settlement-reconciliation.md api_resource="paymentorders" %}
When the contents of the shopping cart changes or anything else that affects
the amount occurs, the paymentorder
must be updated and the Payment Menu
must be refresh
ed.
{% include alert.html type="informative" icon="info" body= "Features that are not
described in the previous sections must not be used, although they are
available in the API. Flags that can be turned to true
must be kept
false
as described in this standard setup documentation." %}
{% include alert.html type="informative" icon="info" body= "Your integration must be resilient to change. Properties, operations, headers, etc., that aren't understood in any response must be ignored. Don't expect a specific order of elements. When in doubt, please follow the robustness principle." %}