Pay by Square QR kód v Node.js cez REST API

Návod ako generovať Pay by Square QR kódy v Node.js pomocou REST API. Fetch API aj axios príklady, PNG výstup za pár riadkov.

Úvod

Node.js 18+ priniesol natívne fetch() — to znamená, že na volanie REST API nepotrebujete ani node-fetch, ani axios, ani žiadnu inú závislosť. V tomto článku ukážeme dva spôsoby generovania Pay by Square QR kódov v Node.js — cez natívny fetch() a cez axios — plus ako integrovať oba v Express.js routerom alebo Next.js API route.

Všetky príklady sú otestované proti reálnemu Easy Square API. Na konci každého príkladu nájdete Dockerfile na spustenie bez lokálnej Node.js inštalácie.


Čo budete potrebovať

  • Node.js 18+ pre natívne fetch() (alebo staršie s node-fetch/axios)
  • API kľúč z easy-square.sk/registracia/ — kredit plán od 0,003 € bez DPH za QR kód
  • (voliteľne) axios pre projekty ktoré ho už používajú
  • (voliteľne) Docker pre spustenie bez lokálnej Node.js inštalácie

Základná integrácia — natívny fetch (Node 18+)

Uložte nasledujúci súbor ako example.mjs:

import { writeFile } from 'node:fs/promises';

const apiUrl = 'https://api.easy-square.sk/api/v1/pay-by-square/qr-code';

const payload = {
  beneficiaryName: 'Firma s.r.o.',
  iban: 'SK3112000000198742637541',
  amount: 42.50,
  variableSymbol: '2026001',
};

const res = await fetch(apiUrl, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-Api-Email': process.env.ES_API_EMAIL,
    'X-Api-Key': process.env.ES_API_KEY,
  },
  body: JSON.stringify(payload),
});

if (!res.ok) {
  console.error(`HTTP ${res.status}: ${await res.text()}`);
  process.exit(1);
}

const buffer = Buffer.from(await res.arrayBuffer());
await writeFile('qr.png', buffer);
console.log(`QR kód uložený: qr.png (${buffer.length} bajtov)`);

Spustenie:

ES_API_EMAIL=vas@email.sk \
ES_API_KEY=esq_vas_kluc \
node example.mjs

Spustenie cez Docker — bez inštalácie Node.js

Pridajte Dockerfile vedľa example.mjs:

FROM node:20-alpine
WORKDIR /app
COPY example.mjs .
CMD ["node", "example.mjs"]

Build a run:

docker build -t es-node .
docker run --rm \
  -e ES_API_EMAIL=vas@email.sk \
  -e ES_API_KEY=esq_vas_kluc \
  -v $(pwd):/app/out \
  es-node

Upravte cestu v writeFile na /app/out/qr.png, aby sa súbor objavil v priečinku, z ktorého ste spustili docker run.


Integrácia cez axios

Pre projekty, ktoré už majú axios, sa pokojne vydajte známou cestou. Vytvorte example-axios.mjs:

import { writeFile } from 'node:fs/promises';
import axios from 'axios';

const response = await axios.post(
  'https://api.easy-square.sk/api/v1/pay-by-square/qr-code',
  {
    beneficiaryName: 'Firma s.r.o.',
    iban: 'SK3112000000198742637541',
    amount: 42.50,
    variableSymbol: '2026001',
  },
  {
    headers: {
      'X-Api-Email': process.env.ES_API_EMAIL,
      'X-Api-Key': process.env.ES_API_KEY,
    },
    responseType: 'arraybuffer',
  }
);

await writeFile('qr.png', Buffer.from(response.data));
console.log(`QR kód uložený: qr.png`);

Kľúčový detail — responseType: 'arraybuffer'. Bez neho axios pokúsi odpoveď parsovať ako JSON a skončíte s poškodenými bajtmi.

Docker variant s axiosom

FROM node:20-alpine
WORKDIR /app
RUN npm install axios --silent
COPY example-axios.mjs .
CMD ["node", "example-axios.mjs"]

Build a run rovnako ako pri fetch variante.


Použitie v Express.js endpointe

V skutočnej aplikácii budete chcieť generovať QR kódy cez vlastný HTTP endpoint. Takto vyzerá minimálny Express server:

