Johan Broddfelt

Swish Merchant payment setup

Certificates can be confusing to implement. I have done this for different types of solutions and almost every time I'm just trying out different things and basically guessing until I get things to work. The main reason for my struggle is that there are almost always multiple documentations in play and the naming of files are different everywhere. And the reason for all the different types of files are not that well described. Right now I'm trying to get the Swedish payment service Swish to work on my website, using Apache. So, that is what I will use as the basis for my exploration. You will probably have another integration to figure out. But hopefully this post can help you get some things clearer. After a couple of roundtrips with the support, reading a lot of different posts online, speaking to my old coluege and friend Jacob and me building a RESTful API in php for another project. I finally manage to understand what the necessary steps were to get things to work.

Check your environment

First check that you are using the right version of TSL by running openssl s_client -connect YOUR_URL.COM:443 -tls1_1. This command can also be used to verify that you have installed the certificate correctly when you are done. So, remember it.
If it works you should find this line in the output Secure Renegotiation IS supported and not this one Secure Renegotiation IS NOT supported.

- Use of HTTPS
You should know this. But if you want to check see if you can access your website using https://YOUR_URL.COM. If your site works using this URL you are good to go.

Creating certificates

You need to get a client TLS certificate from Swish Certificate Management and install it on your server.
- Generate a pair of 4096 bit RSA keys on your server and create a certificate request (CSR) in a PKCS#10 format.

For details please consult your web solution documentation... Now, in my case I use apache and is refered to the openSSL documentation.

(Starting in Windows where I have the Keystore app installed)
1. Create an empty Keystore: (A KeyStore is a file that serves as a container for private keys, certificates and symetric keys)
Replace YOUR_OWN_ALIAS with somting you can remember like my_key_123.

C:> keytool -genkey -alias YOUR_OWN_ALIAS -keyalg RSA -keystore KeyStore.jks -keysize 4096

In my case I used "C:/Program Files/Java/jdk1.8.0_161/bin/keytool.exe" -genkey -alias my_key_123 -keyalg RSA -keystore KeyStore.jks -keysize 4096

Ange nyckellagerlösenord:
Ange det nya lösenordet igen:
Vad heter du i för- och efternamn?
  [Unknown]:  Johan Broddfelt
Vad heter din avdelning inom organisationen?
  [Unknown]:  Utveckling
Vad heter din organisation?
  [Unknown]:  Citypolarna
Vad heter din ort eller plats?
  [Unknown]:  Malmoe
Vad heter ditt land eller din provins?
  [Unknown]:  Sweden
Vilken är den tvåställiga landskoden?
  [Unknown]:  SE
Är CN=Johan Broddfelt, OU=Citypolarna, O=Firma Johan Broddfelt,
L=Malmoe, ST=Sweden, C=SE korrekt?
  [nej]:  ja

Ange nyckellösenord för 
        (RETURN om det är identiskt med nyckellagerlösenordet):

Warning:
Nyckellagret JKS använder ett proprietärt format. Du bör migrera till PKCS12, som är ett branschstandardformat, med "keytool -importkeystore -srckeystore KeyStore.jks -destkeystore KeyStore.jks -deststoretype pkcs12".

2. Now we change this to a PKCS12 key: (Converts the keystore file to the correct version)

C:> keytool -importkeystore -srckeystore KeyStore.jks -destkeystore KeyStore.jks -deststoretype pkcs12

3. Extract the CSR from the KeyStore:
Remember YOUR_OWN_ALIAS and replace it here as well.

C:> keytool -certreq -alias YOUR_OWN_ALIAS -file csr.txt -keystore KeyStore.jks

(Here I copy all files to Linux)
4. Extract the private key from the KeyStore:

# openssl pkcs12 -in KeyStore.jks -nodes -nocerts -out swish.key

5. Generate the pem certificate file at Swish Portal:
Go to https://portal.swish.nu and upload your csr.txt file or copy the content into the text form. You then get a certificate you can download which we below will call Your_Swish_Cert.pem

