API Calls
Payment initiation: POST to https://env
.zignsec.com/api/v4/swish/payments
Payment results: Callback or GET from https://env
.zignsec.com/api/v4/swish/payments/{id}
Refund initiation: POST to https://env
.zignsec.com/api/v4/swish/refunds
Refund results: Callback or GET from https://env
.zignsec.com/api/v4/swish/refunds/{id}
Where env
is gateway
or test-gateway
and id
is the payment or refund request identifier retrieved from the initiation response’s location
HTTP header.
API documentation
Call Order
To request a payment from a person to the pre-setup merchant’s bank account:
- Payment initiation: POST to SwishPayments to create a new payment request.
- Payment results: Result automatically POST:ed to callback (recommended) OR poll periodically for status updates through a GET endpoint.
To do a Refund of all or part of an earlier payment, transferred from the merchant’s bank to the person’s account:
- Refund initiation: POST to SwishRefunds to create a new refund request.
- Refund results: Results automatically POST:ed to callback (recommended) OR poll periodically for status updates through a GET endpoint..
Workflow E-commerce vs M-commerce
Two workflows exist: E-commerce (with phone number, any device) and M-commerce (without phone number, same device). E-commerce is suitable for web shops and M-commerce for mobile app integrations. For a detailed description over the differences see these graphics. All technical Swish documentation is found on developer.getswish.se/manuals. There you can also find the API reference. Notes:
- New parameters: Validation of
payerSSN
andageLimit
will be available early 2019. - New use case: Swish pay out –
/swishReimbursements
will be available in Q3 2019. “Pay out” is a reversed standard payment flow with the money going from the merchant to the person. Technically it looks the same as/refunds
but without theoriginalPaymentReference
parameter and without refund’s restrictions on theamount
.
The prerequisites
- For the merchant: Need to set up a bank account for receiving Swish payments, and also a certificate bound to the merchant’s name and finally set up callback endpoints on merchant side that will have the payment and refund results data POST:ed to.
- For the user: The person needs to have a bank account connected to the swish service. Need to setup the Swish app and the BankID app on the same device. The Swish app will internally start up the BankID app on the same device for confirmation of the payment. Note: For testing of the swish service no swish app is needed – the swish server will answer with fabricated responses in the test environment.
Payment step 1. Create a payment request
Example of creating a payment request sent to a specific mobile phone number, 46776543210
POST https://test-gateway.zignsec.com/api/v4/swish/payments HTTP/1.1 Authorization: YOUR_KEY_HERE Content-Type: application/json; charset=utf-8 Host: test-gateway.zignsec.com Content-Length: 213 Connection: Keep-Alive { "payerAlias": "46776543210", "payeePaymentReference": "235235076", "callbackUrl": "https://xyzcasino.com/callback", "amount": "100", "currency": "SEK", "message": "Kingston USB Flash Drive 8 GB" }
Response Example (data in HTTP Headers)
Location: https://test-gateway.zignsec.com/api/v4/swish/payments/ADECC7EF970641B7A4325D87188D1BA1/
Payment request parameters
Property | Type | Description | Required |
---|---|---|---|
amount | String | The amount of money to pay. The amount cannot be less than 1 SEK and not more than 999999999999.99 SEK. Valid value has to be all numbers or with 2 digit decimal | Required |
currency | String | The currency to use. Only supported value currently is SEK. | Required |
payeePaymentReference | String | Internal payment reference of the merchant’s. This could be an order id or similar. It should contain 1-35 characters. | |
payerAlias | String | If set the E-commerce workflow will run otherwise the M-commerce. The registered Cell phone number of the person that makes the payment. It can only contain numbers and has to be at least 8 and at most 15 numbers. It also needs to match the following format in order to be found in Swish: country code + cell phone number (without leading zero). E.g.: 46712345678 If payerAlias is left out you must start swish app via the swish autostart URL(= M-commerce workflow) Build the start-URL using the PaymentRequestToken from a header in the response to open the swish app, in the custom swish URL scheme e.g.: swish://paymentrequest?token=f34DS34lfd0d03fdDselkfd3ffk21 | |
message | String | A text description of the payment that will be presented to the paying person. Max 50 characters. Allowed characters are the letters a-o ̈, A-Ö, the numbers 0-9 and the special characters :;.,?!()”. For test environment this field is also used to trigger specific error responses – the errorCode as defined in section 0 can be set in the message property in order to simulate negative responses. | |
callbackUrl | String | Need not be used in production, since it is set through the merchant setting. The URL where Swish will notify the merchant of the outcome of the Payment request. The URL has to use HTTPS. | |
(payeeAlias) | String | payeeAlias should not be set: This is set statically for each merchant by Zignsec to swish number of the merchant, it is set in merchant setting. “Swish number” is another name for a payeeAlias and it always starts with “123”. In test the Zignsec merchant’s payeeAlias of 1231181189 is automatically configured, and in prod Zignsec will set the payeeAlias when the agreement is signed and set up from the bank. | |
upcoming: payerSSN | String | Available Q4/2019. For validation by Swish that this SSN-specified person is the one owning the payerAlias. The response error code when wrong SSN was used will be VR02 . | |
upcoming: ageLimit | int | Available Q1/2020. For validation by Swish that the person paying has the given minimum age. The response error code when person was underage will be VR01 . |
Payment response fields
Property | Type | Description |
---|---|---|
Location | String | The URL where to check payment status. The recommendation is to rely on the callbackurl instead, which will have results automatically POST:ed to. |
PaymentRequestToken | String | Mostly relevant for M-commerce. The PaymentRequestToken that is needed to open the swish app, binding the app to the specific payment request. Used with the custom URL scheme e.g.: swish://paymentrequest?token=f34DS34lfd0d03fdDselkfd3ffk21 |
Payment step 2. Retrieve payment results
Data will be sent to the webhook URL that set through ZignSec setting or through the callbackUrl
parameter in the request call.
Callback example
{ "id": "D8DB6C74849243C3B93F5A8213D41795", "state": "Finished", "errors": [], "payeePaymentReference": "0123456789", "paymentReference": "92BC9BA471B142B68A68B5FE4DB45ECA", "callbackUrl": "https://xyzcasino.com/callback", "payerAlias": "46776543210", "payeeAlias": "1231181189", "currency": "SEK", "message": "Kingston USB Flash Drive 8 GB", "errorMessage": "", "status": "PAID", "amount": "100", "dateCreated": "2019-01-24T09:19:36.373+0000", "datePaid": "2019-01-24T09:19:40.373+0000", "errorCode": null }
Example of GET payment status
GET https://test-gateway.zignsec.com/api/v4/swish/payments/ADECC7EF970641A7A4325D81188D1BA1/ HTTP/1.1 Host: test-gateway.zignsec.com
Callback model and GET response model have almost the same structure, with following differences:
amount
is string type in callback, but float type in GET response
Callback field Description
Property | Type | Description |
---|---|---|
id | String | Payment request ID |
state | String | Session state |
errors | A JSON array of error conditions, see error handling. | |
payeePaymentReference | String | Payment reference of the payee, which is the merchant that receives the payment. This reference could be order id or similar. |
paymentReference | String | Payment reference, from the bank, of the payment that occurred based on the Payment request. Only available if status is PAID. |
callbackUrl | String | URL that Swish will use to notify caller about the outcome of the Payment request. The URL has to use HTTPS. |
payerAlias | String | The registered Cell phone number of the person that makes the payment. It can only contain numbers and has to be at least 8 and at most 15 numbers. It also needs to match the following format in order to be found in Swish: countryCode + cell phone number (without leading zero). E.g.:46712345678 |
payeeAlias | String | The Swish number of the payee |
amount | String | The amount of money to pay. The amount cannot be less than 1 SEK and not more than 999999999999.99 SEK. Valid value have to be all numbers or with 2 digit decimal separated with a period. |
currency | String | The currency to use. Only supported value currently is SEK. |
message | String | Merchant supplied message about the payment/order. Max 50 chars. Allowed characters are the letters a-ö, A-Ö, the numbers 0-9 and the special characters :;.,?!()”. |
status | String | The status of the transaction. Possible values: CREATED, PAID, DECLINED, ERROR. |
dateCreated | String | The time and date that the payment request was created. |
datePaid | String | The time and date that the payment request was paid. Only applicable if status was PAID. |
errorCode | String | A code indicating what type of error occurred. Only applicable if status is ERROR. |
errorMessage | String | A descriptive error message (in English) indicating what type of error occurred. Only applicable if status is ERROR |
additionalInformation | String | Additional information about the error. Only applicable if status is ERROR. |
Session state
Refund step 1. Create a Refund request
Example of creating a Refund request for an earlier payment with id D8DB6C74849243C3B93F5A8213D41795
POST https://test-gateway.zignsec.com/v2/swishrefunds HTTP/1.1 Authorization: YOUR_KEY_HERE Content-Type: application/json; charset=utf-8 Host: test-gateway.zignsec.com Content-Length: 322 Expect: 100-continue Connection: Keep-Alive { "payeeAlias": "46776543210", "payerPaymentReference": "0123456789", "originalPaymentReference": "D8DB6C74849243C3B93F5A8213D41795", "callbackUrl": "https://xyzcasino.com/callback", "amount": "100", "currency": "SEK", "message": "Refund for Kingston USB Flash Drive 8 GB" }
Refund response example (data in HTTP Headers)
Location: https://test-gateway.zignsec.com/api/v4/swish/refunds/ADECC7EF970641A7A4325D81188D1BA1/
Refund request parameters
Note that the contents of payerAlias and payeeAlias are reversed during a Refund call. So it is the recipient’s mobile number that should be put in payeeAlias now.. The payerAlias field is the merchant’s swish number, and need not be set since is a static merchant configuration.
Property | Type | Description | Required |
---|---|---|---|
originalPaymentReference | String | Payment reference to the original payment that this refund is for. | Required |
currency | String | The currency to use. Only supported value currently is SEK. | Required |
amount | String | The amount of money to pay. The amount cannot be less than 1 SEK and not more than 999999999999.99 SEK. Valid value have to be all numbers or with 2 digit decimal separated with a period. | Required |
payeeAlias | String | The registered Cell phone number of the person that makes the refund. It can only contain numbers and has to be at least 8 and at most 15 numbers. It also needs to match the following format in order to be found in Swish: countryCode + cell phone number (without leading zero). For example 46712345678 | Required |
payerPaymentReference | String | Payment reference of the payee, which is the merchant that receives the payment. This reference could be order id or similar. | |
message | String | Merchant supplied message about the payment/order. Max 50 chars. Allowed characters are the letters a-ö, A-Ö, the numbers 0-9 and the special characters :;.,?!()”. | |
callbackUrl | String | Need not be used in production, since it is set through the merchant setting Swish_Webhook_Refund_PROD The URL where Swish will notify the merchant of the outcome of the Refund request. The URL has to use HTTPS. | |
(payerAlias) | String | payerAlias should not be set (configured via merchant settings) During a Refund the payerAlias equals the Merchant’s swish number. |
Refund step 2. Retrieve refund results
The webhook URL which will receive the refund results is set in ZignSec setting or in the callbackUrl
parameter in the refund request.
Callback example
{ "id": "5B71F1BF4B3C4DF09DD084A22806F32F", "state": "Finished", "errors": [], "amount": "100.00", "originalPaymentReference": "D8DB6C74849243C3B93F5A8213D41795", "dateCreated": "2019-01-30T09:44:15.296+0000", "datePaid": "2019-01-30T09:44:23.381+0000", "payerPaymentReference": null, "payerAlias": "1231181189", "callbackUrl": "https://xyzcasino.com/callback", "currency": "SEK", "payeeAlias": "4671234768", "message": "Refund for Kingston USB Flash Drive 8 GB", "status": "PAID" }
GET status of a Refund
GET https://test-gateway.zignsec.com/api/v4/swish/refunds/{SESSION_IDENTIFIER}/ HTTP/1.1 Host: test-gateway.zignsec.com
Callback model and GET response model have almost the same structure, with following differences:
amount
is string type in callback, but float type in GET response
Callback field Description
Property | Type | Description |
---|---|---|
payeePaymentReference | String | Payment reference of the payee, which is the merchant that receives the payment. This reference could be order id or similar. |
state | String | Session state |
errors | A JSON array of error conditions, see error handling. | |
callbackUrl | String | URL that Swish will use to notify caller about the outcome of the Payment request. The URL has to use HTTPS. |
payerAlias | String | The registered Cell phone number of the person that makes the payment. It can only contain numbers and has to be at least 8 and at most 15 numbers. It also needs to match the following format in order to be found in Swish: countryCode + cell phone number (without leading zero). E.g.:n46712345678 |
payeeAlias | String | The Swish number of the payee |
amount | String | The amount of money to pay. The amount cannot be less than 1 SEK and not more than 999999999999.99 SEK. Valid value have to be all numbers or with 2 digit decimal separated with a period. |
currency | String | The currency to use. Only supported value currently is SEK. |
message | String | Merchant supplied message about the payment/order. Max 50 chars. Allowed characters are the letters a-ö, A-Ö, the numbers 0-9 and the special characters :;.,?!()”. |
id | String | Payment request ID |
paymentReference | String | Payment reference, from the bank, of the payment that occurred based on the Payment request. Only available if status is PAID. |
status | String | The status of the transaction. Possible values: CREATED, PAID, DECLINED, ERROR. |
dateCreated | String | The time and date that the payment request was created. |
datePaid | String | The time and date that the payment request was paid. Only applicable if status was PAID. |
errorCode | String | A code indicating what type of error occurred. Only applicable if status is ERROR. |
errorMessage | String | A descriptive error message (in English) indicating what type of error occurred. Only applicable if status is ERROR |
additionalInformation | String | Additional information about the error. Only applicable if status is ERROR. |
Possible HTTP status codes after Payment
HTTP status codes | Returned scenarios |
---|---|
201 Created | Returned when Payment request was successfully created. Will return a Location header and if it is M-Commerce case, it will also return PaymentRequestToken header. |
400 Bad Request | Returned when the Create Payment Request operation was malformed. Can return an Array of Error Objects. |
401 Unauthorized | Returned when there are authentication problems with the certificate. Or the Swish number in the certificate is not enrolled. Will return nothing else. |
403 Forbidden | Returned when the payeeAlias in the payment request object is not the same as Merchants Swish-number. |
415 Unsupported Media Type | Returned when Content-Type header is not “application/json”. Will return nothing else. |
422 Unprocessable Entity | Returned when there are validation errors. Will return an Array of Error Objects. |
500 Internal Server Error | Returned if there was some unknown/unforeseen error that occurred on the server, this should normally not happen. Will return nothing else. |
List of possible error codes
List of possible error codes for Status Code 422
Error codes | Description | Possible return in callback |
---|---|---|
FF08 | PayeePaymentReference is invalid | N |
BE18 | Payer alias is invalid. Note: Configuration error payer not well formed. | N |
PA02 | Amount value is missing or not a valid number | N |
AM06 | Amount value is too low | N |
AM02 | Amount value is too large | N |
AM03 | Invalid or missing Currency | N |
RP02 | Wrong formatted message Note: Not expected, covered by error code ZS501 | N |
RP06 | Another active ongoing PaymentRequest already exists for this payerAlias. Only applicable for E-Commerce. Note: The request will be canceled with this error code. The ongoing PaymentRequest will be active for 3 minutes when it reaches timeout or if the payer ends it within this timeframe. | N |
ACMT03 | Payer not Enrolled | Y |
ACMT01 | Counterpart is not activated. Note: The payer’s app has been deactivated by the payer by activating the service on another unit or the bank has deactivated the app or terminated the service. | Y |
ACMT07 | Payee not Enrolled. Note: Phone number not configured with Swish. | Y |
RF07 | Transaction declined | Y |
BANKIDCL | Payer cancelled BankID signing | Y |
FF10 | Bank system processing error | Y |
TM01 | Swish timed out before the payment was started | Y |
DS24 | Swish timed out waiting for an answer from the banks after payment was started. Note: If this happens Swish has no knowledge of whether the payment was successful or not. The Merchant should inform its consumer about this and recommend them to check with their bank about the status of this payment. | Y |
BANKIDONGOING | BankID already in use. | Y |
BANKIDUNKN | BankID is not able to authorize the payment. | Y |
(RP03) | (Callback URL is missing or does not use Https) Handled by ZS103 and ZS104 | N |
(RP01) | (Payee alias is missing or empty) Handled by ZS105 | N |
(PA06) | (Upcoming, parameter payerSSN invalid, bad formatted SSN validation parameter.) | N |
(PA08) | (Upcoming, parameter ageLimit invalid, not valid value of ageLimit parameter.) | N |
(VA02) | (Upcoming, payerSSN-validation – the payerAlias owner not same SSN.) | N |
(VA01) | (Upcoming, ageLimit validation – the payerAlias owner is under the ageLimit.) | N |
List of possible error codes for Status Code 400
Error codes | Description | Possible return in callback |
---|---|---|
ZS100 | Authorization header is missing | N |
ZS101 | Authorization header is invalid | N |
ZS102 | No Merchant found with Authorization header | N |
ZS103 | Callback URL is invalid or missing | N |
ZS104 | Callback URL HTTPS is required | N |
ZS105 | Swish_PayeeAlias not configured on ZignSec side | N |
ZS106 | Swish_CertificateThumbprint not configured on ZignSec side | N |
ZS107 | Swish_RootCAThumbprint not configured on ZignSec side | N |
ZS108 | Client Certificate not configured on ZignSec side | N |
ZS200 | payeeAlias field should be empty Note: Parameter not in use – a Zignsec merchant must preconfigure a payeeAlias. | N |
ZS201 | Payment session ID is not found | N |
ZS300 | Payment with following originalPaymentReference not found in refund | N |
ZS301 | Refund session ID is not found | N |
ZS500 | Unknown Exception – {Additional information} | N |
ZS501 | The request JSON is not well formed | N |
Error response
400 or 422 Status code – Returned when there are errors. Will return an Array of Error ObjectsSample of Error Response
{ "errors": [ { "code": "PA02", "description": "Amount value is missing or not a valid number" }, { "code": "AM03", "description": "Invalid or missing Currency" }, { "code": "RF08", "description": "Amount value is too large or amount exceeds the amount of the original payment minus any previous refunds" } ] }