zpl.tools
Bar codes

^B9 - UPC-E Bar Code

Six-digit compressed UPC for small retail packages.

^B9 prints a UPC-E symbol. A UPC-E is a UPC-A number with its runs of zeros suppressed, so it fits on packages too small for the full twelve digits. UPC-E works only for number-system-0 codes, and the manufacturer number and the product number must also follow the zero-suppression rules. The field data is therefore the full UPC-A digits, and the printer computes the compressed form.

Use ^BU UPC-A or ^BE EAN-13 where the package has room.

Syntax

^B9o,h,f,g,e

Support

Supportedparsed: full · state: full · rendered: full

Every documented parameter renders the same output Labelary produces.

Labelary renders this command.

Parameters

oBar code orientationoptional · one of a set

Rotation of the symbol and interpretation line.

Default
the orientation set by ^FW, which itself defaults to N
Invalid value
discarded, and the default applies. The renderer reports an unrecognized character as invalid, and uses the default.
Test coverage
Values exercised: N, R, I, B. The invalid-value rule is not pinned by a test.
N
No rotation (default)
R
Rotated 90° clockwise
I
Rotated 180°. The symbol reads upside down
B
Rotated 270° clockwise
hBar code heightoptional · dots

Height of the bars, without the interpretation line.

Default
the height set by ^BY, which itself defaults to 10 dots
Accepted range
1 to 32000 dots
Invalid value
clamped to the nearest allowed value. We measured this against live Labelary on 2026-07-12. The renderer clamps an out-of-range value to the violated bound, and does not ignore it.
Test coverage
Bounds pinned: below the minimum (0), above the maximum (33000). No test at the minimum or maximum. The invalid-value rule is not pinned by a test.
fPrint interpretation lineoptional · Y or N

Whether the renderer prints the interpretation line.

Default
Y
Invalid value
discarded, and the default applies. The renderer reports any character except Y or N, and uses the default.
Test coverage
Values exercised: Y, N. The invalid-value rule is not pinned by a test.
Y
Print the text (default)
N
Print the symbol only
gInterpretation line aboveoptional · Y or N

Where the interpretation line sits. It has no effect without that line.

Default
N
Invalid value
discarded, and the default applies. The renderer reports any character except Y or N, and uses the default.
Test coverage
Values exercised: Y, N. The invalid-value rule is not pinned by a test.
Y
Above the symbol
N
Below the symbol (default)
eShow check digitoptional · Y or N

Whether the check digit appears in the interpretation line. The renderer always encodes it in the symbol.

Default
Y
Invalid value
discarded, and the default applies. The renderer reports any character except Y or N, and shows the check digit.
Test coverage
Values exercised: Y, N. The invalid-value rule is not pinned by a test.
Y
Show it (default)
N
Hide it

Behavior

The field data is exactly ten digits: a five-digit manufacturer's code and then a five-digit product code. The field data is the whole uncompressed sequence, and ZPL calculates and prints the shortened version. ZPL cannot accept the six compressed digits and interpret them as a UPC-A.

Zero suppression works only for certain combinations. The guide states them as rules on the product code:

  • manufacturer's number ending 000, 100 or 200 — product codes 00000 to 00999;
  • ending 300 to 900 — product codes 00000 to 00099;
  • ending 10 to 90 — product codes 00000 to 00009;
  • not ending in zero — product codes 00005 to 00009.

A number outside those bands has no UPC-E form. Validate the number before the label is built.

The printer always encodes the check digit, and the fifth argument only decides whether it appears in the interpretation line. UPC-E has a fixed print ratio, so the ^BY ratio argument has no effect. UPC-E prints at full size on 6, 12 and 24 dot/mm printheads, as UPC-A does, and at 77 per cent on an 8 dot/mm head.

Known issues

Tested behavior

Differences from the specification

zpl.tools against the ZPL II guide

Where our renderer behaves differently from the specification.

  • The guide takes the default orientation from ^FW. The renderer applies ^FW to text fields only. A barcode after ^FWR prints unrotated unless its own o argument rotates it. — not pinned by a test

zpl.tools against Labelary

Where our output differs from Labelary for the same input. These are the differences that break a migration.

  • Nine digits or more truncate on the left to the eight-digit form, the rule the guide states for the rest of the retail family. Labelary prints 0 123455 8 for 123456789, 1234567890 and 12345678901 alike. No reading of UPC-E explains that rule, and the renderer does not reproduce it. The two engines encode different articles for the same field data. — not pinned by a test

Example

The guide's own payload: ten uncompressed digits, printed as the compressed six-digit symbol.

^XA
^FO50,50^BY3
^B9N,80,Y,N,Y
^FD1230000045^FS
^XZ

Open in viewer