@halftome/szamlazz-client 1.0.8 → 2.0.2

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/dist/index.d.ts CHANGED
@@ -1,14 +1,16 @@
1
- import type { InvoiceOptions, LineItem, ReverseInvoiceOptions, KeyAuth, CredentialAuth, InvoiceCreationResponse } from './types';
1
+ import type { InvoiceOptions, LineItem, ReverseInvoiceOptions, KeyAuth, CredentialAuth, InvoiceItemResponse } from './types.js';
2
2
  export declare class Client {
3
3
  readonly key?: string;
4
4
  readonly username?: string;
5
5
  readonly password?: string;
6
6
  readonly apiUrl = "https://www.szamlazz.hu/szamla/";
7
7
  constructor(auth: KeyAuth | CredentialAuth);
8
+ private decodeResponse;
8
9
  private sendRequest;
9
10
  private authAttributes;
10
- generateInvoice(options: InvoiceOptions, items?: Array<LineItem>): Promise<InvoiceCreationResponse>;
11
- reverseInvoice(invoice: string, options: ReverseInvoiceOptions): Promise<InvoiceCreationResponse>;
11
+ generateInvoice(options: InvoiceOptions, items?: Array<LineItem>): Promise<InvoiceItemResponse>;
12
+ reverseInvoice(invoice: string, options: ReverseInvoiceOptions): Promise<InvoiceItemResponse>;
13
+ testConnection(): Promise<boolean>;
12
14
  }
13
15
  export default Client;
