Skip to content

Upgrading Static → Dynamic

Basic upgrade

typescript
import { fromString } from '@heigoly/qris/parse'
import { charge, setAmount } from '@heigoly/qris/upgrade'
import { encode } from '@heigoly/qris/encode'

const doc = fromString('000201010211...')
const paid = charge(doc, 50000)     // attaches Rp50.000
const result = encode(paid)         // QRIS string with CRC

With convenience fee

typescript
// Fixed fee
const paid = charge(doc, 50000, { type: 'fixed', value: 2000 })
// Amount: Rp50.000 + Fee: Rp2.000

// Percentage fee
const paid = charge(doc, 100000, { type: 'percentage', value: 2.5 })
// Amount: Rp100.000 + Fee: 2.5%

Step by step with setAmount

typescript
import { verify } from '@heigoly/qris/verify'

// Inspect the decoded document first
const doc = fromString(input)
// Check document validity
console.log(verify(doc))

// Upgrade in stages
const withAmount = setAmount(doc, 50000)
const withFee = setAmount(withAmount, 50000, { type: 'fixed', value: 2000 })

// Serialize to final string
const output = encode(withFee)

Using charge vs setAmount

FunctionBehavior
charge(doc, amount, fee?)Refuses to upgrade already-dynamic QRIS (throws QRISError). Use when you expect a static QRIS.
setAmount(doc, amount, fee?)Always applies the upgrade, even if already dynamic. Use when you want to overwrite the amount.

What happens during upgrade

Before (static)After (dynamic)
00: 0100: 01
01: 1101: 12 ← changed
26: DANA26: DANA
52: 581252: 5812
53: 36053: 360
54: 50000 ← new
55: 02 ← if fee
56: 2000 ← if fee
58: ID58: ID
59: Warung...59: Warung...
60: Kab...60: Kab...
63: C8C063: 3F1A ← new CRC