6. Convert swish.key certificate from the pkcs12 keystore into the pkcs12 format.

# openssl pkcs12 -export -in Your_Swish_Cert.pem -inkey swish.key -out swish.p12

(Copying everything back to Windows)
7. Import the swish.p12 file in to the KeyStore.jks:

C:> keytool -v -importkeystore -srckeystore swish.p12 -srcstoretype PKCS12 -destkeystore KeyStore.jks

7b: The next step might not be needed in most cases but if there are issues with the handshake it might help. Since the reason I'm writing this documentation is because I got the following error (Curl error: error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure). I think I will try this step as well this time.
This step actually failed the last time I tried it. With the error java.io.FileNotFoundException: Swish_Server_Root.crt (File not found). Luckilly it did not seem to be a problem.

C:> keytool -importcert -alias YOUR_OWN_ALIAS -keystore Your_TrustStore.jks -file Swish_Server_Root.crt

8. Package all keys in one file:
Now we take the swish.key and copy the text from "-----BEGIN PRIVATE KEY-----" to "-----END PRIVATE KEY-----" into a new file and call it swish.pem. Then we take the three certificates from swish_cert.pem and paste after the key in the same file.

Now we have one file called swish.pem containing something like this:

-----BEGIN PRIVATE KEY-----
MOIJQwIBADA...
-----END PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MOIFezCCA2O...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MOIFzTCCA7W...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MOIFrTCCA5W...
-----END CERTIFICATE-----

This is our pem certificate file we will use in the integration.

(And copy everything back to Linux where the production is running)

The code

Now for the code. You can try to call swish using curl in console. This is what the test sample from Swish looks like.

curl.exe" -v --request POST https://mss.cpc.getswish.net/swish-cpcapi/api/v1/paymentrequests --header "Content-Type: application/json" --cert "Swish Merchant Test Certificate 1231181189.p12":swish --cert-type p12 --cacert "Swish TLS Root CA.pem" --tlsv1.1 --data @- <

But it is slightly missleading if you are about to use cURL in php. Because as you saw above, we merged the two files with certificates into one swish.pem. So, this is what it looks like using php.

$postData = '
{
    "payeePaymentReference": "' . $paymentReference . '",' // Code provided by you as a reference
   . '"callbackUrl": "' . $callbackUrl . '",' // See below swish_ipn.php
   . '"payerAlias": "' . $payerAlias . '",' // 4670xxxxxxxx - eg. the phone number of the user
   . '"payeeAlias": "' . $payeeAlias . '",' // 123xxxxxxx - eg. your number
   . '"amount": "' . $amount . '",' // Amount in SEK
   . '"currency": "' . $currency . '",' // 'SEK'
   . '"message": "' . $message . '"}'; // If the user included a message when paying
$ch = curl_init();
$header = array(
	'Content-Type: application/json',                                                                                
	'Content-Length: ' . strlen($postData)
);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_POST, $url);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, TRUE);
if (substr($url, 0, 5) == 'https') { curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); }
curl_setopt($ch, CURLOPT_SSLCERT, '/path/swish.pem');
curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'pem');
curl_setopt($ch, CURLOPT_SSLCERTPASSWD, '***PASSWORD***');

$result = curl_exec($ch);
if ($result === false) {
	echo curl_error($ch);
}
$response_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($response_code == 200 or $response_code == 201) {
	echo 'The request was successfull.'; // Actually you should expect to get 201 in return.
} else {
	echo 'The request failed. Code: ' . $response_code;
}

Get payment notifications

Now all you need is the swish_ipn.php file the get the response from Swish when a payment has been completed.

$postData = file_get_contents("php://input");
// You want to write this to a log or a file for starters, so that you can see what comes back so you know how to deal with it.
file_put_contents('swish_payments.log', $postData)

That's it for this post, hope you find it useful and that it make it easier to implement Swish payments using php.

- swish, payment, software

<< MySQL to DB2
Follow using RSS

Comment

