ZignSec

Swish Payments -se

Swedish Swish payments are performed with the mobile Swish app and the BankID app. The Swish app can be started anonymously on the same device, or with a phone number specified for payment on any device with a matching setup – much the same way as the Swedish BankID login can be initiated with or without specifying a personal number.

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 and ageLimit 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 /swishRefunds but without the originalPaymentReference parameter and without refund’s restrictions on the amount.

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.

API Calls

Payment initiation: POST to https://env.zignsec.com/v2/swishpayments
Payment results: Callback or GET from https://env.zignsec.com/v2/swishpayments/{id}
Refund initation: POST to https://env.zignsec.com/v2/swishrefunds
Refund results: Callback or GET from https://env.zignsec.com/v2/swishrefunds/{id} … where env is api or test and id is the payment or refund request identifier retrieved from the initiation response’s location HTTP header.

Call Order

To request a payment from a person to the pre-setup merchant’s bank account:

To do a Refund of all or part of an earlier payment, transferred from the merchant’s bank to the person’s account:

Payment step 1. Create a payment request

Example of creating a payment request sent to a specific mobile phone number, 46776543210

            POST https://test.zignsec.com/v2/swishpayments HTTP/1.1
Authorization: YOUR_KEY_HERE
Content-Type: application/json; charset=utf-8
Host: test.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.zignsec.com/v2/swishpayments/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 Swish_webhook_PROD 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_PayeeAlias_TEST and Swish_PayeeAlias_PROD. “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 Will come first week in March 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 Will come first week in March 2019. 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 callback url 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 swish_webhook_test/swish_webhook_prod or through the callbackUrl parameter in the request call.

Callback example

            {
  "id": "D8DB6C74849243C3B93F5A8213D41795",
  "payeePaymentReference": "0123456789",
  "paymentReference": "92BC9BA471B142B68A68B5FE4DB45ECA",
  "callbackUrl": "https://xyzcasino.com/callback",
  "payerAlias": null,
  "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.zignsec.com/v2/swishpayments/ADECC7EF970641A7A4325D81188D1BA1/ HTTP/1.1
Host: test.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
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 seperated 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.

Refund step 1. Create a Refund request

Example of creating a Refund request for an earlier payment with id D8DB6C74849243C3B93F5A8213D41795

            POST https://test.zignsec.com/v2/swishrefunds HTTP/1.1
Authorization: YOUR_KEY_HERE 
Content-Type: application/json; charset=utf-8
Host: test.zignsec.com
Content-Length: 322
Expect: 100-continue
Connection: Keep-Alive

{
  "payerAlias": "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.zignsec.com/v2/swishrefunds/ADECC7EF970641A7A4325D81188D1BA1/
        

Refund request parameters

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 seperated with a period. Required
payerAlias 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
payeePaymentReference 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.  
(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_PayeeAlias_TEST and Swish_PayeeAlias_PROD. “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.

Refund step 2. Retrieve refund results

The webhook url which will receive the refund results is set in ZignSec setting Swish_Webhook_Refund_{env} or in the callbackUrl parameter in the refund request.

Callback example

            {
  "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",
  "id": "5B71F1BF4B3C4DF09DD084A22806F32F",
  "payeeAlias": "4671234768",
  "message": "Refund for Kingston USB Flash Drive 8 GB",
  "status": "PAID"
}

        

GET status of a Refund

            GET https://test.zignsec.com/v2/swishrefunds/{SESSION_IDENTIFIER}/ HTTP/1.1
Host: test.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.
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 seperated 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 Objects

Sample 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"
    }
  ]
}