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:
| Parameter | Values | Description |
|---|---|---|
type | stpqr | qr | zimswitch | The QR style. stpqr is the Scan to Pay-branded template (recommended for SA). qr is plain. zimswitch is the Zimbabwe interoperable QR template. |
code | The 10-digit code returned by POST /code/create | The QR payload to encode |
Query parameters (optional):
| Parameter | Values | Description |
|---|---|---|
colorCode | 0, 1, 2, 3 | Template colour. 0 = Orange (default), 1 = B&W, 2 = Grey, 3 = Black |
plain | any value | If 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
| Use | Recommended size | Notes |
|---|---|---|
| Mobile / web display | 200–300 px wide | Phone cameras handle this easily, even at modest screen brightness |
| POS terminal screen | 250–400 px wide | Larger if customers stand at arm's length |
| Counter sticker / printed poster | At least 4 cm × 4 cm physical | Print at 300 DPI or better; ensure clear quiet zone (white margin) around the QR |
| Outdoor signage | At least 10 cm × 10 cm | More 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
- Choose your QR pattern → Static QR, Dynamic QR
- Update or invalidate a code after rendering → Managing QR codes
- Print scheme branding requirements → Going live
- What happens when the customer scans → Webhooks
Updated 4 days ago
