@laranex/myanmar-payments 4.0.0-dev.1 → 4.0.0-dev.11
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 +19 -4
- package/README.md +3 -3
- package/dist/cjs/aya-pay/aya-pay.d.ts +13 -9
- package/dist/cjs/aya-pay/aya-pay.js +16 -12
- package/dist/cjs/core/amount.d.ts +4 -3
- package/dist/cjs/core/amount.js +13 -4
- package/dist/cjs/core/callback.d.ts +14 -8
- package/dist/cjs/core/callback.js +19 -11
- package/dist/cjs/core/crypto.d.ts +6 -1
- package/dist/cjs/core/crypto.js +17 -3
- package/dist/cjs/core/env.d.ts +21 -5
- package/dist/cjs/core/env.js +49 -12
- package/dist/cjs/core/errors.d.ts +9 -3
- package/dist/cjs/core/errors.js +12 -4
- package/dist/cjs/core/http.d.ts +10 -11
- package/dist/cjs/core/http.js +7 -9
- package/dist/cjs/core/index.d.ts +2 -2
- package/dist/cjs/core/index.js +3 -2
- package/dist/cjs/core/json.d.ts +2 -2
- package/dist/cjs/core/json.js +3 -3
- package/dist/cjs/core/status.d.ts +3 -3
- package/dist/cjs/core/status.js +2 -2
- package/dist/cjs/core/values.d.ts +2 -0
- package/dist/cjs/core/values.js +5 -0
- package/dist/cjs/cyber-source/cyber-source.d.ts +12 -14
- package/dist/cjs/cyber-source/cyber-source.js +39 -26
- package/dist/cjs/kbz-pay/kbz-pay.d.ts +36 -12
- package/dist/cjs/kbz-pay/kbz-pay.js +54 -23
- package/dist/cjs/kbz-pay/signer.d.ts +4 -1
- package/dist/cjs/kbz-pay/signer.js +7 -2
- package/dist/cjs/wave-money/wave-money.d.ts +34 -16
- package/dist/cjs/wave-money/wave-money.js +38 -31
- package/dist/cjs/yoma-mmqr/yoma-mmqr.d.ts +17 -13
- package/dist/cjs/yoma-mmqr/yoma-mmqr.js +21 -19
- package/dist/esm/aya-pay/aya-pay.d.ts +13 -9
- package/dist/esm/aya-pay/aya-pay.js +18 -14
- package/dist/esm/core/amount.d.ts +4 -3
- package/dist/esm/core/amount.js +13 -4
- package/dist/esm/core/callback.d.ts +14 -8
- package/dist/esm/core/callback.js +19 -11
- package/dist/esm/core/crypto.d.ts +6 -1
- package/dist/esm/core/crypto.js +17 -3
- package/dist/esm/core/env.d.ts +21 -5
- package/dist/esm/core/env.js +45 -10
- package/dist/esm/core/errors.d.ts +9 -3
- package/dist/esm/core/errors.js +12 -4
- package/dist/esm/core/http.d.ts +10 -11
- package/dist/esm/core/http.js +6 -8
- package/dist/esm/core/index.d.ts +2 -2
- package/dist/esm/core/index.js +2 -1
- package/dist/esm/core/json.d.ts +2 -2
- package/dist/esm/core/json.js +3 -3
- package/dist/esm/core/status.d.ts +3 -3
- package/dist/esm/core/status.js +2 -2
- package/dist/esm/core/values.d.ts +2 -0
- package/dist/esm/core/values.js +4 -0
- package/dist/esm/cyber-source/cyber-source.d.ts +12 -14
- package/dist/esm/cyber-source/cyber-source.js +41 -28
- package/dist/esm/kbz-pay/kbz-pay.d.ts +36 -12
- package/dist/esm/kbz-pay/kbz-pay.js +56 -25
- package/dist/esm/kbz-pay/signer.d.ts +4 -1
- package/dist/esm/kbz-pay/signer.js +8 -3
- package/dist/esm/wave-money/wave-money.d.ts +34 -16
- package/dist/esm/wave-money/wave-money.js +41 -34
- package/dist/esm/yoma-mmqr/yoma-mmqr.d.ts +17 -13
- package/dist/esm/yoma-mmqr/yoma-mmqr.js +23 -21
- package/package.json +2 -2
- package/skills/node-myanmar-payments/SKILL.md +26 -22
package/dist/cjs/core/http.js
CHANGED
|
@@ -1,21 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Transport = exports.GatewayResponse = exports.FetchHttpClient =
|
|
3
|
+
exports.Transport = exports.GatewayResponse = exports.FetchHttpClient = void 0;
|
|
4
4
|
exports.httpClientFrom = httpClientFrom;
|
|
5
5
|
const errors_js_1 = require("./errors.js");
|
|
6
6
|
const json_js_1 = require("./json.js");
|
|
7
|
-
/** The default request timeout: 30 seconds. */
|
|
8
|
-
exports.DEFAULT_TIMEOUT_MS = 30_000;
|
|
9
7
|
/**
|
|
10
|
-
* The default {@link HttpClient}: the global `fetch` (or the one you pass) with
|
|
11
|
-
*
|
|
8
|
+
* The default {@link HttpClient}: the global `fetch` (or the one you pass) with the timeout you
|
|
9
|
+
* give it. Gateways build one with their `timeoutSeconds` setting when you pass no client.
|
|
12
10
|
*/
|
|
13
11
|
class FetchHttpClient {
|
|
14
12
|
fetchFunction;
|
|
15
13
|
timeoutMs;
|
|
16
|
-
constructor(options
|
|
14
|
+
constructor(options) {
|
|
17
15
|
this.fetchFunction = options.fetch;
|
|
18
|
-
this.timeoutMs = options.timeoutMs
|
|
16
|
+
this.timeoutMs = options.timeoutMs;
|
|
19
17
|
}
|
|
20
18
|
async send(request) {
|
|
21
19
|
const fetchFunction = this.fetchFunction ?? globalThis.fetch;
|
|
@@ -43,9 +41,9 @@ class FetchHttpClient {
|
|
|
43
41
|
}
|
|
44
42
|
exports.FetchHttpClient = FetchHttpClient;
|
|
45
43
|
/** @internal */
|
|
46
|
-
function httpClientFrom(options
|
|
44
|
+
function httpClientFrom(options, timeoutSeconds) {
|
|
47
45
|
return (options.httpClient ??
|
|
48
|
-
new FetchHttpClient({ fetch: options.fetch, timeoutMs:
|
|
46
|
+
new FetchHttpClient({ fetch: options.fetch, timeoutMs: timeoutSeconds * 1000 }));
|
|
49
47
|
}
|
|
50
48
|
/** A decoded gateway response. @internal */
|
|
51
49
|
class GatewayResponse {
|
package/dist/cjs/core/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export { Amount, type AmountInput } from './amount.js';
|
|
2
2
|
export { MemoryTokenCache, type TokenCache } from './cache.js';
|
|
3
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
|
|
4
|
+
export { DEFAULT_TIMEOUT_SECONDS, type EnvSource } from './env.js';
|
|
5
5
|
export { ApiError, ConfigurationError, InvalidPaymentDataError, PaymentError, SignatureVerificationError, } from './errors.js';
|
|
6
|
-
export {
|
|
6
|
+
export { FetchHttpClient, type FetchFunction, type FetchHttpClientOptions, type GatewayOptions, type HttpClient, type HttpRequest, type HttpResponse, type RequestOptions, } from './http.js';
|
|
7
7
|
export { AppPayment, FormPayment, QrPayment, RedirectPayment, type FormField, type PaymentResult, } from './results.js';
|
|
8
8
|
export { PaymentFlow, PaymentStatus, resolveStatus } from './status.js';
|
package/dist/cjs/core/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
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.
|
|
3
|
+
exports.resolveStatus = exports.PaymentStatus = exports.PaymentFlow = exports.RedirectPayment = exports.QrPayment = exports.FormPayment = exports.AppPayment = exports.FetchHttpClient = exports.SignatureVerificationError = exports.PaymentError = exports.InvalidPaymentDataError = exports.ConfigurationError = exports.ApiError = exports.DEFAULT_TIMEOUT_SECONDS = exports.PaymentStatusResult = exports.PaymentCallback = exports.CallbackRequest = exports.Acknowledgement = exports.MemoryTokenCache = exports.Amount = void 0;
|
|
4
4
|
var amount_js_1 = require("./amount.js");
|
|
5
5
|
Object.defineProperty(exports, "Amount", { enumerable: true, get: function () { return amount_js_1.Amount; } });
|
|
6
6
|
var cache_js_1 = require("./cache.js");
|
|
@@ -10,6 +10,8 @@ Object.defineProperty(exports, "Acknowledgement", { enumerable: true, get: funct
|
|
|
10
10
|
Object.defineProperty(exports, "CallbackRequest", { enumerable: true, get: function () { return callback_js_1.CallbackRequest; } });
|
|
11
11
|
Object.defineProperty(exports, "PaymentCallback", { enumerable: true, get: function () { return callback_js_1.PaymentCallback; } });
|
|
12
12
|
Object.defineProperty(exports, "PaymentStatusResult", { enumerable: true, get: function () { return callback_js_1.PaymentStatusResult; } });
|
|
13
|
+
var env_js_1 = require("./env.js");
|
|
14
|
+
Object.defineProperty(exports, "DEFAULT_TIMEOUT_SECONDS", { enumerable: true, get: function () { return env_js_1.DEFAULT_TIMEOUT_SECONDS; } });
|
|
13
15
|
var errors_js_1 = require("./errors.js");
|
|
14
16
|
Object.defineProperty(exports, "ApiError", { enumerable: true, get: function () { return errors_js_1.ApiError; } });
|
|
15
17
|
Object.defineProperty(exports, "ConfigurationError", { enumerable: true, get: function () { return errors_js_1.ConfigurationError; } });
|
|
@@ -17,7 +19,6 @@ Object.defineProperty(exports, "InvalidPaymentDataError", { enumerable: true, ge
|
|
|
17
19
|
Object.defineProperty(exports, "PaymentError", { enumerable: true, get: function () { return errors_js_1.PaymentError; } });
|
|
18
20
|
Object.defineProperty(exports, "SignatureVerificationError", { enumerable: true, get: function () { return errors_js_1.SignatureVerificationError; } });
|
|
19
21
|
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
22
|
Object.defineProperty(exports, "FetchHttpClient", { enumerable: true, get: function () { return http_js_1.FetchHttpClient; } });
|
|
22
23
|
var results_js_1 = require("./results.js");
|
|
23
24
|
Object.defineProperty(exports, "AppPayment", { enumerable: true, get: function () { return results_js_1.AppPayment; } });
|
package/dist/cjs/core/json.d.ts
CHANGED
|
@@ -32,8 +32,8 @@ export declare function parseJsonObject(text: string): LosslessObject | undefine
|
|
|
32
32
|
/** @internal */
|
|
33
33
|
export declare function isLosslessObject(value: unknown): value is LosslessObject;
|
|
34
34
|
/**
|
|
35
|
-
* Converts a lossless value to plain JavaScript values
|
|
36
|
-
*
|
|
35
|
+
* Converts a lossless value to plain JavaScript values for the `raw` fields of results. Numbers
|
|
36
|
+
* become their exact text as a string (`1000.50` stays `"1000.50"`), so no precision is lost.
|
|
37
37
|
*
|
|
38
38
|
* @internal
|
|
39
39
|
*/
|
package/dist/cjs/core/json.js
CHANGED
|
@@ -56,14 +56,14 @@ function isLosslessObject(value) {
|
|
|
56
56
|
!(value instanceof JsonNumber));
|
|
57
57
|
}
|
|
58
58
|
/**
|
|
59
|
-
* Converts a lossless value to plain JavaScript values
|
|
60
|
-
*
|
|
59
|
+
* Converts a lossless value to plain JavaScript values for the `raw` fields of results. Numbers
|
|
60
|
+
* become their exact text as a string (`1000.50` stays `"1000.50"`), so no precision is lost.
|
|
61
61
|
*
|
|
62
62
|
* @internal
|
|
63
63
|
*/
|
|
64
64
|
function toPlain(value) {
|
|
65
65
|
if (value instanceof JsonNumber) {
|
|
66
|
-
return
|
|
66
|
+
return value.text;
|
|
67
67
|
}
|
|
68
68
|
if (Array.isArray(value)) {
|
|
69
69
|
return value.map(toPlain);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* A gateway-independent payment status. Every gateway's own status values are mapped onto these.
|
|
3
3
|
*/
|
|
4
|
-
export type PaymentStatus = 'successful' | 'pending' | 'failed' | '
|
|
4
|
+
export type PaymentStatus = 'successful' | 'pending' | 'failed' | 'canceled' | 'expired' | 'unknown';
|
|
5
5
|
/**
|
|
6
6
|
* The payment statuses, plus helpers.
|
|
7
7
|
*
|
|
@@ -18,13 +18,13 @@ export declare const PaymentStatus: Readonly<{
|
|
|
18
18
|
/** The payment was attempted and failed or was rejected. */
|
|
19
19
|
Failed: "failed";
|
|
20
20
|
/** The payment or order was canceled or closed before completing. */
|
|
21
|
-
|
|
21
|
+
Canceled: "canceled";
|
|
22
22
|
/** The payment window ran out before the customer paid. */
|
|
23
23
|
Expired: "expired";
|
|
24
24
|
/** The gateway sent a status this package does not recognize. Inspect `gatewayStatus`. */
|
|
25
25
|
Unknown: "unknown";
|
|
26
26
|
/** Every status, in the order above. */
|
|
27
|
-
values: readonly ["successful", "pending", "failed", "
|
|
27
|
+
values: readonly ["successful", "pending", "failed", "canceled", "expired", "unknown"];
|
|
28
28
|
/** Whether the status will not change any more: `false` for `pending` and `unknown`. */
|
|
29
29
|
isFinal(status: PaymentStatus): boolean;
|
|
30
30
|
}>;
|
package/dist/cjs/core/status.js
CHANGED
|
@@ -18,7 +18,7 @@ exports.PaymentStatus = Object.freeze({
|
|
|
18
18
|
/** The payment was attempted and failed or was rejected. */
|
|
19
19
|
Failed: 'failed',
|
|
20
20
|
/** The payment or order was canceled or closed before completing. */
|
|
21
|
-
|
|
21
|
+
Canceled: 'canceled',
|
|
22
22
|
/** The payment window ran out before the customer paid. */
|
|
23
23
|
Expired: 'expired',
|
|
24
24
|
/** The gateway sent a status this package does not recognize. Inspect `gatewayStatus`. */
|
|
@@ -28,7 +28,7 @@ exports.PaymentStatus = Object.freeze({
|
|
|
28
28
|
'successful',
|
|
29
29
|
'pending',
|
|
30
30
|
'failed',
|
|
31
|
-
'
|
|
31
|
+
'canceled',
|
|
32
32
|
'expired',
|
|
33
33
|
'unknown',
|
|
34
34
|
]),
|
|
@@ -14,3 +14,5 @@ export declare function optional(source: Record<string, unknown>, key: string):
|
|
|
14
14
|
export declare function trimmed(source: Record<string, unknown>, key: string): string;
|
|
15
15
|
/** The value at `key` when it is an object (not an array). @internal */
|
|
16
16
|
export declare function object(source: Record<string, unknown>, key: string): LosslessObject | undefined;
|
|
17
|
+
/** Whether `value` is an object or array, which a gateway never signs. @internal */
|
|
18
|
+
export declare function isNested(value: unknown): boolean;
|
package/dist/cjs/core/values.js
CHANGED
|
@@ -5,6 +5,7 @@ exports.get = get;
|
|
|
5
5
|
exports.optional = optional;
|
|
6
6
|
exports.trimmed = trimmed;
|
|
7
7
|
exports.object = object;
|
|
8
|
+
exports.isNested = isNested;
|
|
8
9
|
const json_js_1 = require("./json.js");
|
|
9
10
|
/**
|
|
10
11
|
* Returns a scalar as the text a gateway signs: strings as is, numbers exactly as sent, booleans as
|
|
@@ -43,3 +44,7 @@ function object(source, key) {
|
|
|
43
44
|
const value = source[key];
|
|
44
45
|
return (0, json_js_1.isLosslessObject)(value) ? value : undefined;
|
|
45
46
|
}
|
|
47
|
+
/** Whether `value` is an object or array, which a gateway never signs. @internal */
|
|
48
|
+
function isNested(value) {
|
|
49
|
+
return typeof value === 'object' && value !== null && !(value instanceof json_js_1.JsonNumber);
|
|
50
|
+
}
|
|
@@ -10,27 +10,24 @@ export interface CyberSourceConfigOptions {
|
|
|
10
10
|
accessKey: string;
|
|
11
11
|
/** The profile's secret key, which signs the fields. */
|
|
12
12
|
secretKey: string;
|
|
13
|
-
/**
|
|
14
|
-
sandbox?: boolean | undefined;
|
|
15
|
-
/** Overrides the Secure Acceptance base URL. */
|
|
13
|
+
/** Overrides the Secure Acceptance base URL, e.g. to point at the test environment. */
|
|
16
14
|
baseUrl?: string | undefined;
|
|
17
15
|
}
|
|
18
16
|
/**
|
|
19
|
-
* A CyberSource Secure Acceptance profile. A missing credential throws a `ConfigurationError`.
|
|
17
|
+
* A CyberSource Secure Acceptance profile. A missing credential throws a `ConfigurationError`. The
|
|
18
|
+
* URL defaults to production.
|
|
20
19
|
*/
|
|
21
20
|
export declare class CyberSourceConfig {
|
|
22
|
-
static readonly SANDBOX_URL = "https://testsecureacceptance.cybersource.com";
|
|
23
21
|
static readonly PRODUCTION_URL = "https://secureacceptance.cybersource.com";
|
|
24
22
|
readonly profileId: string;
|
|
25
23
|
readonly accessKey: string;
|
|
26
24
|
readonly secretKey: string;
|
|
27
|
-
readonly sandbox: boolean;
|
|
28
25
|
/** The base URL in use. */
|
|
29
26
|
readonly baseUrl: string;
|
|
30
27
|
constructor(options: CyberSourceConfigOptions);
|
|
31
28
|
/**
|
|
32
29
|
* Reads `CYBER_SOURCE_PROFILE_ID`, `CYBER_SOURCE_ACCESS_KEY`, `CYBER_SOURCE_SECRET_KEY`,
|
|
33
|
-
*
|
|
30
|
+
* and `CYBER_SOURCE_BASE_URL`.
|
|
34
31
|
*/
|
|
35
32
|
static fromEnv(env?: EnvSource): CyberSourceConfig;
|
|
36
33
|
}
|
|
@@ -61,12 +58,12 @@ export interface CyberSourcePaymentData {
|
|
|
61
58
|
returnUrl?: string | undefined;
|
|
62
59
|
/** The page shown on cancel (`override_custom_cancel_page`), at most 255 characters. */
|
|
63
60
|
cancelUrl?: string | undefined;
|
|
64
|
-
/** An ISO 4217 code
|
|
65
|
-
currency
|
|
66
|
-
/** What to do with the card
|
|
67
|
-
transactionType
|
|
68
|
-
/** The hosted page language, e.g. `en-us
|
|
69
|
-
locale
|
|
61
|
+
/** An ISO 4217 code, e.g. `MMK`. */
|
|
62
|
+
currency: string;
|
|
63
|
+
/** What to do with the card, e.g. `sale`. */
|
|
64
|
+
transactionType: CyberSourceTransactionType;
|
|
65
|
+
/** The hosted page language, e.g. `en-us`. */
|
|
66
|
+
locale: string;
|
|
70
67
|
}
|
|
71
68
|
/**
|
|
72
69
|
* CyberSource Secure Acceptance hosted checkout for card payments: signs the form and verifies the
|
|
@@ -87,7 +84,8 @@ export declare class CyberSource {
|
|
|
87
84
|
initiate(data: CyberSourcePaymentData): FormPayment;
|
|
88
85
|
/**
|
|
89
86
|
* Verifies CyberSource's result post. The same check works for the browser post to your receipt
|
|
90
|
-
* page.
|
|
87
|
+
* page. Only the fields listed in `signed_field_names` are trusted: `decision` and
|
|
88
|
+
* `req_reference_number` must be signed, and unsigned fields are left out of the result.
|
|
91
89
|
*/
|
|
92
90
|
handleCallback(request: CallbackRequest): PaymentCallback;
|
|
93
91
|
/** Signs the fields listed in `signed_field_names`; `undefined` when a listed field is missing. */
|
|
@@ -11,35 +11,31 @@ const status_js_1 = require("../core/status.js");
|
|
|
11
11
|
const validate_js_1 = require("../core/validate.js");
|
|
12
12
|
const values_js_1 = require("../core/values.js");
|
|
13
13
|
/**
|
|
14
|
-
* A CyberSource Secure Acceptance profile. A missing credential throws a `ConfigurationError`.
|
|
14
|
+
* A CyberSource Secure Acceptance profile. A missing credential throws a `ConfigurationError`. The
|
|
15
|
+
* URL defaults to production.
|
|
15
16
|
*/
|
|
16
17
|
class CyberSourceConfig {
|
|
17
|
-
static SANDBOX_URL = 'https://testsecureacceptance.cybersource.com';
|
|
18
18
|
static PRODUCTION_URL = 'https://secureacceptance.cybersource.com';
|
|
19
19
|
profileId;
|
|
20
20
|
accessKey;
|
|
21
21
|
secretKey;
|
|
22
|
-
sandbox;
|
|
23
22
|
/** The base URL in use. */
|
|
24
23
|
baseUrl;
|
|
25
24
|
constructor(options) {
|
|
26
25
|
this.profileId = (0, env_js_1.requireSetting)('cyber_source', 'profile_id', options.profileId);
|
|
27
26
|
this.accessKey = (0, env_js_1.requireSetting)('cyber_source', 'access_key', options.accessKey);
|
|
28
27
|
this.secretKey = (0, env_js_1.requireSetting)('cyber_source', 'secret_key', options.secretKey);
|
|
29
|
-
this.
|
|
30
|
-
this.baseUrl = (0, env_js_1.trimUrl)((0, env_js_1.optionalSetting)(options.baseUrl) ??
|
|
31
|
-
(this.sandbox ? CyberSourceConfig.SANDBOX_URL : CyberSourceConfig.PRODUCTION_URL));
|
|
28
|
+
this.baseUrl = (0, env_js_1.trimUrl)((0, env_js_1.optionalSetting)(options.baseUrl) ?? CyberSourceConfig.PRODUCTION_URL);
|
|
32
29
|
}
|
|
33
30
|
/**
|
|
34
31
|
* Reads `CYBER_SOURCE_PROFILE_ID`, `CYBER_SOURCE_ACCESS_KEY`, `CYBER_SOURCE_SECRET_KEY`,
|
|
35
|
-
*
|
|
32
|
+
* and `CYBER_SOURCE_BASE_URL`.
|
|
36
33
|
*/
|
|
37
34
|
static fromEnv(env = (0, env_js_1.defaultEnv)()) {
|
|
38
35
|
return new CyberSourceConfig({
|
|
39
36
|
profileId: (0, env_js_1.envFirst)(env, 'CYBER_SOURCE_PROFILE_ID'),
|
|
40
37
|
accessKey: (0, env_js_1.envFirst)(env, 'CYBER_SOURCE_ACCESS_KEY'),
|
|
41
38
|
secretKey: (0, env_js_1.envFirst)(env, 'CYBER_SOURCE_SECRET_KEY'),
|
|
42
|
-
sandbox: (0, env_js_1.envSandbox)(env, 'CYBER_SOURCE_SANDBOX'),
|
|
43
39
|
baseUrl: (0, env_js_1.envFirst)(env, 'CYBER_SOURCE_BASE_URL'),
|
|
44
40
|
});
|
|
45
41
|
}
|
|
@@ -77,7 +73,7 @@ const STATUSES = {
|
|
|
77
73
|
REVIEW: 'pending',
|
|
78
74
|
DECLINE: 'failed',
|
|
79
75
|
ERROR: 'failed',
|
|
80
|
-
CANCEL: '
|
|
76
|
+
CANCEL: 'canceled',
|
|
81
77
|
};
|
|
82
78
|
/**
|
|
83
79
|
* CyberSource Secure Acceptance hosted checkout for card payments: signs the form and verifies the
|
|
@@ -113,9 +109,12 @@ class CyberSource {
|
|
|
113
109
|
.string('cancelUrl', data.cancelUrl)
|
|
114
110
|
.url('cancelUrl', data.cancelUrl)
|
|
115
111
|
.max('cancelUrl', data.cancelUrl, 255)
|
|
116
|
-
.
|
|
117
|
-
.pattern('
|
|
118
|
-
.
|
|
112
|
+
.required('currency', data.currency)
|
|
113
|
+
.pattern('currency', data.currency, /^[A-Z]{3}$/, 'a three letter ISO 4217 code')
|
|
114
|
+
.required('transactionType', data.transactionType)
|
|
115
|
+
.when(!TRANSACTION_TYPES.includes(String(data.transactionType)), 'transactionType', 'The transactionType field is not a supported transaction type.')
|
|
116
|
+
.required('locale', data.locale)
|
|
117
|
+
.pattern('locale', data.locale, /^[a-z]{2}-[a-z]{2}$/, 'a locale code such as en-us')
|
|
119
118
|
.validate();
|
|
120
119
|
}
|
|
121
120
|
/**
|
|
@@ -130,11 +129,11 @@ class CyberSource {
|
|
|
130
129
|
transaction_uuid: (0, crypto_js_1.randomHex)(),
|
|
131
130
|
signed_field_names: SIGNED_FIELDS.join(','),
|
|
132
131
|
signed_date_time: new Date().toISOString().replace(/\.\d{3}Z$/, 'Z'),
|
|
133
|
-
locale: data.locale
|
|
134
|
-
transaction_type: data.transactionType
|
|
132
|
+
locale: data.locale,
|
|
133
|
+
transaction_type: data.transactionType,
|
|
135
134
|
reference_number: data.orderId,
|
|
136
135
|
amount: String((0, validate_js_1.toAmount)(data.amount)),
|
|
137
|
-
currency: data.currency
|
|
136
|
+
currency: data.currency,
|
|
138
137
|
override_custom_receipt_page: data.returnUrl ?? '',
|
|
139
138
|
override_backoffice_post_url: data.callbackUrl,
|
|
140
139
|
override_custom_cancel_page: data.cancelUrl ?? '',
|
|
@@ -149,31 +148,39 @@ class CyberSource {
|
|
|
149
148
|
}
|
|
150
149
|
/**
|
|
151
150
|
* Verifies CyberSource's result post. The same check works for the browser post to your receipt
|
|
152
|
-
* page.
|
|
151
|
+
* page. Only the fields listed in `signed_field_names` are trusted: `decision` and
|
|
152
|
+
* `req_reference_number` must be signed, and unsigned fields are left out of the result.
|
|
153
153
|
*/
|
|
154
154
|
handleCallback(request) {
|
|
155
155
|
const payload = (0, callback_js_1.losslessInput)(request);
|
|
156
156
|
const expected = this.sign(payload);
|
|
157
|
-
|
|
157
|
+
const names = signedNames(payload);
|
|
158
|
+
if (expected === undefined ||
|
|
159
|
+
!(0, crypto_js_1.safeEqual)(expected, (0, values_js_1.get)(payload, 'signature')) ||
|
|
160
|
+
!names.includes('decision') ||
|
|
161
|
+
!names.includes('req_reference_number')) {
|
|
158
162
|
throw new errors_js_1.SignatureVerificationError('CyberSource callback signature verification failed.', (0, json_js_1.toPlainObject)(payload));
|
|
159
163
|
}
|
|
160
|
-
|
|
164
|
+
// A signature only covers the listed fields, so anything else in the post could have been
|
|
165
|
+
// added by the sender (e.g. a `decision` next to the signed request fields).
|
|
166
|
+
const signed = {};
|
|
167
|
+
for (const name of [...names, 'signature']) {
|
|
168
|
+
(0, json_js_1.setKey)(signed, name, payload[name]);
|
|
169
|
+
}
|
|
170
|
+
const decision = (0, values_js_1.trimmed)(signed, 'decision').toUpperCase();
|
|
161
171
|
return new callback_js_1.PaymentCallback({
|
|
162
|
-
orderId: (0, values_js_1.get)(
|
|
172
|
+
orderId: (0, values_js_1.get)(signed, 'req_reference_number'),
|
|
163
173
|
status: (0, status_js_1.resolveStatus)(STATUSES, decision),
|
|
164
174
|
gatewayStatus: decision,
|
|
165
|
-
gatewayReference: (0, values_js_1.optional)(
|
|
166
|
-
amount: (0, values_js_1.get)(
|
|
167
|
-
raw: (0, json_js_1.toPlainObject)(
|
|
175
|
+
gatewayReference: (0, values_js_1.optional)(signed, 'transaction_id'),
|
|
176
|
+
amount: (0, values_js_1.get)(signed, 'auth_amount') || (0, values_js_1.optional)(signed, 'req_amount'),
|
|
177
|
+
raw: (0, json_js_1.toPlainObject)(signed),
|
|
168
178
|
});
|
|
169
179
|
}
|
|
170
180
|
/** Signs the fields listed in `signed_field_names`; `undefined` when a listed field is missing. */
|
|
171
181
|
sign(fields) {
|
|
172
182
|
const pairs = [];
|
|
173
|
-
for (const name of (
|
|
174
|
-
if (name === '') {
|
|
175
|
-
continue;
|
|
176
|
-
}
|
|
183
|
+
for (const name of signedNames(fields)) {
|
|
177
184
|
const value = (0, values_js_1.scalarString)(fields[name]);
|
|
178
185
|
if (value === undefined) {
|
|
179
186
|
return undefined;
|
|
@@ -186,3 +193,9 @@ class CyberSource {
|
|
|
186
193
|
}
|
|
187
194
|
}
|
|
188
195
|
exports.CyberSource = CyberSource;
|
|
196
|
+
/** The names listed in `signed_field_names`, in order. */
|
|
197
|
+
function signedNames(fields) {
|
|
198
|
+
return (0, values_js_1.get)(fields, 'signed_field_names')
|
|
199
|
+
.split(',')
|
|
200
|
+
.filter((name) => name !== '');
|
|
201
|
+
}
|
|
@@ -12,33 +12,46 @@ export interface KbzPayConfigOptions {
|
|
|
12
12
|
appKey: string;
|
|
13
13
|
/** The `merch_code` KBZ issued. */
|
|
14
14
|
merchantCode: string;
|
|
15
|
-
/**
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Seconds before the default HTTP client gives up on a request, a whole number greater than 0
|
|
17
|
+
* (or its text). Defaults to 30 (`DEFAULT_TIMEOUT_SECONDS`) when unset or blank. A
|
|
18
|
+
* client you pass keeps its own timeout.
|
|
19
|
+
*/
|
|
20
|
+
timeoutSeconds?: number | string | null | undefined;
|
|
21
|
+
/** Overrides the API base URL, e.g. to point at UAT or go through a proxy. */
|
|
18
22
|
apiUrl?: string | undefined;
|
|
19
23
|
/** Overrides the PWA checkout URL. A trailing `#` or `#/` is normalized to `#/`. */
|
|
20
24
|
pwaUrl?: string | undefined;
|
|
25
|
+
/**
|
|
26
|
+
* Minutes the customer has to pay each order, a whole number from 1 to 120 (or its text).
|
|
27
|
+
* A payment's own `timeToLiveMinutes` overrides it. Unset or blank is allowed, but then every
|
|
28
|
+
* payment must set its own.
|
|
29
|
+
*/
|
|
30
|
+
timeToLiveMinutes?: number | string | null | undefined;
|
|
21
31
|
}
|
|
22
32
|
/**
|
|
23
|
-
* KBZ Pay credentials and endpoints. A missing
|
|
33
|
+
* KBZ Pay credentials and endpoints. A missing setting throws a `ConfigurationError`. The URLs
|
|
34
|
+
* default to production; UAT and production issue separate credentials.
|
|
24
35
|
*/
|
|
25
36
|
export declare class KbzPayConfig {
|
|
26
|
-
static readonly SANDBOX_API_URL = "http://api-uat.kbzpay.com/payment/gateway/uat";
|
|
27
37
|
static readonly PRODUCTION_API_URL = "https://api.kbzpay.com/payment/gateway";
|
|
28
|
-
static readonly SANDBOX_PWA_URL = "https://static.kbzpay.com/pgw/uat/pwa/#/";
|
|
29
38
|
static readonly PRODUCTION_PWA_URL = "https://wap.kbzpay.com/pgw/pwa/#/";
|
|
30
39
|
readonly appId: string;
|
|
31
40
|
readonly appKey: string;
|
|
32
41
|
readonly merchantCode: string;
|
|
33
|
-
|
|
42
|
+
/** Seconds before the default HTTP client gives up on a request. */
|
|
43
|
+
readonly timeoutSeconds: number;
|
|
34
44
|
/** The API base URL in use. */
|
|
35
45
|
readonly apiUrl: string;
|
|
36
46
|
/** The PWA checkout URL in use, always ending in `/`. */
|
|
37
47
|
readonly pwaUrl: string;
|
|
48
|
+
/** Minutes the customer has to pay each order unless the payment sets its own; `undefined` when unset. */
|
|
49
|
+
readonly timeToLiveMinutes: number | undefined;
|
|
38
50
|
constructor(options: KbzPayConfigOptions);
|
|
39
51
|
/**
|
|
40
|
-
* Reads `KBZ_PAY_APP_ID`, `KBZ_PAY_APP_KEY`, `KBZ_PAY_MERCHANT_CODE`,
|
|
41
|
-
* `KBZ_PAY_BASE_URL` and
|
|
52
|
+
* Reads `KBZ_PAY_APP_ID`, `KBZ_PAY_APP_KEY`, `KBZ_PAY_MERCHANT_CODE`,
|
|
53
|
+
* `MYANMAR_PAYMENTS_HTTP_TIMEOUT`, `KBZ_PAY_BASE_URL`, `KBZ_PAY_PWA_BASE_REDIRECT_URL` and
|
|
54
|
+
* `KBZ_PAY_TIME_TO_LIVE_IN_MINUTES`.
|
|
42
55
|
*/
|
|
43
56
|
static fromEnv(env?: EnvSource): KbzPayConfig;
|
|
44
57
|
}
|
|
@@ -54,8 +67,11 @@ export interface KbzPayPaymentData {
|
|
|
54
67
|
callbackUrl: string;
|
|
55
68
|
/** The product name shown to the customer. */
|
|
56
69
|
title?: string | undefined;
|
|
57
|
-
/**
|
|
58
|
-
|
|
70
|
+
/**
|
|
71
|
+
* Minutes the customer has to pay before the order expires, 1 to 120. Overrides the config's
|
|
72
|
+
* `timeToLiveMinutes`; one of the two is required.
|
|
73
|
+
*/
|
|
74
|
+
timeToLiveMinutes?: number | undefined;
|
|
59
75
|
/** Free text KBZ sends back unchanged in the callback, at most 512 characters once URL-encoded. */
|
|
60
76
|
callbackInfo?: string | undefined;
|
|
61
77
|
}
|
|
@@ -79,13 +95,21 @@ export declare class KbzPay {
|
|
|
79
95
|
*
|
|
80
96
|
* The redirect only works on a phone with the KBZ Pay app installed, and its Referer must match
|
|
81
97
|
* the URL registered with KBZ.
|
|
98
|
+
* Throws `InvalidPaymentDataError` before any request when neither the payment nor the config sets
|
|
99
|
+
* a time to live.
|
|
82
100
|
*/
|
|
83
101
|
pwa(data: KbzPayPaymentData, options?: RequestOptions): Promise<RedirectPayment>;
|
|
84
|
-
/**
|
|
102
|
+
/**
|
|
103
|
+
* Creates an order and returns a QR payload for the customer to scan with the KBZ Pay app.
|
|
104
|
+
* Throws `InvalidPaymentDataError` before any request when neither the payment nor the config sets
|
|
105
|
+
* a time to live.
|
|
106
|
+
*/
|
|
85
107
|
qr(data: KbzPayPaymentData, options?: RequestOptions): Promise<QrPayment>;
|
|
86
108
|
/**
|
|
87
109
|
* Creates an order and returns the signed values your mobile app passes to `KBZPay.startPay()`.
|
|
88
110
|
* The SDK's own result only means the payment screen closed; rely on the callback or `status()`.
|
|
111
|
+
* Throws `InvalidPaymentDataError` before any request when neither the payment nor the config sets
|
|
112
|
+
* a time to live.
|
|
89
113
|
*/
|
|
90
114
|
app(data: KbzPayPaymentData, options?: RequestOptions): Promise<AppPayment>;
|
|
91
115
|
/** Asks KBZ Pay for the current state of an order (`queryorder`). */
|