@finteqhub/sdk-js 0.16.0 → 0.17.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/CHANGELOG.md CHANGED
@@ -1,13 +1,32 @@
1
1
  # Changelog
2
2
 
3
- Notable changes to `@finteqhub/sdk-js`. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
3
+ Notable changes to the SDK. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
4
+
5
+ ## 0.17.0
6
+
7
+ ### Breaking changes
8
+
9
+ - The SDK class is now exported as `Processing`; the previous class name is no longer exported.
10
+ - The constructor takes a single options object instead of positional arguments. The object is validated like the positional arguments were; passing positional arguments throws `TypeError: sdk-js: constructor expects an options object`. Unknown keys are rejected too (`TypeError: sdk-js: unknown option "issecure"`), so a misspelled option, or a `merchantId` left over from 0.15.0, fails loudly instead of silently falling back to the default. The new `ProcessingOptions` type is exported.
11
+
12
+ Migration:
13
+
14
+ ```
15
+ // 0.16.0: positional arguments
16
+ (apiUrl, fingerprintVisitorId, sessionId, isSecure, retryOptions)
17
+
18
+ // 0.17.0: an options object
19
+ new Processing({ apiUrl, fingerprintVisitorId, sessionId, isSecure, retryOptions });
20
+ ```
21
+
22
+ `isSecure` and `retryOptions` stay optional, with the same defaults (`false` and `{}`).
4
23
 
5
24
  ## 0.16.0
6
25
 
7
26
  ### Breaking changes
8
27
 
9
28
  - The SDK no longer sends the `x-merchant-id` header (previously on every request) or the `x-project-id` header (previously on `submit-form` and `operations` requests, taken from the session response). This release requires a backend that no longer expects these headers; against older backends `submit-form` and `sessions` requests are rejected with 400.
10
- - The `merchantId` constructor argument was removed together with the header. The constructor is now `new FinteqHubProcessing(apiUrl, fingerprintVisitorId, sessionId, isSecure?, retryOptions?)` — every argument after `fingerprintVisitorId` shifts one position to the left. Callers must drop the third argument; a call site that still passes it fails argument validation (`isSecure` receives the session id, which is not a boolean, and the constructor throws a `TypeError`).
29
+ - The `merchantId` constructor argument was removed together with the header. The constructor arguments are now `(apiUrl, fingerprintVisitorId, sessionId, isSecure?, retryOptions?)` — every argument after `fingerprintVisitorId` shifts one position to the left. Callers must drop the third argument; a call site that still passes it fails argument validation (`isSecure` receives the session id, which is not a boolean, and the constructor throws a `TypeError`).
11
30
 
12
31
  ### Changed
13
32
 