import express from 'express';

const app = express();
app.use(express.json());

app.post('/api/generate-qr', async (req, res) => {
  const { iban, amount, variableSymbol, beneficiaryName } = req.body;

  const apiRes = await fetch(
    'https://api.easy-square.sk/api/v1/pay-by-square/qr-code',
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-Api-Email': process.env.ES_API_EMAIL,
        'X-Api-Key': process.env.ES_API_KEY,
      },
      body: JSON.stringify({ iban, amount, variableSymbol, beneficiaryName }),
    }
  );

  if (!apiRes.ok) {
    return res.status(apiRes.status).json({ error: await apiRes.text() });
  }

  res.set('Content-Type', 'image/png');
  res.send(Buffer.from(await apiRes.arrayBuffer()));
});

app.listen(3000, () => console.log('Server beží na porte 3000'));

Dôležité — API kľúč držte len na serveri, nikdy ho neposielajte klientovi. Frontend volá vaš vlastný endpoint (/api/generate-qr), ten potom volá Easy Square.


Použitie v Next.js / Nuxt.js

V Next.js použite API route (app/api/generate-qr/route.js):

export async function POST(request) {
  const body = await request.json();

  const apiRes = await fetch(
    'https://api.easy-square.sk/api/v1/pay-by-square/qr-code',
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-Api-Email': process.env.ES_API_EMAIL,
        'X-Api-Key': process.env.ES_API_KEY,
      },
      body: JSON.stringify(body),
    }
  );

  return new Response(await apiRes.arrayBuffer(), {
    status: apiRes.ok ? 200 : apiRes.status,
    headers: { 'Content-Type': 'image/png' },
  });
}

V Nuxt.js ekvivalent je server/api/generate-qr.post.js — rovnaká logika, iné API.

V oboch prípadoch umiestnite API kľúč do .env.local (nikdy do NEXT_PUBLIC_ premenných) — inak skončí v bundle pre prehliadač.

Ak potrebujete QR kód vracať ako inline dáta do React/Vue komponentu, zabaľte výstup do base64 a pošlite ako JSON. Frontend ho potom renderuje cez <img src="data:image/png;base64,...">. Tento vzor sa hodí aj pre SSR faktúry, kde nechcete závisieť od externých URL súborov.


Časté chyby a riešenia

Poškodený PNG pri použití axios

Nezabudnite na responseType: 'arraybuffer'. Bez neho axios vráti reťazec, v ktorom sú binárne bajty prepísané na UTF-8 a PNG sa stane neopravným.

fetch is not defined v staršom Node.js

Potrebujete Node.js 18 alebo novší. V starších verziách použite node-fetch alebo axios.

HTTP 401 — Neautorizovaný

Skontrolujte oba headery X-Api-Email a X-Api-Key. Kľúč začína prefixom esq_ a musí zodpovedať registrovanému emailu.

HTTP 429 — Rate limit

Free generátor na hlavnej stránke povoľuje 100 QR kódov denne (bez registrácie, bez API kľúča). API s vlastným kľúčom vyžaduje kredit plán — 0,003 € bez DPH za QR kód bez denného limitu.

Buffer vs. Stream pre veľký objem

Ak generujete stovky QR kódov naraz (napr. nočný dávkový import faktúr), pozor na pamäť — každý PNG má ~12 kB a pri 1000 volaniach naraz to v RAM narastie. Odporúčame generovať v menších dávkach (napr. cez p-limit s limitom 10 paralelných volaní).

API kľúč v klientskom JS

Bezpečnostné riziko — volanie priamo z prehliadača odhalí kľúč v Network tabe. Riešenie: proxy cez vlastný backend, tak ako v Express.js / Next.js príklade vyššie.


Záver

Node.js integrácia Pay by Square cez Easy Square REST API je rýchla — natívny fetch() v Node 18+ odstránil potrebu externých závislostí úplne. Pre existujúce axios projekty stačí jedno POST volanie s responseType: 'arraybuffer'.

Pre PHP stack nájdete rovnocenný návod v článku Pay by Square QR kód v PHP cez REST API. Zoznam všetkých parametrov (farby, logo, rámček, veľkosť) nájdete v REST API dokumentácii. Pre registráciu navštívte easy-square.sk/registracia/.