THE VIETQR REFERENCE
API Reference
Start with the core for payloads, or jump to the component props for your framework. Looking for a first example? Read the integration guide.
@viet-qr/core
API documentation for the core library (Vanilla JS / TypeScript).
generateVietQR(options)
The main function to generate the EMVCo payload string.
| Property | Type | Required | Description |
|---|---|---|---|
bankId | string | Yes | Bank BIN (e.g. 970436) or Short Name (e.g. VCB). |
accountNo | string | Yes | Account number (max 50 chars). |
accountName | string | Optional | Account holder name (Recommended). |
amount | number | Optional | Payment amount. If omitted, generates a Static QR. |
content | string | Optional | Payment description. |
isCard | boolean | Optional | Transfer via Card Number instead of Account Number. Defaults to false. |
parseVietQR(qrString)
Parses a standard VietQR string into a structured object and validates its integrity (CRC checksum, format).
| Return Field | Type | Always present | Description |
|---|---|---|---|
isValid | boolean | Yes | True if the QR string is valid and checksum matches. |
isDynamic | boolean | Yes | True if the QR contains a specific amount. |
isCard | boolean | Optional | True if payment is via Card Number (QRIBFTTC). |
beneficiary | object | Optional | Contains bankBin, accountNo, and accountName. |
transaction | object | Optional | Contains amount and content. |
errorMessage | string | Optional | Reason for failure if isValid is false. |
Utility Functions
getBankByBin(bin: string): Returns bank info by BIN.getBankByCode(code: string): Returns bank info by bank code (e.g. VCB, TCB).getBankByName(name: string): Returns bank info by short name (e.g. Vietcombank).sanitizeAccountName(name: string): Removes accents and special characters, returning uppercase text.removeVietnameseAccents(str: string): Removes Vietnamese accents from a string.fetchBankList(url: string): Fetches bank list from an API or CDN.setBankList(banks: Bank[]): Manually inject a bank list into the library.
fetchBankList accepts either a bare Bank[] JSON array, or an object with a .data array (vietqr.io's own API shape). Either way, each bank record must use snake_case keys on the wire — full_name, swift_code — matching vietqr.io's API; the library maps them to camelCase (fullName, swiftCode) internally.
@viet-qr/react
The React wrapper for generating QR codes.
import { VietQR, VietQRButton, useVietQR } from '@viet-qr/react';
export default function App() {
return (
<>
<VietQR bankId="VCB" accountNo="112233" amount={50000} />
<VietQRButton bankId="VCB" accountNo="112233" label="Thanh toán" />
</>
);
}@viet-qr/vue
The Vue wrapper for generating QR codes.
<script setup>
import { VietQR, VietQRButton, useVietQR } from '@viet-qr/vue';
import '@viet-qr/vue/style.css'; // Cho VietQRButton
</script>
<template>
<VietQR bankId="VCB" accountNo="112233" :amount="50000" />
<VietQRButton bankId="VCB" accountNo="112233" label="Thanh toán" />
</template>@viet-qr/svelte
The Svelte wrapper for generating QR codes.
<script>
import { VietQR, VietQRButton, useVietQR } from '@viet-qr/svelte';
</script>
<VietQR bankId="VCB" accountNo="112233" amount={50000} />
<VietQRButton bankId="VCB" accountNo="112233" label="Thanh toán" />@viet-qr/templates
Pre-built beautiful UI templates for your QR codes.
Available for React, Vue, Svelte, and Vanilla JS (Web Components). All templates accept the exact same props as the base <VietQR /> component.
// React
import { CompactCard, PayStandee } from '@viet-qr/templates/react';
// Vue
import { CompactCard, PayStandee } from '@viet-qr/templates/vue';
// Svelte
import { CompactCard, PayStandee } from '@viet-qr/templates/svelte';<!-- Vanilla JS / HTML -->
<script src="https://unpkg.com/@viet-qr/templates/dist/elements/index.global.js"></script>
<link rel="stylesheet" href="https://unpkg.com/@viet-qr/templates/dist/styles.css" />
<!-- Basic QR, no card wrapper -->
<viet-qr-basic bank-id="VCB" account-no="112233"></viet-qr-basic>
<!-- Pre-built templates -->
<viet-qr-compact bank-id="VCB" account-no="112233" theme="dark"></viet-qr-compact>
<viet-qr-standee bank-id="VCB" account-no="112233" is-card="true"></viet-qr-standee>
<!-- Button Modal Web Component -->
<viet-qr-button bank-id="VCB" account-no="112233" label="Thanh toán" theme="dark"></viet-qr-button>Vanilla attributes are kebab-case (bank-id, account-no, is-card, ...). is-card is a string "true"/"false", not presence-based.
Unlike @viet-qr/react/vue/svelte (compiled bundles), @viet-qr/templates's Svelte components ship as raw .svelte/.ts source under src/svelte — your own build tool compiles them. Svelte 4 projects need extra Vite config (see the Docs page's "Note for Svelte 4 users").
UI Components Props
React, Vue, and Svelte share the same core props. A few extras only exist on some frameworks — called out explicitly below instead of glossed over.
<VietQR />
Inherits every field from `VietQROptions` above (`bankId`, `accountNo`, `accountName`, `amount`, `content`, `isCard`), plus:
| Property | Type | Default | Description |
|---|---|---|---|
renderAs | 'svg' | 'canvas' | 'svg' | Rendering mode. |
size | number | 256 | Width & height in pixels. |
level | 'L' | 'M' | 'Q' | 'H' | 'Q' | Error-correction level. Use 'Q' or 'H' if overlaying a logo via imageSettings. |
imageSettings | ImageSettings | - | Settings to overlay a logo in the center of the QR. |
Framework-specific extras (not available everywhere):
| Property | Type | Frameworks | Description |
|---|---|---|---|
className | string | React, Vue, Svelte | CSS class for the wrapper. |
style | CSSProperties / StyleValue / string | React, Vue, Svelte | Inline styles. |
bgColor / fgColor | string | React, Vue, Svelte | Background / dot color. Default white / black. |
includeMargin | boolean | React, Vue, Svelte | Adds a four-module quiet zone around the QR. Default true. |
ImageSettings Object
Used for configuring the center logo overlay:
type ImageSettings = {
src: string; // URL or base64 of the logo image
width: number; // Width of the logo in pixels
height: number; // Height of the logo in pixels
x?: number; // pixels
y?: number; // pixels
crossOrigin?: 'anonymous' | 'use-credentials' | ''; // canvas export / CORS
excavate?: boolean; // Clear the QR modules behind the logo (default: false)
};CompactCard & PayStandee
React/Vue/Svelte templates inherit the QR props above. Vanilla equivalents expose the smaller kebab-case attribute API shown in the Vanilla guide. Templates add:
| Property | Type | Default | Description |
|---|---|---|---|
theme | 'light' | 'dark' | 'light' | Color theme of the card. |
locale | 'vi' | 'en' | 'vi' | Template UI language and VND formatting; does not change payment data. |
messages | Partial<VietQRMessages> | - | Override individual labels. Explicit title/subtitle props take priority. |
bankLogo | string | - | CompactCard only. Logo URL shown instead of the bank name. |
title / subtitle | string | - | PayStandee only. Banner heading text. |
The bank display name (when no bankLogo is given) is auto-resolved from bankId via getBankByBin/getBankByCode — no need to pass it separately.
<VietQRButton />
Inherits `VietQROptions` (`bankId`, `accountNo`, `accountName`, `amount`, `content`, `isCard`) — not the `<VietQR />`-specific props above — plus:
| Property | Type | Default | Description |
|---|---|---|---|
label | string | 'Thanh toán VietQR' | Overrides the translated pay label, including an empty string. |
locale | 'vi' | 'en' | 'vi' | Button/dialog language and VND formatting. |
messages | Partial<VietQRMessages> | — | Override pay, title and close labels; updates open dialogs. |
size | number | 260 | QR size (pixels) inside the modal. |
variant | 'default' | 'outline' | 'ghost' | 'default' | Button visual style. |
theme | 'light' | 'dark' | 'light' | Color theme of the popup modal only — not the trigger button. |
Open/close callbacks use each framework's own idiom, not a shared prop name: React — onOpen/onClose props; Vue — @open/@close emits; Svelte — on:open/on:close dispatched events.
useVietQR
A reactive alternative to <VietQR /> for building fully custom UI. Same concept in all three frameworks, but the signature is not identical — read the code sample for your framework carefully.
React
Takes a plain `VietQROptions` object, returns a plain object memoized with `useMemo`.
import { useVietQR } from '@viet-qr/react';
function MyCustomQR() {
const { payload, isValid, error } = useVietQR({
bankId: 'VCB',
accountNo: '112233',
amount: 50000,
});
if (!isValid) return <p>{error}</p>;
return <MyOwnQRRenderer value={payload} />;
}Vue
Takes a plain object *or* a `ComputedRef<VietQROptions>`; returns `{ payload, isValid, error }` where each field is itself a `ComputedRef`.
<script setup>
import { useVietQR } from '@viet-qr/vue';
const { payload, isValid, error } = useVietQR({
bankId: 'VCB',
accountNo: '112233',
amount: 50000,
});
</script>
<template>
<p v-if="!isValid">{{ error }}</p>
<MyOwnQRRenderer v-else :value="payload" />
</template>Svelte
Different shape on purpose: it takes a Svelte Readable store, not a plain object — wrap your options in writable() first. Returns a Readable you subscribe to with $.
<script>
import { writable } from 'svelte/store';
import { useVietQR } from '@viet-qr/svelte';
const options = writable({ bankId: 'VCB', accountNo: '112233', amount: 50000 });
const qr = useVietQR(options);
</script>
{#if !$qr.isValid}
<p>{$qr.error}</p>
{:else}
<MyOwnQRRenderer value={$qr.payload} />
{/if}Export / Download QR
React, Vue and Svelte VietQR component refs expose exportQR(options) → Promise<Blob> and downloadQR(options) → Promise<void>. All four Web Components expose the same methods.
All adapters and template entry points also export DOM helpers. SVG rendering exports SVG or PNG; canvas exports PNG. Files include the QR and its embedded logo, not the surrounding card text. Remote logos need CORS; handle rejected promises.
import { downloadQR } from '@viet-qr/templates/react'; // /vue, /svelte, /elements
await downloadQR(document.querySelector('.vqr-compact-card__qr-wrapper'), {
format: 'png', filename: 'payment',
});Web Component translations: set locale="en" and assign element.messages = { accountNumber: "Recipient account" }. Framework templates and VietQRButton use locale and messages props; explicit button labels override translations.