ezha-payment
qris-go
Go✨ New

Go library for parsing, generating, validating, and converting QRIS payment payloads. Zero dependencies.

Last updated Jun 29, 2026
18
Stars
5
Forks
3
Issues
0
Stars/day
Attention Score
61
Language breakdown
Go 98.7%
Makefile 1.3%
Files click to expand
README

qris-go

A Go library for parsing, generating, validating, and converting QRIS payment payloads.

CI Go Reference License: MIT Go Version Release

Why this exists

QRIS (Quick Response Code Indonesian Standard) is Indonesia's national QR payment standard. As of mid-2025 it serves around 57 million users and 39 million merchants, and it now supports cross-border payments across five countries, including Japan and South Korea, with further expansion across APEC economies underway. This library provides a dependency-free, spec-aligned toolkit for working with QRIS payloads in Go: decoding them, building them, validating them, and converting static QRs into dynamic ones at the point of sale.

Features

  • Parser for EMVCo Merchant Presented Mode TLV payloads with CRC-16/CCITT-FALSE verification
  • Merchant account info parsing for tags 26-51 (PSP-specific entries and national QRIS routing)
  • Additional data (tag 62) parsing
  • Builder API for generating valid QRIS payloads with automatic length and CRC computation
  • Validation layer aligned with the ASPI/EMVCo specification
  • ConvertStaticToDynamic for the acquirer point-of-sale use case
  • Typed constants for merchant criteria, currency, country, and globally unique identifiers
  • Standard library only, no external dependencies

Installation

go get github.com/ezha-payment/qris-go

Quick start: parsing

package main

import ( "fmt" "log"

qris "github.com/ezha-payment/qris-go" )

func main() { p, err := qris.Parse(payload) if err != nil { log.Fatal(err) }

fmt.Println(p.MerchantName, p.MerchantCity) fmt.Println(p.MPAN(), p.MID()) if p.IsStatic() { fmt.Println("static QR") } }

Usage: building a payload

The Builder computes every TLV length prefix and the trailing CRC automatically. Typed constants are passed with an explicit string conversion.

payload, err := qris.NewBuilder().
	Static().
	MerchantName("WARUNG SAMPLE").
	MerchantCity("JAKARTA").
	MCC("4812").
	Currency(string(qris.CurrencyIDR)).
	Country(string(qris.CountryID)).
	AddQRISAccount("9360091500001234567", "ID1020012345678", string(qris.CriteriaUMI)).
	Build()
if err != nil {
	log.Fatal(err)
}
fmt.Println(payload)

Build validates the payload before returning; an invalid configuration yields a *qris.ValidationError listing every offending field.

Usage: converting static to dynamic

A merchant displays a static QR; at checkout the point-of-sale embeds the purchase amount and emits a dynamic payload. Every original field is preserved; only the point of initiation method, amount, and optional additional data change.

dynamic, err := qris.ConvertStaticToDynamic(staticPayload, "25000",
	qris.WithReferenceLabel("INV-2024-001"),
)
if err != nil {
	log.Fatal(err)
}
fmt.Println(dynamic)

Runnable versions of these examples live in examples/.

API overview

Full reference: pkg.go.dev/github.com/ezha-payment/qris-go.

| Symbol | Purpose | | --- | --- | | Parse(string) (*Payload, error) | Decode a QRIS payload, verifying its CRC. | | Payload | Parsed payload with typed accessors (MPAN, MID, IsStatic, IsDynamic, QRISMerchantAccount, PSPMerchantAccounts). | | NewBuilder() *Builder | Fluent builder for generating payloads. | | Validate(Payload) error | Strict ASPI/EMVCo validation, returning a ValidationError. | | ConvertStaticToDynamic(payload, amount string, ...ConvertOption) | Embed an amount into a static QR. | | WithReferenceLabel, WithTerminalLabel, WithStoreLabel | Additional-data overrides for conversion. | | MerchantCriteria, CurrencyCode, CountryCode, GUI | Typed constants for enum-like fields. |

Specification references

  • ASPI QRIS Specification
  • EMVCo Merchant Presented Mode (MPM) Specification v1.1
  • Bank Indonesia PADG No. 21/18/PADG/2019

Disclaimer

This library implements public specifications. Not affiliated with Bank Indonesia or ASPI. Not a substitute for official certification.

Contributing

Contributions are welcome. See CONTRIBUTING.md for how to run tests, code style, and the pull request process.

License

Released under the MIT License.

🔗 More in this category

© 2026 GitRepoTrend · ezha-payment/qris-go · Updated daily from GitHub