4vplacek/qr-payment 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

4vplacek/qr-payment

Composer 安装命令:

composer require 4vplacek/qr-payment

包简介

Multiformátový generátor platebních QR kódů pro CZ (SPAYD), SK (Payment Link / Payme v2) a EU/SEPA (EPC QR / GiroCode).

README 文档

README

Multiformátový generátor platebních QR kódů nad jedním sdíleným datovým modelem.

Formát Region Výstup Standard
SPAYD 🇨🇿 ČR SPD*1.0*... Czech Banking Association
Payment Link (Payme v2) 🇸🇰 SK https://payme.sk/2/... SBA Payment Link Standard 2.0
EPC QR (GiroCode) 🇪🇺 EU/SEPA BCD\n002\n... EPC069-12
  • QR kód dle ISO/IEC 18004, error correction level M (15 %)
  • ASCII normalizace jmen/zpráv (odstranění diakritiky)
  • Žádné zaokrouhlování částek — vstup jako string nebo int (centy), nikdy float
  • Okamžitá platba u CZ QR ve výchozím stavu (SPAYD PT:IP)

Instalace

composer require 4vplacek/qr-payment

Vyžaduje PHP ≥ 8.1 a rozšíření mbstring, intl, gd.

Použití

use Vplacek\QrPayment\PaymentData;
use Vplacek\QrPayment\Serializer\SpaydSerializer;
use Vplacek\QrPayment\Serializer\PaymentLinkSerializer;
use Vplacek\QrPayment\Serializer\EpcQrSerializer;
use Vplacek\QrPayment\Qr\QrRenderer;
use Vplacek\QrPayment\Qr\QrLabelOutput;

$payment = (new PaymentData())
    ->setIban('CZ6508000000192000145399')
    ->setAmount('250.00')          // string nebo int (centy) — NIKDY float
    ->setCurrency('CZK')
    ->setVariableSymbol('123456')
    ->setRecipientName('Petr Novák')
    ->setMessage('Faktura 2026/001');

CZ — SPAYD

echo (new SpaydSerializer())->serialize($payment);
// SPD*1.0*ACC:CZ6508000000192000145399*AM:250.00*CC:CZK*MSG:FAKTURA 2026/001*PT:IP*RN:PETR NOVAK*X-VS:123456
// PT:IP = okamžitá platba (viz níže), přidává se automaticky

file_put_contents('qr.png', QrRenderer::fromSpayd($payment)->png());
echo QrRenderer::fromSpayd($payment)->svg();

// Brandovaný SVG: rámeček + nápis „QR platba" (oficiální branding ČBA)
use Vplacek\QrPayment\Qr\BrandedSvgOutput;
use Vplacek\QrPayment\Serializer\SpaydSerializer;

$svg = BrandedSvgOutput::qrPlatba((new SpaydSerializer())->serialize($payment))->svg();

SK — Payment Link / Payme v2

Vyžaduje měnu EUR a jméno příjemce. type určuje povinnost ostatních polí (p = P2P, m = POI dynamic, e = e-commerce, q = POI static/donation).

$sk = (new PaymentData())
    ->setIban('SK3112000000198742637541')
    ->setAmount('99.90')
    ->setCurrency('EUR')
    ->setVariableSymbol('1234567890')
    ->setRecipientName('Janko Hraško');

echo (new PaymentLinkSerializer(PaymentLinkSerializer::TYPE_P2P))->serialize($sk);
// https://payme.sk/2/p/PME?IBAN=SK...&CN=Janko+Hrasko&AM=99.90&CC=EUR&PI=%2FVS1234567890

// Brandovaný SVG s Payme logem pod QR kódem
$svg = BrandedSvgOutput::payme((new PaymentLinkSerializer())->serialize($sk))->svg();

EU/SEPA — EPC QR / GiroCode

Vyžaduje měnu EUR a jméno příjemce. Payload je omezen na 331 bytů.

$eu = (new PaymentData())
    ->setIban('DE71110220330123456789')
    ->setBic('BHBLDEHHXXX')
    ->setAmount('12.50')
    ->setCurrency('EUR')
    ->setRecipientName('Franz Mustermann')
    ->setMessage('Rechnung 123');

echo (new EpcQrSerializer())->serialize($eu);