Name
Mail (Not public)
Send mail updates on new comments
30 comments
Jag tror baserat på en av mina tidigare kommentarer här att du bör deaktivera SSL3 och se till att servern kör med TLS1.2 eller senare istället.
2024-08-08 00:18:44 - Johan
Ja, jag har fortfarande samma kod körandes idag och jag gjock igenom och uppdaterade certifikatet i våras, då jag även gjorde några uppdateringar i sidan för att göra den tydligare.

Det låter som att problemet ligger i vilken version av SSL du kör på servern. Men det är lite svårt att svara på utifrån enbart felmeddelandet. Jag skulle rekommendera dig att kontakta Swish support eller se om denna forumtråd kanske har några svar.
https://serverfault.com/questions/889631/curl-fails-to-retrieve-https-content-error14094410ssl-routinesssl3-read-byte
2024-08-07 23:16:32 - Johan
Funkar detta idag? Jag får detta error Error: error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure. Vet inte vad jag ska göra.
2024-08-07 20:49:00 - JE
I have now updated the steps to generate the certificate files. In order to make it a bit clearer what is needed.
2024-02-28 23:59:34 - Johan
Rikard, du kan använda header("Location: https://min_sida.se/tack.php"); efter "if ($response_code == 200 or $response_code == 201) {" alternativt så bygger du in tacksidan med en include("tack.php");
/ Johan
2023-08-21 07:34:54 - Johan
Hej Johan jag har en fråga till dig. Jag har integrerat swish api i mitt php baserad e-commerce system den fungerar utmärkt , men jag har ett problem, efter att kunden ha gjort swishbetalningen vill jag att kunden automatiskt ska gå till tacksidan, hur lägger jag till en kod för detta. min webbplats är en php-baserad webbplats.
mvh
Rikard
2023-08-20 23:37:51 - Rikard
Nä, det skulle jag i allra högsta grad försöka undvika om jag kan. Private keys ska ingen annan ha tillgång till.
2022-03-22 10:06:11 - Johan
En fråga är det säkert för swish.key file att vara når från url alltså, t.ex att man kan se privat RSA nyckel genom att navigera till www.site.com/swish.key ?
2022-03-22 09:55:40 - nara
En fråga är det säkert för swish.key file att vara når från url alltså, t.ex att man kan se privat RSA nyckel genom att navigera till www.site.com/swish.key ?
2022-03-22 09:50:18 - nara
Jag kan konstatera att min implementation fortfarande fungerar. Jag har fått ett flertal inbetalningar sedan den 17:e januari.
2022-01-25 07:43:01 - Johan
Senaste inbetalningen jag fått var den 17 januari, jag ska hålla ett öga på om där kommer fler de närmaste dagarna. TLS1.2 är ju den senaste så det ska i alla fall inte vara problemet. Möjligen att där skulle vara något med sslv3 som har brister och därmed borde deaktiveras.
2022-01-19 09:30:33 -
Hej, sedan 17 januari 2022 så har det inte fungerat att göra payment requests. Jag får detta felmeddelande:

error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure

