fints-lib 0.6.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 +21 -0
- package/README.md +263 -0
- package/package.json +80 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2018 Frederick Gnodtke
|
|
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
ADDED
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
# fints-lib
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/fints-lib)
|
|
4
|
+
[](https://github.com/larsdecker/fints/actions/workflows/ci.yml)
|
|
5
|
+
|
|
6
|
+
A client library for communicating with [FinTS servers](https://www.hbci-zka.de/).
|
|
7
|
+
|
|
8
|
+
> **Note:** This is a fork and continuation of [Prior99/fints](https://github.com/Prior99/fints). Published as `fints-lib` on npm.
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install fints-lib
|
|
14
|
+
# or
|
|
15
|
+
yarn add fints-lib
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Example
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
import { PinTanClient } from "fints-lib";
|
|
22
|
+
|
|
23
|
+
const startDate = new Date("2018-08-10T12:00:00Z");
|
|
24
|
+
const endDate = new Date("2018-10-10T12:00:00Z");
|
|
25
|
+
|
|
26
|
+
const client = new PinTanClient({
|
|
27
|
+
url: "https://example.com/fints",
|
|
28
|
+
name: "username",
|
|
29
|
+
pin: 12345,
|
|
30
|
+
blz: 12345678,
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
const accounts = await client.accounts();
|
|
34
|
+
console.info(accounts); // List of all accounts.
|
|
35
|
+
|
|
36
|
+
const statements = await client.statements(accounts[0], startDate, endDate);
|
|
37
|
+
console.info(statements); // List of all statements with transactions in specified date range.
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
### Handling login TAN challenges
|
|
42
|
+
|
|
43
|
+
Some banks require a TAN as part of the login dialog. When that happens the library raises a `TanRequiredError`. The error now includes enhanced information about the TAN process state and context. You can complete the login by submitting the TAN and continue working with the returned dialog:
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
import { TanRequiredError, TanProcessStep } from "fints-lib";
|
|
47
|
+
|
|
48
|
+
try {
|
|
49
|
+
const accounts = await client.accounts();
|
|
50
|
+
} catch (error) {
|
|
51
|
+
if (error instanceof TanRequiredError) {
|
|
52
|
+
// Enhanced error information
|
|
53
|
+
console.log("TAN Challenge:", error.challengeText);
|
|
54
|
+
console.log("Process Step:", error.getStepDescription());
|
|
55
|
+
console.log("Triggering Segment:", error.triggeringSegment);
|
|
56
|
+
console.log("Is Multi-Step:", error.isMultiStep());
|
|
57
|
+
|
|
58
|
+
// Complete the login with TAN
|
|
59
|
+
const dialog = await client.completeLogin(error.dialog, error.transactionReference, "123456");
|
|
60
|
+
const accounts = await client.accounts(dialog);
|
|
61
|
+
await dialog.end();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
[Submitting SEPA credit transfers](#submitting-a-credit-transfer)
|
|
67
|
+
[Submitting SEPA direct debits](#submitting-a-direct-debit)
|
|
68
|
+
|
|
69
|
+
[Further code examples](README_advanced_usage.md)
|
|
70
|
+
|
|
71
|
+
## Features
|
|
72
|
+
|
|
73
|
+
- **FinTS 3.0 Compatibility**: Full support for FinTS 3.0 (HBCI version 300) protocol
|
|
74
|
+
- **Enhanced Error Handling**: Comprehensive error code mapping with specific exception types
|
|
75
|
+
- **Timeout & Retry**: Configurable HTTP timeouts and automatic retry with exponential backoff
|
|
76
|
+
- **Multi-Step TAN Flows**: Enhanced support for complex TAN authentication flows
|
|
77
|
+
- Load list of accounts.
|
|
78
|
+
- Load list of statements and transactions in specified range.
|
|
79
|
+
- Fetch current account balances.
|
|
80
|
+
- List depot holdings.
|
|
81
|
+
- Initiate SEPA credit transfers (pain.001) with TAN handling.
|
|
82
|
+
- Submit SEPA direct debit orders (pain.008) with TAN handling.
|
|
83
|
+
- Parse statement [MT940](https://en.wikipedia.org/wiki/MT940) format.
|
|
84
|
+
- Parse transaction descriptions.
|
|
85
|
+
- Extract [reference tags](https://www.dzbank.de/content/dam/dzbank_de/de/home/produkte_services/Firmenkunden/PDF-Dokumente/transaction%20banking/elektronicBanking/SEPA-Belegungsregeln_MT940-DK_082016.~644b217ec96b35dfffcaf18dc2df800a.pdf) from transactions.
|
|
86
|
+
- List supported TAN methods.
|
|
87
|
+
- Parse basic metadata.
|
|
88
|
+
|
|
89
|
+
## Configuration Options
|
|
90
|
+
|
|
91
|
+
### Basic Configuration
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
const client = new PinTanClient({
|
|
95
|
+
url: "https://example.com/fints",
|
|
96
|
+
name: "username",
|
|
97
|
+
pin: 12345,
|
|
98
|
+
blz: 12345678,
|
|
99
|
+
});
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Advanced Configuration with Timeout & Retry
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
const client = new PinTanClient({
|
|
106
|
+
url: "https://example.com/fints",
|
|
107
|
+
name: "username",
|
|
108
|
+
pin: 12345,
|
|
109
|
+
blz: 12345678,
|
|
110
|
+
// Optional: Configure HTTP timeout (default: 30000ms)
|
|
111
|
+
timeout: 45000,
|
|
112
|
+
// Optional: Configure max retry attempts (default: 3)
|
|
113
|
+
maxRetries: 5,
|
|
114
|
+
// Optional: Configure retry delay for exponential backoff (default: 1000ms)
|
|
115
|
+
retryDelay: 2000,
|
|
116
|
+
// Optional: Enable debug mode
|
|
117
|
+
debug: true,
|
|
118
|
+
});
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Error Handling
|
|
122
|
+
|
|
123
|
+
The library now provides comprehensive error handling with specific exception types:
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
import {
|
|
127
|
+
FinTSError,
|
|
128
|
+
AuthenticationError,
|
|
129
|
+
PinError,
|
|
130
|
+
OrderRejectedError,
|
|
131
|
+
DialogAbortedError,
|
|
132
|
+
StrongAuthenticationRequiredError,
|
|
133
|
+
} from "fints-lib";
|
|
134
|
+
|
|
135
|
+
try {
|
|
136
|
+
const accounts = await client.accounts();
|
|
137
|
+
} catch (error) {
|
|
138
|
+
if (error instanceof PinError) {
|
|
139
|
+
console.error("PIN is incorrect:", error.message);
|
|
140
|
+
} else if (error instanceof AuthenticationError) {
|
|
141
|
+
console.error("Authentication failed:", error.message);
|
|
142
|
+
} else if (error instanceof StrongAuthenticationRequiredError) {
|
|
143
|
+
console.error("Strong customer authentication (PSD2) required:", error.message);
|
|
144
|
+
} else if (error instanceof FinTSError) {
|
|
145
|
+
console.error("FinTS error:", error.code, error.message);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Error Code Mapping
|
|
151
|
+
|
|
152
|
+
All FinTS error codes are now mapped to descriptive messages:
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
import { formatErrorCode, getErrorCodeInfo } from "fints-lib";
|
|
156
|
+
|
|
157
|
+
// Get detailed information about an error code
|
|
158
|
+
const info = getErrorCodeInfo("9942"); // PIN incorrect
|
|
159
|
+
console.log(info.category); // "error"
|
|
160
|
+
console.log(info.message); // "PIN falsch"
|
|
161
|
+
|
|
162
|
+
// Format error code with message
|
|
163
|
+
const formatted = formatErrorCode("9942", "Custom message");
|
|
164
|
+
// Output: "[9942] PIN falsch - Custom message"
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Missing
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
## Submitting a credit transfer
|
|
171
|
+
|
|
172
|
+
```typescript
|
|
173
|
+
import { PinTanClient, TanRequiredError, CreditTransferRequest } from "fints-lib";
|
|
174
|
+
|
|
175
|
+
const client = new PinTanClient({
|
|
176
|
+
url: "https://example.com/fints",
|
|
177
|
+
name: "username",
|
|
178
|
+
pin: 12345,
|
|
179
|
+
blz: 12345678,
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
const accounts = await client.accounts();
|
|
183
|
+
const account = accounts[0];
|
|
184
|
+
|
|
185
|
+
const transfer: CreditTransferRequest = {
|
|
186
|
+
debtorName: "John Doe",
|
|
187
|
+
creditor: {
|
|
188
|
+
name: "ACME GmbH",
|
|
189
|
+
iban: "DE44500105175407324931",
|
|
190
|
+
bic: "INGDDEFFXXX",
|
|
191
|
+
},
|
|
192
|
+
amount: 100.0,
|
|
193
|
+
remittanceInformation: "Invoice 0815",
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
try {
|
|
197
|
+
const submission = await client.creditTransfer(account, transfer);
|
|
198
|
+
console.log(submission.taskId);
|
|
199
|
+
} catch (error) {
|
|
200
|
+
if (error instanceof TanRequiredError) {
|
|
201
|
+
const submission = error.creditTransferSubmission!;
|
|
202
|
+
const completed = await client.completeCreditTransfer(
|
|
203
|
+
error.dialog,
|
|
204
|
+
error.transactionReference,
|
|
205
|
+
"123456",
|
|
206
|
+
submission,
|
|
207
|
+
);
|
|
208
|
+
console.log(completed.taskId);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
## Submitting a direct debit
|
|
214
|
+
|
|
215
|
+
```typescript
|
|
216
|
+
import { PinTanClient, TanRequiredError, DirectDebitRequest } from "fints-lib";
|
|
217
|
+
|
|
218
|
+
const client = new PinTanClient({
|
|
219
|
+
url: "https://example.com/fints",
|
|
220
|
+
name: "username",
|
|
221
|
+
pin: 12345,
|
|
222
|
+
blz: 12345678,
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
const accounts = await client.accounts();
|
|
226
|
+
const account = accounts[0];
|
|
227
|
+
|
|
228
|
+
const debit: DirectDebitRequest = {
|
|
229
|
+
creditorName: "ACME GmbH",
|
|
230
|
+
creditorId: "DE98ZZZ09999999999",
|
|
231
|
+
debtor: {
|
|
232
|
+
name: "John Doe",
|
|
233
|
+
iban: "DE02120300000000202051",
|
|
234
|
+
},
|
|
235
|
+
amount: 42.5,
|
|
236
|
+
mandateId: "MANDATE-123",
|
|
237
|
+
mandateSignatureDate: new Date("2022-01-10"),
|
|
238
|
+
requestedCollectionDate: new Date(),
|
|
239
|
+
remittanceInformation: "Invoice 0815",
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
try {
|
|
243
|
+
const submission = await client.directDebit(account, debit);
|
|
244
|
+
console.log(submission.taskId);
|
|
245
|
+
} catch (error) {
|
|
246
|
+
if (error instanceof TanRequiredError) {
|
|
247
|
+
const submission = error.directDebitSubmission!;
|
|
248
|
+
const completed = await client.completeDirectDebit(
|
|
249
|
+
error.dialog,
|
|
250
|
+
error.transactionReference,
|
|
251
|
+
"123456",
|
|
252
|
+
submission,
|
|
253
|
+
);
|
|
254
|
+
console.log(completed.taskId);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
## Resources
|
|
260
|
+
|
|
261
|
+
- [API Reference](https://prior99.gitlab.io/fints)
|
|
262
|
+
- [Official specification](https://www.hbci-zka.de/spec/3_0.htm)
|
|
263
|
+
- [Database of banks with their URLs](https://github.com/jhermsmeier/fints-institute-db)
|
package/package.json
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "fints-lib",
|
|
3
|
+
"version": "0.6.0",
|
|
4
|
+
"description": "FinTS client library with psd2 support",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"fints",
|
|
7
|
+
"hbci",
|
|
8
|
+
"banking",
|
|
9
|
+
"api",
|
|
10
|
+
"ios",
|
|
11
|
+
"nodejs",
|
|
12
|
+
"node",
|
|
13
|
+
"psd2",
|
|
14
|
+
"sepa",
|
|
15
|
+
"mt940",
|
|
16
|
+
"pain.001",
|
|
17
|
+
"pain.008",
|
|
18
|
+
"german-banking",
|
|
19
|
+
"online-banking"
|
|
20
|
+
],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"prebuild": "cxsd -t generated https://raw.githubusercontent.com/hbci4j/hbci4java/master/src/main/resources/pain.001.001.03.xsd",
|
|
23
|
+
"build": "tsc -p ./tsconfig-build.json",
|
|
24
|
+
"clean": "rm -rf dist",
|
|
25
|
+
"docs": "typedoc --mode file --out docs/ src/",
|
|
26
|
+
"test": "TZ=UTC jest --testPathIgnorePatterns=test-pin-tan-client-e2e",
|
|
27
|
+
"test:acceptance": "TZ=UTC jest test-pin-tan-client-e2e"
|
|
28
|
+
},
|
|
29
|
+
"files": [
|
|
30
|
+
"dist",
|
|
31
|
+
"LICENSE",
|
|
32
|
+
"package.json",
|
|
33
|
+
"README.md"
|
|
34
|
+
],
|
|
35
|
+
"main": "dist/index.js",
|
|
36
|
+
"repository": {
|
|
37
|
+
"type": "git",
|
|
38
|
+
"url": "https://github.com/larsdecker/fints",
|
|
39
|
+
"directory": "packages/fints"
|
|
40
|
+
},
|
|
41
|
+
"typings": "dist/index.d.ts",
|
|
42
|
+
"author": "Frederick Gnodtke",
|
|
43
|
+
"contributors": [
|
|
44
|
+
{
|
|
45
|
+
"name": "Mathias Arens",
|
|
46
|
+
"email": "github@mathiasarens.de",
|
|
47
|
+
"url": "https://github.com/mathiasarens"
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"name": "Lars Decker",
|
|
51
|
+
"url": "https://github.com/larsdecker"
|
|
52
|
+
}
|
|
53
|
+
],
|
|
54
|
+
"license": "MIT",
|
|
55
|
+
"devDependencies": {
|
|
56
|
+
"@types/invariant": "^2.2.37",
|
|
57
|
+
"@types/isomorphic-fetch": "^0.0.39",
|
|
58
|
+
"@types/istanbul-lib-report": "^3.0.3",
|
|
59
|
+
"@types/jest": "^29.5.14",
|
|
60
|
+
"@types/node": "^25.0.3",
|
|
61
|
+
"cxsd": "^0.1.1",
|
|
62
|
+
"fetch-mock": "^12.6.0",
|
|
63
|
+
"fints-institute-db": "^0.16.0",
|
|
64
|
+
"jest": "^29.7.0",
|
|
65
|
+
"minimatch": "^10.0.1",
|
|
66
|
+
"ts-jest": "^29.4.6",
|
|
67
|
+
"typedoc": "^0.27.9",
|
|
68
|
+
"typescript": "^5.8.0"
|
|
69
|
+
},
|
|
70
|
+
"dependencies": {
|
|
71
|
+
"bind-decorator": "^1.0.11",
|
|
72
|
+
"date-fns": "^4.1.0",
|
|
73
|
+
"fast-xml-parser": "^5.3.3",
|
|
74
|
+
"iconv-lite": "^0.7.1",
|
|
75
|
+
"invariant": "^2.2.4",
|
|
76
|
+
"isomorphic-fetch": "^3.0.0",
|
|
77
|
+
"mt940-js": "^1.0.0",
|
|
78
|
+
"winston": "^3.19.0"
|
|
79
|
+
}
|
|
80
|
+
}
|