A Java library for parsing and building EMVCo-compliant QR payloads, including CRC-16/CCITT validation and a fluent API for generating consumer-presented payment QR strings.
The project follows the EMVCo Consumer Presented QR Code Specification and is packaged as a reusable JVM library.
- Parsing raw EMVCo QR strings into structured Java objects
- Building QR payloads with a fluent
EMVCoBuilder - CRC calculation and validation helpers
- A tag registry for root tags and supported sub-tags
- Convenience helpers for navigating parsed fields
- Gradle publication metadata for generating Maven-ready artifacts
- Java 17 or newer
- Gradle 9+ (the wrapper is included)
Once the artifact is published to your target Maven repository, you can consume it with the following coordinates:
- Group:
com.roshka - Artifact:
emvcoparser - Version:
1.0.0
dependencies {
implementation("com.roshka:emvcoparser:1.0.0")
}<dependency>
<groupId>com.roshka</groupId>
<artifactId>emvcoparser</artifactId>
<version>1.0.0</version>
</dependency>
mvnrepository.comdoes not host artifacts itself; it indexes packages that have already been published to repositories such as Maven Central, GitHub Packages, or a private Nexus/Artifactory server.
import com.roshka.emvco.EMVCoHelper;
import com.roshka.emvco.EMVCoParser;
import com.roshka.emvco.model.EMVCo;
import com.roshka.emvco.model.EMVCoField;
String qrString = "0002010102115204000053036005802PY5912Mi Comercio6008Asuncion6304C82B";
EMVCo emvco = EMVCoParser.parse(qrString);
if (emvco.isValid()) {
for (EMVCoField field : emvco.getFields()) {
System.out.println(field.getTag().getMessage() + ": " + field.getValue());
}
}
EMVCoHelper helper = new EMVCoHelper(emvco);
String merchantName = helper.getFieldValue("59");
String country = EMVCoParser.getCountry(emvco);EMVCo emvco = EMVCoParser.parse(qrString, false);import com.roshka.emvco.EMVCoBuilder;
String qrCode = EMVCoBuilder.create()
.payloadFormatIndicator("01")
.pointOfInitialization("11")
.merchantAccountInformation("26", "00", "py.gov.bcp.qr", "10", "https://example.com/qr")
.merchantCategoryCode("0000")
.transactionCurrency("600")
.transactionAmount("100.00")
.countryCode("PY")
.merchantName("Mi Comercio")
.merchantCity("Asuncion")
.billNumber("INV-0042")
.referenceLabel("REF-XYZ")
.terminalLabel("TERM-01")
.build();EMVCo emvco = EMVCoBuilder.create()
.payloadFormatIndicator("01")
.merchantCategoryCode("0000")
.transactionCurrency("600")
.countryCode("PY")
.merchantName("Mi Comercio")
.merchantCity("Asuncion")
.buildAndParse();| Type | Responsibility |
|---|---|
EMVCoParser |
Parses raw QR payloads into EMVCo objects and optionally validates CRC |
EMVCoBuilder |
Creates EMVCo payload strings with a fluent API |
EMVCoHelper |
Provides convenience access to parsed fields by ID |
EMVCoCRCUtil |
Calculates and validates CRC-16/CCITT values |
EMVCoTags |
Central registry of supported root tags and sub-tags |
EMVCoTag |
Immutable tag descriptor with getCode(), getMessage(), and hasSubTags() accessor methods |
EMVCoUtil |
Internal helper methods for transforming parsed fields |
| Type | Responsibility |
|---|---|
EMVCo |
Root parsed result, containing the original value, fields, validation state, and error message |
EMVCoField |
Individual EMVCo field with tag metadata, raw value, and optional sub-fields |
QRCodeType |
Enum of QR ecosystems and classifications used by surrounding integrations |
| Type | Responsibility |
|---|---|
EMVCOParserException |
Checked exception used internally while parsing malformed payloads |
EMVCOParserErrorCodes |
Error code constants |
EMVCOParserExceptionUtil |
Factory helpers for standardized parser exceptions |
| Tag | Description |
|---|---|
00 |
Payload Format Indicator |
01 |
Point of Initialization Method |
02-51 |
Merchant Account Information |
52 |
Merchant Category Code |
53 |
Transaction Currency |
54 |
Transaction Amount |
55 |
Tip or Convenience Indicator |
56 |
Value of Convenience Fee Fixed |
57 |
Value of Convenience Fee Percentage |
58 |
Country Code |
59 |
Merchant Name |
60 |
Merchant City |
61 |
Postal Code |
62 |
Additional Data Field Template |
63 |
CRC |
64 |
Merchant Information Language Template |
65-79 |
RFU for EMVCo |
80-99 |
Unreserved Templates |
| Sub-tag | Description |
|---|---|
01 |
Bill Number |
02 |
Mobile Number |
03 |
Store Label |
04 |
Loyalty Number |
05 |
Reference Label |
06 |
Customer Label |
07 |
Terminal Label |
08 |
Purpose of Transaction |
09 |
Additional Consumer Data Request |
10 |
Merchant Tax ID |
11 |
Merchant Channel |
| Sub-tag | Description |
|---|---|
00 |
Language Preference |
01 |
Merchant Name - Alternate Language |
02 |
Merchant City - Alternate Language |
03-99 |
RFU for EMVCo |
src/main/java/com/roshka/emvco/
├── EMVCoBuilder.java
├── EMVCoCRCUtil.java
├── EMVCoHelper.java
├── EMVCoParser.java
├── EMVCoTag.java
├── EMVCoTags.java
├── EMVCoUtil.java
├── exceptions/
│ ├── EMVCOParserErrorCodes.java
│ ├── EMVCOParserException.java
│ └── EMVCOParserExceptionUtil.java
└── model/
├── EMVCo.java
├── EMVCoField.java
└── QRCodeType.java
./gradlew clean build./gradlew test./gradlew javadocGenerated HTML documentation is written to build/docs/javadoc/.
The Gradle build now produces the standard artifacts expected by Maven consumers:
- Binary jar:
build/libs/emvcoparser-<version>.jar - Sources jar:
build/libs/emvcoparser-<version>-sources.jar - Javadoc jar:
build/libs/emvcoparser-<version>-javadoc.jar - Generated POM: published with the Maven publication
Create all publishable artifacts with:
./gradlew clean build sourcesJar javadocJar./gradlew publishToMavenLocal./gradlew publishMavenJavaPublicationToBuildRepoRepositoryThis stages a repository layout under:
build/maven-repository/com/roshka/emvcoparser/<version>/
That directory is useful for checking the final jar, sources jar, javadoc jar, checksum files, and generated POM before releasing to a public repository.
The build file includes Maven publication metadata for:
- project name and description
- SCM URLs
- developer information
- organization metadata
- optional signing via
signingKeyandsigningPassword
You can override the version during release:
./gradlew -PprojectVersion=1.0.1 clean build publishToMavenLocalIf you plan to release publicly, also define license metadata before publishing:
./gradlew \
-PpomLicenseName="Apache License, Version 2.0" \
-PpomLicenseUrl="https://www.apache.org/licenses/LICENSE-2.0.txt" \
-PprojectVersion=1.0.0 \
publishToMavenLocalThe library uses CRC-16/CCITT with:
- Polynomial:
0x1021 - Initial value:
0xFFFF - Coverage: the full QR payload up to and including the
63field header (6304), excluding only the final four hexadecimal CRC characters
Example:
boolean valid = EMVCoCRCUtil.validateCRC(qrString);
int crc = EMVCoCRCUtil.calculateCRC("000201...6304".getBytes());
String crcHex = String.format("%04X", crc);This project is developed and maintained by Roshka.