Rendering the QR

Two ways to display a Scan to Pay code as a QR — use the platform's styled PNG endpoint, or render the code yourself.

Once you've created a code, you need to present it to the customer as a scannable QR. You have two options: let Scan to Pay render a branded PNG for you, or generate the QR yourself from the 10-digit code value.

The Scan to Pay-rendered PNG is the recommended path for most integrators — it's themed, scheme-compliant, and trivial to embed.


Option A — use the Scan to Pay PNG endpoint

A single GET request returns a PNG with Scan to Pay branding around your code.

GET https://qa.scantopay.io/pluto/public/{type}/{code}

Path parameters:

ParameterValuesDescription
typestpqr | qr | zimswitchThe QR style. stpqr is the Scan to Pay-branded template (recommended for SA). qr is plain. zimswitch is the Zimbabwe interoperable QR template.
codeThe 10-digit code returned by POST /code/createThe QR payload to encode

Query parameters (optional):

ParameterValuesDescription
colorCode0, 1, 2, 3Template colour. 0 = Orange (default), 1 = B&W, 2 = Grey, 3 = Black
plainany valueIf present, returns an unstyled QR with no template chrome — just the code encoded as a QR

Embed in HTML

The simplest usage is a plain <img> tag:

<img
  src="https://qa.scantopay.io/pluto/public/stpqr/0123456789"
  alt="Scan to Pay"
  width="200"
  height="200" />

With a black variant:

<img src="https://qa.scantopay.io/pluto/public/stpqr/0123456789?colorCode=3" />

With no template chrome (plain QR only):

<img src="https://qa.scantopay.io/pluto/public/stpqr/0123456789?plain=true" />

Endpoint is unauthenticated

The QR endpoint is under /public/** and requires no Basic Auth or JWT. That means you can embed the URL directly in HTML or send it to the customer's browser. The endpoint reveals nothing sensitive — anyone with the code value can already pay it.

Caching

The platform doesn't set aggressive cache headers on this response. The image is essentially deterministic for a given (type, code, colorCode, plain) tuple — you can safely cache the PNG on your own CDN if you serve many QRs.


Option B — render the QR yourself

If you'd rather generate the QR locally (offline rendering, terminal SDK, no network call to Scan to Pay), encode the 10-digit code as a Type-2 QR using any QR library. The payload is just the digits — there's no URL wrapper, no prefix.

Node.js (qrcode):

const QRCode = require('qrcode');
const code = '0123456789';

const pngBuffer = await QRCode.toBuffer(code, {
  errorCorrectionLevel: 'M',
  margin: 2,
  width: 300,
});

Python (qrcode):

import qrcode
img = qrcode.make('0123456789')
img.save('payment.png')

Java (zxing):

QRCodeWriter writer = new QRCodeWriter();
BitMatrix matrix = writer.encode("0123456789", BarcodeFormat.QR_CODE, 300, 300);
MatrixToImageWriter.writeToPath(matrix, "PNG", Paths.get("payment.png"));

You won't get the Scan to Pay branding this way, so if your design requires the standard scheme template, use Option A.


Sizing and print guidelines

UseRecommended sizeNotes
Mobile / web display200–300 px widePhone cameras handle this easily, even at modest screen brightness
POS terminal screen250–400 px wideLarger if customers stand at arm's length
Counter sticker / printed posterAt least 4 cm × 4 cm physicalPrint at 300 DPI or better; ensure clear quiet zone (white margin) around the QR
Outdoor signageAt least 10 cm × 10 cmMore if scanned from further than 30 cm; high contrast essential

Scan to Pay's stpqr template includes the right quiet zone automatically. If you render your own QR (Option B), allow ~4 modules of quiet zone around the code.


What's next