@munchi_oy/payments 1.4.8 → 1.5.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/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/dist/src/MunchiPaymentSDK.d.ts +1 -0
- package/dist/src/MunchiPaymentSDK.d.ts.map +1 -1
- package/dist/src/strategies/IPaymentStrategy.d.ts +5 -0
- package/dist/src/strategies/IPaymentStrategy.d.ts.map +1 -1
- package/dist/src/strategies/VivaAppToAppStrategy.d.ts +51 -0
- package/dist/src/strategies/VivaAppToAppStrategy.d.ts.map +1 -0
- package/dist/src/types/payment.d.ts +3 -1
- package/dist/src/types/payment.d.ts.map +1 -1
- package/dist/src/types/sdk.d.ts +13 -0
- package/dist/src/types/sdk.d.ts.map +1 -1
- package/dist/src/utils/parsing.d.ts +3 -0
- package/dist/src/utils/parsing.d.ts.map +1 -0
- package/dist/src/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/MunchiPaymentSDK.ts +101 -14
- package/src/strategies/IPaymentStrategy.ts +6 -0
- package/src/strategies/VivaAppToAppStrategy.ts +810 -0
- package/src/types/payment.ts +3 -1
- package/src/types/sdk.ts +16 -0
- package/src/utils/parsing.ts +21 -0
- package/src/version.ts +1 -1
package/src/MunchiPaymentSDK.ts
CHANGED
|
@@ -3,7 +3,9 @@ import type { AxiosInstance } from "axios";
|
|
|
3
3
|
import { version } from "../package.json";
|
|
4
4
|
import { PaymentErrorCode, PaymentSDKError } from "./error";
|
|
5
5
|
import type { IPaymentStrategy } from "./strategies/IPaymentStrategy";
|
|
6
|
+
import { StrategyExecutionMode } from "./strategies/IPaymentStrategy";
|
|
6
7
|
import { NetsStrategy } from "./strategies/NetsStrategy";
|
|
8
|
+
import { VivaAppToAppStrategy } from "./strategies/VivaAppToAppStrategy";
|
|
7
9
|
import { VivaStrategy } from "./strategies/VivaStrategy";
|
|
8
10
|
import { WorldlineStrategy } from "./strategies/WorldlineStrategy";
|
|
9
11
|
import {
|
|
@@ -17,7 +19,7 @@ import {
|
|
|
17
19
|
SdkPaymentStatus,
|
|
18
20
|
type TransactionOptions,
|
|
19
21
|
} from "./types/payment";
|
|
20
|
-
import type { ILogger, SDKOptions } from "./types/sdk";
|
|
22
|
+
import type { AppToAppConfig, ILogger, SDKOptions } from "./types/sdk";
|
|
21
23
|
|
|
22
24
|
type StateListener = (state: PaymentInteractionState) => void;
|
|
23
25
|
|
|
@@ -33,6 +35,7 @@ export class MunchiPaymentSDK implements IMunchiPaymentSDK {
|
|
|
33
35
|
private _currentSessionId: string | undefined;
|
|
34
36
|
private _autoResetTimer: ReturnType<typeof setTimeout> | undefined;
|
|
35
37
|
private autoResetOptions: SDKOptions["autoResetOnPaymentComplete"];
|
|
38
|
+
private appToAppConfig: AppToAppConfig | undefined;
|
|
36
39
|
|
|
37
40
|
private static readonly TERMINAL_STATES = [
|
|
38
41
|
PaymentInteractionState.SUCCESS,
|
|
@@ -57,6 +60,7 @@ export class MunchiPaymentSDK implements IMunchiPaymentSDK {
|
|
|
57
60
|
this.logger = options.logger;
|
|
58
61
|
this.timeoutMs = options.timeoutMs || 30000;
|
|
59
62
|
this.autoResetOptions = options.autoResetOnPaymentComplete;
|
|
63
|
+
this.appToAppConfig = options.appToApp;
|
|
60
64
|
this.strategy = strategy ?? this.resolveStrategy(config);
|
|
61
65
|
}
|
|
62
66
|
|
|
@@ -187,6 +191,16 @@ export class MunchiPaymentSDK implements IMunchiPaymentSDK {
|
|
|
187
191
|
return new NetsStrategy(this.axios, this.messaging, config);
|
|
188
192
|
case PaymentProvider.Worldline:
|
|
189
193
|
return new WorldlineStrategy(this.axios, this.messaging, config);
|
|
194
|
+
case PaymentProvider.Viva:
|
|
195
|
+
if (this.appToAppConfig?.enabled) {
|
|
196
|
+
return new VivaAppToAppStrategy(
|
|
197
|
+
this.axios,
|
|
198
|
+
this.messaging,
|
|
199
|
+
config,
|
|
200
|
+
this.appToAppConfig,
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
return new VivaStrategy(this.axios, this.messaging, config);
|
|
190
204
|
|
|
191
205
|
default:
|
|
192
206
|
return new VivaStrategy(this.axios, this.messaging, config);
|
|
@@ -245,19 +259,25 @@ export class MunchiPaymentSDK implements IMunchiPaymentSDK {
|
|
|
245
259
|
params,
|
|
246
260
|
internalStateCallback,
|
|
247
261
|
);
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
262
|
+
const executionMode =
|
|
263
|
+
this.strategy.getExecutionMode?.() ?? StrategyExecutionMode.Managed;
|
|
264
|
+
|
|
265
|
+
const result =
|
|
266
|
+
executionMode === StrategyExecutionMode.CallbackDriven
|
|
267
|
+
? await transactionPromise
|
|
268
|
+
: await Promise.race([
|
|
269
|
+
transactionPromise,
|
|
270
|
+
new Promise<never>((_, reject) => {
|
|
271
|
+
setTimeout(() => {
|
|
272
|
+
reject(
|
|
273
|
+
new PaymentSDKError(
|
|
274
|
+
PaymentErrorCode.TIMEOUT,
|
|
275
|
+
"Transaction timed out",
|
|
276
|
+
),
|
|
277
|
+
);
|
|
278
|
+
}, this.timeoutMs);
|
|
279
|
+
}),
|
|
280
|
+
]);
|
|
261
281
|
|
|
262
282
|
if (result.success) {
|
|
263
283
|
this.transitionTo(PaymentInteractionState.SUCCESS);
|
|
@@ -551,6 +571,7 @@ export class MunchiPaymentSDK implements IMunchiPaymentSDK {
|
|
|
551
571
|
this.logger?.info("Initiating refund", { orderRef: params.orderRef });
|
|
552
572
|
// Clear any stale session before starting a new refund flow.
|
|
553
573
|
this._currentSessionId = undefined;
|
|
574
|
+
this._cancellationIntent = false;
|
|
554
575
|
|
|
555
576
|
// Ensure we are in a valid state to start a refund
|
|
556
577
|
const isRestingState = MunchiPaymentSDK.RESTING_STATES.includes(
|
|
@@ -589,6 +610,17 @@ export class MunchiPaymentSDK implements IMunchiPaymentSDK {
|
|
|
589
610
|
if (result.success) {
|
|
590
611
|
this.transitionTo(PaymentInteractionState.SUCCESS);
|
|
591
612
|
this.safeFireCallback(() => callbacks.onSuccess?.(result));
|
|
613
|
+
} else if (
|
|
614
|
+
this._cancellationIntent ||
|
|
615
|
+
result.status === SdkPaymentStatus.CANCELLED
|
|
616
|
+
) {
|
|
617
|
+
this.transitionTo(PaymentInteractionState.FAILED);
|
|
618
|
+
this.safeFireCallback(() =>
|
|
619
|
+
callbacks.onCancelled?.({
|
|
620
|
+
orderRef: params.orderRef,
|
|
621
|
+
refPaymentId: this._currentSessionId,
|
|
622
|
+
}),
|
|
623
|
+
);
|
|
592
624
|
} else {
|
|
593
625
|
this.transitionTo(PaymentInteractionState.FAILED);
|
|
594
626
|
this.safeFireCallback(() => callbacks.onError?.(result));
|
|
@@ -602,6 +634,61 @@ export class MunchiPaymentSDK implements IMunchiPaymentSDK {
|
|
|
602
634
|
} catch (error) {
|
|
603
635
|
this.logger?.error("Refund failed", error);
|
|
604
636
|
|
|
637
|
+
if (this._cancellationIntent) {
|
|
638
|
+
try {
|
|
639
|
+
if (this._currentSessionId) {
|
|
640
|
+
const finalStatus = await this.verifyWithRetry(
|
|
641
|
+
params,
|
|
642
|
+
this._currentSessionId,
|
|
643
|
+
);
|
|
644
|
+
|
|
645
|
+
if (finalStatus.success) {
|
|
646
|
+
this.transitionTo(PaymentInteractionState.SUCCESS);
|
|
647
|
+
this.safeFireCallback(() => callbacks.onSuccess?.(finalStatus));
|
|
648
|
+
return finalStatus;
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
if (finalStatus.status === SdkPaymentStatus.CANCELLED) {
|
|
652
|
+
this.transitionTo(PaymentInteractionState.FAILED);
|
|
653
|
+
this.safeFireCallback(() =>
|
|
654
|
+
callbacks.onCancelled?.({
|
|
655
|
+
orderRef: params.orderRef,
|
|
656
|
+
refPaymentId: this._currentSessionId,
|
|
657
|
+
}),
|
|
658
|
+
);
|
|
659
|
+
return finalStatus;
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
this.transitionTo(PaymentInteractionState.FAILED);
|
|
663
|
+
this.safeFireCallback(() => callbacks.onError?.(finalStatus));
|
|
664
|
+
return finalStatus;
|
|
665
|
+
}
|
|
666
|
+
} catch (verifyError) {
|
|
667
|
+
this.logger?.warn("Refund final status verification failed", {
|
|
668
|
+
verifyError,
|
|
669
|
+
});
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
this.transitionTo(PaymentInteractionState.FAILED);
|
|
673
|
+
|
|
674
|
+
this.safeFireCallback(() =>
|
|
675
|
+
callbacks.onCancelled?.({
|
|
676
|
+
orderRef: params.orderRef,
|
|
677
|
+
refPaymentId: this._currentSessionId,
|
|
678
|
+
}),
|
|
679
|
+
);
|
|
680
|
+
|
|
681
|
+
return {
|
|
682
|
+
success: false,
|
|
683
|
+
status: SdkPaymentStatus.CANCELLED,
|
|
684
|
+
errorCode: this.normalizeErrorCode(PaymentErrorCode.CANCELLED),
|
|
685
|
+
orderId: params.orderRef,
|
|
686
|
+
...(this._currentSessionId
|
|
687
|
+
? { transactionId: this._currentSessionId }
|
|
688
|
+
: {}),
|
|
689
|
+
};
|
|
690
|
+
}
|
|
691
|
+
|
|
605
692
|
this.transitionTo(PaymentInteractionState.FAILED);
|
|
606
693
|
|
|
607
694
|
const errorResult = this.generateErrorResult(
|
|
@@ -5,7 +5,13 @@ import type {
|
|
|
5
5
|
RefundRequest,
|
|
6
6
|
} from "../types/payment";
|
|
7
7
|
|
|
8
|
+
export enum StrategyExecutionMode {
|
|
9
|
+
Managed = "managed",
|
|
10
|
+
CallbackDriven = "callback_driven",
|
|
11
|
+
}
|
|
12
|
+
|
|
8
13
|
export interface IPaymentStrategy {
|
|
14
|
+
getExecutionMode?(): StrategyExecutionMode;
|
|
9
15
|
|
|
10
16
|
processPayment(
|
|
11
17
|
request: PaymentRequest,
|