cmi-node 1.0.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/dist/constants/confirmationModes.cjs +19 -0
- package/dist/constants/confirmationModes.d.ts +5 -0
- package/dist/constants/confirmationModes.d.ts.map +1 -0
- package/dist/constants/confirmationModes.js.map +1 -0
- package/dist/constants/confirmationModes.mjs +15 -0
- package/dist/constants/currencies.cjs +73 -0
- package/dist/constants/currencies.d.ts +219 -0
- package/dist/constants/currencies.d.ts.map +1 -0
- package/dist/constants/currencies.js.map +1 -0
- package/dist/constants/currencies.mjs +66 -0
- package/dist/constants/fields.cjs +54 -0
- package/dist/constants/fields.d.ts +9 -0
- package/dist/constants/fields.d.ts.map +1 -0
- package/dist/constants/fields.js.map +1 -0
- package/dist/constants/fields.mjs +48 -0
- package/dist/constants/index.cjs +7 -0
- package/dist/constants/index.d.ts +7 -0
- package/dist/constants/index.d.ts.map +1 -0
- package/dist/constants/index.js.map +1 -0
- package/dist/constants/index.mjs +7 -0
- package/dist/constants/languages.cjs +56 -0
- package/dist/constants/languages.d.ts +5 -0
- package/dist/constants/languages.d.ts.map +1 -0
- package/dist/constants/languages.js.map +1 -0
- package/dist/constants/languages.mjs +52 -0
- package/dist/constants/storeTypes.cjs +26 -0
- package/dist/constants/storeTypes.d.ts +5 -0
- package/dist/constants/storeTypes.d.ts.map +1 -0
- package/dist/constants/storeTypes.js.map +1 -0
- package/dist/constants/storeTypes.mjs +22 -0
- package/dist/constants/tranTypes.cjs +22 -0
- package/dist/constants/tranTypes.d.ts +5 -0
- package/dist/constants/tranTypes.d.ts.map +1 -0
- package/dist/constants/tranTypes.js.map +1 -0
- package/dist/constants/tranTypes.mjs +18 -0
- package/dist/core/CMIPaymentGateway.cjs +94 -0
- package/dist/core/CMIPaymentGateway.d.ts +29 -0
- package/dist/core/CMIPaymentGateway.d.ts.map +1 -0
- package/dist/core/CMIPaymentGateway.js.map +1 -0
- package/dist/core/CMIPaymentGateway.mjs +92 -0
- package/dist/core/CallbackHandler.cjs +92 -0
- package/dist/core/CallbackHandler.d.ts +16 -0
- package/dist/core/CallbackHandler.d.ts.map +1 -0
- package/dist/core/CallbackHandler.js.map +1 -0
- package/dist/core/CallbackHandler.mjs +90 -0
- package/dist/core/CallbackVerifier.cjs +92 -0
- package/dist/core/CallbackVerifier.d.ts +12 -0
- package/dist/core/CallbackVerifier.d.ts.map +1 -0
- package/dist/core/CallbackVerifier.js.map +1 -0
- package/dist/core/CallbackVerifier.mjs +90 -0
- package/dist/core/FormGenerator.cjs +44 -0
- package/dist/core/FormGenerator.d.ts +7 -0
- package/dist/core/FormGenerator.d.ts.map +1 -0
- package/dist/core/FormGenerator.js.map +1 -0
- package/dist/core/FormGenerator.mjs +42 -0
- package/dist/core/PaymentBuilder.cjs +63 -0
- package/dist/core/PaymentBuilder.d.ts +17 -0
- package/dist/core/PaymentBuilder.d.ts.map +1 -0
- package/dist/core/PaymentBuilder.js.map +1 -0
- package/dist/core/PaymentBuilder.mjs +61 -0
- package/dist/core/index.cjs +12 -0
- package/dist/core/index.d.ts +7 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/index.mjs +6 -0
- package/dist/index.cjs +44 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +11 -0
- package/dist/logger/index.cjs +55 -0
- package/dist/logger/index.d.ts +16 -0
- package/dist/logger/index.d.ts.map +1 -0
- package/dist/logger/index.js.map +1 -0
- package/dist/logger/index.mjs +51 -0
- package/dist/middleware/express.middleware.cjs +12 -0
- package/dist/middleware/express.middleware.d.ts +5 -0
- package/dist/middleware/express.middleware.d.ts.map +1 -0
- package/dist/middleware/express.middleware.js.map +1 -0
- package/dist/middleware/express.middleware.mjs +9 -0
- package/dist/middleware/fastify.helper.cjs +25 -0
- package/dist/middleware/fastify.helper.d.ts +6 -0
- package/dist/middleware/fastify.helper.d.ts.map +1 -0
- package/dist/middleware/fastify.helper.js.map +1 -0
- package/dist/middleware/fastify.helper.mjs +22 -0
- package/dist/middleware/hono.helper.cjs +32 -0
- package/dist/middleware/hono.helper.d.ts +6 -0
- package/dist/middleware/hono.helper.d.ts.map +1 -0
- package/dist/middleware/hono.helper.js.map +1 -0
- package/dist/middleware/hono.helper.mjs +29 -0
- package/dist/middleware/index.cjs +6 -0
- package/dist/middleware/index.d.ts +6 -0
- package/dist/middleware/index.d.ts.map +1 -0
- package/dist/middleware/index.js.map +1 -0
- package/dist/middleware/index.mjs +6 -0
- package/dist/middleware/nestjs.helper.cjs +33 -0
- package/dist/middleware/nestjs.helper.d.ts +10 -0
- package/dist/middleware/nestjs.helper.d.ts.map +1 -0
- package/dist/middleware/nestjs.helper.js.map +1 -0
- package/dist/middleware/nestjs.helper.mjs +30 -0
- package/dist/middleware/nextjs.helper.cjs +44 -0
- package/dist/middleware/nextjs.helper.d.ts +4 -0
- package/dist/middleware/nextjs.helper.d.ts.map +1 -0
- package/dist/middleware/nextjs.helper.js.map +1 -0
- package/dist/middleware/nextjs.helper.mjs +42 -0
- package/dist/types/callback-handler.types.cjs +2 -0
- package/dist/types/callback-handler.types.d.ts +28 -0
- package/dist/types/callback-handler.types.d.ts.map +1 -0
- package/dist/types/callback-handler.types.js.map +1 -0
- package/dist/types/callback-handler.types.mjs +2 -0
- package/dist/types/callback.types.cjs +2 -0
- package/dist/types/callback.types.d.ts +14 -0
- package/dist/types/callback.types.d.ts.map +1 -0
- package/dist/types/callback.types.js.map +1 -0
- package/dist/types/callback.types.mjs +2 -0
- package/dist/types/config.types.cjs +2 -0
- package/dist/types/config.types.d.ts +11 -0
- package/dist/types/config.types.d.ts.map +1 -0
- package/dist/types/config.types.js.map +1 -0
- package/dist/types/config.types.mjs +2 -0
- package/dist/types/confirmation-mode.types.cjs +2 -0
- package/dist/types/confirmation-mode.types.d.ts +2 -0
- package/dist/types/confirmation-mode.types.d.ts.map +1 -0
- package/dist/types/confirmation-mode.types.js.map +1 -0
- package/dist/types/confirmation-mode.types.mjs +2 -0
- package/dist/types/gateway.types.cjs +2 -0
- package/dist/types/gateway.types.d.ts +16 -0
- package/dist/types/gateway.types.d.ts.map +1 -0
- package/dist/types/gateway.types.js.map +1 -0
- package/dist/types/gateway.types.mjs +2 -0
- package/dist/types/index.cjs +6 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/index.mjs +6 -0
- package/dist/types/payment.types.cjs +2 -0
- package/dist/types/payment.types.d.ts +29 -0
- package/dist/types/payment.types.d.ts.map +1 -0
- package/dist/types/payment.types.js.map +1 -0
- package/dist/types/payment.types.mjs +2 -0
- package/dist/utils/crypto/index.cjs +2 -0
- package/dist/utils/crypto/index.d.ts +2 -0
- package/dist/utils/crypto/index.d.ts.map +1 -0
- package/dist/utils/crypto/index.js.map +1 -0
- package/dist/utils/crypto/index.mjs +2 -0
- package/dist/utils/crypto/timing-safe.util.cjs +23 -0
- package/dist/utils/crypto/timing-safe.util.d.ts +3 -0
- package/dist/utils/crypto/timing-safe.util.d.ts.map +1 -0
- package/dist/utils/crypto/timing-safe.util.js.map +1 -0
- package/dist/utils/crypto/timing-safe.util.mjs +20 -0
- package/dist/utils/formatter.util.cjs +42 -0
- package/dist/utils/formatter.util.d.ts +9 -0
- package/dist/utils/formatter.util.d.ts.map +1 -0
- package/dist/utils/formatter.util.js.map +1 -0
- package/dist/utils/formatter.util.mjs +40 -0
- package/dist/utils/generator.util.cjs +14 -0
- package/dist/utils/generator.util.d.ts +5 -0
- package/dist/utils/generator.util.d.ts.map +1 -0
- package/dist/utils/generator.util.js.map +1 -0
- package/dist/utils/generator.util.mjs +12 -0
- package/dist/utils/hash.util.cjs +42 -0
- package/dist/utils/hash.util.d.ts +4 -0
- package/dist/utils/hash.util.d.ts.map +1 -0
- package/dist/utils/hash.util.js.map +1 -0
- package/dist/utils/hash.util.mjs +40 -0
- package/dist/utils/index.cjs +6 -0
- package/dist/utils/index.d.ts +6 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/index.mjs +6 -0
- package/dist/utils/sanitization.util.cjs +26 -0
- package/dist/utils/sanitization.util.d.ts +6 -0
- package/dist/utils/sanitization.util.d.ts.map +1 -0
- package/dist/utils/sanitization.util.js.map +1 -0
- package/dist/utils/sanitization.util.mjs +24 -0
- package/dist/validators/config.validator.cjs +53 -0
- package/dist/validators/config.validator.d.ts +8 -0
- package/dist/validators/config.validator.d.ts.map +1 -0
- package/dist/validators/config.validator.js.map +1 -0
- package/dist/validators/config.validator.mjs +51 -0
- package/dist/validators/index.cjs +4 -0
- package/dist/validators/index.d.ts +4 -0
- package/dist/validators/index.d.ts.map +1 -0
- package/dist/validators/index.js.map +1 -0
- package/dist/validators/index.mjs +4 -0
- package/dist/validators/payment.validator.cjs +161 -0
- package/dist/validators/payment.validator.d.ts +7 -0
- package/dist/validators/payment.validator.d.ts.map +1 -0
- package/dist/validators/payment.validator.js.map +1 -0
- package/dist/validators/payment.validator.mjs +159 -0
- package/dist/validators/validator.cjs +50 -0
- package/dist/validators/validator.d.ts +10 -0
- package/dist/validators/validator.d.ts.map +1 -0
- package/dist/validators/validator.js.map +1 -0
- package/dist/validators/validator.mjs +48 -0
- package/package.json +88 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
export class CallbackHandler {
|
|
2
|
+
constructor(gateway, options) {
|
|
3
|
+
this.gateway = gateway;
|
|
4
|
+
this.options = {
|
|
5
|
+
autoRespond: options?.autoRespond ?? true,
|
|
6
|
+
successResponse: options?.successResponse ?? "",
|
|
7
|
+
failureResponse: options?.failureResponse ?? "FAILURE",
|
|
8
|
+
onSuccess: options?.onSuccess ?? (() => { }),
|
|
9
|
+
onFailure: options?.onFailure ?? (() => { }),
|
|
10
|
+
supportGetMethod: options?.supportGetMethod ?? true,
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
middleware() {
|
|
14
|
+
return async (req, res, next) => {
|
|
15
|
+
try {
|
|
16
|
+
const params = this.extractParams(req);
|
|
17
|
+
const result = this.gateway.verifyCallback(params);
|
|
18
|
+
if (result.success) {
|
|
19
|
+
await Promise.resolve(this.options.onSuccess(result));
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
await Promise.resolve(this.options.onFailure(result));
|
|
23
|
+
}
|
|
24
|
+
if (this.options.autoRespond) {
|
|
25
|
+
this.sendResponse(res, result);
|
|
26
|
+
}
|
|
27
|
+
else if (next) {
|
|
28
|
+
req.paymentResult = result;
|
|
29
|
+
next();
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
if (this.options.autoRespond) {
|
|
34
|
+
res.status(500).send("FAILURE");
|
|
35
|
+
}
|
|
36
|
+
else if (next) {
|
|
37
|
+
next(error);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
extractParams(req) {
|
|
43
|
+
const method = (req.method || "POST").toUpperCase();
|
|
44
|
+
if (method === "POST") {
|
|
45
|
+
return req.body || {};
|
|
46
|
+
}
|
|
47
|
+
if (this.options.supportGetMethod) {
|
|
48
|
+
return req.query || req.body || {};
|
|
49
|
+
}
|
|
50
|
+
return req.body || {};
|
|
51
|
+
}
|
|
52
|
+
sendResponse(res, result) {
|
|
53
|
+
try {
|
|
54
|
+
if (result.success) {
|
|
55
|
+
const response = this.options.successResponse || result.status;
|
|
56
|
+
res.status(200).send(response);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
const response = this.options.failureResponse;
|
|
60
|
+
res.status(200).send(response);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
res.status(500).send("ERROR");
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
async handle(params) {
|
|
68
|
+
const result = this.gateway.verifyCallback(params);
|
|
69
|
+
if (result.success) {
|
|
70
|
+
await Promise.resolve(this.options.onSuccess(result));
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
await Promise.resolve(this.options.onFailure(result));
|
|
74
|
+
}
|
|
75
|
+
return result;
|
|
76
|
+
}
|
|
77
|
+
getResponse(result) {
|
|
78
|
+
if (result.success) {
|
|
79
|
+
return {
|
|
80
|
+
status: 200,
|
|
81
|
+
body: this.options.successResponse || result.status,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
status: 200,
|
|
86
|
+
body: this.options.failureResponse,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=CallbackHandler.js.map
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
const { HashUtil } = require("../utils/index.cjs");
|
|
2
|
+
const { timingSafeCompare } = require("../utils/crypto/index.cjs");
|
|
3
|
+
class CallbackVerifier {
|
|
4
|
+
constructor(config) {
|
|
5
|
+
this.config = config;
|
|
6
|
+
}
|
|
7
|
+
verify(callbackParams) {
|
|
8
|
+
console.log('[Callback] Received parameters:', callbackParams);
|
|
9
|
+
try {
|
|
10
|
+
const receivedHash = callbackParams.HASH || callbackParams.hash;
|
|
11
|
+
if (!receivedHash) {
|
|
12
|
+
return {
|
|
13
|
+
success: false,
|
|
14
|
+
status: 'FAILURE',
|
|
15
|
+
message: 'Hash not found in callback',
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
const paramsForHash = { ...callbackParams };
|
|
19
|
+
delete paramsForHash.HASH;
|
|
20
|
+
delete paramsForHash.hash;
|
|
21
|
+
delete paramsForHash.encoding;
|
|
22
|
+
const calculatedHash = HashUtil.generate(paramsForHash, this.config.storeKey);
|
|
23
|
+
console.log('[Callback] Hash verification:');
|
|
24
|
+
console.log(' Received:', receivedHash.substring(0, 20) + '...');
|
|
25
|
+
console.log(' Calculated:', calculatedHash.substring(0, 20) + '...');
|
|
26
|
+
if (!timingSafeCompare(receivedHash, calculatedHash)) {
|
|
27
|
+
console.log('[Callback] ❌ Hash mismatch - possible tampering detected!');
|
|
28
|
+
return {
|
|
29
|
+
success: false,
|
|
30
|
+
status: 'FAILURE',
|
|
31
|
+
message: 'Hash verification failed - possible tampering',
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
console.log('[Callback] ✅ Hash verified successfully');
|
|
35
|
+
const returnCode = String(callbackParams.ProcReturnCode || callbackParams.ReturnCode || '');
|
|
36
|
+
if (returnCode === '00') {
|
|
37
|
+
console.log('[Callback] ✅ Payment successful');
|
|
38
|
+
const response = this.getConfirmationResponse();
|
|
39
|
+
return {
|
|
40
|
+
success: true,
|
|
41
|
+
status: response,
|
|
42
|
+
message: 'Payment successful',
|
|
43
|
+
orderData: {
|
|
44
|
+
orderId: callbackParams.oid,
|
|
45
|
+
amount: parseFloat(callbackParams.amount),
|
|
46
|
+
currency: callbackParams.currency,
|
|
47
|
+
transactionId: callbackParams.TransId ||
|
|
48
|
+
callbackParams.transId ||
|
|
49
|
+
callbackParams.oid,
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
console.log(`[Callback] ❌ Payment failed with code: ${returnCode}`);
|
|
55
|
+
return {
|
|
56
|
+
success: false,
|
|
57
|
+
status: 'FAILURE',
|
|
58
|
+
message: `Payment failed with return code: ${returnCode}`,
|
|
59
|
+
errorCode: returnCode,
|
|
60
|
+
errorMessage: callbackParams.ErrMsg || callbackParams.errMsg,
|
|
61
|
+
orderData: {
|
|
62
|
+
orderId: callbackParams.oid,
|
|
63
|
+
amount: parseFloat(callbackParams.amount),
|
|
64
|
+
currency: callbackParams.currency,
|
|
65
|
+
transactionId: callbackParams.TransId ||
|
|
66
|
+
callbackParams.transId ||
|
|
67
|
+
callbackParams.oid,
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
console.error('[Callback] Error verifying callback:', error);
|
|
74
|
+
return {
|
|
75
|
+
success: false,
|
|
76
|
+
status: 'FAILURE',
|
|
77
|
+
message: `Error verifying callback: ${error instanceof Error ? error.message : String(error)}`,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
getConfirmationResponse() {
|
|
82
|
+
if (this.config.confirmationMode === 'auto') {
|
|
83
|
+
return 'ACTION=POSTAUTH';
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
return 'APPROVED';
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=CallbackVerifier.js.map
|
|
91
|
+
|
|
92
|
+
module.exports.CallbackVerifier = CallbackVerifier;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { CallbackResult, ConfirmationMode } from '../types/index.js';
|
|
2
|
+
export interface CallbackVerifierConfig {
|
|
3
|
+
storeKey: string;
|
|
4
|
+
confirmationMode: ConfirmationMode;
|
|
5
|
+
}
|
|
6
|
+
export declare class CallbackVerifier {
|
|
7
|
+
private readonly config;
|
|
8
|
+
constructor(config: CallbackVerifierConfig);
|
|
9
|
+
verify(callbackParams: Record<string, any>): CallbackResult;
|
|
10
|
+
private getConfirmationResponse;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=CallbackVerifier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CallbackVerifier.d.ts","sourceRoot":"","sources":["../../src/core/CallbackVerifier.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAC;AAI1D,MAAM,WAAW,sBAAsB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,gBAAgB,CAAC;CACtC;AAKD,qBAAa,gBAAgB;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAyB;gBAEpC,MAAM,EAAE,sBAAsB;IAY1C,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,cAAc;IAmG3D,OAAO,CAAC,uBAAuB;CASlC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CallbackVerifier.js","sourceRoot":"","sources":["../../src/core/CallbackVerifier.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { HashUtil } from '../utils/index.mjs';
|
|
2
|
+
import { timingSafeCompare } from '../utils/crypto/index.mjs';
|
|
3
|
+
export class CallbackVerifier {
|
|
4
|
+
constructor(config) {
|
|
5
|
+
this.config = config;
|
|
6
|
+
}
|
|
7
|
+
verify(callbackParams) {
|
|
8
|
+
console.log('[Callback] Received parameters:', callbackParams);
|
|
9
|
+
try {
|
|
10
|
+
const receivedHash = callbackParams.HASH || callbackParams.hash;
|
|
11
|
+
if (!receivedHash) {
|
|
12
|
+
return {
|
|
13
|
+
success: false,
|
|
14
|
+
status: 'FAILURE',
|
|
15
|
+
message: 'Hash not found in callback',
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
const paramsForHash = { ...callbackParams };
|
|
19
|
+
delete paramsForHash.HASH;
|
|
20
|
+
delete paramsForHash.hash;
|
|
21
|
+
delete paramsForHash.encoding;
|
|
22
|
+
const calculatedHash = HashUtil.generate(paramsForHash, this.config.storeKey);
|
|
23
|
+
console.log('[Callback] Hash verification:');
|
|
24
|
+
console.log(' Received:', receivedHash.substring(0, 20) + '...');
|
|
25
|
+
console.log(' Calculated:', calculatedHash.substring(0, 20) + '...');
|
|
26
|
+
if (!timingSafeCompare(receivedHash, calculatedHash)) {
|
|
27
|
+
console.log('[Callback] ❌ Hash mismatch - possible tampering detected!');
|
|
28
|
+
return {
|
|
29
|
+
success: false,
|
|
30
|
+
status: 'FAILURE',
|
|
31
|
+
message: 'Hash verification failed - possible tampering',
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
console.log('[Callback] ✅ Hash verified successfully');
|
|
35
|
+
const returnCode = String(callbackParams.ProcReturnCode || callbackParams.ReturnCode || '');
|
|
36
|
+
if (returnCode === '00') {
|
|
37
|
+
console.log('[Callback] ✅ Payment successful');
|
|
38
|
+
const response = this.getConfirmationResponse();
|
|
39
|
+
return {
|
|
40
|
+
success: true,
|
|
41
|
+
status: response,
|
|
42
|
+
message: 'Payment successful',
|
|
43
|
+
orderData: {
|
|
44
|
+
orderId: callbackParams.oid,
|
|
45
|
+
amount: parseFloat(callbackParams.amount),
|
|
46
|
+
currency: callbackParams.currency,
|
|
47
|
+
transactionId: callbackParams.TransId ||
|
|
48
|
+
callbackParams.transId ||
|
|
49
|
+
callbackParams.oid,
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
console.log(`[Callback] ❌ Payment failed with code: ${returnCode}`);
|
|
55
|
+
return {
|
|
56
|
+
success: false,
|
|
57
|
+
status: 'FAILURE',
|
|
58
|
+
message: `Payment failed with return code: ${returnCode}`,
|
|
59
|
+
errorCode: returnCode,
|
|
60
|
+
errorMessage: callbackParams.ErrMsg || callbackParams.errMsg,
|
|
61
|
+
orderData: {
|
|
62
|
+
orderId: callbackParams.oid,
|
|
63
|
+
amount: parseFloat(callbackParams.amount),
|
|
64
|
+
currency: callbackParams.currency,
|
|
65
|
+
transactionId: callbackParams.TransId ||
|
|
66
|
+
callbackParams.transId ||
|
|
67
|
+
callbackParams.oid,
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
console.error('[Callback] Error verifying callback:', error);
|
|
74
|
+
return {
|
|
75
|
+
success: false,
|
|
76
|
+
status: 'FAILURE',
|
|
77
|
+
message: `Error verifying callback: ${error instanceof Error ? error.message : String(error)}`,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
getConfirmationResponse() {
|
|
82
|
+
if (this.config.confirmationMode === 'auto') {
|
|
83
|
+
return 'ACTION=POSTAUTH';
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
return 'APPROVED';
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=CallbackVerifier.js.map
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
const { SanitizationUtil } = require("../utils/index.cjs");
|
|
2
|
+
class FormGenerator {
|
|
3
|
+
constructor(gatewayUrl) {
|
|
4
|
+
this.gatewayUrl = gatewayUrl;
|
|
5
|
+
}
|
|
6
|
+
generate(params) {
|
|
7
|
+
const escapedGatewayUrl = SanitizationUtil.escapeHtml(this.gatewayUrl);
|
|
8
|
+
const formInputs = Object.entries(params)
|
|
9
|
+
.map(([key, value]) => {
|
|
10
|
+
const escapedKey = SanitizationUtil.escapeHtml(key);
|
|
11
|
+
const escapedValue = SanitizationUtil.escapeHtml(String(value));
|
|
12
|
+
return `<input type="hidden" name="${escapedKey}" value="${escapedValue}" />`;
|
|
13
|
+
})
|
|
14
|
+
.join('\n');
|
|
15
|
+
console.log('Generated payment form HTML. \n', formInputs);
|
|
16
|
+
return `
|
|
17
|
+
<!DOCTYPE html>
|
|
18
|
+
<html>
|
|
19
|
+
<head>
|
|
20
|
+
<meta charset="UTF-8">
|
|
21
|
+
<title>Payment Redirect</title>
|
|
22
|
+
</head>
|
|
23
|
+
<body onload="document.paymentForm.submit();">
|
|
24
|
+
<form method="POST" action="${escapedGatewayUrl}" name="paymentForm">
|
|
25
|
+
${formInputs}
|
|
26
|
+
<noscript>
|
|
27
|
+
<input type="submit" value="Click here to complete payment" />
|
|
28
|
+
</noscript>
|
|
29
|
+
</form>
|
|
30
|
+
</body>
|
|
31
|
+
</html>
|
|
32
|
+
`.trim();
|
|
33
|
+
}
|
|
34
|
+
generateInputs(params) {
|
|
35
|
+
return Object.entries(params).map(([key, value]) => {
|
|
36
|
+
const escapedKey = SanitizationUtil.escapeHtml(key);
|
|
37
|
+
const escapedValue = SanitizationUtil.escapeHtml(String(value));
|
|
38
|
+
return `<input type="hidden" name="${escapedKey}" value="${escapedValue}" />`;
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=FormGenerator.js.map
|
|
43
|
+
|
|
44
|
+
module.exports.FormGenerator = FormGenerator;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormGenerator.d.ts","sourceRoot":"","sources":["../../src/core/FormGenerator.ts"],"names":[],"mappings":"AAYA,qBAAa,aAAa;IACtB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;gBAExB,UAAU,EAAE,MAAM;IAU9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM;IAwC7C,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,EAAE;CAOxD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormGenerator.js","sourceRoot":"","sources":["../../src/core/FormGenerator.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAC;AAK1C,MAAM,OAAO,aAAa;IAGtB,YAAY,UAAkB;QAC1B,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IACjC,CAAC;IAQD,QAAQ,CAAC,MAA2B;QAChC,MAAM,iBAAiB,GAAG,gBAAgB,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAIvE,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;aACpC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;YAClB,MAAM,UAAU,GAAG,gBAAgB,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;YACpD,MAAM,YAAY,GAAG,gBAAgB,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YAChE,OAAO,8BAA8B,UAAU,YAAY,YAAY,MAAM,CAAC;QAClF,CAAC,CAAC;aACD,IAAI,CAAC,IAAI,CAAC,CAAC;QAEhB,OAAO,CAAC,GAAG,CAAC,iCAAiC,EAAE,UAAU,CAAC,CAAC;QAE3D,OAAO;;;;;;;;wCAQyB,iBAAiB;cAC3C,UAAU;;;;;;;OAOjB,CAAC,IAAI,EAAE,CAAC;IACX,CAAC;IAQD,cAAc,CAAC,MAA2B;QACtC,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;YAC/C,MAAM,UAAU,GAAG,gBAAgB,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;YACpD,MAAM,YAAY,GAAG,gBAAgB,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YAChE,OAAO,8BAA8B,UAAU,YAAY,YAAY,MAAM,CAAC;QAClF,CAAC,CAAC,CAAC;IACP,CAAC;CACJ"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { SanitizationUtil } from '../utils/index.mjs';
|
|
2
|
+
export class FormGenerator {
|
|
3
|
+
constructor(gatewayUrl) {
|
|
4
|
+
this.gatewayUrl = gatewayUrl;
|
|
5
|
+
}
|
|
6
|
+
generate(params) {
|
|
7
|
+
const escapedGatewayUrl = SanitizationUtil.escapeHtml(this.gatewayUrl);
|
|
8
|
+
const formInputs = Object.entries(params)
|
|
9
|
+
.map(([key, value]) => {
|
|
10
|
+
const escapedKey = SanitizationUtil.escapeHtml(key);
|
|
11
|
+
const escapedValue = SanitizationUtil.escapeHtml(String(value));
|
|
12
|
+
return `<input type="hidden" name="${escapedKey}" value="${escapedValue}" />`;
|
|
13
|
+
})
|
|
14
|
+
.join('\n');
|
|
15
|
+
console.log('Generated payment form HTML. \n', formInputs);
|
|
16
|
+
return `
|
|
17
|
+
<!DOCTYPE html>
|
|
18
|
+
<html>
|
|
19
|
+
<head>
|
|
20
|
+
<meta charset="UTF-8">
|
|
21
|
+
<title>Payment Redirect</title>
|
|
22
|
+
</head>
|
|
23
|
+
<body onload="document.paymentForm.submit();">
|
|
24
|
+
<form method="POST" action="${escapedGatewayUrl}" name="paymentForm">
|
|
25
|
+
${formInputs}
|
|
26
|
+
<noscript>
|
|
27
|
+
<input type="submit" value="Click here to complete payment" />
|
|
28
|
+
</noscript>
|
|
29
|
+
</form>
|
|
30
|
+
</body>
|
|
31
|
+
</html>
|
|
32
|
+
`.trim();
|
|
33
|
+
}
|
|
34
|
+
generateInputs(params) {
|
|
35
|
+
return Object.entries(params).map(([key, value]) => {
|
|
36
|
+
const escapedKey = SanitizationUtil.escapeHtml(key);
|
|
37
|
+
const escapedValue = SanitizationUtil.escapeHtml(String(value));
|
|
38
|
+
return `<input type="hidden" name="${escapedKey}" value="${escapedValue}" />`;
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=FormGenerator.js.map
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
const { PaymentValidator } = require("../validators/index.cjs");
|
|
2
|
+
const { HashUtil, SanitizationUtil, FormatterUtil, GeneratorUtil } = require("../utils/index.cjs");
|
|
3
|
+
const { normalizeLanguage } = require("../constants/index.cjs");
|
|
4
|
+
const { OPTIONAL_PAYMENT_FIELDS, STANDARD_PAYMENT_FIELDS } = require("../constants/fields.cjs");
|
|
5
|
+
class PaymentBuilder {
|
|
6
|
+
constructor(config) {
|
|
7
|
+
this.config = config;
|
|
8
|
+
}
|
|
9
|
+
build(paymentRequest) {
|
|
10
|
+
PaymentValidator.validate(paymentRequest);
|
|
11
|
+
const oid = paymentRequest.oid || GeneratorUtil.generateOrderId();
|
|
12
|
+
const rnd = paymentRequest.rnd || GeneratorUtil.generateRandom();
|
|
13
|
+
const params = {
|
|
14
|
+
clientid: this.config.clientId,
|
|
15
|
+
amount: FormatterUtil.formatAmount(paymentRequest.amount),
|
|
16
|
+
currency: FormatterUtil.formatCurrencyNumeric(String(paymentRequest.currency)),
|
|
17
|
+
oid,
|
|
18
|
+
rnd,
|
|
19
|
+
email: SanitizationUtil.sanitizeEmail(paymentRequest.email),
|
|
20
|
+
BillToName: SanitizationUtil.sanitizeString(paymentRequest.BillToName, 50),
|
|
21
|
+
okUrl: paymentRequest.okUrl,
|
|
22
|
+
failUrl: paymentRequest.failUrl,
|
|
23
|
+
storetype: FormatterUtil.formatStoreType(this.config.storetype),
|
|
24
|
+
trantype: this.config.trantype,
|
|
25
|
+
lang: normalizeLanguage(paymentRequest.lang || 'fr'),
|
|
26
|
+
shopurl: this.config.shopUrl,
|
|
27
|
+
};
|
|
28
|
+
params.hashAlgorithm = paymentRequest.hashAlgorithm ?? 'ver3';
|
|
29
|
+
params.encoding = paymentRequest.encoding ?? 'UTF-8';
|
|
30
|
+
if (this.config.callbackUrl) {
|
|
31
|
+
params.callbackURL = this.config.callbackUrl;
|
|
32
|
+
}
|
|
33
|
+
this.addOptionalFields(params, paymentRequest);
|
|
34
|
+
params.AutoRedirect = FormatterUtil.formatAutoRedirect(paymentRequest.AutoRedirect ?? false);
|
|
35
|
+
if (paymentRequest.amountCur !== undefined && paymentRequest.amountCur > 0) {
|
|
36
|
+
params.amountCur = FormatterUtil.formatAmount(paymentRequest.amountCur);
|
|
37
|
+
}
|
|
38
|
+
if (paymentRequest.symbolCur !== undefined) {
|
|
39
|
+
params.symbolCur = FormatterUtil.formatCurrencyCode(paymentRequest.symbolCur);
|
|
40
|
+
}
|
|
41
|
+
this.addCustomFields(params, paymentRequest);
|
|
42
|
+
params.hash = HashUtil.generate(params, this.config.storeKey);
|
|
43
|
+
return params;
|
|
44
|
+
}
|
|
45
|
+
addOptionalFields(params, paymentRequest) {
|
|
46
|
+
for (const field of OPTIONAL_PAYMENT_FIELDS) {
|
|
47
|
+
if (paymentRequest[field]) {
|
|
48
|
+
params[field] = SanitizationUtil.sanitizeString(String(paymentRequest[field]), 100);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
addCustomFields(params, paymentRequest) {
|
|
53
|
+
const standardFields = new Set(STANDARD_PAYMENT_FIELDS);
|
|
54
|
+
for (const [key, value] of Object.entries(paymentRequest)) {
|
|
55
|
+
if (!standardFields.has(key) && !(key in params) && value !== undefined && value !== null) {
|
|
56
|
+
params[key] = String(value);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=PaymentBuilder.js.map
|
|
62
|
+
|
|
63
|
+
module.exports.PaymentBuilder = PaymentBuilder;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { PaymentRequest } from '../types/index.js';
|
|
2
|
+
export interface PaymentBuilderConfig {
|
|
3
|
+
clientId: string;
|
|
4
|
+
storeKey: string;
|
|
5
|
+
storetype: string;
|
|
6
|
+
trantype: string;
|
|
7
|
+
shopUrl: string;
|
|
8
|
+
callbackUrl?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare class PaymentBuilder {
|
|
11
|
+
private readonly config;
|
|
12
|
+
constructor(config: PaymentBuilderConfig);
|
|
13
|
+
build(paymentRequest: PaymentRequest): Record<string, any>;
|
|
14
|
+
private addOptionalFields;
|
|
15
|
+
private addCustomFields;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=PaymentBuilder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PaymentBuilder.d.ts","sourceRoot":"","sources":["../../src/core/PaymentBuilder.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAMxC,MAAM,WAAW,oBAAoB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB;AAKD,qBAAa,cAAc;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuB;gBAElC,MAAM,EAAE,oBAAoB;IAUxC,KAAK,CAAC,cAAc,EAAE,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAkE1D,OAAO,CAAC,iBAAiB;IAiBzB,OAAO,CAAC,eAAe;CAa1B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PaymentBuilder.js","sourceRoot":"","sources":["../../src/core/PaymentBuilder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { PaymentValidator } from '../validators/index.mjs';
|
|
2
|
+
import { HashUtil, SanitizationUtil, FormatterUtil, GeneratorUtil } from '../utils/index.mjs';
|
|
3
|
+
import { normalizeLanguage } from '../constants/index.mjs';
|
|
4
|
+
import { OPTIONAL_PAYMENT_FIELDS, STANDARD_PAYMENT_FIELDS } from '../constants/fields.mjs';
|
|
5
|
+
export class PaymentBuilder {
|
|
6
|
+
constructor(config) {
|
|
7
|
+
this.config = config;
|
|
8
|
+
}
|
|
9
|
+
build(paymentRequest) {
|
|
10
|
+
PaymentValidator.validate(paymentRequest);
|
|
11
|
+
const oid = paymentRequest.oid || GeneratorUtil.generateOrderId();
|
|
12
|
+
const rnd = paymentRequest.rnd || GeneratorUtil.generateRandom();
|
|
13
|
+
const params = {
|
|
14
|
+
clientid: this.config.clientId,
|
|
15
|
+
amount: FormatterUtil.formatAmount(paymentRequest.amount),
|
|
16
|
+
currency: FormatterUtil.formatCurrencyNumeric(String(paymentRequest.currency)),
|
|
17
|
+
oid,
|
|
18
|
+
rnd,
|
|
19
|
+
email: SanitizationUtil.sanitizeEmail(paymentRequest.email),
|
|
20
|
+
BillToName: SanitizationUtil.sanitizeString(paymentRequest.BillToName, 50),
|
|
21
|
+
okUrl: paymentRequest.okUrl,
|
|
22
|
+
failUrl: paymentRequest.failUrl,
|
|
23
|
+
storetype: FormatterUtil.formatStoreType(this.config.storetype),
|
|
24
|
+
trantype: this.config.trantype,
|
|
25
|
+
lang: normalizeLanguage(paymentRequest.lang || 'fr'),
|
|
26
|
+
shopurl: this.config.shopUrl,
|
|
27
|
+
};
|
|
28
|
+
params.hashAlgorithm = paymentRequest.hashAlgorithm ?? 'ver3';
|
|
29
|
+
params.encoding = paymentRequest.encoding ?? 'UTF-8';
|
|
30
|
+
if (this.config.callbackUrl) {
|
|
31
|
+
params.callbackURL = this.config.callbackUrl;
|
|
32
|
+
}
|
|
33
|
+
this.addOptionalFields(params, paymentRequest);
|
|
34
|
+
params.AutoRedirect = FormatterUtil.formatAutoRedirect(paymentRequest.AutoRedirect ?? false);
|
|
35
|
+
if (paymentRequest.amountCur !== undefined && paymentRequest.amountCur > 0) {
|
|
36
|
+
params.amountCur = FormatterUtil.formatAmount(paymentRequest.amountCur);
|
|
37
|
+
}
|
|
38
|
+
if (paymentRequest.symbolCur !== undefined) {
|
|
39
|
+
params.symbolCur = FormatterUtil.formatCurrencyCode(paymentRequest.symbolCur);
|
|
40
|
+
}
|
|
41
|
+
this.addCustomFields(params, paymentRequest);
|
|
42
|
+
params.hash = HashUtil.generate(params, this.config.storeKey);
|
|
43
|
+
return params;
|
|
44
|
+
}
|
|
45
|
+
addOptionalFields(params, paymentRequest) {
|
|
46
|
+
for (const field of OPTIONAL_PAYMENT_FIELDS) {
|
|
47
|
+
if (paymentRequest[field]) {
|
|
48
|
+
params[field] = SanitizationUtil.sanitizeString(String(paymentRequest[field]), 100);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
addCustomFields(params, paymentRequest) {
|
|
53
|
+
const standardFields = new Set(STANDARD_PAYMENT_FIELDS);
|
|
54
|
+
for (const [key, value] of Object.entries(paymentRequest)) {
|
|
55
|
+
if (!standardFields.has(key) && !(key in params) && value !== undefined && value !== null) {
|
|
56
|
+
params[key] = String(value);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=PaymentBuilder.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from './CMIPaymentGateway.js';
|
|
2
|
+
from './CallbackHandler.js';
|
|
3
|
+
from './PaymentBuilder.js';
|
|
4
|
+
from './FormGenerator.js';
|
|
5
|
+
from './CallbackVerifier.js';
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
7
|
+
|
|
8
|
+
module.exports.CMIPaymentGateway = CMIPaymentGateway;
|
|
9
|
+
module.exports.CallbackHandler = CallbackHandler;
|
|
10
|
+
module.exports.PaymentBuilder = PaymentBuilder;
|
|
11
|
+
module.exports.FormGenerator = FormGenerator;
|
|
12
|
+
module.exports.CallbackVerifier = CallbackVerifier;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { CMIPaymentGateway } from './CMIPaymentGateway.js';
|
|
2
|
+
export { CallbackHandler } from './CallbackHandler.js';
|
|
3
|
+
export { PaymentBuilder } from './PaymentBuilder.js';
|
|
4
|
+
export { FormGenerator } from './FormGenerator.js';
|
|
5
|
+
export { CallbackVerifier } from './CallbackVerifier.js';
|
|
6
|
+
export type { ConfirmationMode, CallbackMiddleware, CMIPaymentGatewayOptions, } from '../types/index.js';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAGtD,YAAY,EACV,gBAAgB,EAChB,kBAAkB,EAClB,wBAAwB,GACzB,MAAM,QAAQ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { CMIPaymentGateway } from './CMIPaymentGateway.mjs';
|
|
2
|
+
export { CallbackHandler } from './CallbackHandler.mjs';
|
|
3
|
+
export { PaymentBuilder } from './PaymentBuilder.mjs';
|
|
4
|
+
export { FormGenerator } from './FormGenerator.mjs';
|
|
5
|
+
export { CallbackVerifier } from './CallbackVerifier.mjs';
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
from './core/index.js';
|
|
2
|
+
from './constants/index.js';
|
|
3
|
+
from './validators/index.js';
|
|
4
|
+
from './utils/crypto/index.js';
|
|
5
|
+
from './logger/index.js';
|
|
6
|
+
from './middleware/index.js';
|
|
7
|
+
from './middleware/index.js';
|
|
8
|
+
from './middleware/index.js';
|
|
9
|
+
from './middleware/index.js';
|
|
10
|
+
from './middleware/index.js';
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
12
|
+
|
|
13
|
+
module.exports.CMIPaymentGateway = CMIPaymentGateway;
|
|
14
|
+
module.exports.CallbackHandler = CallbackHandler;
|
|
15
|
+
module.exports.PaymentBuilder = PaymentBuilder;
|
|
16
|
+
module.exports.FormGenerator = FormGenerator;
|
|
17
|
+
module.exports.CallbackVerifier = CallbackVerifier;
|
|
18
|
+
module.exports. = ;
|
|
19
|
+
module.exports.SUPPORTED_CURRENCIES = SUPPORTED_CURRENCIES;
|
|
20
|
+
module.exports.SUPPORTED_LANGUAGES = SUPPORTED_LANGUAGES;
|
|
21
|
+
module.exports.SUPPORTED_STORE_TYPES = SUPPORTED_STORE_TYPES;
|
|
22
|
+
module.exports.BILLING_FIELDS = BILLING_FIELDS;
|
|
23
|
+
module.exports.OPTIONAL_PAYMENT_FIELDS = OPTIONAL_PAYMENT_FIELDS;
|
|
24
|
+
module.exports.STANDARD_PAYMENT_FIELDS = STANDARD_PAYMENT_FIELDS;
|
|
25
|
+
module.exports.HASH_SANITIZE_FIELDS = HASH_SANITIZE_FIELDS;
|
|
26
|
+
module.exports. = ;
|
|
27
|
+
module.exports.ConfigValidator = ConfigValidator;
|
|
28
|
+
module.exports.PaymentValidator = PaymentValidator;
|
|
29
|
+
module.exports.timingSafeCompare = timingSafeCompare;
|
|
30
|
+
module.exports.sha512Base64 = sha512Base64;
|
|
31
|
+
module.exports.logger = logger;
|
|
32
|
+
module.exports.configureLogger = configureLogger;
|
|
33
|
+
module.exports.resetLogger = resetLogger;
|
|
34
|
+
module.exports.createExpressMiddleware = createExpressMiddleware;
|
|
35
|
+
module.exports.createCallbackHandler = createCallbackHandler;
|
|
36
|
+
module.exports. = ;
|
|
37
|
+
module.exports.createNextJsHandler = createNextJsHandler;
|
|
38
|
+
module.exports.handleNextJsCallback = handleNextJsCallback;
|
|
39
|
+
module.exports.createFastifyHandler = createFastifyHandler;
|
|
40
|
+
module.exports.registerFastifyCallback = registerFastifyCallback;
|
|
41
|
+
module.exports.createHonoHandler = createHonoHandler;
|
|
42
|
+
module.exports.registerHonoCallback = registerHonoCallback;
|
|
43
|
+
module.exports.NestJSCallbackHandler = NestJSCallbackHandler;
|
|
44
|
+
module.exports.createNestJSHandler = createNestJSHandler;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { CMIPaymentGateway, CallbackHandler, PaymentBuilder, FormGenerator, CallbackVerifier, } from './core/index.js';
|
|
2
|
+
export type { PaymentConfig, PaymentRequest, CallbackResult, CallbackHandlerOptions, CallbackRequest, CallbackResponse, ConfirmationMode, CallbackMiddleware, CMIPaymentGatewayOptions } from './types/index.js';
|
|
3
|
+
export { SUPPORTED_CURRENCIES, SUPPORTED_LANGUAGES, SUPPORTED_STORE_TYPES, BILLING_FIELDS, OPTIONAL_PAYMENT_FIELDS, STANDARD_PAYMENT_FIELDS, HASH_SANITIZE_FIELDS, } from './constants/index.js';
|
|
4
|
+
export { ConfigValidator, PaymentValidator } from './validators/index.js';
|
|
5
|
+
export { timingSafeCompare, sha512Base64 } from './utils/crypto/index.js';
|
|
6
|
+
export { logger, configureLogger, resetLogger } from './logger/index.js';
|
|
7
|
+
export { createExpressMiddleware, createCallbackHandler, } from './middleware/index.js';
|
|
8
|
+
export { createNextJsHandler, handleNextJsCallback } from './middleware/index.js';
|
|
9
|
+
export { createFastifyHandler, registerFastifyCallback } from './middleware/index.js';
|
|
10
|
+
export { createHonoHandler, registerHonoCallback } from './middleware/index.js';
|
|
11
|
+
export { NestJSCallbackHandler, createNestJSHandler } from './middleware/index.js';
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|