@@ -41,7 +60,7 @@ No code changes: the SDK behaves exactly as in 0.13.0 (only the version reported
41
60
 
42
61
  ### Breaking changes
43
62
 
44
- - The SDK identification header sent with every request was renamed from `X-Finteqhub-SDK` to `x-pgw-sdk`, now spelled in lower case to match the other headers the SDK sends. Header names are case-insensitive, so only the name itself changed; the value format (`sdk-js/<version>`) is unchanged.
63
+ - The SDK identification header sent with every request was renamed to `x-pgw-sdk`, spelled in lower case to match the other headers the SDK sends. Backends that read the header by its previous name must switch to `x-pgw-sdk`; the value format (`sdk-js/<version>`) is unchanged.
45
64
 
46
65
  ## 0.12.0
47
66
 
package/README.md CHANGED
@@ -1,16 +1,28 @@
1
1
  # processing-sdk
2
2
 
3
- Use `new FinteqHubProcessing(apiUrl: string, fingerprintVisitorId: string, sessionId: string, isSecure?: boolean, retryOptions?: RetryOptions)` to create an instance of the FinteqHubProcessing object. The FinteqHubProcessing object is your entrypoint to FinteqHub processing SDK.
3
+ Use `new Processing(options: ProcessingOptions)` to create an instance of the Processing object. The Processing object is your entrypoint to the processing SDK.
4
4
 
5
5
  ```
6
- const processing = new FinteqHubProcessing('api-url', 'fingerprint-visitor-id', 'session-id');
6
+ interface ProcessingOptions {
7
+ apiUrl: string;
8
+ fingerprintVisitorId: string;
9
+ sessionId: string;
10
+ isSecure?: boolean; // default false
11
+ retryOptions?: RetryOptions; // default {}
12
+ }
13
+
14
+ const processing = new Processing({
15
+ apiUrl: 'api-url',
16
+ fingerprintVisitorId: 'fingerprint-visitor-id',
17
+ sessionId: 'session-id',
18
+ });
7
19
  ```
8
20
 
9
- The constructor validates its arguments and throws a `TypeError` when `apiUrl`, `fingerprintVisitorId` or `sessionId` is missing, empty or not a string, when `isSecure` is not a boolean, or when `retryOptions` is malformed (see [Retries and error diagnostics](#retries-and-error-diagnostics)).
21
+ The constructor validates its options and throws a `TypeError` when they are not an object, when they contain an unknown key (for example a misspelled `issecure`), when `apiUrl`, `fingerprintVisitorId` or `sessionId` is missing, empty or not a string, when `isSecure` is not a boolean, or when `retryOptions` is malformed (see [Retries and error diagnostics](#retries-and-error-diagnostics)).
10
22
 
11
23
  ## Retries and error diagnostics
12
24
 
13
- Failed HTTP requests are retried automatically with exponential backoff (`100ms → 200ms → 500ms → 1000ms → 2000ms`; every retry after the fifth waits 2000ms). Retries can be configured via the optional `retryOptions` constructor argument (the fifth one, after `isSecure`):
25
+ Failed HTTP requests are retried automatically with exponential backoff (`100ms → 200ms → 500ms → 1000ms → 2000ms`; every retry after the fifth waits 2000ms). Retries can be configured via the optional `retryOptions` constructor option:
14
26
 
15
27
  ```
16
28
  interface RetryOptions {
@@ -18,16 +30,22 @@ interface RetryOptions {
18
30
  retryStatusCode?: (statusCode: number) => boolean; // default: statusCode < 200 || statusCode === 408 || statusCode >= 500
19
31
  }
20
32
 
21
- const processing = new FinteqHubProcessing('api-url', 'fingerprint-visitor-id', 'session-id', false, {
22
- retryCount: 3,
33
+ const processing = new Processing({
34
+ apiUrl: 'api-url',
35
+ fingerprintVisitorId: 'fingerprint-visitor-id',
36
+ sessionId: 'session-id',
37
+ retryOptions: { retryCount: 3 },
23
38
  });
24
39
  ```
25
40
 
26
41
  To disable retries entirely, pass `retryCount: 0` — every request is then sent exactly once, as in 0.11.0. Error diagnostics (`RequestError`, the `console.error` dump) are still collected:
27
42
 
28
43
  ```
29
- const processing = new FinteqHubProcessing('api-url', 'fingerprint-visitor-id', 'session-id', false, {
30
- retryCount: 0,
44
+ const processing = new Processing({
45
+ apiUrl: 'api-url',
46
+ fingerprintVisitorId: 'fingerprint-visitor-id',
47
+ sessionId: 'session-id',
48
+ retryOptions: { retryCount: 0 },
31
49
  });
32
50
  ```
33
51
 
@@ -59,7 +77,7 @@ Every request the SDK makes carries an extra header:
59
77
  x-pgw-sdk: sdk-js/<version>
60
78
  ```
61
79
 
62
- The value contains the SDK name and version (kept in sync with `package.json` by a test) — for example `sdk-js/0.11.0`. FinteqHub uses this header to identify traffic coming from the official SDK integration — for example to notify affected merchants when a security fix is released. It does not affect authentication or request routing.
80
+ The value contains the SDK name and version (kept in sync with `package.json` by a test) — for example `sdk-js/0.11.0`. The backend uses this header to identify traffic coming from the official SDK integration — for example to notify affected merchants when a security fix is released. It does not affect authentication or request routing.
63
81
 
64
82
  The header is added automatically to every request and cannot be disabled.
65
83
 
@@ -94,13 +112,13 @@ processing
94
112
  The minimal flow is to construct the instance and call `submitForm` — no other request is needed before it. Use it when your own UI already knows what to collect from the customer (for example, the payment method and its credential fields are fixed on your side):
95
113
 
96
114
  ```
97
- import { FinteqHubProcessing } from "@finteqhub/sdk-js";
115
+ import { Processing } from "@finteqhub/sdk-js";
98
116
  import FingerprintJS from "@fingerprintjs/fingerprintjs";
99
117
 
100
118
  const fp = await FingerprintJS.load();
101
119
  const result = await fp.get();
102
120
 
103
- const processing = new FinteqHubProcessing(apiUrl, result.visitorId, sessionId);
121
+ const processing = new Processing({ apiUrl, fingerprintVisitorId: result.visitorId, sessionId });
104
122
 
105
123
  const data = {/** collect data from form **/}
106
124
 
@@ -115,7 +133,7 @@ processing
115
133
  Call `getSession` first when the form itself is built from the session: available payment methods, their credential fields, the operation amount and currency. `submitForm` does not use the result — it only drives your UI:
116
134
 
117
135
  ```
118
- const processing = new FinteqHubProcessing(apiUrl, result.visitorId, sessionId);
136
+ const processing = new Processing({ apiUrl, fingerprintVisitorId: result.visitorId, sessionId });
119
137
 
120
138
  const session = await processing.getSession();
121
139
 
@@ -3,6 +3,13 @@ export interface RetryOptions {
3
3
  retryCount?: number;
4
4
  retryStatusCode?: (statusCode: number) => boolean;
5
5
  }
6
+ export interface ProcessingOptions {
7
+ apiUrl: string;
8
+ fingerprintVisitorId: string;
9
+ sessionId: string;
10
+ isSecure?: boolean;
11
+ retryOptions?: RetryOptions;
12
+ }
6
13
  export declare type RequestAttempt = {
7
14
  durationMs: number;
8
15
  status?: number;
@@ -44,14 +51,14 @@ export declare class RequestError extends Error {
44
51
  diagnostics: RequestDiagnostics;
45
52
  constructor(message: string, diagnostics: RequestDiagnostics);
46
53
  }
47
- export declare class FinteqHubProcessing {
54
+ export declare class Processing {
48
55
  private apiUrl;
49
56
  private fingerprintVisitorId;
50
57
  private sessionId;
51
58
  private projectId;
52
59
  private isSecure;
53
60
  private retryOptions;
54
- constructor(apiUrl: string, fingerprintVisitorId: string, sessionId: string, isSecure?: boolean, retryOptions?: RetryOptions);
61
+ constructor(options: ProcessingOptions);
55
62
  getSession(): Promise<SessionResponse>;
56
63
  submitForm(data: SubmitData): Promise<ProcessOperationRedirectResponse>;
57
64
  private processOperation;
@@ -24,9 +24,10 @@ const sanitizeBody = (body) => body.slice(0, MAX_BODY_SNIPPET_LENGTH).replace(/\
24
24
  // 400 is deliberately not retried: the backend returns it for deterministic validation
25
25
  // failures and for duplicate-submit rejections — retrying either only delays the error
26
26
  const defaultRetryStatusCode = (statusCode) => statusCode < 200 || statusCode === 408 || statusCode >= 500;
27
- export class FinteqHubProcessing {
28
- constructor(apiUrl, fingerprintVisitorId, sessionId, isSecure = false, retryOptions = {}) {
29
- validateArguments({ apiUrl, fingerprintVisitorId, sessionId, isSecure, retryOptions });
27
+ export class Processing {
28
+ constructor(options) {
29
+ validateArguments(options);
30
+ const { apiUrl, fingerprintVisitorId, sessionId, isSecure = false, retryOptions = {} } = options;
30
31
  this.apiUrl = apiUrl;
31
32
  this.fingerprintVisitorId = fingerprintVisitorId;
32
33
  this.sessionId = sessionId;
@@ -1,4 +1,4 @@
1
- import type { RetryOptions } from "./processing";
1
+ import type { ProcessingOptions } from "./processing";
2
2
  export declare const DeviceType: {
3
3
  Unknown: string;
4
4
  Computer: string;
@@ -10,14 +10,7 @@ export declare const DeviceType: {
10
10
  };
11
11
  export declare function uuid(): string;
12
12
  export declare function getDeviceType(): string;
13
- declare type ConstructorArguments = {
14
- apiUrl: string;
15
- fingerprintVisitorId: string;
16
- sessionId: string;
17
- isSecure: boolean;
18
- retryOptions: RetryOptions;
19
- };
20
- export declare function validateArguments(args: ConstructorArguments): void;
13
+ export declare function validateArguments(options: ProcessingOptions): void;
21
14
  /** Returns native browser hints, falling back to low entropy values if needed. */
22
15
  export declare function getClientHints(): Promise<{
23
16
  architecture?: string;
@@ -79,4 +72,3 @@ export declare function getDeviceData(): Promise<{
79
72
  };
80
73
  };
81
74
  }>;
82
- export {};
package/dist/src/utils.js CHANGED
@@ -50,16 +50,27 @@ export function getDeviceType() {
50
50
  return DeviceType.Unknown;
51
51
  }
52
52
  const REQUIRED_STRINGS = ["apiUrl", "fingerprintVisitorId", "sessionId"];
53
- export function validateArguments(args) {
53
+ const KNOWN_OPTIONS = [...REQUIRED_STRINGS, "isSecure", "retryOptions"];
54
+ export function validateArguments(options) {
55
+ // catches callers still using the positional signature from 0.16.0 and earlier
56
+ if (typeof options !== "object" || options === null) {
57
+ throw new TypeError("sdk-js: constructor expects an options object");
58
+ }
59
+ // a misspelled key (e.g. `issecure`) would otherwise silently fall back to the default
60
+ for (const key of Object.keys(options)) {
61
+ if (!KNOWN_OPTIONS.includes(key)) {
62
+ throw new TypeError(`sdk-js: unknown option "${key}"`);
63
+ }
64
+ }
54
65
  for (const key of REQUIRED_STRINGS) {
55
- if (typeof args[key] !== "string" || args[key] === "") {
66
+ if (typeof options[key] !== "string" || options[key] === "") {
56
67
  throw new TypeError(`sdk-js: ${key} must be a non-empty string`);
57
68
  }
58
69
  }
59
- if (typeof args.isSecure !== "boolean") {
70
+ const { isSecure = false, retryOptions = {} } = options;
71
+ if (typeof isSecure !== "boolean") {
60
72
  throw new TypeError("sdk-js: isSecure must be a boolean");
61
73
  }
62
- const { retryOptions } = args;
63
74
  if (typeof retryOptions !== "object" || retryOptions === null) {
64
75
  throw new TypeError("sdk-js: retryOptions must be an object");
65
76
  }
@@ -1,3 +1,3 @@
1
1
  export declare const SDK_HEADER_NAME = "x-pgw-sdk";
2
- export declare const SDK_VERSION = "0.16.0";
2
+ export declare const SDK_VERSION = "0.17.0";
3
3
  export declare const SDK_HEADER_VALUE: string;
@@ -1,3 +1,3 @@
1
1
  export const SDK_HEADER_NAME = "x-pgw-sdk";
2
- export const SDK_VERSION = "0.16.0";
2
+ export const SDK_VERSION = "0.17.0";
3
3
  export const SDK_HEADER_VALUE = `sdk-js/${SDK_VERSION}`;
package/package.json CHANGED
@@ -1,14 +1,13 @@
1
1
  {
2
2
  "name": "@finteqhub/sdk-js",
3
- "version": "0.16.0",
4
- "description": "SDK for interacting with FinteqHub processing API",
3
+ "version": "0.17.0",
4
+ "description": "SDK for interacting with the processing API",
5
5
  "main": "./dist/index.js",
6
6
  "typings": "./dist/index.d.ts",
7
7
  "files": [
8
8
  "dist/*",
9
9
  "CHANGELOG.md"
10
10
  ],
11
- "author": "FinteqHub",
12
11
  "repository": {
13
12
  "type": "git",
14
13
  "url": "git+https://github.com/finteqhub/sdk-js.git"