Johan Broddfelt
/* Comments on code */

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.
1. Create an empty Keystore: (A KeyStore is a file that serves as a container for private keys, certificates and symetric keys)
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".

Now we change this to a PKCS12 key:
keytool -importkeystore -srckeystore KeyStore.jks -destkeystore KeyStore.jks -deststoretype pkcs12 converts the keystore file to the correct version
Extract the CSR from the KeyStore: ("csr.txt" is the Certificate Signing Request that you should use at "https://comcert.getswish.net" to generate your new certificate with.) keytool -certreq -alias YOUR_OWN_ALIAS -file csr.txt -keystore KeyStore.jks
or as I used it:

"C:/Program/Java/jdk1.8.0_161/bin/keytool.exe" -certreq -alias my_key_123 -file csr.txt -keystore KeyStore.jks


Extract the private key from the KeyStore

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


Now this swish.key certificate from the pkcs12 keystore should be converted into the pkcs12 format.

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


But we still need to get (Your_Swish_Cert.pem) and we get that using the instructions in this documentation that describes how we use Swish website to generate the Swish_Cert using our Certificate Signing Request (CSR), (PKCS#12 with 4096-bit RSA key) we named csr.txt. We can use the PEM or PKCS#7 format. Since we are expecting to get a PEM file I go with the default selected PEM format.

Now I successfully generated that and copy the new Swish certificate into a file I call swish_cert.pem. Now we can run the following:

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


Now we want to import the swish.p12 file in to the KeyStore.jks as well. Here is how we do that:

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


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.

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


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.

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 @- <<!{ "payeePaymentReference": "0123456789","callbackUrl": https://callback.se/"https://example.com/api/swishcb/paymentrequests","payerAlias": "4671234768","payeeAlias": "1231181189","amount": "100","currency": "SEK","message": "Kingston USB Flash Drive 8 GB"}

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

Follow using RSS

<< MySQL to DB2

Comment

Name
Mail (Not public)
Send mail uppdates on new comments
24 comments
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 https://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 https://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å https://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 https://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 >>