mmpay-browser-sdk 1.0.6 → 1.0.8

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/README.md CHANGED
@@ -39,6 +39,7 @@ showPaymentModal(paymentData: PaymentData): Promise<CreatePaymentResponse>
39
39
  MMPayApp.showPaymentModal({
40
40
  amount: 50000,
41
41
  orderId: 'ORD-' + new Date().getTime(),
42
+ customMessage: 'Your custom message here', // Optional
42
43
  callbackUrl: 'https://yoursite.com/confirmation' // Optional [Default callback input in our console will be called if no specified]
43
44
  }, (result) => {
44
45
  if (result.success) {
@@ -65,6 +66,7 @@ const MMPayApp = new MMPaySDK('pk_live_YOUR_KEY', {
65
66
  MMPayApp.showPaymentModal({
66
67
  amount: 50000,
67
68
  orderId: 'ORD-' + new Date().getTime(),
69
+ customMessage: 'Your custom message here', // Optional
68
70
  callbackUrl: 'https://yoursite.com/confirmation' // Optional [Default callback input in our console will be called if no specified]
69
71
  }, (result) => {
70
72
  if (result.success) {
@@ -88,6 +90,7 @@ createPayment(paymentData: PaymentData): Promise<CreatePaymentResponse>
88
90
  MMPayApp.createPayment({
89
91
  amount: 50000,
90
92
  orderId: 'ORD-' + new Date().getTime(),
93
+ customMessage: 'Your custom message here', // Optional
91
94
  callbackUrl: 'https://yoursite.com/confirmation' // Optional [Default callback input in our console will be called if no specified]
92
95
  }).then((result) => {
93
96
  if (result.qr) {
@@ -153,12 +156,14 @@ export class MMPayService {
153
156
  * @param {number} amount
154
157
  * @param {string} orderId
155
158
  * @param {string} callbackUrl
159
+ * @param {string} customMessage
156
160
  */
157
- modalPay(amount: number, orderId: string, callbackUrl?: string) {
161
+ modalPay(amount: number, orderId: string, callbackUrl?: string, customMessage?: string) {
158
162
  this.mmpay.showPaymentModal({
159
163
  amount,
160
164
  orderId,
161
165
  callbackUrl,
166
+ customMessage,
162
167
  }, (result: ModalResponse) => {
163
168
  if (result.success) {
164
169
  console.log('Redirect Some where');
@@ -169,12 +174,14 @@ export class MMPayService {
169
174
  * @param {number} amount
170
175
  * @param {string} orderId
171
176
  * @param {string} callbackUrl
177
+ * @param {string} customMessage
172
178
  */
173
- pay(amount: number, orderId: string, callbackUrl?: string) {
179
+ pay(amount: number, orderId: string, callbackUrl?: string, customMessage?: string) {
174
180
  this.mmpay.createPayment({
175
181
  amount,
176
182
  orderId,
177
183
  callbackUrl,
184
+ customMessage,
178
185
  })
179
186
  .then((result: PayResponse) => {
180
187
  if (result.qr) {
@@ -1,14 +1,24 @@
1
- export interface ICorePayParams {
1
+ export interface SDKOptions {
2
+ pollInterval?: number;
3
+ environment?: 'sandbox' | 'production';
4
+ baseUrl?: string;
5
+ merchantName?: string;
6
+ }
7
+ export interface ICreateTokenRequestParams {
2
8
  amount: number;
3
9
  orderId: string;
4
- callbackUrl?: string;
10
+ nonce?: string;
11
+ }
12
+ export interface ICreateTokenResponse {
13
+ orderId: string;
14
+ token: string;
5
15
  }
6
16
  export interface ICreatePaymentRequestParams {
7
17
  amount: number;
8
- currency?: string;
9
18
  orderId: string;
10
19
  callbackUrl?: string;
11
20
  nonce?: string;
21
+ customMessage?: string;
12
22
  }
13
23
  export interface ICreatePaymentResponse {
14
24
  _id: string;
@@ -18,17 +28,6 @@ export interface ICreatePaymentResponse {
18
28
  transactionRefId: string;
19
29
  qr: string;
20
30
  }
21
- export interface ICreateTokenRequestParams {
22
- amount: number;
23
- currency?: string;
24
- orderId: string;
25
- callbackUrl?: string;
26
- nonce?: string;
27
- }
28
- export interface ICreateTokenResponse {
29
- orderId: string;
30
- token: string;
31
- }
32
31
  export interface IPollingRequest {
33
32
  amount: number;
34
33
  currency?: string;
@@ -45,12 +44,6 @@ export interface PolliongResult {
45
44
  success: boolean;
46
45
  transaction: IPollingResponse;
47
46
  }
48
- export interface SDKOptions {
49
- pollInterval?: number;
50
- environment?: 'sandbox' | 'production';
51
- baseUrl?: string;
52
- merchantName?: string;
53
- }
54
47
  export declare class MMPaySDK {
55
48
  private POLL_INTERVAL_MS;
56
49
  private tokenKey;
@@ -59,113 +52,26 @@ export declare class MMPaySDK {
59
52
  private merchantName;
60
53
  private environment;
61
54
  private pollIntervalId;
55
+ private countdownIntervalId;
62
56
  private onCompleteCallback;
63
57
  private overlayElement;
64
58
  private pendingApiResponse;
65
59
  private pendingPaymentPayload;
66
60
  private readonly QR_SIZE;
67
- /**
68
- * constructor
69
- * @param publishableKey
70
- * @param options
71
- */
61
+ private readonly TIMEOUT_SECONDS;
72
62
  constructor(publishableKey: string, options?: SDKOptions);
73
- /**
74
- * _callApi
75
- * @param endpoint
76
- * @param data
77
- * @returns
78
- */
79
63
  private _callApi;
80
- /**
81
- * _callApiTokenRequest
82
- * @param {ICreateTokenRequestParams} payload
83
- * @param {number} payload.amount
84
- * @param {string} payload.currency
85
- * @param {string} payload.orderId
86
- * @param {string} payload.nonce
87
- * @param {string} payload.callbackUrl
88
- * @returns {Promise<ICreateTokenResponse>}
89
- */
90
64
  private _callApiTokenRequest;
91
- /**
92
- * _callApiPaymentRequest
93
- * @param {ICreatePaymentRequestParams} payload
94
- * @param {number} payload.amount
95
- * @param {string} payload.currency
96
- * @param {string} payload.orderId
97
- * @param {string} payload.nonce
98
- * @param {string} payload.callbackUrl
99
- * @returns {Promise<ICreatePaymentResponse>}
100
- */
101
65
  private _callApiPaymentRequest;
102
- /**
103
- * createPayment
104
- * @param {ICorePayParams} params
105
- * @param {number} params.amount
106
- * @param {string} params.orderId
107
- * @param {string} params.callbackUrl
108
- * @returns {Promise<ICreatePaymentResponse>}
109
- */
110
- createPayment(params: ICorePayParams): Promise<ICreatePaymentResponse>;
111
- /**
112
- * showPaymentModal
113
- * @param {ICorePayParams} params
114
- * @param {number} params.amount
115
- * @param {string} params.orderId
116
- * @param {string} params.callbackUrl
117
- * @param {Function} onComplete
118
- */
119
- showPaymentModal(params: ICorePayParams, onComplete: (result: PolliongResult) => void): Promise<void>;
120
- /**
121
- * _createAndRenderModal
122
- * @param {string} contentHtml
123
- * @param {boolean} isTerminal
124
- * @returns
125
- */
66
+ createPayment(params: ICreatePaymentRequestParams): Promise<ICreatePaymentResponse>;
67
+ showPaymentModal(params: ICreatePaymentRequestParams, onComplete: (result: PolliongResult) => void): Promise<void>;
126
68
  private _createAndRenderModal;
127
- /**
128
- * _renderQrModalContent
129
- * @param {ICreatePaymentResponse} apiResponse
130
- * @param {CreatePaymentRequest} payload
131
- * @param {string} merchantName
132
- */
133
69
  private _renderQrModalContent;
134
- /**
135
- * _showTerminalMessage
136
- * @param {string} orderId
137
- * @param {string} status
138
- * @param {string} message
139
- */
140
70
  private _showTerminalMessage;
141
- /**
142
- * _showCancelConfirmationModal
143
- */
144
71
  private _showCancelConfirmationModal;
145
- /**
146
- * _reRenderPendingModalInstance
147
- */
148
72
  private _reRenderPendingModalInstance;
149
- /**
150
- * Cleans up the modal and stops polling.
151
- * @param {boolean} restoreBodyScroll
152
- */
153
73
  private _cleanupModal;
154
- /**
155
- * _injectQrScript
156
- * @param {string} qrData
157
- * @param {string} qrCanvasId
158
- */
159
74
  private _injectQrScript;
160
- /**
161
- * _startPolling
162
- * @param {IPollingRequest} payload
163
- * @param {number} payload.amount
164
- * @param {string} payload.currency
165
- * @param {string} payload.orderId
166
- * @param {string} payload.nonce
167
- * @param {string} payload.callbackUrl
168
- * @param {Function} onComplete
169
- */
170
75
  private _startPolling;
76
+ private _startCountdown;
171
77
  }
package/dist/cjs/index.js CHANGED
@@ -2,18 +2,15 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MMPaySDK = void 0;
4
4
  class MMPaySDK {
5
- /**
6
- * constructor
7
- * @param publishableKey
8
- * @param options
9
- */
10
5
  constructor(publishableKey, options = {}) {
11
6
  this.pollIntervalId = undefined;
7
+ this.countdownIntervalId = undefined;
12
8
  this.onCompleteCallback = null;
13
9
  this.overlayElement = null;
14
10
  this.pendingApiResponse = null;
15
11
  this.pendingPaymentPayload = null;
16
12
  this.QR_SIZE = 290;
13
+ this.TIMEOUT_SECONDS = 300;
17
14
  if (!publishableKey) {
18
15
  throw new Error("A Publishable Key is required to initialize [MMPaySDK].");
19
16
  }
@@ -23,12 +20,6 @@ class MMPaySDK {
23
20
  this.merchantName = options.merchantName || 'Your Merchant';
24
21
  this.POLL_INTERVAL_MS = options.pollInterval || 5000;
25
22
  }
26
- /**
27
- * _callApi
28
- * @param endpoint
29
- * @param data
30
- * @returns
31
- */
32
23
  async _callApi(endpoint, data = {}) {
33
24
  let config = {
34
25
  'Content-Type': 'application/json',
@@ -52,16 +43,6 @@ class MMPaySDK {
52
43
  }
53
44
  return response.json();
54
45
  }
55
- /**
56
- * _callApiTokenRequest
57
- * @param {ICreateTokenRequestParams} payload
58
- * @param {number} payload.amount
59
- * @param {string} payload.currency
60
- * @param {string} payload.orderId
61
- * @param {string} payload.nonce
62
- * @param {string} payload.callbackUrl
63
- * @returns {Promise<ICreateTokenResponse>}
64
- */
65
46
  async _callApiTokenRequest(payload) {
66
47
  try {
67
48
  const endpoint = this.environment === 'sandbox'
@@ -74,16 +55,6 @@ class MMPaySDK {
74
55
  throw error;
75
56
  }
76
57
  }
77
- /**
78
- * _callApiPaymentRequest
79
- * @param {ICreatePaymentRequestParams} payload
80
- * @param {number} payload.amount
81
- * @param {string} payload.currency
82
- * @param {string} payload.orderId
83
- * @param {string} payload.nonce
84
- * @param {string} payload.callbackUrl
85
- * @returns {Promise<ICreatePaymentResponse>}
86
- */
87
58
  async _callApiPaymentRequest(payload) {
88
59
  try {
89
60
  const endpoint = this.environment === 'sandbox'
@@ -96,61 +67,55 @@ class MMPaySDK {
96
67
  throw error;
97
68
  }
98
69
  }
99
- /**
100
- * createPayment
101
- * @param {ICorePayParams} params
102
- * @param {number} params.amount
103
- * @param {string} params.orderId
104
- * @param {string} params.callbackUrl
105
- * @returns {Promise<ICreatePaymentResponse>}
106
- */
107
70
  async createPayment(params) {
108
- const payload = {
71
+ const tokenPayload = {
72
+ amount: params.amount,
73
+ orderId: params.orderId,
74
+ nonce: new Date().getTime().toString() + '_mmp'
75
+ };
76
+ const paymentPayload = {
109
77
  amount: params.amount,
110
78
  orderId: params.orderId,
111
79
  callbackUrl: params.callbackUrl,
112
- currency: 'MMK',
80
+ customMessage: params.customMessage,
113
81
  nonce: new Date().getTime().toString() + '_mmp'
114
82
  };
115
83
  try {
116
- const tokenResponse = await this._callApiTokenRequest(payload);
84
+ const tokenResponse = await this._callApiTokenRequest(tokenPayload);
117
85
  this.tokenKey = tokenResponse.token;
118
- const apiResponse = await this._callApiPaymentRequest(payload);
119
- return apiResponse;
86
+ return await this._callApiPaymentRequest(paymentPayload);
120
87
  }
121
88
  catch (error) {
122
89
  console.error("Payment request failed:", error);
123
90
  throw error;
124
91
  }
125
92
  }
126
- /**
127
- * showPaymentModal
128
- * @param {ICorePayParams} params
129
- * @param {number} params.amount
130
- * @param {string} params.orderId
131
- * @param {string} params.callbackUrl
132
- * @param {Function} onComplete
133
- */
134
93
  async showPaymentModal(params, onComplete) {
135
94
  const initialContent = `<div class="mmpay-overlay-content"><div style="text-align: center; color: #fff;">ငွေပေးချေမှု စတင်နေသည်...</div></div>`;
136
95
  this._createAndRenderModal(initialContent, false);
137
96
  this.onCompleteCallback = onComplete;
138
- const payload = {
97
+ const tokenPayload = {
98
+ amount: params.amount,
99
+ orderId: params.orderId,
100
+ nonce: new Date().getTime().toString() + '_mmp'
101
+ };
102
+ const paymentPayload = {
139
103
  amount: params.amount,
140
104
  orderId: params.orderId,
141
105
  callbackUrl: params.callbackUrl,
142
- currency: 'MMK',
106
+ customMessage: params.customMessage,
143
107
  nonce: new Date().getTime().toString() + '_mmp'
144
108
  };
145
109
  try {
146
- const tokenResponse = await this._callApiTokenRequest(payload);
110
+ const tokenResponse = await this._callApiTokenRequest(tokenPayload);
147
111
  this.tokenKey = tokenResponse.token;
148
- const apiResponse = await this._callApiPaymentRequest(payload);
112
+ const apiResponse = await this._callApiPaymentRequest(paymentPayload);
149
113
  if (apiResponse && apiResponse.qr && apiResponse.transactionRefId) {
150
114
  this.pendingApiResponse = apiResponse;
151
- this.pendingPaymentPayload = payload;
152
- this._renderQrModalContent(apiResponse, payload, this.merchantName);
153
- this._startPolling(payload, onComplete);
115
+ this.pendingPaymentPayload = paymentPayload;
116
+ this._renderQrModalContent(apiResponse, paymentPayload, this.merchantName);
117
+ this._startPolling(paymentPayload, onComplete);
118
+ this._startCountdown(paymentPayload.orderId);
154
119
  }
155
120
  else {
156
121
  this._showTerminalMessage(apiResponse.orderId || 'N/A', 'FAILED', 'ငွေပေးချေမှု စတင်ရန် မအောင်မြင်ပါ။ QR ဒေတာ မရရှိပါ။');
@@ -158,15 +123,9 @@ class MMPaySDK {
158
123
  }
159
124
  catch (error) {
160
125
  this.tokenKey = null;
161
- this._showTerminalMessage(payload.orderId || 'N/A', 'FAILED', 'ငွေပေးချေမှု စတင်စဉ် အမှားအယွင်း ဖြစ်ပွားသည်။ ကွန်ဆိုးလ်တွင် ကြည့်ပါ။');
126
+ this._showTerminalMessage(paymentPayload.orderId || 'N/A', 'FAILED', 'ငွေပေးချေမှု စတင်စဉ် အမှားအယွင်း ဖြစ်ပွားသည်။ ကွန်ဆိုးလ်တွင် ကြည့်ပါ။');
162
127
  }
163
128
  }
164
- /**
165
- * _createAndRenderModal
166
- * @param {string} contentHtml
167
- * @param {boolean} isTerminal
168
- * @returns
169
- */
170
129
  _createAndRenderModal(contentHtml, isTerminal = false) {
171
130
  this._cleanupModal(false);
172
131
  const overlay = document.createElement('div');
@@ -200,7 +159,6 @@ class MMPaySDK {
200
159
  width: 100%;
201
160
  padding: 20px 0;
202
161
  }
203
- /* Card Base Styles */
204
162
  .mmpay-card {
205
163
  background: #ffffff;
206
164
  border-radius: 16px;
@@ -272,15 +230,9 @@ class MMPaySDK {
272
230
  };
273
231
  window.MMPayReRenderModal = () => this._reRenderPendingModalInstance();
274
232
  overlay.innerHTML += `<div class="mmpay-overlay-content">${contentHtml}</div>`;
275
- document.body.style.overflow = 'hidden'; // FIX: Prevent body scroll when modal is open
233
+ document.body.style.overflow = 'hidden';
276
234
  return overlay;
277
235
  }
278
- /**
279
- * _renderQrModalContent
280
- * @param {ICreatePaymentResponse} apiResponse
281
- * @param {CreatePaymentRequest} payload
282
- * @param {string} merchantName
283
- */
284
236
  _renderQrModalContent(apiResponse, payload, merchantName) {
285
237
  const qrData = apiResponse.qr;
286
238
  const amountDisplay = `${apiResponse.amount.toFixed(2)} MMK`;
@@ -307,7 +259,7 @@ class MMPaySDK {
307
259
  <style>
308
260
  .mmpay-card { max-width: 350px; padding: 16px; }
309
261
  .mmpay-header { color: #1f2937; font-size: 1rem; font-weight: bold; margin-bottom: 8px; }
310
- .mmpay-qr-container { padding: 0; margin: 10px auto; display: inline-block; line-height: 0; width: 300px; height: 300px; }
262
+ .mmpay-qr-container { padding: 0; margin: 5px auto 10px auto; display: inline-block; line-height: 0; width: 300px; height: 300px; }
311
263
  #${qrCanvasId} { display: block; background: white; border-radius: 8px; width: 100%; height: 100%; }
312
264
  .mmpay-amount { font-size: 1.2rem; font-weight: 800; color: #1f2937; margin: 0; }
313
265
  .mmpay-separator { border-top: 1px solid #f3f4f6; margin: 12px 0; }
@@ -316,10 +268,28 @@ class MMPaySDK {
316
268
  .mmpay-detail span { text-align: left; }
317
269
  .mmpay-secure-text { color: #757575; border-radius: 9999px; font-size: 0.8rem; font-weight: 600; display: inline-flex; align-items: center; justify-content: center; }
318
270
  .mmpay-warning { font-size: 0.75rem; color: #9ca3af; font-weight: 500; margin-top: 12px; line-height: 1.5; }
271
+
272
+ .mmpay-timer-badge {
273
+ background-color: #fef2f2;
274
+ color: #b91c1c;
275
+ padding: 4px 10px;
276
+ border-radius: 12px;
277
+ font-weight: 700;
278
+ font-size: 0.85rem;
279
+ display: inline-flex;
280
+ align-items: center;
281
+ gap: 5px;
282
+ margin: 8px 0;
283
+ border: 1px solid #fee2e2;
284
+ }
285
+ .mmpay-timer-icon {
286
+ width: 14px;
287
+ height: 14px;
288
+ fill: currentColor;
289
+ }
319
290
  </style>
320
291
 
321
292
  <div class="mmpay-card">
322
- <!-- Close Button - Triggers Confirmation Modal -->
323
293
  <button class="mmpay-close-btn" onclick="MMPayCloseModal(false)">
324
294
  <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" viewBox="0 0 16 16">
325
295
  <path d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z"/>
@@ -334,6 +304,14 @@ class MMPaySDK {
334
304
  ${merchantName} သို့ပေးချေပါ
335
305
  </div>
336
306
 
307
+ <div class="mmpay-timer-badge" id="mmpay-timer-badge">
308
+ <svg class="mmpay-timer-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
309
+ <path d="M8 3.5a.5.5 0 0 0-1 0V9a.5.5 0 0 0 .252.434l3.5 2a.5.5 0 0 0 .496-.868L8 8.71V3.5z"/>
310
+ <path d="M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16zm7-8A7 7 0 1 1 1 8a7 7 0 0 1 14 0z"/>
311
+ </svg>
312
+ <span id="mmpay-countdown-text">05:00</span>
313
+ </div>
314
+
337
315
  <div class="mmpay-amount">${amountDisplay}</div>
338
316
 
339
317
  <div class="mmpay-qr-container">
@@ -366,17 +344,11 @@ class MMPaySDK {
366
344
  this._createAndRenderModal(qrContentHtml, false);
367
345
  this._injectQrScript(qrData, qrCanvasId);
368
346
  }
369
- /**
370
- * _showTerminalMessage
371
- * @param {string} orderId
372
- * @param {string} status
373
- * @param {string} message
374
- */
375
347
  _showTerminalMessage(orderId, status, message) {
376
348
  this._cleanupModal(true);
377
- const successColor = '#10b981'; // Tailwind Green 500
378
- const failureColor = '#ef4444'; // Tailwind Red 500
379
- const expiredColor = '#f59e0b'; // Tailwind Amber 500
349
+ const successColor = '#10b981';
350
+ const failureColor = '#ef4444';
351
+ const expiredColor = '#f59e0b';
380
352
  let color;
381
353
  let iconSvg;
382
354
  let statusText;
@@ -388,7 +360,6 @@ class MMPaySDK {
388
360
  </svg>`;
389
361
  }
390
362
  else {
391
- // Shared icon for FAILED and EXPIRED (X mark)
392
363
  color = status === 'FAILED' ? failureColor : expiredColor;
393
364
  statusText = status === 'FAILED' ? 'မအောင်မြင်' : 'သက်တမ်းကုန်';
394
365
  iconSvg = `<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" fill="${color}" viewBox="0 0 16 16">
@@ -412,16 +383,17 @@ class MMPaySDK {
412
383
  </button>
413
384
  </div>
414
385
  `;
415
- this._createAndRenderModal(content, true); // Set isTerminal=true so the close button always forces cleanup
386
+ this._createAndRenderModal(content, true);
416
387
  }
417
- /**
418
- * _showCancelConfirmationModal
419
- */
420
388
  _showCancelConfirmationModal() {
421
389
  if (this.pollIntervalId !== undefined) {
422
390
  window.clearInterval(this.pollIntervalId);
423
391
  this.pollIntervalId = undefined;
424
392
  }
393
+ if (this.countdownIntervalId !== undefined) {
394
+ window.clearInterval(this.countdownIntervalId);
395
+ this.countdownIntervalId = undefined;
396
+ }
425
397
  this._cleanupModal(false);
426
398
  const content = `
427
399
  <div class="mmpay-card mmpay-terminal-card" style="
@@ -443,11 +415,8 @@ class MMPaySDK {
443
415
  </div>
444
416
  </div>
445
417
  `;
446
- this._createAndRenderModal(content, false); // Set isTerminal=false so the close button calls MMPayCloseModal(true)
418
+ this._createAndRenderModal(content, false);
447
419
  }
448
- /**
449
- * _reRenderPendingModalInstance
450
- */
451
420
  _reRenderPendingModalInstance() {
452
421
  if (this.pendingApiResponse && this.pendingPaymentPayload && this.onCompleteCallback) {
453
422
  this._cleanupModal(true);
@@ -457,15 +426,15 @@ class MMPaySDK {
457
426
  this._cleanupModal(true);
458
427
  }
459
428
  }
460
- /**
461
- * Cleans up the modal and stops polling.
462
- * @param {boolean} restoreBodyScroll
463
- */
464
429
  _cleanupModal(restoreBodyScroll) {
465
430
  if (this.pollIntervalId !== undefined) {
466
431
  window.clearInterval(this.pollIntervalId);
467
432
  this.pollIntervalId = undefined;
468
433
  }
434
+ if (this.countdownIntervalId !== undefined) {
435
+ window.clearInterval(this.countdownIntervalId);
436
+ this.countdownIntervalId = undefined;
437
+ }
469
438
  if (this.overlayElement && this.overlayElement.parentNode) {
470
439
  this.overlayElement.parentNode.removeChild(this.overlayElement);
471
440
  this.overlayElement = null;
@@ -476,11 +445,6 @@ class MMPaySDK {
476
445
  delete window.MMPayCloseModal;
477
446
  delete window.MMPayReRenderModal;
478
447
  }
479
- /**
480
- * _injectQrScript
481
- * @param {string} qrData
482
- * @param {string} qrCanvasId
483
- */
484
448
  _injectQrScript(qrData, qrCanvasId) {
485
449
  const script = document.createElement('script');
486
450
  script.src = "https://cdn.jsdelivr.net/npm/qrious@4.0.2/dist/qrious.min.js";
@@ -503,16 +467,6 @@ class MMPaySDK {
503
467
  };
504
468
  document.head.appendChild(script);
505
469
  }
506
- /**
507
- * _startPolling
508
- * @param {IPollingRequest} payload
509
- * @param {number} payload.amount
510
- * @param {string} payload.currency
511
- * @param {string} payload.orderId
512
- * @param {string} payload.nonce
513
- * @param {string} payload.callbackUrl
514
- * @param {Function} onComplete
515
- */
516
470
  async _startPolling(payload, onComplete) {
517
471
  if (this.pollIntervalId !== undefined) {
518
472
  window.clearInterval(this.pollIntervalId);
@@ -546,7 +500,29 @@ class MMPaySDK {
546
500
  checkStatus();
547
501
  this.pollIntervalId = window.setInterval(checkStatus, this.POLL_INTERVAL_MS);
548
502
  }
503
+ _startCountdown(orderId) {
504
+ if (this.countdownIntervalId !== undefined) {
505
+ window.clearInterval(this.countdownIntervalId);
506
+ }
507
+ let remaining = this.TIMEOUT_SECONDS;
508
+ const timerElement = document.getElementById('mmpay-countdown-text');
509
+ const updateDisplay = () => {
510
+ if (!timerElement)
511
+ return;
512
+ const minutes = Math.floor(remaining / 60);
513
+ const seconds = remaining % 60;
514
+ timerElement.innerText = `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
515
+ };
516
+ this.countdownIntervalId = window.setInterval(() => {
517
+ remaining--;
518
+ updateDisplay();
519
+ if (remaining <= 0) {
520
+ window.clearInterval(this.countdownIntervalId);
521
+ this.countdownIntervalId = undefined;
522
+ this._showTerminalMessage(orderId, 'EXPIRED', 'သတ်မှတ်ချိန်ကုန်သွားပါပြီ။');
523
+ }
524
+ }, 1000);
525
+ }
549
526
  }
550
527
  exports.MMPaySDK = MMPaySDK;
551
- // Make the SDK class and its instance methods accessible globally
552
528
  window.MMPaySDK = MMPaySDK;