Standard NAPAS 247 & EMVCo QR Code Infrastructure for Vietnam Banking Ecosystem
TiαΊΏng Viα»t (Vietnamese) | Documentation (English) | OpenAPI Specification
VietQR Core SDK is an enterprise-grade, high-performance polyglot SDK suite and self-hosted Gateway service complying strictly with the Vietnamese National Standard NAPAS 247 and the international EMVCo QR Code Specification for Payment Systems.
Engineered for PaaS & SaaS architectures, it operates with 100% self-hosted local assets (zero external calls to 3rd-party CDNs), binds seamlessly to custom domains, and provides out-of-the-box native SDKs across 13 programming languages and major web frameworks (Laravel, Node.js Express/Next.js, Python FastAPI/Flask, Go, .NET).
| Feature | Description |
|---|---|
| Zero 3rd-Party Calls | 100% of bank logos (62+ banks), brand badges, and fonts are hosted locally. Zero external dependency on img.vietqr.io or cdn.vietqr.io. |
| Vector SVG Engine & PNG | High-precision SVG rendering (.svg) with embedded vector paths, crisp typography, and base64 bank logos. Seamlessly coexists with high-speed raster PNG (.png). |
| 7 Card Templates | compact2 (default), compact, qr_only, print, loax, vietqr_pro, and payos. Custom themes auto-map to compact2; unknown/casing mismatches fallback to compact. |
| Custom Domain & Flexible Routing | Full compatibility with /image/<BANK_ID>-<ACCOUNT_NO>-<TEMPLATE>.(svg|png), /image/<BANK_ID>-<ACCOUNT_NO>.(svg|png), and legacy routes /<BANK_ID>/<ACCOUNT_NO>/<AMOUNT>/<DESC>/<TEMPLATE>.<MEDIA>. |
| Smart Raster-to-SVG Redirect | REDIRECT_RASTER_TO_SVG=true automatically redirects desktop and non-mobile browsers to ultra-sharp .svg while preserving PNG for mobile WebView compatibility. |
| Ultra-Fast Gateway Engine | Built in Rust (Axum + Tokio). Capable of handling 50,000+ requests/sec with < 50MB RAM footprint. |
| Polyglot SDKs (55+ Languages) | Native client libraries across 55+ programming languages (Rust, Go, Node.js/TypeScript, PHP/Laravel, Python, C# .NET, Java, Kotlin, Swift, Ruby, Dart/Flutter, C, C++, Scala, Groovy, Clojure, Elixir, Erlang, Haskell, OCaml, F#, R, Julia, Lua, Perl, Zig, Nim, Crystal, D, Pascal, Fortran, V, Racket, Common Lisp, Scheme, Tcl, Ada, Prolog, Bash, PowerShell, Objective-C, Solidity, WASM, AWK, Haxe, VB.NET, Elm, PureScript, CoffeeScript, ReScript, Apex, ActionScript, Vyper, Ballerina, Smalltalk). |
| VNPay v2.1.0 Gateway | Official VNPay v2.1.0 HMAC-SHA512 checkout payment URL generator and IPN return validation. |
| Interactive Studio & QR Scanner | Drag-drop, paste, or upload QR images to extract account, bank, and amount via client-side jsQR and server-side /api/v1/decode. Real-time prefix search for banks. |
| 44+ Banking & Wallet Deeplinks | Direct URL schemes and Android intent URIs for 44+ Vietnamese mobile banking and wallet apps on iOS and Android. |
vietqr-core-sdk/
βββ assets/ # Local offline assets (Zero 3rd-party dependencies)
β βββ banks/ # 62+ Bank logos in high-res PNG (indexed by BIN & Code)
β βββ brand/ # VietQR, NAPAS, PTN badges
β βββ fonts/ # Roboto-Bold typography supporting Vietnamese diacritics
βββ data/
β βββ banks.json # Canonical NAPAS bank catalog
β βββ deeplinks.json # 44+ Mobile banking & wallet app URL schemes
βββ sdks/ # Multilingual SDK implementations
β βββ c/ # Pure C99 SDK (CMake, Shared/Static Library)
β βββ cpp/ # Modern C++17 Fluent SDK
β βββ rust/ # High-performance Rust crate
β βββ golang/ # Idiomatic Go package
β βββ nodejs/ # Node.js & TypeScript SDK
β βββ php/ # PHP 7.4 / 8.x Composer library
β βββ java/ # Java 11+ Maven library
β βββ python/ # Python 3.8+ package
β βββ dotnet/ # .NET Standard 2.0 / .NET 8 / .NET 9
β βββ dart/ # Dart & Flutter SDK
β βββ kotlin/ # Kotlin & Android SDK
β βββ swift/ # Swift & iOS SDK
β βββ ruby/ # Ruby gem
βββ server/ # Rust Axum Gateway Engine (PaaS / SaaS)
β βββ Cargo.toml
β βββ src/
β βββ main.rs # Gateway server entry point
β βββ config.rs # Domain, Port, Scheme, API Key loader
β βββ emvco.rs # EMVCo TLV encoder & CRC16 calculator
β βββ canvas.rs # Multi-template image renderer
β βββ banks.rs # In-memory bank catalog
β βββ deeplink.rs # In-memory deeplink scheme registry
β βββ pay_hub.rs # Interactive responsive Web Pay Hub
β βββ routes.rs # REST endpoints and QuickLink handler
β βββ ui/ # Web Studio and Pay Hub UI templates
βββ deploy/ # Production deployment configurations
β βββ docker/ # Multi-arch Dockerfile & Docker Compose
β βββ linux/ # Automated shell installer & Systemd service
β βββ reverse-proxy/ # Caddy & Nginx reverse proxy templates
βββ docs/ # Comprehensive Bilingual Documentation
β βββ vi/ # Vietnamese documentation (KiαΊΏn trΓΊc, CΓ i ΔαΊ·t, API, SDK)
β βββ en/ # English documentation (Architecture, Deployment, API, SDKs)
β βββ openapi.yaml # Complete OpenAPI 3.0.3 specification
βββ .github/workflows/ # Automated CI/CD workflows
βββ ci.yml # Automated tests across all 9 SDKs
βββ release-artifacts.yml # Cross-platform compilation for 10 OS/CPU targets
βββ docker-publish.yml # Multi-arch Docker build & push to GHCR
cd deploy/docker
cp .env.example .env
.env with your domain:
DOMAIN=qr.yourdomain.com
PORT=8080
SCHEME=https
ACME_EMAIL=admin@yourdomain.com
docker-compose -f docker-compose.prod.yml up -d
Caddy automatically requests and renews valid TLS certificates from Letβs Encrypt and proxies traffic to the Gateway!
Install on any Linux distribution (Ubuntu, Debian, CentOS, RHEL, Alpine):
sudo bash deploy/linux/install.sh --domain qr.yourdomain.com --scheme https
The installer automatically detects CPU architecture (x86_64, aarch64, armv7l), deploys local bank assets, and registers vietqr.service.
Manage the service:
sudo systemctl status vietqr
sudo journalctl -u vietqr -f
Embed crisp vector or high-speed raster QR codes directly into invoices, web apps, emails, and PDFs:
Modern SVG Vector Route:
<img src="https://qr.yourdomain.com/image/970422-0352350917-compact2.svg?amount=50000&addInfo=ORDER100&accountName=NGUYEN+VAN+A" alt="VietQR SVG" />
Short SVG Route (defaults to compact2):
<img src="https://qr.yourdomain.com/image/970422-0352350917.svg" alt="VietQR Default SVG" />
7 Official & Community Templates:
compact2 (Default standard card with bank header, account, and recipient)compact (Minimalist card)qr_only (Pure QR matrix without frame or text)print (High-contrast clean layout for POS thermal and A4/A5 printers)loax (Modern gradient badge with bank branding)vietqr_pro (Enterprise VietQR Pro gold/dark theme)payos (Modern tech-forward fintech styling)Note: Custom user themes auto-render as compact2. Unknown or casing mismatches gracefully fallback to compact.
Legacy API Route Compatibility:
<img src="https://qr.yourdomain.com/MB/0352350917/50000/ORDER100/compact2.svg" alt="Legacy VietQR Route" />
Smart Raster-to-SVG Redirect:
When REDIRECT_RASTER_TO_SVG=true is enabled, non-mobile desktop browsers requesting .png URLs are automatically redirected (HTTP 307) to the infinitely scalable .svg image, while mobile user agents (iOS/Android) continue receiving .png for optimal native rendering.
Directly build authenticated VNPay checkout URLs and verify return/IPN signatures using the updated VNPay v2.1.0 standard:
vnp_Amount = amount * 100)HashSecretRedirect customers on mobile or desktop to a clean, responsive payment hub:
https://qr.yourdomain.com/qr/pay?bin=970436&acc=1234567890&amount=100000&desc=ORDER100
When clicked on iOS or Android, it instantly launches the recipientβs bank app with account and amount pre-filled!
vietqr/core-sdk)Supports Laravel 8, 9, 10, 11+ with auto-discovery, configuration publishing, Facades, and Blade directives:
composer require vietqr/core-sdk
php artisan vendor:publish --tag=vietqr-config
use VietQR\Laravel\Facades\VietQR;
// Generate EMVCo QR code string
$qr = VietQR::generate(bank: 'MB', account: '0352350917', amount: 50000, memo: 'DON HANG #123');
// Generate visual QuickLink image URL on private Gateway
$imageUrl = VietQR::quicklink(bank: 'MB', account: '0352350917', amount: 50000, template: 'compact2');
// Generate 44+ mobile banking app deeplinks
$deeplinks = VietQR::deeplink('MB', '0352350917', 50000, 'DON HANG #123')->getAll();
In Blade views:
<img src="@vietqr('MB', '0352350917', 50000, 'INV123')" alt="VietQR Payment" />
@vietqr/core-sdk)npm install @vietqr/core-sdk
Express.js:
import express from 'express';
import { createVietQRExpressHandler } from '@vietqr/core-sdk';
const app = express();
app.use('/api/vietqr', createVietQRExpressHandler({
defaultBank: '970422',
defaultAccount: '0352350917',
gatewayUrl: 'https://qr.yourdomain.com'
}));
Next.js (App Router):
// app/api/vietqr/route.ts
import { createVietQRNextHandler } from '@vietqr/core-sdk';
export const { GET, POST } = createVietQRNextHandler({
defaultBank: process.env.VIETQR_DEFAULT_BANK || '970422',
defaultAccount: process.env.VIETQR_DEFAULT_ACCOUNT,
gatewayUrl: process.env.VIETQR_GATEWAY_URL,
});
vietqr-core)pip install vietqr-core
Command Line Interface (CLI):
vietqr generate --bank MB --account 0352350917 --amount 50000 --memo "Don hang"
vietqr verify "00020101021238540010A00000072701240006970422..."
vietqr quicklink --bank VCB --account 0011002233 --amount 100000
vietqr banks --query MB
FastAPI Integration:
from fastapi import FastAPI
from vietqr.integrations.fastapi import get_vietqr_router
app = FastAPI()
app.include_router(get_vietqr_router(
default_bank="970422",
default_account="0352350917",
gateway_url="https://qr.yourdomain.com"
))
net/http, Gin, Fiber)import "github.com/vietqr/vietqr-go"
// Mount standard HTTP handler
http.Handle("/vietqr/", vietqr.NewHTTPHandler(vietqr.HandlerOptions{
DefaultBank: "970422",
DefaultAccount: "0352350917",
GatewayURL: "https://qr.yourdomain.com",
}))
using VietQR.Core;
// Register in ServiceCollection
builder.Services.AddSingleton<IVietQRService>(new VietQRService(new VietQROptions {
DefaultBank = "970422",
DefaultAccount = "0352350917",
GatewayUrl = "https://qr.yourdomain.com"
}));
use vietqr::{EMVCoBuilder, QuickLink};
let qr = EMVCoBuilder::new("970436", "1234567890")
.amount(100_000)
.memo("Order 101")
.account_name("NGUYEN VAN A")
.build();
let img_link = QuickLink::new("970436", "1234567890")
.domain("qr.yourdomain.com")
.amount(100_000)
.template("compact2")
.build();
qr, _ := vietqr.New("970436", "1234567890").
WithAmount(100000).
WithMemo("Order 101").
WithAccountName("NGUYEN VAN A").
Build()
import { VietQR, QuickLink } from 'vietqr-core-sdk';
const qr = new VietQR('970436', '1234567890')
.setAmount(100000)
.setMemo('Order 101')
.setAccountName('NGUYEN VAN A')
.build();
use VietQR\VietQR;
$qr = (new VietQR('970436', '1234567890'))
->setAmount(100000)
->setMemo('Order 101')
->setAccountName('NGUYEN VAN A')
->build();
from vietqr import VietQR
qr = (VietQR("970436", "1234567890")
.set_amount(100000)
.set_memo("Order 101")
.set_account_name("NGUYEN VAN A")
.build())
using VietQR.Core;
var qr = new VietQRBuilder("970436", "1234567890")
.WithAmount(100000)
.WithMemo("Order 101")
.WithAccountName("NGUYEN VAN A")
.Build();
| π Architecture: English | TiαΊΏng Viα»t |
| π Deployment & Domain Setup: English | TiαΊΏng Viα»t |
| π‘ REST API & QuickLink Reference: English | TiαΊΏng Viα»t |
| π¦ SDK Integration Guides (9 Languages): English | TiαΊΏng Viα»t |
docs/openapi.yamlThis project is licensed under the MIT License. Maintained by the VietQR Core SDK Community.