// EPC/GiroCode nemá vlastní branding — holý QR
$svg = BrandedSvgOutput::plain((new EpcQrSerializer())->serialize($eu))->svg();

Datový model

Vlastnost SPAYD Payment Link EPC QR
setIban() ACC IBAN řádek 7
setBic() ACC+BIC řádek 5
setAmount() AM AM řádek 8 (EUR12.50)
setCurrency() CC jen EUR jen EUR
setRecipientName() RN (35) CN (70) řádek 6 (70)
setMessage() MSG (60) MSG (140) řádek 10 (140)
setVariableSymbol() X-VS PI=/VS
setSpecificSymbol() X-SS PI=/SS
setConstantSymbol() X-KS PI=/KS
setPaymentReference() RF PI řádek 10 (strukturovaná)
setInstantPayment() PT:IP
setPaymentType() PT
setPurpose() řádek 9 (SEPA purpose)
setDueDate() DT DT (jen p)

Okamžitá platba (CZ)

Okamžitá platba (SPAYD PT:IP) je zapnutá ve výchozím stavu — dnes je běžnější než zadávat datum splatnosti. Banka ji provede, pokud to umožňuje. Ovlivňuje pouze SPAYD; Payment Link ani EPC takové pole nemají.

$payment->setInstantPayment(false);     // klasická (neokamžitá) úhrada
$payment->setPaymentType('STD');        // ruční přepis pole PT (přebije default)

Částky a zaokrouhlování

setAmount() přijímá string ('250.00') nebo int v centech (25000). Float se vědomě nepřijímá — knihovna nikdy nezaokrouhluje. Více než 2 desetinná místa vyhodí InvalidPaymentDataException.

Validace IBAN

Defaultně zapnutá (formát + mod-97 checksum). Vypnutí pro hraniční případy:

$payment->setValidateIban(false)->setIban('...');

Nette / Latte

V presenteru předáme do šablony surová data QR kódu:

public function renderDetail(): void
{
    $payment = (new PaymentData())
        ->setIban('CZ6508000000192000145399')
        ->setAmount('250.00')
        ->setVariableSymbol('123456')
        ->setRecipientName('Petr Novák');

    // PNG binárka pro filtr |dataStream
    $this->template->qrPng = QrRenderer::fromSpayd($payment)->png();

    // nebo rovnou inline SVG s brandingem „QR platba"
    $this->template->qrSvg = BrandedSvgOutput::qrPlatba(
        (new SpaydSerializer())->serialize($payment),
    )->svg();
}

V šabloně Latte:

{* PNG přes vestavěný filtr |dataStream → data:image/png;base64,... *}
<img src="{$qrPng|dataStream}" alt="QR platba">

{* Inline SVG (vektor) — vykreslí se přímo do stránky *}
<div class="qr">{$qrSvg|noescape}</div>

Filtr dataStream zakóduje binární data do data: URI (MIME se detekuje automaticky, případně {$qrPng|dataStream:'image/png'}). Alternativně lze v presenteru rovnou předat hotové data: URI metodami knihovny ->pngDataUri() / ->svgDataUri():

$this->template->qrUri = QrRenderer::fromSpayd($payment)->pngDataUri();
<img src="{$qrUri}" alt="QR platba">

Vývoj

composer install
composer test       # PHPUnit
composer phpstan    # PHPStan level max

Branding

BrandedSvgOutput vykresluje QR jako vlastní SVG (vektor) s brandingem dle formátu:

Preset Formát Vzhled
qrPlatba() CZ tenká černá čára kolem quiet zone + „QR platba" (Arial Bold) — dle grafického manuálu ČBA
payme() SK vložené Payme logo pod QR kódem
plain() EU/ostatní holý QR bez brandingu

Pro PNG popisek bez vektoru je k dispozici QrLabelOutput (vestavěný GD font, volitelně TTF jako DejaVu Sans / Liberation Sans → nulové licenční riziko fontu).

Payme logo

resources/payme-logo.svg je ochranná známka provozovatele standardu Payme (payme.sk / Slovenská banková asociácia). Je přibaleno výhradně pro označení QR kódu příslušným platebním standardem; práva náleží jeho vlastníkovi.

Licence

MIT

统计信息

  • 总下载量: 0
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 2
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-06-27

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固