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.

PropertyTypeRequiredDescription
bankIdstringYesBank BIN (e.g. 970436) or Short Name (e.g. VCB).
accountNostringYesAccount number (max 50 chars).
accountNamestringOptionalAccount holder name (Recommended).
amountnumberOptionalPayment amount. If omitted, generates a Static QR.
contentstringOptionalPayment description.
isCardbooleanOptionalTransfer 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 FieldTypeAlways presentDescription
isValidbooleanYesTrue if the QR string is valid and checksum matches.
isDynamicbooleanYesTrue if the QR contains a specific amount.
isCardbooleanOptionalTrue if payment is via Card Number (QRIBFTTC).
beneficiaryobjectOptionalContains bankBin, accountNo, and accountName.
transactionobjectOptionalContains amount and content.
errorMessagestringOptionalReason 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:

PropertyTypeDefaultDescription
renderAs'svg' | 'canvas''svg'Rendering mode.
sizenumber256Width & height in pixels.
level'L' | 'M' | 'Q' | 'H''Q'Error-correction level. Use 'Q' or 'H' if overlaying a logo via imageSettings.
imageSettingsImageSettings-Settings to overlay a logo in the center of the QR.

Framework-specific extras (not available everywhere):

PropertyTypeFrameworksDescription
classNamestringReact, Vue, SvelteCSS class for the wrapper.
styleCSSProperties / StyleValue / stringReact, Vue, SvelteInline styles.
bgColor / fgColorstringReact, Vue, SvelteBackground / dot color. Default white / black.
includeMarginbooleanReact, Vue, SvelteAdds 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:

PropertyTypeDefaultDescription
theme'light' | 'dark''light'Color theme of the card.
locale'vi' | 'en''vi'Template UI language and VND formatting; does not change payment data.
messagesPartial<VietQRMessages>-Override individual labels. Explicit title/subtitle props take priority.
bankLogostring-CompactCard only. Logo URL shown instead of the bank name.
title / subtitlestring-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:

PropertyTypeDefaultDescription
labelstring'Thanh toán VietQR'Overrides the translated pay label, including an empty string.
locale'vi' | 'en''vi'Button/dialog language and VND formatting.
messagesPartial<VietQRMessages>—Override pay, title and close labels; updates open dialogs.
sizenumber260QR 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.