@laranex/myanmar-payments 0.0.0-stage → 4.0.0-dev.1
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 +21 -0
- package/LICENSE.md +21 -0
- package/README.md +10 -2
- package/dist/cjs/aya-pay/aya-pay.d.ts +122 -0
- package/dist/cjs/aya-pay/aya-pay.js +301 -0
- package/dist/cjs/aya-pay/index.d.ts +1 -0
- package/dist/cjs/aya-pay/index.js +8 -0
- package/dist/cjs/core/amount.d.ts +57 -0
- package/dist/cjs/core/amount.js +107 -0
- package/dist/cjs/core/cache.d.ts +26 -0
- package/dist/cjs/core/cache.js +35 -0
- package/dist/cjs/core/callback.d.ts +180 -0
- package/dist/cjs/core/callback.js +304 -0
- package/dist/cjs/core/crypto.d.ts +19 -0
- package/dist/cjs/core/crypto.js +50 -0
- package/dist/cjs/core/env.d.ts +21 -0
- package/dist/cjs/core/env.js +54 -0
- package/dist/cjs/core/errors.d.ts +56 -0
- package/dist/cjs/core/errors.js +78 -0
- package/dist/cjs/core/http.d.ts +81 -0
- package/dist/cjs/core/http.js +128 -0
- package/dist/cjs/core/index.d.ts +8 -0
- package/dist/cjs/core/index.js +30 -0
- package/dist/cjs/core/json.d.ts +44 -0
- package/dist/cjs/core/json.js +254 -0
- package/dist/cjs/core/results.d.ts +122 -0
- package/dist/cjs/core/results.js +147 -0
- package/dist/cjs/core/status.d.ts +50 -0
- package/dist/cjs/core/status.js +60 -0
- package/dist/cjs/core/validate.d.ts +46 -0
- package/dist/cjs/core/validate.js +148 -0
- package/dist/cjs/core/values.d.ts +16 -0
- package/dist/cjs/core/values.js +45 -0
- package/dist/cjs/cyber-source/cyber-source.d.ts +95 -0
- package/dist/cjs/cyber-source/cyber-source.js +188 -0
- package/dist/cjs/cyber-source/index.d.ts +1 -0
- package/dist/cjs/cyber-source/index.js +7 -0
- package/dist/cjs/index.d.ts +7 -0
- package/dist/cjs/index.js +25 -0
- package/dist/cjs/kbz-pay/index.d.ts +2 -0
- package/dist/cjs/kbz-pay/index.js +8 -0
- package/dist/cjs/kbz-pay/kbz-pay.d.ts +102 -0
- package/dist/cjs/kbz-pay/kbz-pay.js +266 -0
- package/dist/cjs/kbz-pay/signer.d.ts +15 -0
- package/dist/cjs/kbz-pay/signer.js +36 -0
- package/dist/cjs/myanmar-payments.d.ts +50 -0
- package/dist/cjs/myanmar-payments.js +73 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/wave-money/index.d.ts +1 -0
- package/dist/cjs/wave-money/index.js +6 -0
- package/dist/cjs/wave-money/wave-money.d.ts +111 -0
- package/dist/cjs/wave-money/wave-money.js +251 -0
- package/dist/cjs/yoma-mmqr/index.d.ts +1 -0
- package/dist/cjs/yoma-mmqr/index.js +6 -0
- package/dist/cjs/yoma-mmqr/yoma-mmqr.d.ts +105 -0
- package/dist/cjs/yoma-mmqr/yoma-mmqr.js +233 -0
- package/dist/esm/aya-pay/aya-pay.d.ts +122 -0
- package/dist/esm/aya-pay/aya-pay.js +296 -0
- package/dist/esm/aya-pay/index.d.ts +1 -0
- package/dist/esm/aya-pay/index.js +1 -0
- package/dist/esm/core/amount.d.ts +57 -0
- package/dist/esm/core/amount.js +103 -0
- package/dist/esm/core/cache.d.ts +26 -0
- package/dist/esm/core/cache.js +31 -0
- package/dist/esm/core/callback.d.ts +180 -0
- package/dist/esm/core/callback.js +294 -0
- package/dist/esm/core/crypto.d.ts +19 -0
- package/dist/esm/core/crypto.js +41 -0
- package/dist/esm/core/env.d.ts +21 -0
- package/dist/esm/core/env.js +45 -0
- package/dist/esm/core/errors.d.ts +56 -0
- package/dist/esm/core/errors.js +70 -0
- package/dist/esm/core/http.d.ts +81 -0
- package/dist/esm/core/http.js +121 -0
- package/dist/esm/core/index.d.ts +8 -0
- package/dist/esm/core/index.js +7 -0
- package/dist/esm/core/json.d.ts +44 -0
- package/dist/esm/core/json.js +244 -0
- package/dist/esm/core/results.d.ts +122 -0
- package/dist/esm/core/results.js +139 -0
- package/dist/esm/core/status.d.ts +50 -0
- package/dist/esm/core/status.js +56 -0
- package/dist/esm/core/validate.d.ts +46 -0
- package/dist/esm/core/validate.js +142 -0
- package/dist/esm/core/values.d.ts +16 -0
- package/dist/esm/core/values.js +38 -0
- package/dist/esm/cyber-source/cyber-source.d.ts +95 -0
- package/dist/esm/cyber-source/cyber-source.js +184 -0
- package/dist/esm/cyber-source/index.d.ts +1 -0
- package/dist/esm/cyber-source/index.js +1 -0
- package/dist/esm/index.d.ts +7 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/kbz-pay/index.d.ts +2 -0
- package/dist/esm/kbz-pay/index.js +2 -0
- package/dist/esm/kbz-pay/kbz-pay.d.ts +102 -0
- package/dist/esm/kbz-pay/kbz-pay.js +262 -0
- package/dist/esm/kbz-pay/signer.d.ts +15 -0
- package/dist/esm/kbz-pay/signer.js +32 -0
- package/dist/esm/myanmar-payments.d.ts +50 -0
- package/dist/esm/myanmar-payments.js +69 -0
- package/dist/esm/wave-money/index.d.ts +1 -0
- package/dist/esm/wave-money/index.js +1 -0
- package/dist/esm/wave-money/wave-money.d.ts +111 -0
- package/dist/esm/wave-money/wave-money.js +246 -0
- package/dist/esm/yoma-mmqr/index.d.ts +1 -0
- package/dist/esm/yoma-mmqr/index.js +1 -0
- package/dist/esm/yoma-mmqr/yoma-mmqr.d.ts +105 -0
- package/dist/esm/yoma-mmqr/yoma-mmqr.js +229 -0
- package/package.json +151 -4
- package/skills/node-myanmar-payments/SKILL.md +109 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.envFirst = envFirst;
|
|
4
|
+
exports.envSandbox = envSandbox;
|
|
5
|
+
exports.envInt = envInt;
|
|
6
|
+
exports.requireSetting = requireSetting;
|
|
7
|
+
exports.optionalSetting = optionalSetting;
|
|
8
|
+
exports.trimUrl = trimUrl;
|
|
9
|
+
exports.defaultEnv = defaultEnv;
|
|
10
|
+
const errors_js_1 = require("./errors.js");
|
|
11
|
+
/** The first non-empty value among `keys`, trimmed, or `''`. @internal */
|
|
12
|
+
function envFirst(env, ...keys) {
|
|
13
|
+
for (const key of keys) {
|
|
14
|
+
const value = env[key]?.trim();
|
|
15
|
+
if (value) {
|
|
16
|
+
return value;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return '';
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Reads a `*_SANDBOX` variable. Only `false`, `0`, `f`, `no` and `off` (any case) select
|
|
23
|
+
* production; unset or unrecognized values mean sandbox.
|
|
24
|
+
*
|
|
25
|
+
* @internal
|
|
26
|
+
*/
|
|
27
|
+
function envSandbox(env, key) {
|
|
28
|
+
const value = env[key]?.trim().toLowerCase() ?? '';
|
|
29
|
+
return !['false', '0', 'f', 'no', 'off'].includes(value);
|
|
30
|
+
}
|
|
31
|
+
/** An integer variable, or `undefined` when unset or not an integer. @internal */
|
|
32
|
+
function envInt(env, key) {
|
|
33
|
+
const value = env[key]?.trim() ?? '';
|
|
34
|
+
return /^[+-]?\d+$/.test(value) ? Number.parseInt(value, 10) : undefined;
|
|
35
|
+
}
|
|
36
|
+
/** The trimmed value, or throws a {@link ConfigurationError} naming `key`. @internal */
|
|
37
|
+
function requireSetting(gateway, key, value) {
|
|
38
|
+
if (typeof value !== 'string' || value.trim() === '') {
|
|
39
|
+
throw new errors_js_1.ConfigurationError(gateway, key);
|
|
40
|
+
}
|
|
41
|
+
return value;
|
|
42
|
+
}
|
|
43
|
+
/** A trimmed optional string, `undefined` when blank. @internal */
|
|
44
|
+
function optionalSetting(value) {
|
|
45
|
+
return typeof value === 'string' && value.trim() !== '' ? value : undefined;
|
|
46
|
+
}
|
|
47
|
+
/** Removes trailing slashes. @internal */
|
|
48
|
+
function trimUrl(url) {
|
|
49
|
+
return url.replace(/\/+$/, '');
|
|
50
|
+
}
|
|
51
|
+
/** The default environment: `process.env`. @internal */
|
|
52
|
+
function defaultEnv() {
|
|
53
|
+
return process.env;
|
|
54
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base class of every error thrown by this package.
|
|
3
|
+
*/
|
|
4
|
+
export declare class PaymentError extends Error {
|
|
5
|
+
constructor(message: string, options?: {
|
|
6
|
+
cause?: unknown;
|
|
7
|
+
});
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Thrown when payment data has values the gateway would reject. Thrown before any request is sent.
|
|
11
|
+
*/
|
|
12
|
+
export declare class InvalidPaymentDataError extends PaymentError {
|
|
13
|
+
/** Field name to error message, e.g. `{ amount: 'The amount field is required.' }`. */
|
|
14
|
+
readonly errors: Readonly<Record<string, string>>;
|
|
15
|
+
constructor(errors: Record<string, string>);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Thrown when a gateway rejects a request or answers with an error, including errors sent with
|
|
19
|
+
* HTTP 200, or when it cannot be reached (the network error is the `cause`).
|
|
20
|
+
*/
|
|
21
|
+
export declare class ApiError extends PaymentError {
|
|
22
|
+
/** The gateway's own error code, e.g. `ORDER_ID_USED` or `09`. */
|
|
23
|
+
readonly gatewayCode: string | undefined;
|
|
24
|
+
/** The gateway's own error message. */
|
|
25
|
+
readonly gatewayMessage: string | undefined;
|
|
26
|
+
/** The HTTP status of the response, or `0` when no response was received. */
|
|
27
|
+
readonly httpStatus: number;
|
|
28
|
+
/** The decoded response body. */
|
|
29
|
+
readonly raw: Readonly<Record<string, unknown>>;
|
|
30
|
+
constructor(message: string, details?: {
|
|
31
|
+
gatewayCode?: string | undefined;
|
|
32
|
+
gatewayMessage?: string | undefined;
|
|
33
|
+
httpStatus?: number;
|
|
34
|
+
raw?: Record<string, unknown>;
|
|
35
|
+
cause?: unknown;
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Thrown when a callback, return redirect or gateway response fails signature verification.
|
|
40
|
+
* Never act on its payload.
|
|
41
|
+
*/
|
|
42
|
+
export declare class SignatureVerificationError extends PaymentError {
|
|
43
|
+
/** The unverified payload, for logging only. */
|
|
44
|
+
readonly raw: Readonly<Record<string, unknown>>;
|
|
45
|
+
constructor(message: string, raw?: Record<string, unknown>);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Thrown when a gateway is missing a credential or setting it needs.
|
|
49
|
+
*/
|
|
50
|
+
export declare class ConfigurationError extends PaymentError {
|
|
51
|
+
/** The gateway, e.g. `kbz_pay`. */
|
|
52
|
+
readonly gateway: string;
|
|
53
|
+
/** The missing setting, e.g. `app_key`. */
|
|
54
|
+
readonly key: string;
|
|
55
|
+
constructor(gateway: string, key: string);
|
|
56
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ConfigurationError = exports.SignatureVerificationError = exports.ApiError = exports.InvalidPaymentDataError = exports.PaymentError = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Base class of every error thrown by this package.
|
|
6
|
+
*/
|
|
7
|
+
class PaymentError extends Error {
|
|
8
|
+
constructor(message, options) {
|
|
9
|
+
super(message, options);
|
|
10
|
+
this.name = new.target.name;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
exports.PaymentError = PaymentError;
|
|
14
|
+
/**
|
|
15
|
+
* Thrown when payment data has values the gateway would reject. Thrown before any request is sent.
|
|
16
|
+
*/
|
|
17
|
+
class InvalidPaymentDataError extends PaymentError {
|
|
18
|
+
/** Field name to error message, e.g. `{ amount: 'The amount field is required.' }`. */
|
|
19
|
+
errors;
|
|
20
|
+
constructor(errors) {
|
|
21
|
+
const messages = Object.keys(errors)
|
|
22
|
+
.sort()
|
|
23
|
+
.map((field) => errors[field]);
|
|
24
|
+
super(`Invalid payment data: ${messages.join(' ')}`);
|
|
25
|
+
this.errors = Object.freeze({ ...errors });
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
exports.InvalidPaymentDataError = InvalidPaymentDataError;
|
|
29
|
+
/**
|
|
30
|
+
* Thrown when a gateway rejects a request or answers with an error, including errors sent with
|
|
31
|
+
* HTTP 200, or when it cannot be reached (the network error is the `cause`).
|
|
32
|
+
*/
|
|
33
|
+
class ApiError extends PaymentError {
|
|
34
|
+
/** The gateway's own error code, e.g. `ORDER_ID_USED` or `09`. */
|
|
35
|
+
gatewayCode;
|
|
36
|
+
/** The gateway's own error message. */
|
|
37
|
+
gatewayMessage;
|
|
38
|
+
/** The HTTP status of the response, or `0` when no response was received. */
|
|
39
|
+
httpStatus;
|
|
40
|
+
/** The decoded response body. */
|
|
41
|
+
raw;
|
|
42
|
+
constructor(message, details = {}) {
|
|
43
|
+
super(message, details.cause === undefined ? undefined : { cause: details.cause });
|
|
44
|
+
this.gatewayCode = details.gatewayCode;
|
|
45
|
+
this.gatewayMessage = details.gatewayMessage;
|
|
46
|
+
this.httpStatus = details.httpStatus ?? 0;
|
|
47
|
+
this.raw = details.raw ?? {};
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
exports.ApiError = ApiError;
|
|
51
|
+
/**
|
|
52
|
+
* Thrown when a callback, return redirect or gateway response fails signature verification.
|
|
53
|
+
* Never act on its payload.
|
|
54
|
+
*/
|
|
55
|
+
class SignatureVerificationError extends PaymentError {
|
|
56
|
+
/** The unverified payload, for logging only. */
|
|
57
|
+
raw;
|
|
58
|
+
constructor(message, raw = {}) {
|
|
59
|
+
super(message);
|
|
60
|
+
this.raw = raw;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
exports.SignatureVerificationError = SignatureVerificationError;
|
|
64
|
+
/**
|
|
65
|
+
* Thrown when a gateway is missing a credential or setting it needs.
|
|
66
|
+
*/
|
|
67
|
+
class ConfigurationError extends PaymentError {
|
|
68
|
+
/** The gateway, e.g. `kbz_pay`. */
|
|
69
|
+
gateway;
|
|
70
|
+
/** The missing setting, e.g. `app_key`. */
|
|
71
|
+
key;
|
|
72
|
+
constructor(gateway, key) {
|
|
73
|
+
super(`The ${gateway} configuration is missing [${key}].`);
|
|
74
|
+
this.gateway = gateway;
|
|
75
|
+
this.key = key;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
exports.ConfigurationError = ConfigurationError;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { type LosslessObject } from './json.js';
|
|
2
|
+
/** A request a gateway sends. Gateways only send `POST`s. */
|
|
3
|
+
export interface HttpRequest {
|
|
4
|
+
method: 'POST';
|
|
5
|
+
url: string;
|
|
6
|
+
headers: Record<string, string>;
|
|
7
|
+
body: string;
|
|
8
|
+
/** Aborts the request, e.g. when the caller's own request is canceled. */
|
|
9
|
+
signal?: AbortSignal | undefined;
|
|
10
|
+
}
|
|
11
|
+
/** A gateway's response: its status and raw body text. */
|
|
12
|
+
export interface HttpResponse {
|
|
13
|
+
status: number;
|
|
14
|
+
body: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Sends the gateway's HTTP requests. Implement it to add proxies, tracing, retries or a test
|
|
18
|
+
* double; the default is {@link FetchHttpClient}. Throw on network failures; any non-2xx status
|
|
19
|
+
* is a normal response.
|
|
20
|
+
*/
|
|
21
|
+
export interface HttpClient {
|
|
22
|
+
send(request: HttpRequest): Promise<HttpResponse>;
|
|
23
|
+
}
|
|
24
|
+
/** The `fetch` function {@link FetchHttpClient} uses, e.g. `globalThis.fetch` or `undici.fetch`. */
|
|
25
|
+
export type FetchFunction = (input: string, init: RequestInit) => Promise<Response>;
|
|
26
|
+
/** Options of {@link FetchHttpClient}. */
|
|
27
|
+
export interface FetchHttpClientOptions {
|
|
28
|
+
/** The `fetch` to call; defaults to the global `fetch`. */
|
|
29
|
+
fetch?: FetchFunction | undefined;
|
|
30
|
+
/** Milliseconds before a request is aborted; defaults to 30000. `0` disables the timeout. */
|
|
31
|
+
timeoutMs?: number | undefined;
|
|
32
|
+
}
|
|
33
|
+
/** The default request timeout: 30 seconds. */
|
|
34
|
+
export declare const DEFAULT_TIMEOUT_MS = 30000;
|
|
35
|
+
/**
|
|
36
|
+
* The default {@link HttpClient}: the global `fetch` (or the one you pass) with a 30 second
|
|
37
|
+
* timeout.
|
|
38
|
+
*/
|
|
39
|
+
export declare class FetchHttpClient implements HttpClient {
|
|
40
|
+
private readonly fetchFunction;
|
|
41
|
+
private readonly timeoutMs;
|
|
42
|
+
constructor(options?: FetchHttpClientOptions);
|
|
43
|
+
send(request: HttpRequest): Promise<HttpResponse>;
|
|
44
|
+
}
|
|
45
|
+
/** Options every gateway that calls an API accepts. */
|
|
46
|
+
export interface GatewayOptions {
|
|
47
|
+
/** Sends the requests. Takes precedence over `fetch` and `timeoutMs`. */
|
|
48
|
+
httpClient?: HttpClient | undefined;
|
|
49
|
+
/** The `fetch` the default client calls, e.g. a mocked one in tests. */
|
|
50
|
+
fetch?: FetchFunction | undefined;
|
|
51
|
+
/** Milliseconds before the default client aborts a request; defaults to 30000. */
|
|
52
|
+
timeoutMs?: number | undefined;
|
|
53
|
+
}
|
|
54
|
+
/** Per-call options of every network method. */
|
|
55
|
+
export interface RequestOptions {
|
|
56
|
+
/** Aborts the gateway call, e.g. with `AbortSignal.timeout(5000)` or the incoming request's signal. */
|
|
57
|
+
signal?: AbortSignal | undefined;
|
|
58
|
+
}
|
|
59
|
+
/** @internal */
|
|
60
|
+
export declare function httpClientFrom(options?: GatewayOptions): HttpClient;
|
|
61
|
+
/** A decoded gateway response. @internal */
|
|
62
|
+
export declare class GatewayResponse {
|
|
63
|
+
readonly status: number;
|
|
64
|
+
readonly body: string;
|
|
65
|
+
constructor(status: number, body: string);
|
|
66
|
+
successful(): boolean;
|
|
67
|
+
/** The body as a JSON object with exact numbers, or `{}` when it is not one. */
|
|
68
|
+
json(): LosslessObject;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Posts the JSON and form requests the gateways use.
|
|
72
|
+
*
|
|
73
|
+
* @internal
|
|
74
|
+
*/
|
|
75
|
+
export declare class Transport {
|
|
76
|
+
private readonly client;
|
|
77
|
+
constructor(client: HttpClient);
|
|
78
|
+
postJson(url: string, data: unknown, headers?: Record<string, string>, signal?: AbortSignal): Promise<GatewayResponse>;
|
|
79
|
+
postForm(url: string, data: Record<string, string>, headers?: Record<string, string>, signal?: AbortSignal): Promise<GatewayResponse>;
|
|
80
|
+
private post;
|
|
81
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Transport = exports.GatewayResponse = exports.FetchHttpClient = exports.DEFAULT_TIMEOUT_MS = void 0;
|
|
4
|
+
exports.httpClientFrom = httpClientFrom;
|
|
5
|
+
const errors_js_1 = require("./errors.js");
|
|
6
|
+
const json_js_1 = require("./json.js");
|
|
7
|
+
/** The default request timeout: 30 seconds. */
|
|
8
|
+
exports.DEFAULT_TIMEOUT_MS = 30_000;
|
|
9
|
+
/**
|
|
10
|
+
* The default {@link HttpClient}: the global `fetch` (or the one you pass) with a 30 second
|
|
11
|
+
* timeout.
|
|
12
|
+
*/
|
|
13
|
+
class FetchHttpClient {
|
|
14
|
+
fetchFunction;
|
|
15
|
+
timeoutMs;
|
|
16
|
+
constructor(options = {}) {
|
|
17
|
+
this.fetchFunction = options.fetch;
|
|
18
|
+
this.timeoutMs = options.timeoutMs ?? exports.DEFAULT_TIMEOUT_MS;
|
|
19
|
+
}
|
|
20
|
+
async send(request) {
|
|
21
|
+
const fetchFunction = this.fetchFunction ?? globalThis.fetch;
|
|
22
|
+
if (typeof fetchFunction !== 'function') {
|
|
23
|
+
throw new TypeError('No fetch implementation is available; pass one with the fetch option.');
|
|
24
|
+
}
|
|
25
|
+
const response = await fetchFunction(request.url, {
|
|
26
|
+
method: request.method,
|
|
27
|
+
headers: request.headers,
|
|
28
|
+
body: request.body,
|
|
29
|
+
signal: combineSignals(request.signal, this.timeoutMs) ?? null,
|
|
30
|
+
});
|
|
31
|
+
let body;
|
|
32
|
+
try {
|
|
33
|
+
body = await response.text();
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
throw new errors_js_1.ApiError(`Could not read response from ${request.url}: ${describe(error)}`, {
|
|
37
|
+
httpStatus: response.status,
|
|
38
|
+
cause: error,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
return { status: response.status, body };
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
exports.FetchHttpClient = FetchHttpClient;
|
|
45
|
+
/** @internal */
|
|
46
|
+
function httpClientFrom(options = {}) {
|
|
47
|
+
return (options.httpClient ??
|
|
48
|
+
new FetchHttpClient({ fetch: options.fetch, timeoutMs: options.timeoutMs }));
|
|
49
|
+
}
|
|
50
|
+
/** A decoded gateway response. @internal */
|
|
51
|
+
class GatewayResponse {
|
|
52
|
+
status;
|
|
53
|
+
body;
|
|
54
|
+
constructor(status, body) {
|
|
55
|
+
this.status = status;
|
|
56
|
+
this.body = body;
|
|
57
|
+
}
|
|
58
|
+
successful() {
|
|
59
|
+
return this.status >= 200 && this.status < 300;
|
|
60
|
+
}
|
|
61
|
+
/** The body as a JSON object with exact numbers, or `{}` when it is not one. */
|
|
62
|
+
json() {
|
|
63
|
+
return (0, json_js_1.parseJsonObject)(this.body) ?? {};
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
exports.GatewayResponse = GatewayResponse;
|
|
67
|
+
/**
|
|
68
|
+
* Posts the JSON and form requests the gateways use.
|
|
69
|
+
*
|
|
70
|
+
* @internal
|
|
71
|
+
*/
|
|
72
|
+
class Transport {
|
|
73
|
+
client;
|
|
74
|
+
constructor(client) {
|
|
75
|
+
this.client = client;
|
|
76
|
+
}
|
|
77
|
+
postJson(url, data, headers = {}, signal) {
|
|
78
|
+
return this.post(url, JSON.stringify(data), { 'Content-Type': 'application/json', Accept: 'application/json', ...headers }, signal);
|
|
79
|
+
}
|
|
80
|
+
postForm(url, data, headers = {}, signal) {
|
|
81
|
+
return this.post(url, new URLSearchParams(data).toString(), {
|
|
82
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
83
|
+
Accept: 'application/json',
|
|
84
|
+
...headers,
|
|
85
|
+
}, signal);
|
|
86
|
+
}
|
|
87
|
+
async post(url, body, headers, signal) {
|
|
88
|
+
let response;
|
|
89
|
+
try {
|
|
90
|
+
response = await this.client.send({ method: 'POST', url, headers, body, signal });
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
if (error instanceof errors_js_1.PaymentError) {
|
|
94
|
+
throw error;
|
|
95
|
+
}
|
|
96
|
+
throw new errors_js_1.ApiError(`Could not reach ${url}: ${describe(error)}`, { cause: error });
|
|
97
|
+
}
|
|
98
|
+
return new GatewayResponse(response.status, response.body);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
exports.Transport = Transport;
|
|
102
|
+
function describe(error) {
|
|
103
|
+
return error instanceof Error ? error.message : String(error);
|
|
104
|
+
}
|
|
105
|
+
function combineSignals(signal, timeoutMs) {
|
|
106
|
+
const signals = [];
|
|
107
|
+
if (signal !== undefined) {
|
|
108
|
+
signals.push(signal);
|
|
109
|
+
}
|
|
110
|
+
if (timeoutMs > 0) {
|
|
111
|
+
signals.push(AbortSignal.timeout(timeoutMs));
|
|
112
|
+
}
|
|
113
|
+
if (signals.length <= 1) {
|
|
114
|
+
return signals[0];
|
|
115
|
+
}
|
|
116
|
+
// AbortSignal.any() needs Node 20.3; this works on every supported version.
|
|
117
|
+
const controller = new AbortController();
|
|
118
|
+
for (const source of signals) {
|
|
119
|
+
if (source.aborted) {
|
|
120
|
+
controller.abort(source.reason);
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
source.addEventListener('abort', () => {
|
|
124
|
+
controller.abort(source.reason);
|
|
125
|
+
}, { once: true });
|
|
126
|
+
}
|
|
127
|
+
return controller.signal;
|
|
128
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { Amount, type AmountInput } from './amount.js';
|
|
2
|
+
export { MemoryTokenCache, type TokenCache } from './cache.js';
|
|
3
|
+
export { Acknowledgement, CallbackRequest, PaymentCallback, PaymentStatusResult, type AcknowledgementInit, type BodyInput, type CallbackRequestInit, type HeadersInput, type NodeRequestLike, type PaymentCallbackInit, type PaymentStatusResultInit, type QueryInput, type ServerResponseLike, type WebRequestLike, } from './callback.js';
|
|
4
|
+
export type { EnvSource } from './env.js';
|
|
5
|
+
export { ApiError, ConfigurationError, InvalidPaymentDataError, PaymentError, SignatureVerificationError, } from './errors.js';
|
|
6
|
+
export { DEFAULT_TIMEOUT_MS, FetchHttpClient, type FetchFunction, type FetchHttpClientOptions, type GatewayOptions, type HttpClient, type HttpRequest, type HttpResponse, type RequestOptions, } from './http.js';
|
|
7
|
+
export { AppPayment, FormPayment, QrPayment, RedirectPayment, type FormField, type PaymentResult, } from './results.js';
|
|
8
|
+
export { PaymentFlow, PaymentStatus, resolveStatus } from './status.js';
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveStatus = exports.PaymentStatus = exports.PaymentFlow = exports.RedirectPayment = exports.QrPayment = exports.FormPayment = exports.AppPayment = exports.FetchHttpClient = exports.DEFAULT_TIMEOUT_MS = exports.SignatureVerificationError = exports.PaymentError = exports.InvalidPaymentDataError = exports.ConfigurationError = exports.ApiError = exports.PaymentStatusResult = exports.PaymentCallback = exports.CallbackRequest = exports.Acknowledgement = exports.MemoryTokenCache = exports.Amount = void 0;
|
|
4
|
+
var amount_js_1 = require("./amount.js");
|
|
5
|
+
Object.defineProperty(exports, "Amount", { enumerable: true, get: function () { return amount_js_1.Amount; } });
|
|
6
|
+
var cache_js_1 = require("./cache.js");
|
|
7
|
+
Object.defineProperty(exports, "MemoryTokenCache", { enumerable: true, get: function () { return cache_js_1.MemoryTokenCache; } });
|
|
8
|
+
var callback_js_1 = require("./callback.js");
|
|
9
|
+
Object.defineProperty(exports, "Acknowledgement", { enumerable: true, get: function () { return callback_js_1.Acknowledgement; } });
|
|
10
|
+
Object.defineProperty(exports, "CallbackRequest", { enumerable: true, get: function () { return callback_js_1.CallbackRequest; } });
|
|
11
|
+
Object.defineProperty(exports, "PaymentCallback", { enumerable: true, get: function () { return callback_js_1.PaymentCallback; } });
|
|
12
|
+
Object.defineProperty(exports, "PaymentStatusResult", { enumerable: true, get: function () { return callback_js_1.PaymentStatusResult; } });
|
|
13
|
+
var errors_js_1 = require("./errors.js");
|
|
14
|
+
Object.defineProperty(exports, "ApiError", { enumerable: true, get: function () { return errors_js_1.ApiError; } });
|
|
15
|
+
Object.defineProperty(exports, "ConfigurationError", { enumerable: true, get: function () { return errors_js_1.ConfigurationError; } });
|
|
16
|
+
Object.defineProperty(exports, "InvalidPaymentDataError", { enumerable: true, get: function () { return errors_js_1.InvalidPaymentDataError; } });
|
|
17
|
+
Object.defineProperty(exports, "PaymentError", { enumerable: true, get: function () { return errors_js_1.PaymentError; } });
|
|
18
|
+
Object.defineProperty(exports, "SignatureVerificationError", { enumerable: true, get: function () { return errors_js_1.SignatureVerificationError; } });
|
|
19
|
+
var http_js_1 = require("./http.js");
|
|
20
|
+
Object.defineProperty(exports, "DEFAULT_TIMEOUT_MS", { enumerable: true, get: function () { return http_js_1.DEFAULT_TIMEOUT_MS; } });
|
|
21
|
+
Object.defineProperty(exports, "FetchHttpClient", { enumerable: true, get: function () { return http_js_1.FetchHttpClient; } });
|
|
22
|
+
var results_js_1 = require("./results.js");
|
|
23
|
+
Object.defineProperty(exports, "AppPayment", { enumerable: true, get: function () { return results_js_1.AppPayment; } });
|
|
24
|
+
Object.defineProperty(exports, "FormPayment", { enumerable: true, get: function () { return results_js_1.FormPayment; } });
|
|
25
|
+
Object.defineProperty(exports, "QrPayment", { enumerable: true, get: function () { return results_js_1.QrPayment; } });
|
|
26
|
+
Object.defineProperty(exports, "RedirectPayment", { enumerable: true, get: function () { return results_js_1.RedirectPayment; } });
|
|
27
|
+
var status_js_1 = require("./status.js");
|
|
28
|
+
Object.defineProperty(exports, "PaymentFlow", { enumerable: true, get: function () { return status_js_1.PaymentFlow; } });
|
|
29
|
+
Object.defineProperty(exports, "PaymentStatus", { enumerable: true, get: function () { return status_js_1.PaymentStatus; } });
|
|
30
|
+
Object.defineProperty(exports, "resolveStatus", { enumerable: true, get: function () { return status_js_1.resolveStatus; } });
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A JSON number kept as the exact text the gateway sent, so `1000.50` stays `1000.50` and large
|
|
3
|
+
* integers keep every digit. Only used internally while verifying signatures and reading values.
|
|
4
|
+
*
|
|
5
|
+
* @internal
|
|
6
|
+
*/
|
|
7
|
+
export declare class JsonNumber {
|
|
8
|
+
readonly text: string;
|
|
9
|
+
constructor(text: string);
|
|
10
|
+
}
|
|
11
|
+
/** A value decoded by {@link parseJson}: numbers are {@link JsonNumber}s. @internal */
|
|
12
|
+
export type LosslessValue = string | boolean | null | JsonNumber | LosslessValue[] | {
|
|
13
|
+
[key: string]: LosslessValue;
|
|
14
|
+
};
|
|
15
|
+
/** A decoded JSON object whose numbers are {@link JsonNumber}s. @internal */
|
|
16
|
+
export type LosslessObject = {
|
|
17
|
+
[key: string]: LosslessValue;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Parses strict JSON (RFC 8259) without passing numbers through a float. Returns `undefined` when
|
|
21
|
+
* the text is not valid JSON.
|
|
22
|
+
*
|
|
23
|
+
* @internal
|
|
24
|
+
*/
|
|
25
|
+
export declare function parseJson(text: string): LosslessValue | undefined;
|
|
26
|
+
/**
|
|
27
|
+
* Parses JSON and returns it only when it is an object (not an array, string or null).
|
|
28
|
+
*
|
|
29
|
+
* @internal
|
|
30
|
+
*/
|
|
31
|
+
export declare function parseJsonObject(text: string): LosslessObject | undefined;
|
|
32
|
+
/** @internal */
|
|
33
|
+
export declare function isLosslessObject(value: unknown): value is LosslessObject;
|
|
34
|
+
/**
|
|
35
|
+
* Converts a lossless value to plain JavaScript values (numbers become `number`), for the `raw`
|
|
36
|
+
* fields of results.
|
|
37
|
+
*
|
|
38
|
+
* @internal
|
|
39
|
+
*/
|
|
40
|
+
export declare function toPlain(value: LosslessValue): unknown;
|
|
41
|
+
/** @internal */
|
|
42
|
+
export declare function toPlainObject(value: LosslessObject): Record<string, unknown>;
|
|
43
|
+
/** Sets a key without letting `__proto__` change the object's prototype. @internal */
|
|
44
|
+
export declare function setKey(target: Record<string, unknown>, key: string, value: unknown): void;
|