Information for Developers of QR Codes for Tax
On printed versions of annual tax documents, tax data may still be "electronically delivered" through the use of two-dimensional bar codes known as QR Codes.
As seen below, the tax document information in FDX-standard JSON format is encoded in the QR codes.
Data as JSON
{ "taxW2" : { "taxYear" : 2022, "taxFormDate" : "2021-03-30", "taxFormType" : "TaxW2", "employeeTin" : "XXX-XX-1234", "employerTin" : "12-3456789", "employerNameAddress" : { "line1" : "12021 Sunset Valley Dr", "line2" : "Suite 230", "city" : "Preston", "state" : "VA", "postalCode" : "20191", "name1" : "Tax Form Issuer, Inc" }, "controlNumber" : "012547 WY/OA7", "employeeName" : { "first" : "Kris", "middle" : "Q", "last" : "Public" }, "employeeAddress" : { "line1" : "1 Main St", "city" : "Melrose", "state" : "NY", "postalCode" : "12121" }, "wages" : 44416.74, "federalTaxWithheld" : 6907.16, "socialSecurityWages" : 47162.92, "socialSecurityTaxWithheld" : 2924.1, "medicareWages" : 47162.92, "medicareTaxWithheld" : 683.86, "codes" : [ { "code" : "C", "amount" : 301.5 }, { "code" : "D", "amount" : 2746.18 }, { "code" : "DD", "amount" : 4781.88 } ], "retirementPlan" : true, "stateTaxWithholding" : [ { "stateTaxWithheld" : 1726.78, "state" : "OH", "stateTaxId" : "OH 036-133505158F-01", "stateIncome" : 44416.74 } ], "localTaxWithholding" : [ { "localTaxWithheld" : 427.62, "localityName" : "Kirtland", "state" : "OH", "localIncome" : 44416.74 } ] } }
QR code containing the data
How to add QR codes to your tax documents
- Instantiate the TaxDataForQR object. (Make sure to set the softwareId and version property values.)
- Serialize the object to JSON.
- Convert the JSON to a QR Code Image
- Place the image in available space on your tax form or accompanying page.
Java developers may find the below information and code snippets helpful
To Serialize Object to JSON
Use the Jackson library available as a Maven dependency.
<properties> <jackson.version>2.15.2</jackson.version> </properties> <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>${jackson.version}</version> </dependency>
This code will serialize the object to JSON
public static String convert( TaxDataForQR taxDataForQR ) { String json = ""; try { StringWriter sw = new StringWriter( ); ObjectMapper objectMapper = new ObjectMapper( ); // Indentation recommended but not required objectMapper.configure( SerializationFeature.INDENT_OUTPUT, true ); // Do not include null values objectMapper.setSerializationInclusion( JsonInclude.Include.NON_NULL ); objectMapper.writeValue( sw, taxDataForQR ); json = sw.toString( ); } catch ( JsonGenerationException e ) { LOGGER.severe( e.getMessage( ) ); } catch ( JsonMappingException e ) { LOGGER.severe( e.getMessage( ) ); } catch ( IOException e ) { LOGGER.severe( e.getMessage( ) ); } return json; }
To Convert JSON to a QR Code Image
The ZXing ("Zebra Crossing") barcode scanning library for Java is an open source project at https://github.com/zxing/zxing and provides QR code generation functionality.
Maven users can obtain the library by adding the below dependency to your project pom.xml file.
<properties> <zxing.version>3.4.1</zxing.version> </properties> <dependency> <groupId>com.google.zxing</groupId> <artifactId>core</artifactId> <version>${zxing.version}</version> </dependency>
The library will create an image and place it into an output stream that you supply:
ByteArrayOutputStream outputStream = new ByteArrayOutputStream( );
You specify the image format wanted. Here we assume PNG format.
String format = "png"; // or "jpg", if preferred
You then specify the preferred image size. The library will not return an image smaller than is necessary to hold the data to be encoded. Therefore, if you set the preferred width and height to 1 pixel, the minimum size image necessary to encode the json string will be generated
int preferredWidth = 1; int preferredHeight = 1;
You then set the desired error correction level. It is our experience that a level of LOW is sufficient for this purpose. You do this by creating a “Hint” Map as seen here:
Map<EncodeHintType, Object> hintMap = new HashMap<>( ); hintMap.put( EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L );
You then instantiate a QRCodeWriter object.
QRCodeWriter qrCodeWriter = new QRCodeWriter( );
The object’s encode method will create an object of type BitMatrix.
Important Note: If the json string is too large to fit in a QR code, an error will be thrown.
BitMatrix bitMatrix = qrCodeWriter.encode( json, BarcodeFormat.QR_CODE, preferredWidth, preferredHeight, hintMap );
The library’s MatrixToImageWriter class has a writeToStream static method that will populate your output stream with the qr code image data.
MatrixToImageWriter.writeToStream( bitMatrix, format, outputStream );
Your output stream may be converted to a byte array.
byte[] imgData = outputStream.toByteArray( );
You then place the image on your form in the location you specify.
Important: Do not scale down the image. Doing so will remove pixels from the image and make it unscannable.