14
- export * from './types';
16
+ export * from './types.js';
package/dist/index.js CHANGED
@@ -1,46 +1,23 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
- }) : (function(o, m, k, k2) {
6
- if (k2 === undefined) k2 = k;
7
- o[k2] = m[k];
8
- }));
9
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
10
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
11
- };
12
- var __importDefault = (this && this.__importDefault) || function (mod) {
13
- return (mod && mod.__esModule) ? mod : { "default": mod };
14
- };
15
- Object.defineProperty(exports, "__esModule", { value: true });
16
- exports.Client = void 0;
17
- const xmlbuilder2_1 = require("xmlbuilder2");
18
- const node_fetch_1 = __importDefault(require("node-fetch"));
19
- const form_data_1 = __importDefault(require("form-data"));
20
- const url_1 = require("url");
21
- class Client {
1
+ import { create, convert } from 'xmlbuilder2';
2
+ import { URL } from 'url';
3
+ const toDateStr = (date) => date.toLocaleDateString('sv-SE', { timeZone: 'Europe/Budapest' });
4
+ export class Client {
5
+ key;
6
+ username;
7
+ password;
8
+ apiUrl = 'https://www.szamlazz.hu/szamla/';
22
9
  constructor(auth) {
23
- this.apiUrl = 'https://www.szamlazz.hu/szamla/';
24
10
  this.key = auth.key;
25
11
  this.username = auth.username;
26
12
  this.password = auth.password;
27
13
  }
28
- async sendRequest(type, content) {
29
- // Build XML
30
- const doc = (0, xmlbuilder2_1.create)({ encoding: 'UTF-8' }, content);
31
- const xml = doc.end({ prettyPrint: false });
32
- // Build Request
33
- const form = new form_data_1.default();
34
- form.append(type, xml, type);
35
- // Send Request
36
- const response = await (0, node_fetch_1.default)(this.apiUrl, { method: 'POST', body: form });
37
- const result = await response.text();
14
+ decodeResponse(response) {
38
15
  // Decode Response
39
16
  try {
40
- const obj = (0, xmlbuilder2_1.convert)(result, { format: 'object' });
17
+ const obj = convert(response, { format: 'object' });
41
18
  // Decode hosted url params:
42
- const url = new url_1.URL(obj.xmlszamlavalasz?.vevoifiokurl?.$);
43
- const pdfUrl = new url_1.URL(obj.xmlszamlavalasz?.vevoifiokurl?.$);
19
+ const url = new URL(obj.xmlszamlavalasz?.vevoifiokurl?.$);
20
+ const pdfUrl = new URL(obj.xmlszamlavalasz?.vevoifiokurl?.$);
44
21
  pdfUrl.searchParams.append('action', 'szamlapdf');
45
22
  pdfUrl.searchParams.delete('page');
46
23
  const decoded = {
@@ -61,9 +38,20 @@ class Client {
61
38
  return decoded;
62
39
  }
63
40
  catch (e) {
64
- throw new Error(result);
41
+ throw new Error(response);
65
42
  }
66
43
  }
44
+ async sendRequest(type, content) {
45
+ // Build XML
46
+ const doc = create({ encoding: 'UTF-8' }, content);
47
+ const xml = doc.end({ prettyPrint: false });
48
+ // Build Request
49
+ const form = new FormData();
50
+ form.append(type, new Blob([xml], { type: 'application/xml' }), type);
51
+ // Send Request
52
+ const response = await fetch(this.apiUrl, { method: 'POST', body: form });
53
+ return await response.text();
54
+ }
67
55
  authAttributes() {
68
56
  return {
69
57
  szamlaagentkulcs: this.key,
@@ -82,11 +70,12 @@ class Client {
82
70
  eszamla: options.eInvoice,
83
71
  szamlaLetoltes: options.downloadPDF ?? false,
84
72
  valaszVerzio: 2,
73
+ szamlaKulsoAzon: options.externalId,
85
74
  },
86
75
  fejlec: {
87
- keltDatum: options.issueDate,
88
- teljesitesDatum: options.completionDate,
89
- fizetesiHataridoDatum: options.dueDate,
76
+ keltDatum: toDateStr(options.issueDate),
77
+ teljesitesDatum: toDateStr(options.completionDate),
78
+ fizetesiHataridoDatum: toDateStr(options.dueDate),
90
79
  fizmod: options.paymentMethod,
91
80
  penznem: options.currency,
92
81
  szamlaNyelve: options.language,
@@ -100,7 +89,7 @@ class Client {
100
89
  elado: {
101
90
  bank: options.payee?.bankName,
102
91
  bankszamlaszam: options.payee?.bankAccountNumber,
103
- emailReplyTo: options.email?.replyTo,
92
+ emailReplyto: options.email?.replyTo,
104
93
  emailTargy: options.email?.subject,
105
94
  emailSzoveg: options.email?.content,
106
95
  },
@@ -133,7 +122,7 @@ class Client {
133
122
  },
134
123
  },
135
124
  };
136
- return await this.sendRequest('action-xmlagentxmlfile', doc);
125
+ return this.decodeResponse(await this.sendRequest('action-xmlagentxmlfile', doc));
137
126
  }
138
127
  async reverseInvoice(invoice, options) {
139
128
  const doc = {
@@ -149,51 +138,27 @@ class Client {
149
138
  },
150
139
  fejlec: {
151
140
  szamlaszam: invoice,
152
- keltDatum: options.issueDate,
153
- teljesitesDatum: options.completionDate,
141
+ keltDatum: toDateStr(options.issueDate),
142
+ teljesitesDatum: toDateStr(options.completionDate),
154
143
  },
155
144
  },
156
145
  };
157
- return await this.sendRequest('action-szamla_agent_st', doc);
146
+ return this.decodeResponse(await this.sendRequest('action-szamla_agent_st', doc));
147
+ }
148
+ async testConnection() {
149
+ const doc = {
150
+ xmlszamlaxml: {
151
+ '@xmlns': 'http://www.szamlazz.hu/xmlszamlaxml',
152
+ '@xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance',
153
+ '@xsi:schemaLocation': 'http://www.szamlazz.hu/xmlszamlaxml https://www.szamlazz.hu/szamla/docs/xsds/agentxml/xmlszamlaxml.xsd',
154
+ ...this.authAttributes(),
155
+ szamlaszam: 'NEMLETEZIKSOHANEMISFOG',
156
+ },
157
+ };
158
+ const r = await this.sendRequest('action-szamla_agent_xml', doc);
159
+ const obj = convert(r, { format: 'object' });
160
+ return obj.xmlszamlavalasz?.hibakod.$ == 7;
158
161
  }
159
162
  }
160
- exports.Client = Client;
161
- exports.default = Client;
162
- __exportStar(require("./types"), exports);
163
- /*
164
- const c = new Client({ username: 'demo', password: 'demo' })
165
- const now = new Date().toISOString().split('T')[0]
166
-
167
- c.generateInvoice(
168
- {
169
- eInvoice: true,
170
- completionDate: now,
171
- dueDate: now,
172
- issueDate: now,
173
- currency: Currency.HUF,
174
- sendEmail: false,
175
- language: Language.HU,
176
- paymentMethod: PaymentMethod.Card,
177
- settled: true,
178
- comment: 'some random comment',
179
- customer: {
180
- name: 'Test',
181
- address: 'Test',
182
- city: 'Test',
183
- zip: 'TST111',
184
- },
185
- },
186
- [
187
- {
188
- amount: 1,
189
- amountName: 'db',
190
- grossAmount: 1000,
191
- netAmount: 1000,
192
- name: 'Test',
193
- netUnitPrice: 1000,
194
- taxAmount: 0,
195
- vatRate: NamedVATRate.AAM,
196
- },
197
- ],
198
- ).then(console.log)
199
- */
163
+ export default Client;
164
+ export * from './types.js';
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,54 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { Client, NamedVATRate, PaymentMethod } from './index.js';
3
+ describe('Client', () => {
4
+ const client = new Client({ username: 'demo', password: 'demo' });
5
+ it('should generate and reverse an invoice', { timeout: 30000 }, async () => {
6
+ const result = await client.generateInvoice({
7
+ eInvoice: true,
8
+ currency: 'HUF',
9
+ sendEmail: false,
10
+ language: 'hu',
11
+ paymentMethod: PaymentMethod.Card,
12
+ settled: true,
13
+ comment: 'some random comment',
14
+ issueDate: new Date(),
15
+ completionDate: new Date(),
16
+ dueDate: new Date(),
17
+ customer: {
18
+ name: 'Test',
19
+ address: 'Test',
20
+ city: 'Test',
21
+ zip: 'TST111',
22
+ },
23
+ }, [
24
+ {
25
+ amount: 1,
26
+ amountName: 'db',
27
+ grossAmount: 1000,
28
+ netAmount: 1000,
29
+ name: 'Test',
30
+ netUnitPrice: 1000,
31
+ taxAmount: 0,
32
+ vatRate: NamedVATRate.AAM,
33
+ },
34
+ ]);
35
+ expect(result.invoice.number).toBeDefined();
36
+ expect(result.net).toBe(1000);
37
+ expect(result.gross).toBe(1000);
38
+ const reverseResult = await client.reverseInvoice(result.invoice.number, {
39
+ eInvoice: true,
40
+ issueDate: new Date(),
41
+ completionDate: new Date(),
42
+ });
43
+ expect(reverseResult.invoice.number).toBeDefined();
44
+ });
45
+ it('should validate credentials with testConnection', async () => {
46
+ const isValid = await client.testConnection();
47
+ expect(isValid).toBe(true);
48
+ });
49
+ it('should reject invalid credentials', async () => {
50
+ const badClient = new Client({ username: 'invalid', password: 'invalid' });
51
+ const isValid = await badClient.testConnection();
52
+ expect(isValid).toBe(false);
53
+ });
54
+ });
package/dist/types.d.ts CHANGED
@@ -1,46 +1,31 @@
1
- /// <reference types="node" />
2
1
  export declare enum NamedVATRate {
3
- TEHK = "TEHK",
4
- TAHK = "TAHK",
5
- TAM = "TAM",
6
- AAM = "AAM",
7
- EUT = "EUT",
8
- EUKT = "EUKT",
9
- MAA = "MAA",
10
- F_AFA = "F.AFA",
11
- K_AFA = "K.AFA",
12
- HO = "HO",
13
- EUE = "EUE",
14
- EUFADE = "EUFADE",
15
- EUFAD37 = "EUFAD37",
16
- ATK = "ATK",
17
- NAM = "NAM",
18
- EAM = "EAM",
19
- KBAUK = "KBAUK",
2
+ TEHK = "TEHK",// Outside the scope of Hungarian VAT
3
+ TAHK = "TAHK",// Not subject to VAT
4
+ TAM = "TAM",// supply exempt from VAT / exempt supply
5
+ AAM = "AAM",// person exempt from VAT / exempt person
6
+ EUT = "EUT",// Within EU (former 'EU')
7
+ EUKT = "EUKT",// Outside EU (former 'EUK')
8
+ MAA = "MAA",// exempt from tax
9
+ F_AFA = "F.AFA",// reverse VAT
10
+ K_AFA = "K.AFA",// differential VAT
11
+ HO = "HO",// Harmadik országban teljesített ügylet (TEHK)
12
+ EUE = "EUE",// Másik tagállamban teljesített, nem fordítottan adózó ügylet
13
+ EUFADE = "EUFADE",// Másik tagállamban teljesített, nem az Áfa tv. 37. §-a alá tartozó, fordítottan adózó ügylet
14
+ EUFAD37 = "EUFAD37",// -Áfa tv. 37. §-a alapján másik tagállamban teljesített, fordítottan adózó ügylet
15
+ ATK = "ATK",// ÁFA tárgyi hatályán kívüli
16
+ NAM = "NAM",// adómentesség egyéb nemzetközi ügyletekhez
17
+ EAM = "EAM",// adómentes termékexport harmadik országba
18
+ KBAUK = "KBAUK",// Közösségen belüli termékértékesítés UK
20
19
  KBAET = "KBAET"
21
20
  }
22
- export declare type VATRate = 0 | 5 | 7 | 18 | 19 | 20 | 25 | 27 | NamedVATRate;
21
+ export type VATRate = 0 | 5 | 7 | 18 | 19 | 20 | 25 | 27 | NamedVATRate;
23
22
  export declare enum PaymentMethod {
24
23
  Transfer = "\u00E1tutal\u00E1s",
25
24
  Cash = "k\u00E9szp\u00E9nz",
26
25
  Card = "bankk\u00E1rtya"
27
26
  }
28
- export declare enum Currency {
29
- HUF = "HUF"
30
- }
31
- export declare enum Language {
32
- HU = "hu",
33
- EN = "en",
34
- DE = "de",
35
- IT = "it",
36
- RO = "ro",
37
- SK = "sk",
38
- HR = "hr",
39
- FR = "fr",
40
- ES = "es",
41
- CZ = "cz",
42
- PL = "pl"
43
- }
27
+ export type Currency = 'HUF' | 'EUR' | 'USD' | 'GBP' | 'CHF' | 'JPY' | 'CNY' | 'CZK' | 'PLN' | 'RON';
28
+ export type LanguageCode = 'hu' | 'en' | 'de' | 'it' | 'ro' | 'sk' | 'hr' | 'fr' | 'es' | 'cz' | 'pl' | 'bg' | 'nl' | 'ru' | 'si';
44
29
  export declare enum InvoiceTemplate {
45
30
  SzlaMost = "SzlaMost",
46
31
  SzlaAlap = "SzlaAlap",
@@ -52,12 +37,12 @@ export interface InvoiceOptions {
52
37
  payee?: PayeeDetails;
53
38
  customer: CustomerDetails;
54
39
  eInvoice: boolean;
55
- issueDate: string;
56
- completionDate: string;
57
- dueDate: string;
40
+ issueDate: Date;
41
+ completionDate: Date;
42
+ dueDate: Date;
58
43
  paymentMethod: PaymentMethod | string;
59
44
  currency: Currency;
60
- language: Language;
45
+ language: LanguageCode;
61
46
  sendEmail: boolean;
62
47
  comment?: string;
63
48
  orderNumber?: string;
@@ -67,8 +52,9 @@ export interface InvoiceOptions {
67
52
  template?: InvoiceTemplate;
68
53
  settled?: boolean;
69
54
  downloadPDF?: boolean;
55
+ externalId?: string;
70
56
  }
71
- export declare type ReverseInvoiceOptions = Pick<InvoiceOptions, 'eInvoice' | 'issueDate' | 'completionDate' | 'downloadPDF'>;
57
+ export type ReverseInvoiceOptions = Pick<InvoiceOptions, 'eInvoice' | 'issueDate' | 'completionDate' | 'downloadPDF'>;
72
58
  export interface EmailDetails {
73
59
  replyTo?: string;
74
60
  subject: string;
@@ -93,12 +79,12 @@ export interface CustomerDetails {
93
79
  export interface LineItem {
94
80
  id?: string;
95
81
  name: string;
96
- amount: Number;
82
+ amount: number;
97
83
  amountName: string;
98
- netAmount: Number;
99
- taxAmount: Number;
100
- grossAmount: Number;
101
- netUnitPrice: Number;
84
+ netAmount: number;
85
+ taxAmount: number;
86
+ grossAmount: number;
87
+ netUnitPrice: number;
102
88
  vatRate: VATRate;
103
89
  comment?: string;
104
90
  }
@@ -109,7 +95,7 @@ export interface CredentialAuth {
109
95
  username: string;
110
96
  password: string;
111
97
  }
112
- export interface InvoiceCreationResponse {
98
+ export interface InvoiceItemResponse {
113
99
  invoice: HostedInvoice;
114
100
  net: number;
115
101
  gross: number;
package/dist/types.js CHANGED
@@ -1,7 +1,4 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.InvoiceTemplate = exports.Language = exports.Currency = exports.PaymentMethod = exports.NamedVATRate = void 0;
4
- var NamedVATRate;
1
+ export var NamedVATRate;
5
2
  (function (NamedVATRate) {
6
3
  NamedVATRate["TEHK"] = "TEHK";
7
4
  NamedVATRate["TAHK"] = "TAHK";
@@ -21,36 +18,18 @@ var NamedVATRate;
21
18
  NamedVATRate["EAM"] = "EAM";
22
19
  NamedVATRate["KBAUK"] = "KBAUK";
23
20
  NamedVATRate["KBAET"] = "KBAET";
24
- })(NamedVATRate = exports.NamedVATRate || (exports.NamedVATRate = {}));
25
- var PaymentMethod;
21
+ })(NamedVATRate || (NamedVATRate = {}));
22
+ export var PaymentMethod;
26
23
  (function (PaymentMethod) {
27
24
  PaymentMethod["Transfer"] = "\u00E1tutal\u00E1s";
28
25
  PaymentMethod["Cash"] = "k\u00E9szp\u00E9nz";
29
26
  PaymentMethod["Card"] = "bankk\u00E1rtya";
30
- })(PaymentMethod = exports.PaymentMethod || (exports.PaymentMethod = {}));
31
- var Currency;
32
- (function (Currency) {
33
- Currency["HUF"] = "HUF";
34
- })(Currency = exports.Currency || (exports.Currency = {}));
35
- var Language;
36
- (function (Language) {
37
- Language["HU"] = "hu";
38
- Language["EN"] = "en";
39
- Language["DE"] = "de";
40
- Language["IT"] = "it";
41
- Language["RO"] = "ro";
42
- Language["SK"] = "sk";
43
- Language["HR"] = "hr";
44
- Language["FR"] = "fr";
45
- Language["ES"] = "es";
46
- Language["CZ"] = "cz";
47
- Language["PL"] = "pl";
48
- })(Language = exports.Language || (exports.Language = {}));
49
- var InvoiceTemplate;
27
+ })(PaymentMethod || (PaymentMethod = {}));
28
+ export var InvoiceTemplate;
50
29
  (function (InvoiceTemplate) {
51
30
  InvoiceTemplate["SzlaMost"] = "SzlaMost";
52
31
  InvoiceTemplate["SzlaAlap"] = "SzlaAlap";
53
32
  InvoiceTemplate["SzlaNoEnv"] = "SzlaNoEnv";
54
33
  InvoiceTemplate["Szla8cm"] = "Szla8cm";
55
34
  InvoiceTemplate["SzlaTomb"] = "SzlaTomb";
56
- })(InvoiceTemplate = exports.InvoiceTemplate || (exports.InvoiceTemplate = {}));
35
+ })(InvoiceTemplate || (InvoiceTemplate = {}));
package/package.json CHANGED
@@ -1,41 +1,47 @@
1
1
  {
2
2
  "name": "@halftome/szamlazz-client",
3
- "version": "1.0.8",
4
- "description": "Node.js client for using szamlazz.hu API",
5
- "scripts": {
6
- "build": "tsc",
7
- "dev": "tsc -w",
8
- "test": "echo \"No test yet\" && exit 0"
9
- },
3
+ "version": "2.0.2",
4
+ "type": "module",
5
+ "description": "Javascript client for using szamlazz.hu API",
10
6
  "repository": {
11
7
  "type": "git",
12
8
  "url": "git+https://github.com/half2me/szamlazz-client.git"
13
9
  },
14
10
  "author": "halftome@gmail.com",
15
11
  "types": "./dist/index.d.ts",
16
- "license": "SEE LICENSE IN LICENCE",
12
+ "license": "MIT",
13
+ "sideEffects": false,
14
+ "engines": {
15
+ "node": ">=20"
16
+ },
17
17
  "files": [
18
18
  "dist/**"
19
19
  ],
20
20
  "main": "./dist/index.js",
21
21
  "exports": {
22
- ".": "./dist/index.js"
22
+ ".": {
23
+ "types": "./dist/index.d.ts",
24
+ "default": "./dist/index.js"
25
+ }
23
26
  },
24
27
  "bugs": {
25
28
  "url": "https://github.com/half2me/szamlazz-client/issues"
26
29
  },
27
30
  "homepage": "https://github.com/half2me/szamlazz-client#readme",
28
31
  "devDependencies": {
29
- "@tsconfig/node14": "^1.0.1",
30
- "@types/node": "^16.3.3",
31
- "@types/node-fetch": "^2.5.11",
32
- "prettier": "^2.3.2",
33
- "tslib": "^2.3.0",
34
- "typescript": "^4.3.5"
32
+ "@tsconfig/node24": "^24.0.4",
33
+ "@types/node": "^25.0.10",
34
+ "prettier": "^3.8.1",
35
+ "tslib": "^2.8.1",
36
+ "typescript": "^5.9.3",
37
+ "vitest": "^4.0.18"
35
38
  },
36
39
  "dependencies": {
37
- "form-data": "^4.0.0",
38
- "node-fetch": "^2.6.1",
39
- "xmlbuilder2": "^3.0.2"
40
+ "xmlbuilder2": "^4.0.3"
41
+ },
42
+ "scripts": {
43
+ "build": "tsc",
44
+ "dev": "tsc -w",
45
+ "test": "vitest run"
40
46
  }
41
- }
47
+ }
package/LICENCE DELETED
@@ -1 +0,0 @@
1
- (c) Copyright 2021 Benjamin Tamasi, all rights reserved.