How to make a bank transfer QR code for your shop (VietQR), and keep it safe

What a Vietnamese bank transfer QR code holds, static versus dynamic amounts, message limits, why you must test-scan it, and how to avoid fake QR stickers on a counter.

On this page

A bank transfer QR code is the cheapest way to get paid in Vietnam: a shop, a freelancer, a landlord or a wedding table sticks one code where people can see it, and the payer scans it with their banking app and lands on a transfer that is already filled in. This guide explains what such a code contains, how to make one for your own account, the choices that matter (an amount or not, how long the message can be), and the safety habits that stop a good idea from turning into a scam. You can follow along with the VietQR generator, which builds the code in your browser without sending your account number anywhere. It is an independent tool, not made or endorsed by NAPAS or any bank, and the steps below are a practical guide, not a guarantee that every banking app will behave the same way.

What the code actually says

The codes you see on shop counters follow the VietQR format, which NAPAS (the national payment network) uses for interbank 247 transfers. Underneath it is an ordinary text string in the EMV QR format that payment apps use around the world, and a QR code is only the picture of that text. The string is a list of fields, each written as a two-digit id, a two-digit length and the value. The ones that matter to you are:

  • the bank, as a six-digit number called the BIN (970436 is Vietcombank, 970422 is MBBank);
  • the account number, or a card number for a card transfer;
  • the service, which tells the app whether the destination is an account or a card;
  • the currency (704, Vietnamese dong) and the country (VN);
  • an optional amount, in whole dong with no decimals;
  • an optional message, which becomes the transfer description;
  • a short check value (CRC) at the end, so an app can notice a string that was damaged or edited.

Notice what is not there: the account holder's name. Banking apps normally look the name up after scanning and show it to the payer. That is a feature, not a gap, because it lets the payer confirm who they are paying. It also means a name printed on a card next to the code proves nothing; the code decides where the money goes.

Make the code, step by step

  1. Pick the receiving bank from the list. The list in the generator comes from a public bank list as of 15 October 2026; BINs can change when banks merge or rename, which is one reason for the test below.
  2. Type the account number. Spaces and dashes are ignored, letters are refused, and an account has between 6 and 19 digits. If you want people to pay a card, switch to a card number (16 to 19 digits).
  3. Decide on an amount (next section) and a message.
  4. Choose a card layout and a look. Keep the code dark on a light background: a pale or inverted code is the usual reason a scan fails. A logo in the middle is possible, and raises the error correction so the code survives being partly covered.
  5. Download a PNG for chat or print, an SVG if a printer or designer needs vector, or print straight from the page.

An amount, or none?

A code without an amount is static in the everyday sense: print it once and it works for every customer, who types the price themselves. That is the right choice for a counter, a donation box or a rent reminder. A code with an amount fills the number in for the payer, which prevents typing mistakes and is right for one bill or one order, such as an invoice you send to a customer. The cost is that the code is wrong as soon as the price changes, so never print a code with an amount and leave it up for a week of changing prices. Whichever you choose, the amount is in whole dong: 1.500.000 means one million five hundred thousand, and a decimal is refused.

The message, and why it is cut short

The message field is useful for matching a payment to an order ("DH1234"), but banks accept a narrow set of characters and some apps keep only a short message. The generator therefore strips Vietnamese accents ("Thanh toán" becomes "Thanh toan"), keeps letters, digits, spaces and . , - _ / @ # & ( ), replaces anything else with a space, and cuts at 25 characters. You can allow 50, but a few apps shorten longer messages without telling anyone, so put the important part, such as the order number, at the start.

Test it before you print it

Scanning the finished code with your own banking app takes ten seconds and catches almost every real mistake: a wrong digit in the account number, a bank that does not take QR transfers, a BIN that has changed. Do it twice, with two different banking apps if you can, because apps differ in what they accept. Then check the name the app shows against the account holder you expect. The generator also reads the picture back after drawing it and tells you whether the picture decodes to the same text, but that proves only that the picture is readable, not that the account is right. Nothing replaces a scan with a real banking app.

Fake stickers and other ways this goes wrong

A well-known trick is a second QR sticker placed over a shop's real one, so that customers pay a stranger. A few habits make that much harder:

  • Put your code where staff can see it, not only where customers can reach it, and look at it now and then.
  • Print it on something hard to cover or peel quietly, and consider writing the account holder's name next to it so customers know what the app should show.
  • As a payer, always read the name in the banking app before you confirm. If it is not the shop's name, stop.
  • Be suspicious of a code you receive in a message from someone you do not know, and of any code that asks you to install something.
  • Remember that a code cannot prove that an account exists or whose it is; only the bank can tell you that.

If you only need a code for a link, a Wi-Fi password or a contact, use the QR code generator instead. To read back a code you were given and see its fields, open the "Check a code" tab in the VietQR generator.

Tools mentioned in this article

Back to the blog