@lokal-id/core 0.2.2 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,426 @@
1
+ // Kembaran ("twin"): replaces Indonesian personal data with realistic stand-ins, so a copy of production data can go
2
+ // to staging, a developer's laptop, or a vendor without anyone in it being a real person.
3
+ //
4
+ // Unlike Samaran's [NIK_1] placeholders, the result looks like the original and still works as data:
5
+ // - The same value always gets the same stand-in, across tables and files, so joins and foreign keys hold.
6
+ // - Stand-ins keep what analysis needs and nothing that identifies: a NIK keeps its district, gender, and birth year;
7
+ // a phone number its operator; an address its RT/RW and area; a name its number of words and its casing.
8
+ // - Within one line (a CSV row, an SQL tuple), a birth date follows the stand-in NIK, so the row stays consistent.
9
+ // - Stand-ins come from HMAC-SHA256 under a secret: random for each run unless one is given, and never reversible
10
+ // without it. Unique values (NIK, phone, account numbers) never collide.
11
+ //
12
+ // Node only (node:crypto), like @lokal-id/core/wilayah. python/src/lokal/kembaran.py gives identical output for the
13
+ // same secret.
14
+ import { createHash, randomBytes } from 'node:crypto';
15
+ import { FEMALE_FIRST, FEMALE_LAST, HEALTH, MALE_FIRST, MALE_LAST, MARITAL, NAME_KEEP, RELIGIONS, STREETS, } from './kembaran-data.js';
16
+ import { parsePhone } from './phone.js';
17
+ import { canonical, detectPii, PII_TYPES } from './samaran/index.js';
18
+ export const KEEP_BY_DEFAULT = ['GENDER', 'RELIGION', 'MARITAL_STATUS', 'NATIONALITY'];
19
+ // Values that must stay unique: two people must not end up with one stand-in.
20
+ const UNIQUE = new Set([
21
+ 'NIK', 'KK', 'NPWP', 'PHONE', 'EMAIL', 'BANK_ACCOUNT', 'CARD', 'BPJS', 'SIM', 'NIP', 'PASSPORT', 'PLATE', 'IP',
22
+ ]);
23
+ const MONTHS = [
24
+ ['januari', 'februari', 'maret', 'april', 'mei', 'juni', 'juli', 'agustus', 'september', 'oktober', 'november', 'desember'],
25
+ ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december'],
26
+ ['jan', 'feb', 'mar', 'apr', 'mei', 'jun', 'jul', 'agu', 'sep', 'okt', 'nov', 'des'],
27
+ ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec'],
28
+ ];
29
+ const MONTH_ALIASES = { agt: 7, ags: 7, sept: 8, nop: 10, peb: 1 };
30
+ const MONTH_NAMES = [...new Set([...MONTHS.flat(), ...Object.keys(MONTH_ALIASES)])].sort((a, b) => b.length - a.length).join('|');
31
+ const DMY = /(\d{1,2})([-/. ])(\d{1,2})\2(\d{4})/;
32
+ const YMD = /(\d{4})([-/.])(\d{1,2})\2(\d{1,2})/;
33
+ const D_NAME_Y = new RegExp(`(\\d{1,2})(\\s+)(${MONTH_NAMES})(\\.?\\s+)(\\d{4})`, 'i');
34
+ const EXCEL_SERIAL = /^\d{5}$/;
35
+ const STREET = /\b(Jl|Jln|Jalan|Gg|Gang|Komp|Kompleks|Perum|Perumahan)(\.?\s+)([A-Za-z][A-Za-z.'-]*(?:\s+[A-Za-z][A-Za-z.'-]*)*?)(?=\s+(?:No|Nomor|Blok|Kav|RT|RW)\b|\s*\d|\s*$)/i;
36
+ const INITIAL = /^[A-Za-z]\.$/;
37
+ const LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
38
+ const FEMALE_SET = new Set(FEMALE_FIRST.map((n) => n.toLowerCase()));
39
+ const MALE_SET = new Set(MALE_FIRST.map((n) => n.toLowerCase()));
40
+ /**
41
+ * HMAC-SHA256 under one key, with the padded key hashed once: createHmac re-imports the key on every call, which
42
+ * made a 100,000-row file take seconds longer.
43
+ */
44
+ class Hmac {
45
+ inner;
46
+ outer;
47
+ constructor(secret) {
48
+ const key = Buffer.alloc(64);
49
+ (secret.length > 64 ? createHash('sha256').update(secret).digest() : secret).copy(key);
50
+ this.inner = createHash('sha256').update(key.map((b) => b ^ 0x36));
51
+ this.outer = createHash('sha256').update(key.map((b) => b ^ 0x5c));
52
+ }
53
+ digest(message) {
54
+ return this.outer.copy().update(this.inner.copy().update(message).digest()).digest();
55
+ }
56
+ }
57
+ /** A stream of numbers from HMAC-SHA256(secret, label): the same label always gives the same stream. */
58
+ class Stream {
59
+ block = 0;
60
+ buf = Buffer.alloc(0);
61
+ pos = 32;
62
+ key;
63
+ label;
64
+ constructor(key, label) {
65
+ this.key = key;
66
+ this.label = label;
67
+ }
68
+ int(n) {
69
+ if (this.pos + 4 > 32) {
70
+ this.buf = this.key.digest(`${this.label}#${this.block++}`);
71
+ this.pos = 0;
72
+ }
73
+ const v = this.buf.readUInt32BE(this.pos);
74
+ this.pos += 4;
75
+ return v % n;
76
+ }
77
+ pick(xs) {
78
+ return xs[this.int(xs.length)];
79
+ }
80
+ digits(n) {
81
+ let out = '';
82
+ for (let i = 0; i < n; i++)
83
+ out += String(this.int(10));
84
+ return out;
85
+ }
86
+ }
87
+ const pad = (n, width = 2) => String(n).padStart(width, '0');
88
+ const onlyDigits = (s) => s.replace(/\D/g, '');
89
+ /** Writes `digits` into the digit positions of `template`, keeping its separators: "0812-3456-7890". */
90
+ function putDigits(template, digits) {
91
+ if (onlyDigits(template).length !== digits.length)
92
+ return digits;
93
+ let i = 0;
94
+ return template.replace(/\d/g, () => digits[i++]);
95
+ }
96
+ /** Same casing as `like`: "BUDI", "budi", or "Budi". */
97
+ function caseLike(word, like) {
98
+ if (like.length > 1 && like === like.toUpperCase() && like !== like.toLowerCase())
99
+ return word.toUpperCase();
100
+ if (like === like.toLowerCase() && like !== like.toUpperCase())
101
+ return word.toLowerCase();
102
+ return word;
103
+ }
104
+ /** Each run of digits replaced by random digits of the same length, keeping a leading zero; never a leading zero otherwise. */
105
+ function shapeDigits(s, rng) {
106
+ // "03" stays "0x", as an RT number would be written.
107
+ return s.replace(/\d+/g, (run) => run
108
+ .split('')
109
+ .map((d, i) => (i > 0 ? String(rng.int(10)) : d === '0' && run.length > 1 ? '0' : String(1 + rng.int(9))))
110
+ .join(''));
111
+ }
112
+ /** Letters to random letters of the same case, digits to random digits; anything else stays. */
113
+ function shapeAll(s, rng) {
114
+ let out = '';
115
+ for (const ch of s) {
116
+ if (/\d/.test(ch))
117
+ out += String(rng.int(10));
118
+ else if (/[A-Z]/.test(ch))
119
+ out += LETTERS[rng.int(26)];
120
+ else if (/[a-z]/.test(ch))
121
+ out += LETTERS[rng.int(26)].toLowerCase();
122
+ else
123
+ out += ch;
124
+ }
125
+ return out;
126
+ }
127
+ function luhnFix(digits) {
128
+ const body = digits.slice(0, -1);
129
+ let sum = 0;
130
+ for (let i = 0; i < body.length; i++) {
131
+ let d = Number(body[body.length - 1 - i]);
132
+ if (i % 2 === 0) {
133
+ d *= 2;
134
+ if (d > 9)
135
+ d -= 9;
136
+ }
137
+ sum += d;
138
+ }
139
+ return body + String((10 - (sum % 10)) % 10);
140
+ }
141
+ export class Kembaran {
142
+ key;
143
+ keep;
144
+ keepBirthDate;
145
+ minConfidence;
146
+ fakes = new Map();
147
+ used = new Map();
148
+ nikDays = new Map();
149
+ constructor(options = {}) {
150
+ for (const t of options.keep ?? []) {
151
+ if (!PII_TYPES.includes(t))
152
+ throw new RangeError(`Unknown PII type "${t}". Valid types: ${PII_TYPES.join(', ')}`);
153
+ }
154
+ this.key = new Hmac(options.secret !== undefined ? Buffer.from(options.secret, 'utf8') : randomBytes(32));
155
+ this.keep = new Set(options.keep ?? KEEP_BY_DEFAULT);
156
+ this.keepBirthDate = options.keepBirthDate ?? false;
157
+ this.minConfidence = options.minConfidence ?? 'medium';
158
+ }
159
+ /** Replaces every piece of personal data in a text: a CSV, an SQL dump, JSON, a log, or prose. */
160
+ text(input) {
161
+ const matches = detectPii(input, { minConfidence: this.minConfidence, exclude: [...this.keep] });
162
+ const lineStarts = [0];
163
+ for (let i = input.indexOf('\n'); i >= 0; i = input.indexOf('\n', i + 1))
164
+ lineStarts.push(i + 1);
165
+ const lineOf = (pos) => {
166
+ let lo = 0;
167
+ let hi = lineStarts.length - 1;
168
+ while (lo < hi) {
169
+ const mid = (lo + hi + 1) >> 1;
170
+ if (lineStarts[mid] <= pos)
171
+ lo = mid;
172
+ else
173
+ hi = mid - 1;
174
+ }
175
+ return lo;
176
+ };
177
+ // NIKs first, so a birth date on the same line can follow the stand-in NIK.
178
+ const out = new Array(matches.length);
179
+ const rowDays = new Map();
180
+ matches.forEach((m, i) => {
181
+ if (m.type !== 'NIK')
182
+ return;
183
+ out[i] = this.value('NIK', m.value);
184
+ const day = this.nikDays.get(onlyDigits(out[i]));
185
+ const line = lineOf(m.start);
186
+ if (day && !rowDays.has(line))
187
+ rowDays.set(line, day);
188
+ });
189
+ matches.forEach((m, i) => {
190
+ if (out[i] === undefined)
191
+ out[i] = this.value(m.type, m.value, rowDays.get(lineOf(m.start)));
192
+ });
193
+ let text = '';
194
+ let cursor = 0;
195
+ const replaced = {};
196
+ matches.forEach((m, i) => {
197
+ text += input.slice(cursor, m.start) + out[i];
198
+ cursor = m.end;
199
+ replaced[m.type] = (replaced[m.type] ?? 0) + 1;
200
+ });
201
+ return { text: text + input.slice(cursor), replaced };
202
+ }
203
+ /** The stand-in for one value of a known type. */
204
+ value(type, original, rowDay) {
205
+ if (this.keep.has(type))
206
+ return original;
207
+ const canon = type === 'NAME' ? this.nameCore(original).map((t) => t.toLowerCase()).join(' ') : canonical(type, original);
208
+ if (type === 'BIRTH_DATE' && rowDay && !this.keepBirthDate)
209
+ return this.birthDate(original, new Stream(this.key, 'BIRTH_DATE|row'), rowDay);
210
+ const cacheKey = `${type}|${canon}`;
211
+ const cached = this.fakes.get(cacheKey);
212
+ if (cached !== undefined)
213
+ return this.render(type, original, cached);
214
+ let fake = '';
215
+ for (let attempt = 0; attempt < 100; attempt++) {
216
+ fake = this.make(type, original, canon, new Stream(this.key, `${type}|${canon}|${attempt}`));
217
+ if (!UNIQUE.has(type))
218
+ break;
219
+ const used = this.used.get(type) ?? new Set();
220
+ this.used.set(type, used);
221
+ if (!used.has(fake)) {
222
+ used.add(fake);
223
+ break;
224
+ }
225
+ }
226
+ this.fakes.set(cacheKey, fake);
227
+ return this.render(type, original, fake);
228
+ }
229
+ /** The words of a name that identify the person: not honorifics, titles, or "bin". */
230
+ nameCore(name) {
231
+ return name.split(/\s+/).filter((w) => w && !NAME_KEEP.has(w.toLowerCase().replace(/[.,]/g, '')));
232
+ }
233
+ /** A stand-in in canonical form: digits for numbers, words joined by spaces for names. */
234
+ make(type, original, canon, rng) {
235
+ switch (type) {
236
+ case 'NIK': {
237
+ const d = onlyDigits(original);
238
+ if (d.length !== 16)
239
+ return d.slice(0, 6) + rng.digits(Math.max(0, d.length - 6));
240
+ const female = Number(d.slice(6, 8)) > 40;
241
+ let day = { day: Number(d.slice(6, 8)) - (female ? 40 : 0), month: Number(d.slice(8, 10)) };
242
+ if (!this.keepBirthDate)
243
+ day = { day: 1 + rng.int(28), month: 1 + rng.int(12) };
244
+ const nik = d.slice(0, 6) + pad(day.day + (female ? 40 : 0)) + pad(day.month) + d.slice(10, 12) + pad(1 + rng.int(9999), 4);
245
+ this.nikDays.set(nik, day);
246
+ return nik;
247
+ }
248
+ case 'KK':
249
+ return onlyDigits(original).slice(0, 6) + rng.digits(Math.max(0, onlyDigits(original).length - 6));
250
+ case 'NPWP': {
251
+ const d = onlyDigits(original);
252
+ // An individual's NPWP is their NIK: the same person keeps one stand-in for both.
253
+ if (d.length === 16 && d[0] !== '0')
254
+ return onlyDigits(this.value('NIK', d));
255
+ return d.slice(0, 1) + rng.digits(Math.max(0, d.length - 1));
256
+ }
257
+ case 'PHONE': {
258
+ if (canon.startsWith('+62'))
259
+ return canon.slice(0, 6) + rng.digits(canon.length - 6);
260
+ const d = onlyDigits(original);
261
+ return d.slice(0, 4) + rng.digits(Math.max(0, d.length - 4));
262
+ }
263
+ case 'EMAIL': {
264
+ const female = rng.int(2) === 1;
265
+ const first = rng.pick(female ? FEMALE_FIRST : MALE_FIRST).toLowerCase();
266
+ const last = rng.pick(female ? FEMALE_LAST : MALE_LAST).toLowerCase();
267
+ return `${first}.${last}${pad(rng.int(100))}`;
268
+ }
269
+ case 'NAME': {
270
+ const core = this.nameCore(original);
271
+ const lead = core.find((w) => !INITIAL.test(w))?.toLowerCase().replace(/[.,]/g, '');
272
+ const female = lead !== undefined && FEMALE_SET.has(lead) ? true : lead !== undefined && MALE_SET.has(lead) ? false : rng.int(2) === 1;
273
+ const words = [];
274
+ let firstDone = false;
275
+ for (const w of core) {
276
+ if (INITIAL.test(w))
277
+ words.push(`${LETTERS[rng.int(26)]}.`);
278
+ else if (!firstDone) {
279
+ words.push(rng.pick(female ? FEMALE_FIRST : MALE_FIRST));
280
+ firstDone = true;
281
+ }
282
+ else {
283
+ let next = rng.pick(female ? FEMALE_LAST : MALE_LAST);
284
+ for (let i = 0; i < 5 && words.includes(next); i++)
285
+ next = rng.pick(female ? FEMALE_LAST : MALE_LAST);
286
+ words.push(next);
287
+ }
288
+ }
289
+ return words.join(' ');
290
+ }
291
+ case 'ADDRESS':
292
+ return this.address(original, rng);
293
+ case 'BIRTH_DATE':
294
+ return this.keepBirthDate ? original : this.birthDate(original, rng);
295
+ case 'BANK_ACCOUNT':
296
+ case 'BPJS':
297
+ case 'SIM':
298
+ return rng.digits(onlyDigits(original).length);
299
+ case 'NIP': {
300
+ const d = onlyDigits(original);
301
+ return d.slice(0, 4) + rng.digits(Math.max(0, d.length - 4));
302
+ }
303
+ case 'CARD': {
304
+ const d = onlyDigits(original);
305
+ return d.length > 7 ? luhnFix(d.slice(0, 6) + rng.digits(d.length - 6)) : rng.digits(d.length);
306
+ }
307
+ case 'PASSPORT':
308
+ return original.slice(0, 1) + shapeAll(original.slice(1), rng);
309
+ case 'PLATE': {
310
+ const m = /^([A-Za-z]{1,2})(\s*)(\d{1,4})(\s*)([A-Za-z]{0,3})$/.exec(original.trim());
311
+ if (!m)
312
+ return shapeAll(original, rng);
313
+ const num = String(1 + rng.int(9)) + rng.digits(m[3].length - 1);
314
+ const suffix = m[5].split('').map((c) => caseLike(LETTERS[rng.int(26)], c)).join('');
315
+ return `${m[1]}${m[2]}${num}${m[4]}${suffix}`;
316
+ }
317
+ case 'IP':
318
+ if (original.includes(':'))
319
+ return `2001:db8::${rng.int(65536).toString(16)}:${rng.int(65536).toString(16)}`;
320
+ return `${rng.pick(['192.0.2', '198.51.100', '203.0.113'])}.${1 + rng.int(254)}`;
321
+ case 'GEO':
322
+ return original.replace(/(\.\d{2})(\d+)/g, (_, keep, rest) => keep + rng.digits(rest.length));
323
+ case 'FINANCIAL':
324
+ return shapeDigits(original, rng);
325
+ case 'HEALTH':
326
+ return caseLike(rng.pick(HEALTH), original);
327
+ case 'CRIMINAL_RECORD':
328
+ return caseLike('Tidak ada catatan', original);
329
+ case 'BIOMETRIC': {
330
+ const dot = original.lastIndexOf('.');
331
+ const ext = dot > 0 && original.length - dot <= 5 ? original.slice(dot) : '';
332
+ return shapeAll(original.slice(0, original.length - ext.length), rng) + ext;
333
+ }
334
+ case 'GENDER':
335
+ return original.trim().length === 1 ? rng.pick(['L', 'P']) : rng.pick(['Laki-laki', 'Perempuan']);
336
+ case 'RELIGION':
337
+ return rng.pick(RELIGIONS);
338
+ case 'MARITAL_STATUS':
339
+ return rng.pick(MARITAL);
340
+ case 'NATIONALITY':
341
+ return 'WNI';
342
+ default:
343
+ return shapeAll(original, rng);
344
+ }
345
+ }
346
+ /** A stand-in in the original's format: its separators, its casing, its titles. */
347
+ render(type, original, fake) {
348
+ switch (type) {
349
+ case 'NIK':
350
+ case 'KK':
351
+ case 'NPWP':
352
+ case 'BANK_ACCOUNT':
353
+ case 'BPJS':
354
+ case 'SIM':
355
+ case 'NIP':
356
+ case 'CARD':
357
+ return putDigits(original, fake);
358
+ case 'PHONE': {
359
+ if (!fake.startsWith('+62'))
360
+ return putDigits(original, fake);
361
+ const d = onlyDigits(original);
362
+ const digits = d.startsWith('0') ? `0${fake.slice(3)}` : d.startsWith('62') ? fake.slice(1) : fake.slice(3);
363
+ return putDigits(original, digits);
364
+ }
365
+ case 'EMAIL':
366
+ return original.includes('@') ? `${fake}@example.com` : `${fake} [at] example [dot] com`;
367
+ case 'NAME': {
368
+ const words = fake.split(' ');
369
+ let i = 0;
370
+ return original
371
+ .split(/(\s+)/)
372
+ .map((part) => {
373
+ if (!part || /^\s+$/.test(part) || NAME_KEEP.has(part.toLowerCase().replace(/[.,]/g, '')))
374
+ return part;
375
+ const word = words[i++] ?? part;
376
+ const trail = /[,]$/.test(part) ? ',' : '';
377
+ return caseLike(word, part.replace(/[,]$/, '')) + trail;
378
+ })
379
+ .join('');
380
+ }
381
+ default:
382
+ return fake;
383
+ }
384
+ }
385
+ address(original, rng) {
386
+ const comma = original.indexOf(',');
387
+ const head = comma < 0 ? original : original.slice(0, comma);
388
+ const tail = comma < 0 ? '' : original.slice(comma);
389
+ const street = head.replace(STREET, (_, kind, gap, name) => kind + gap + caseLike(rng.pick(STREETS), name));
390
+ return shapeDigits(street, rng) + tail;
391
+ }
392
+ birthDate(original, rng, rowDay) {
393
+ if (EXCEL_SERIAL.test(original.trim())) {
394
+ const date = new Date(Date.UTC(1899, 11, 30) + Number(original.trim()) * 86400000);
395
+ const day = rowDay ?? { day: 1 + rng.int(28), month: 1 + rng.int(12) };
396
+ return String(Math.round((Date.UTC(date.getUTCFullYear(), day.month - 1, day.day) - Date.UTC(1899, 11, 30)) / 86400000));
397
+ }
398
+ const pick = () => rowDay ?? { day: 1 + rng.int(28), month: 1 + rng.int(12) };
399
+ const width = (s, n) => (s.length >= 2 ? pad(n) : String(n));
400
+ let m = DMY.exec(original);
401
+ if (m) {
402
+ const d = pick();
403
+ return original.replace(DMY, `${width(m[1], d.day)}${m[2]}${width(m[3], d.month)}${m[2]}${m[4]}`);
404
+ }
405
+ m = YMD.exec(original);
406
+ if (m) {
407
+ const d = pick();
408
+ return original.replace(YMD, `${m[1]}${m[2]}${width(m[3], d.month)}${m[2]}${width(m[4], d.day)}`);
409
+ }
410
+ m = D_NAME_Y.exec(original);
411
+ if (m) {
412
+ const d = pick();
413
+ const word = m[3].toLowerCase();
414
+ const family = MONTHS.find((names) => names.includes(word)) ?? MONTHS[2];
415
+ const name = family[d.month - 1];
416
+ const styled = caseLike(name.charAt(0).toUpperCase() + name.slice(1), m[3]);
417
+ return original.replace(D_NAME_Y, `${width(m[1], d.day)}${m[2]}${styled}${m[4]}${m[5]}`);
418
+ }
419
+ return original;
420
+ }
421
+ }
422
+ /** One-shot: replaces personal data in a text with stand-ins under a random secret. */
423
+ export function kembaran(text, options = {}) {
424
+ return new Kembaran(options).text(text);
425
+ }
426
+ //# sourceMappingURL=kembaran.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kembaran.js","sourceRoot":"","sources":["../src/kembaran.ts"],"names":[],"mappings":"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"}
package/dist/qris.d.ts ADDED
@@ -0,0 +1,82 @@
1
+ import type { Issue } from './nik.ts';
2
+ export interface QrisField {
3
+ tag: string;
4
+ value: string;
5
+ /** Sub-fields of a template: merchant accounts (26–51), additional data (62), language (64), 80–99. */
6
+ children?: QrisField[];
7
+ }
8
+ export interface QrisMerchantAccount {
9
+ tag: string;
10
+ /** Globally unique identifier: a reverse domain such as "ID.CO.QRIS.WWW" or "COM.GO-JEK.WWW". */
11
+ gui?: string;
12
+ /** Merchant PAN (sub-tag 01), the account number at the acquirer. */
13
+ pan?: string;
14
+ /** Merchant ID at the acquirer (02); in tag 51 this is the NMID. */
15
+ merchantId?: string;
16
+ /** Merchant criteria (03): UMI, UKE, UME, UBE, … */
17
+ criteria?: string;
18
+ }
19
+ export type QrisTip = {
20
+ kind: 'prompt';
21
+ } | {
22
+ kind: 'fixed';
23
+ value: string;
24
+ } | {
25
+ kind: 'percent';
26
+ value: string;
27
+ };
28
+ export interface QrisAdditionalData {
29
+ billNumber?: string;
30
+ mobileNumber?: string;
31
+ storeLabel?: string;
32
+ loyaltyNumber?: string;
33
+ referenceLabel?: string;
34
+ customerLabel?: string;
35
+ terminalLabel?: string;
36
+ purpose?: string;
37
+ }
38
+ export interface QrisInfo {
39
+ input: string;
40
+ valid: boolean;
41
+ errors: Issue[];
42
+ warnings: Issue[];
43
+ /** `static` (tag 01 = 11): the payer types the amount. `dynamic` (12): the amount is in the code. */
44
+ type?: 'static' | 'dynamic';
45
+ merchantName?: string;
46
+ merchantCity?: string;
47
+ postalCode?: string;
48
+ /** National Merchant ID from tag 51, such as "ID1020021181745". */
49
+ nmid?: string;
50
+ criteria?: string;
51
+ /** "Usaha Mikro", "Usaha Kecil", … for the criteria codes whose meaning is settled. */
52
+ criteriaLabel?: string;
53
+ /** Merchant category code (ISO 18245), such as "5812" for restaurants. */
54
+ mcc?: string;
55
+ /** ISO 4217 numeric: "360" is Rupiah. */
56
+ currency?: string;
57
+ country?: string;
58
+ /** As written in the code, in Rupiah: "25000". */
59
+ amount?: string;
60
+ tip?: QrisTip;
61
+ accounts: QrisMerchantAccount[];
62
+ additional?: QrisAdditionalData;
63
+ crc?: string;
64
+ fields: QrisField[];
65
+ }
66
+ /** CRC-16/CCITT-FALSE (polynomial 0x1021, initial 0xFFFF) over the UTF-8 bytes, as four uppercase hex digits. */
67
+ export declare function qrisCrc(data: string): string;
68
+ /** Reads a QRIS payload: who gets paid, how much, and whether the code is intact. */
69
+ export declare function parseQris(input: string): QrisInfo;
70
+ export interface QrisAmountOptions {
71
+ /** A fixed fee in Rupiah (tag 56), or a percentage (tag 57), added on top of the amount. */
72
+ tip?: {
73
+ fixed: number | string;
74
+ } | {
75
+ percent: number | string;
76
+ };
77
+ }
78
+ /**
79
+ * Turns a QRIS code into a dynamic one for an amount: tag 01 becomes 12, the amount goes into tag 54, and the CRC is
80
+ * recomputed. Every other field stays as it was, so the payment still goes to the same merchant account.
81
+ */
82
+ export declare function setQrisAmount(input: string, amount: number | string, options?: QrisAmountOptions): string;