bihupp-js 0.0.0-stage → 1.0.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Luka Gligorevic
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,337 @@
1
- # Temporary Holding Version
1
+ # bihupp-js
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ JavaScript/TypeScript library implementing the **BIHUPP10** standard for bank payment instructions in Bosnia and Herzegovina.
4
+
5
+ **BIHUPP** (_Bosansko-Hercegovački Unutrašnji Platni Promet_) defines a structured text payload that can be encoded as a QR code that banks scan to pre-fill payment forms. This format was established by the [Association of Banks of Bosnia and Herzegovina](https://ubbih.ba/).
6
+
7
+ Inspired by Saša B.'s BIHUPP QR libraries: [`php-bihupp-qrcode`](https://github.com/sasa-b/php-bihupp-qrcode) and [`kotlin-bihupp-qrcode`](https://github.com/sasa-b/kotlin-bihupp-qrcode).
8
+
9
+ ---
10
+
11
+ ## Installation
12
+
13
+ ```bash
14
+ npm install bihupp-js
15
+ # or
16
+ yarn add bihupp-js
17
+ # or
18
+ pnpm add bihupp-js
19
+ ```
20
+
21
+ Zero dependencies. Works in Node.js, browsers, React Native, Next.js, and any JavaScript environment.
22
+
23
+ ---
24
+
25
+ ## Quick start
26
+
27
+ ```ts
28
+ import {
29
+ PaymentInstruction,
30
+ Name,
31
+ AddressLine1,
32
+ AddressLine2,
33
+ Amount,
34
+ PaymentPurpose,
35
+ RecipientAccount,
36
+ } from "bihupp-js";
37
+
38
+ const instruction = new PaymentInstruction({
39
+ recipient: {
40
+ name: Name.business("Vodovod d.o.o."),
41
+ address: {
42
+ addressLine1: AddressLine1.of("Kralja Petra I Karađorđevića", "97"),
43
+ addressLine2: AddressLine2.of("78000", "Banja Luka"),
44
+ },
45
+ account: RecipientAccount.of({ value: "9876543210987654" }),
46
+ },
47
+ amount: Amount.fromBAM(98.62), // or Amount.fromPennies(9862)
48
+ purpose: PaymentPurpose.of("Račun za vodu - april 2025"),
49
+ reference: { value: "1234-5678-001" },
50
+ });
51
+
52
+ const payload = instruction.toString(); // BIHUPP10 string → encode into QR
53
+ ```
54
+
55
+ ---
56
+
57
+ ## Usage
58
+
59
+ ### Fluent builder
60
+
61
+ If you prefer a fluent API, you can use `PaymentInstructionBuilder`:
62
+
63
+ ```ts
64
+ import {
65
+ PaymentInstructionBuilder,
66
+ Name,
67
+ AddressLine1,
68
+ AddressLine2,
69
+ Amount,
70
+ PaymentPurpose,
71
+ RecipientAccount,
72
+ } from "bihupp-js";
73
+
74
+ const instruction = PaymentInstructionBuilder.create()
75
+ .withRecipient({
76
+ name: Name.business("Vodovod d.o.o."),
77
+ address: {
78
+ addressLine1: AddressLine1.of("Kralja Petra I Karađorđevića", "97"),
79
+ addressLine2: AddressLine2.of("78000", "Banja Luka"),
80
+ },
81
+ account: RecipientAccount.of({ value: "9876543210987654" }),
82
+ })
83
+ .withAmount(Amount.fromBAM(98.62))
84
+ .withPurpose(PaymentPurpose.of("Račun za vodu - april 2025"))
85
+ .build();
86
+ ```
87
+
88
+ ### Standard bank transfer
89
+
90
+ ```ts
91
+ import {
92
+ PaymentInstruction,
93
+ Name,
94
+ AddressLine1,
95
+ AddressLine2,
96
+ Amount,
97
+ PaymentPurpose,
98
+ PaymentPriority,
99
+ RecipientAccount,
100
+ } from "bihupp-js";
101
+
102
+ const instruction = new PaymentInstruction({
103
+ recipient: {
104
+ name: Name.business("Example Company d.o.o."),
105
+ address: {
106
+ addressLine1: AddressLine1.of("Zmaja od Bosne", "75"),
107
+ addressLine2: AddressLine2.of("71000", "Sarajevo"),
108
+ },
109
+ account: RecipientAccount.of({ value: "9876543210987654" }),
110
+ },
111
+ amount: Amount.fromPennies(10000), // 100.00 BAM
112
+ purpose: PaymentPurpose.of("Invoice payment"),
113
+ reference: { value: "INV-2025-001" },
114
+ paymentPriority: PaymentPriority.regular(), // default, can be omitted
115
+ });
116
+ ```
117
+
118
+ ### Omitting the sender
119
+
120
+ When `sender` is `null` or omitted, the bank pre-fills payer details from the logged-in user's session.
121
+
122
+ ```ts
123
+ const instruction = new PaymentInstruction({
124
+ recipient,
125
+ amount: Amount.fromBAM(50),
126
+ purpose: PaymentPurpose.of("Uplata članarine"),
127
+ sender: null,
128
+ });
129
+ ```
130
+
131
+ ### Including a sender
132
+
133
+ ```ts
134
+ import { PhoneNumber } from "bihupp-js";
135
+
136
+ const instruction = new PaymentInstruction({
137
+ recipient,
138
+ amount: Amount.fromBAM(150),
139
+ purpose: PaymentPurpose.of("Plaćanje računa"),
140
+ sender: {
141
+ name: Name.individual("Marko", "Marković"),
142
+ address: {
143
+ addressLine1: AddressLine1.of("Ulica Meše Selimovića", "12"),
144
+ addressLine2: AddressLine2.of("78000", "Banja Luka"),
145
+ },
146
+ account: { value: "1234567890123456" },
147
+ phoneNumber: PhoneNumber.of("+38761234567"), // E.164, optional
148
+ },
149
+ });
150
+ ```
151
+
152
+ ### Multiple recipient accounts (up to 20)
153
+
154
+ ```ts
155
+ const instruction = new PaymentInstruction({
156
+ recipient: {
157
+ ...recipient,
158
+ account: RecipientAccount.of(
159
+ { value: "1234567890123456" },
160
+ { value: "9876543210987654" },
161
+ { value: "1111222233334444" },
162
+ ),
163
+ },
164
+ amount: Amount.fromPennies(5000),
165
+ purpose: PaymentPurpose.of("Test"),
166
+ });
167
+ ```
168
+
169
+ ### Public revenue payment (tax, fees, etc.)
170
+
171
+ ```ts
172
+ const instruction = new PaymentInstruction({
173
+ recipient: {
174
+ name: Name.of("Trezor"),
175
+ address: {
176
+ addressLine1: AddressLine1.of("Aleja Svetog Save", "13"),
177
+ addressLine2: AddressLine2.of("78000", "Banja Luka"),
178
+ },
179
+ account: RecipientAccount.of({ value: "1610000010680092" }),
180
+ },
181
+ amount: Amount.fromBAM(5000),
182
+ purpose: PaymentPurpose.of("Porez na dobit"),
183
+ reference: null,
184
+ publicRevenue: {
185
+ senderTaxId: "4200730150004", // 13 digits (JIB/JMBG)
186
+ paymentType: "3", // single digit
187
+ revenueType: "712115", // 6 digits
188
+ taxPeriodStartDate: "01012024", // ddMMyyyy
189
+ taxPeriodEndDate: "31122024", // ddMMyyyy
190
+ municipalCode: "077", // 3 digits
191
+ budgetOrgCode: "1200200", // 7 digits
192
+ paymentReference: "7110578163", // 10 digits
193
+ },
194
+ });
195
+ ```
196
+
197
+ ### Reading the payload
198
+
199
+ ```ts
200
+ // Get the raw BIHUPP10 string (encode this into a QR code)
201
+ const payload: string = instruction.toString();
202
+
203
+ // Get as array of lines
204
+ const lines: string[] = instruction.lines();
205
+
206
+ // Human-readable debug output
207
+ console.log(instruction.inspect());
208
+ ```
209
+
210
+ ### Parsing a scanned QR code
211
+
212
+ ```ts
213
+ import { parsePaymentInstruction } from "bihupp-js";
214
+
215
+ const result = parsePaymentInstruction(rawStringFromScanner);
216
+
217
+ if (result.success) {
218
+ const { instruction } = result;
219
+ console.log(instruction.recipient.name.value);
220
+ console.log(instruction.amount.pennies / 100, "BAM");
221
+ } else {
222
+ console.error(result.error.message);
223
+ }
224
+ ```
225
+
226
+ ---
227
+
228
+ ## Amount handling
229
+
230
+ `Amount` stores the value as an integer number of **pennies (pfeniga)**:
231
+
232
+ ```ts
233
+ Amount.fromPennies(9862); // 98.62 BAM — from integer pennies
234
+ Amount.fromBAM(98.62); // 98.62 BAM — from decimal
235
+ Amount.fromString("98.62"); // 98.62 BAM — from string (decimal stripped)
236
+ Amount.fromString("9862"); // 98.62 BAM — from string pennies
237
+ ```
238
+
239
+ ---
240
+
241
+ ## Field reference
242
+
243
+ ### `PaymentInstruction` constructor
244
+
245
+ | Parameter | Type | Required | Default | Notes |
246
+ | ----------------- | ---------------------------------- | -------- | ----------- | ------------------------ |
247
+ | `recipient` | `Recipient` | ✅ | — | |
248
+ | `purpose` | `PaymentPurpose` | ✅ | — | Max 110 chars |
249
+ | `amount` | `Amount` | ✅ | — | Integer pennies |
250
+ | `sender` | `Sender \| null` | ❌ | `undefined` | Omit / `null` = bank auto-fills |
251
+ | `reference` | `PaymentReference \| null` | ❌ | `undefined` | Max 30 chars |
252
+ | `paymentPriority` | `PaymentPriority` | ❌ | `regular()` | `N` or `D` |
253
+ | `publicRevenue` | `PublicRevenueInstruction \| null` | ❌ | `undefined` | Tax/fee payments |
254
+
255
+ ### Field constraints
256
+
257
+ #### Sender / Recipient
258
+
259
+ | Field | Max length | Format / Notes |
260
+ | --------------------- | ---------- | --------------------------------------- |
261
+ | `name` | 50 | Alphanumeric + allowed chars |
262
+ | `addressLine1` | 50 | Street + number |
263
+ | `addressLine2` | 25 | Postcode + city |
264
+ | `phoneNumber` | 15 | E.164, must start with `+` |
265
+ | sender `account` | 16 | Digits only |
266
+ | recipient `account(s)`| — | 1–20 accounts, digits only, comma-separated |
267
+
268
+ #### Payment detail
269
+
270
+ | Field | Max length | Format / Notes |
271
+ | ----------- | ---------- | -------------------------------------------- |
272
+ | `purpose` | 110 | Newlines normalized to spaces |
273
+ | `reference` | 30 | |
274
+ | `amount` | 15 | Integer pennies (pfeninzi), **zero-padded** |
275
+
276
+ #### Public revenue fields
277
+
278
+ | Field | Length | Format |
279
+ | --------------------- | ------ | ---------------- |
280
+ | `senderTaxId` | 13 | Exactly 13 digits (JIB/JMBG) |
281
+ | `paymentType` | 1 | Single digit (`0`–`9`) |
282
+ | `revenueType` | 6 | Exactly 6 digits |
283
+ | `taxPeriodStartDate` | 8 | `ddMMyyyy` (8 digits) |
284
+ | `taxPeriodEndDate` | 8 | `ddMMyyyy` (8 digits) |
285
+ | `municipalCode` | 3 | Exactly 3 digits |
286
+ | `budgetOrgCode` | 7 | Exactly 7 digits |
287
+ | `paymentReference` | 10 | Exactly 10 digits |
288
+
289
+ ### Allowed character set
290
+
291
+ Alphanumeric + Bosnian/Croatian/Serbian diacritics (`č ć đ š ž Č Ć Đ Š Ž`) + `, : . ? ( ) + ' / -` and space.
292
+
293
+ ---
294
+
295
+ ## Error handling
296
+
297
+ All validation runs at construction time and throws `BihuppValidationError`:
298
+
299
+ ```ts
300
+ import { BihuppValidationError } from 'bihupp-js';
301
+
302
+ try {
303
+ const instruction = new PaymentInstruction({ ... });
304
+ } catch (err) {
305
+ if (err instanceof BihuppValidationError) {
306
+ console.error(err.field); // e.g. "recipient.name"
307
+ console.error(err.message); // e.g. "[recipient.name] Exceeds maximum length of 50, got 51."
308
+ }
309
+ }
310
+ ```
311
+
312
+ ### Zod schema-based validation (optional)
313
+
314
+ For schema-driven validation and richer error information you can use the optional Zod layer. It lives in a separate entry point, so the core package stays dependency-free. Install `zod` (v4) alongside:
315
+
316
+ ```bash
317
+ npm install zod
318
+ ```
319
+
320
+ ```ts
321
+ import {
322
+ paymentInstructionParamsSchema,
323
+ validatePaymentInstructionWithSchema,
324
+ } from "bihupp-js/zod";
325
+
326
+ // Validate with Zod schema (throws ZodError on failure)
327
+ const parsed = paymentInstructionParamsSchema.parse(params);
328
+
329
+ // Or via helper
330
+ validatePaymentInstructionWithSchema(params);
331
+ ```
332
+
333
+ ---
334
+
335
+ ## License
336
+
337
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,104 @@
1
+ import { P as PaymentInstructionParams, R as Recipient, A as Amount, a as PaymentPurpose, S as Sender, b as PaymentReference, c as PaymentPriority, d as PublicRevenueInstruction, e as ParseResult } from './types-v4INW3qo.mjs';
2
+ export { f as ALLOWED_CHARS_REGEX, g as Account, h as Address, i as AddressLine1, i as AddressLine1Type, j as AddressLine2, j as AddressLine2Type, B as BIHUPP_CURRENCY, k as BIHUPP_VERSION, l as BihuppValidationError, N as Name, N as NameType, m as PaymentPriorityCode, n as PhoneNumber, n as PhoneNumberType, o as RecipientAccount, o as RecipientAccountType } from './types-v4INW3qo.mjs';
3
+
4
+ /**
5
+ * Core BIHUPP10 payment instruction value object.
6
+ *
7
+ * This class is intentionally simple and immutable. For a more ergonomic API,
8
+ * prefer using {@link PaymentInstructionBuilder} which guides you through
9
+ * constructing a valid instruction while preserving field ordering.
10
+ */
11
+ declare class PaymentInstruction {
12
+ #private;
13
+ constructor(params: PaymentInstructionParams);
14
+ /**
15
+ * Returns the BIHUPP10 payload string representation, with fields ordered
16
+ * exactly as required by the specification.
17
+ */
18
+ toString(): string;
19
+ /**
20
+ * Returns the BIHUPP10 payload as an array of lines, in the exact order
21
+ * defined by the BIHUPP10 standard.
22
+ */
23
+ lines(): string[];
24
+ /**
25
+ * Returns a human-readable multi-line string representation of the
26
+ * instruction, useful for logging and debugging.
27
+ */
28
+ inspect(): string;
29
+ /**
30
+ * Returns the underlying structured parameters used to construct this
31
+ * instruction. The returned object is read-only.
32
+ */
33
+ get params(): Readonly<PaymentInstructionParams>;
34
+ }
35
+ /**
36
+ * Fluent builder for constructing BIHUPP10 payment instructions while
37
+ * preserving field ordering and applying validation once at build time.
38
+ *
39
+ * The builder is a thin ergonomic layer over {@link PaymentInstruction}.
40
+ */
41
+ declare class PaymentInstructionBuilder {
42
+ #private;
43
+ /**
44
+ * Creates a new builder instance.
45
+ */
46
+ static create(): PaymentInstructionBuilder;
47
+ /**
48
+ * Sets the recipient block (name, address, account).
49
+ */
50
+ withRecipient(recipient: Recipient): this;
51
+ /**
52
+ * Sets the payment amount.
53
+ */
54
+ withAmount(amount: Amount): this;
55
+ /**
56
+ * Sets the payment purpose.
57
+ */
58
+ withPurpose(purpose: PaymentPurpose): this;
59
+ /**
60
+ * Sets the optional sender block. When `sender` is `null`, the sender
61
+ * section in the payload is left empty so that the bank can auto-fill it.
62
+ */
63
+ withSender(sender: Sender | null): this;
64
+ /**
65
+ * Sets the optional payment reference (e.g. invoice number).
66
+ */
67
+ withReference(reference: PaymentReference | null): this;
68
+ /**
69
+ * Sets the payment priority. If omitted, `regular()` is assumed.
70
+ */
71
+ withPaymentPriority(priority: PaymentPriority): this;
72
+ /**
73
+ * Sets the optional public revenue block (taxes, fees, etc.).
74
+ */
75
+ withPublicRevenue(publicRevenue: PublicRevenueInstruction | null): this;
76
+ /**
77
+ * Builds a validated {@link PaymentInstruction} instance.
78
+ *
79
+ * This method performs a final check that all required fields are present
80
+ * before delegating to {@link PaymentInstruction}, which runs the full
81
+ * BIHUPP10 validation.
82
+ */
83
+ build(): PaymentInstruction;
84
+ }
85
+
86
+ /**
87
+ * Parses a raw BIHUPP10 payload string (as decoded from a QR code)
88
+ * back into a structured PaymentInstructionParams object.
89
+ *
90
+ * @example
91
+ * ```ts
92
+ * const result = parsePaymentInstruction(rawString);
93
+ * if (result.success) {
94
+ * console.log(result.instruction.recipient.name.value);
95
+ * } else {
96
+ * console.error(result.error.message);
97
+ * }
98
+ * ```
99
+ */
100
+ declare function parsePaymentInstruction(raw: string): ParseResult;
101
+
102
+ declare function validatePaymentInstruction(params: PaymentInstructionParams): void;
103
+
104
+ export { Amount, Amount as AmountType, ParseResult, PaymentInstruction, PaymentInstructionBuilder, PaymentInstructionParams, PaymentPriority, PaymentPriority as PaymentPriorityType, PaymentPurpose, PaymentPurpose as PaymentPurposeType, PaymentReference, PublicRevenueInstruction, Recipient, Sender, parsePaymentInstruction, validatePaymentInstruction };
@@ -0,0 +1,104 @@
1
+ import { P as PaymentInstructionParams, R as Recipient, A as Amount, a as PaymentPurpose, S as Sender, b as PaymentReference, c as PaymentPriority, d as PublicRevenueInstruction, e as ParseResult } from './types-v4INW3qo.js';
2
+ export { f as ALLOWED_CHARS_REGEX, g as Account, h as Address, i as AddressLine1, i as AddressLine1Type, j as AddressLine2, j as AddressLine2Type, B as BIHUPP_CURRENCY, k as BIHUPP_VERSION, l as BihuppValidationError, N as Name, N as NameType, m as PaymentPriorityCode, n as PhoneNumber, n as PhoneNumberType, o as RecipientAccount, o as RecipientAccountType } from './types-v4INW3qo.js';
3
+
4
+ /**
5
+ * Core BIHUPP10 payment instruction value object.
6
+ *
7
+ * This class is intentionally simple and immutable. For a more ergonomic API,
8
+ * prefer using {@link PaymentInstructionBuilder} which guides you through
9
+ * constructing a valid instruction while preserving field ordering.
10
+ */
11
+ declare class PaymentInstruction {
12
+ #private;
13
+ constructor(params: PaymentInstructionParams);
14
+ /**
15
+ * Returns the BIHUPP10 payload string representation, with fields ordered
16
+ * exactly as required by the specification.
17
+ */
18
+ toString(): string;
19
+ /**
20
+ * Returns the BIHUPP10 payload as an array of lines, in the exact order
21
+ * defined by the BIHUPP10 standard.
22
+ */
23
+ lines(): string[];
24
+ /**
25
+ * Returns a human-readable multi-line string representation of the
26
+ * instruction, useful for logging and debugging.
27
+ */
28
+ inspect(): string;
29
+ /**
30
+ * Returns the underlying structured parameters used to construct this
31
+ * instruction. The returned object is read-only.
32
+ */
33
+ get params(): Readonly<PaymentInstructionParams>;
34
+ }
35
+ /**
36
+ * Fluent builder for constructing BIHUPP10 payment instructions while
37
+ * preserving field ordering and applying validation once at build time.
38
+ *
39
+ * The builder is a thin ergonomic layer over {@link PaymentInstruction}.
40
+ */
41
+ declare class PaymentInstructionBuilder {
42
+ #private;
43
+ /**
44
+ * Creates a new builder instance.
45
+ */
46
+ static create(): PaymentInstructionBuilder;
47
+ /**
48
+ * Sets the recipient block (name, address, account).
49
+ */
50
+ withRecipient(recipient: Recipient): this;
51
+ /**
52
+ * Sets the payment amount.
53
+ */
54
+ withAmount(amount: Amount): this;
55
+ /**
56
+ * Sets the payment purpose.
57
+ */
58
+ withPurpose(purpose: PaymentPurpose): this;
59
+ /**
60
+ * Sets the optional sender block. When `sender` is `null`, the sender
61
+ * section in the payload is left empty so that the bank can auto-fill it.
62
+ */
63
+ withSender(sender: Sender | null): this;
64
+ /**
65
+ * Sets the optional payment reference (e.g. invoice number).
66
+ */
67
+ withReference(reference: PaymentReference | null): this;
68
+ /**
69
+ * Sets the payment priority. If omitted, `regular()` is assumed.
70
+ */
71
+ withPaymentPriority(priority: PaymentPriority): this;
72
+ /**
73
+ * Sets the optional public revenue block (taxes, fees, etc.).
74
+ */
75
+ withPublicRevenue(publicRevenue: PublicRevenueInstruction | null): this;
76
+ /**
77
+ * Builds a validated {@link PaymentInstruction} instance.
78
+ *
79
+ * This method performs a final check that all required fields are present
80
+ * before delegating to {@link PaymentInstruction}, which runs the full
81
+ * BIHUPP10 validation.
82
+ */
83
+ build(): PaymentInstruction;
84
+ }
85
+
86
+ /**
87
+ * Parses a raw BIHUPP10 payload string (as decoded from a QR code)
88
+ * back into a structured PaymentInstructionParams object.
89
+ *
90
+ * @example
91
+ * ```ts
92
+ * const result = parsePaymentInstruction(rawString);
93
+ * if (result.success) {
94
+ * console.log(result.instruction.recipient.name.value);
95
+ * } else {
96
+ * console.error(result.error.message);
97
+ * }
98
+ * ```
99
+ */
100
+ declare function parsePaymentInstruction(raw: string): ParseResult;
101
+
102
+ declare function validatePaymentInstruction(params: PaymentInstructionParams): void;
103
+
104
+ export { Amount, Amount as AmountType, ParseResult, PaymentInstruction, PaymentInstructionBuilder, PaymentInstructionParams, PaymentPriority, PaymentPriority as PaymentPriorityType, PaymentPurpose, PaymentPurpose as PaymentPurposeType, PaymentReference, PublicRevenueInstruction, Recipient, Sender, parsePaymentInstruction, validatePaymentInstruction };