Ett test på www.cdn77.com/tls-test visar att domännamnet använder TLS1.3. Är det någon annan som fått samma problem?
2022-01-19 09:23:19 - Filip
Du kan nå mig på jb@frontiot.com
2021-06-13 11:10:57 - Johan
Hej Johan!
Blev glad att det går att lösa.
Kan du skicka din mail till mig, så kan vi diskutera pris.
Skulle verkligen vara jättetacksam om jag fick hjälp.
2021-06-13 03:40:43 - VP
Ja, det går. Jag använder själv Swish på det sättet på Citypolarna.se.
2021-05-08 21:05:09 - Johan
Hejsan!
Skulle någon kunna hjälpa mig med det här? Hade betalat pengar.
Vill exempelvis när man köper något på min hemsida så ska Swish skicka till kunden att den måste betala sen när man betalar vill jag att den på nått sätt kopplas till databasen (mysql) o ändrar enkel grej i users för användaren. Går det att lösa?
2021-05-08 16:13:11 - VP
Jag skulle föreslå att du börjar med att göra ett test för att se vilken version av SSL/TSL som körs på servern. Felmeddelandet kan tyda på att https inte är korrekt uppsatt på hemsidan.
Här är en sida där du kan köra ett test www.cdn77.com/tls-test
2021-04-30 09:51:23 - Johan
Hej Johan! Det började inte så bra med att följa din guide. Jag fick "Secure Renegotiation IS NOT supported". Använder Loopia. Vad kan jag göra åt det?
2021-04-30 08:37:47 - Fredrik Nilsson
Kul att höra att du haft nytta av inlägget =)
2020-12-02 23:35:58 - Johan
Ja, det är en separat fil, du anger adressen till den i variablen "callbackUrl" som du skickar med cURL. Det behöver nog inte vara en separat fil så länge du kan identifiera anropet från swish och dirigera det till rätt kod inne i din hemsida.
2020-12-02 23:34:03 - Johan
Måste bara tacka dig för denna guide. Har hållit på och försökt att integrera Swish Handel i min webbshop i veckor nu med hjälp av Swishs egen dokumentation och inte kommit nån vart. Och nu lyckades jag få iväg mitt första lyckade payment request efter att ha läst din guide. Hur fångar man upp callbacken dock? Den sista "code snippet"; är den i en separat php-fil från det första scriptet med Curlen? Min hemsida har inga subpages utan alla delar är uppbyggda av popuprutor (modaler). Är det ett problem när jag sätter CallbackURLen. Återigen tack för hjälpen! Mvh Filip
2020-12-02 22:34:06 - Filip
RSA is the algorithm used to generate the KeyStore.jks. You can find it in the post: "C:/Program Files/Java/jdk1.8.0_161/bin/keytool.exe" -genkey -alias my_key_123 -keyalg RSA -keystore KeyStore.jks -keysize 4096
2020-11-30 21:44:39 - Johan
Kanske bättre på svenska. Hur generear jag RSA nyckel? Certifikatet är klart men behöver RSA nyckel.
2020-11-30 20:47:58 - Constantin
Hi guys...How do I generate RSA key?

Thank you
2020-11-30 20:47:10 - Constantin
PEM är det vanligaste formatet för certifikatfiler. Filändelser som används på PEM filer är .cer, .crt och .pem. Så du ska bara kunna ladda upp den som den är eller ändra ändelsen till .crt så ska det fungera.
2020-11-06 08:39:25 - Johan
Hej
jag har redan genererat .csr och.key files med följande metod
(openssl req -new -newkey rsa:4096 -nodes -keyout swish_priv_key.key -out swish.csr)
och jag har laddat upp crs file till Swish system och genererat PEM file och har laddat när. jag behöver ladda upp swish file till min E-commerce system där finns 2 rad ladda upp .CRT och.Key file nu min frågan är hur ska jag generar CRT file eller måste ändra .PEM file till CRT kan du hjälpa till stor tack
2020-11-06 00:34:43 - roban
Hi Hussein
On macOS there is a tool called "Certificate Assistant" that you can use to generate the files you need. Otherwise I would recommend contacting Swish support, as they can guide you through this as well.
2020-10-18 18:05:31 - Johan
Hi
I have receded your artikel about Swish Api and It was very helpful. I was a little confuses about the Create Certificate. I use System macOS. I can not generate certificate from Swish Certificate Management and I want to use Swish Merchant Test Certificate that there is in document Swish developer. Try to use or test them ever?
Can I take your help about this?
Thanks for you that share your information.
2020-10-18 07:24:47 - hussein
Hi Hussein

I'm not entirely sure what you mean my M commerce, "mobile commerce"? Switch is a Swedish provider of mobile payments that does not work if you do not have a Swedish bank account. But you can use this payment for many kinds of projects in Sweden.
2020-05-21 10:32:49 - Johan
Hi
I have readed your information about Swish Api. This was perfekt. Thank you for information. I have one question about This projekt. Can i use This projekt for M commerce?
Can you help me about This?
2020-05-21 00:26:24 - hussein barbari
1 2 >>