Generate QR codes for Swish payments

Using the Swish API with php-curl running in Docker

Sample PHP Code

This code can be run on any modern web server with PHP and curl support.

$title="Title of the payment"
$amount="Money to be transferred"
$url="https://mpc.getswish.net/qrg-swish/api/v1/prefilled";
$payload='{"format":"png","size":300,"message":{"value":"'
    .$title.
    '","editable":false},"amount":{"value":'
    .$amount.
    ',"editable":false},"payee":{"value":"123456789","editable":true}}';
$ch = curl_init( $url );
curl_setopt( $ch, CURLOPT_POSTFIELDS, $payload );
curl_setopt( $ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json'));
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
$result = curl_exec($ch);
curl_close($ch);

Output with <img> tag

<?php echo "<img src='data:image/png;base64," . base64_encode( $result )."'>"; ?>

Full sample using Bootstrap 4

I prefer to run this kind of application as a Microservice with Docker or Podman, this example is using Docker.

Create a folder and a few files to get started

# mkdir swish-qr
# cd swish-qr

Create a Dockerfile

# vim Dockerfile
FROM php:8.1.1-apache
COPY index.php /var/www/html

Create a shell script to deploy the container

# vim go.sh
#!/bin/bash

_name="swish-qr"
_port="8080"

if [[ "$1" != "up" && "$1" != "down" ]]
then
        echo "Syntax $0 up/down"
        exit 1
fi

[[ "$1" == "up" ]]   && docker run --rm --publish ${_port}:80 --name ${_name} --detach $(docker build -q .)
[[ "$1" == "down" ]] && docker stop ${_name}

And a simple HTML form which will fetch the QR-code using cURL

Do not use in production without sanitizing the input!

# vim index.php
<?php
if( isset($_POST['title']) && isset($_POST['amount']) )
{
	$url="https://mpc.getswish.net/qrg-swish/api/v1/prefilled";
	$payload='{"format":"png","size":300,"message":{"value":"'
		.$_POST['title'].
		'","editable":false},"amount":{"value":'
		.$_POST['amount'].
		',"editable":false},"payee":{"value":"123456789","editable":true}}';

	$ch = curl_init( $url );
	curl_setopt( $ch, CURLOPT_POSTFIELDS, $payload );
	curl_setopt( $ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json'));
	curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
	$result = curl_exec($ch);
	curl_close($ch);
}
?><!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
    <title>Swish QR</title>
  </head>
  <body>

<div class="container">

			<?php if (!isset($result)) : ?>

					<div class="row justify-content-md-center mt-5">
						<div class="col-md-4">
		
							<form method=post>
								<div class="form-group">
									<label for="title">Benämning</label>
									<input name="title" type="text" class="form-control" id="title" aria-describedby="title" placeholder="Benämning..." value="<?php echo isset($_POST['title']) ? $_POST['title'] : ""; ?>" required>
									<small id="emailHelp" class="form-text text-muted">Ordernummer eller beskrivning</small>
								</div>
								<div class="form-group">
									<label for="amount">Pris</label>
									<input name="amount" type="number" class="form-control" id="amount" aria-describedby="amount" placeholder="Summa..." value="<?php echo isset($_POST['amount']) ? $_POST['amount'] : ""; ?>" required>
									<small id="emailHelp" class="form-text text-muted">Pris i SEK, inkl moms</small>
								</div>
								<button type="submit" class="btn btn-primary">Swish QR-Kod</button>
							</form>
						</div>
					</div>

			<?php else : ?>

				<div class="row justify-content-md-center mt-5">
								<div class="col-md-4 text-align-center">
												<div class="card">
																<h5 class="card-header text-center">
																				<strong><?php echo $_POST['title']; ?></strong>
																</h5>
																<div class="card-body">
																				<?php echo "<img src='data:image/png;base64," . base64_encode( $result )."'>"; ?>
																				<br>
																</div>
																<h3 class="card-footer bg-white text-center">
																				<?php echo $_POST['amount']; ?>kr <small>exkl moms.</small>
																</h3>
												</div>
												<a href="/" class="btn btn-light mt-3">Tillbaka</a>
								</div>
				</div>

			<?php endif; ?>

</div>

    <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
  </body>
</html>