mmpay-browser-sdk 1.0.3 → 1.0.4

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.
@@ -1,46 +1,45 @@
1
- export interface PaymentData {
1
+ export interface ICreatePaymentRequest {
2
2
  amount: number;
3
3
  currency: string;
4
4
  orderId: string;
5
5
  callbackUrl?: string;
6
+ nonce?: string;
6
7
  }
7
- export interface CreatePaymentResponse {
8
+ export interface ICreatePaymentResponse {
8
9
  _id: string;
9
10
  amount: number;
10
11
  orderId: string;
11
12
  currency: string;
12
- transactionId: string;
13
+ transactionRefId: string;
13
14
  qr: string;
14
15
  url: string;
15
16
  }
16
- export interface PollingResponse {
17
- _id: string;
18
- appId: string;
17
+ export interface ICreateTokenRequest {
18
+ amount: number;
19
+ currency: string;
20
+ orderId: string;
21
+ callbackUrl?: string;
22
+ nonce?: string;
23
+ }
24
+ export interface ICreateTokenResponse {
19
25
  orderId: string;
26
+ token: string;
27
+ }
28
+ export interface IPollingRequest {
20
29
  amount: number;
21
30
  currency: string;
22
- method?: string;
23
- vendor?: string;
31
+ orderId: string;
24
32
  callbackUrl?: string;
25
- callbackUrlStatus?: 'PENDING' | 'SUCCESS' | 'FAILED';
26
- callbackAt?: Date;
27
- disbursementStatus?: 'NONE' | 'PENDING' | 'COMPLETED' | 'FAILED' | 'CANCELLED';
28
- disburseAt?: Date;
29
- items: {
30
- name: string;
31
- amount: number;
32
- quantity: number;
33
- }[];
34
- merchantId: string;
33
+ nonce?: string;
34
+ }
35
+ export interface IPollingResponse {
36
+ orderId: string;
37
+ transactionRefId: string;
35
38
  status: 'PENDING' | 'SUCCESS' | 'FAILED' | 'EXPIRED';
36
- createdAt: Date;
37
- transactionRefId?: string;
38
- qr?: string;
39
- redirectUrl?: string;
40
39
  }
41
40
  export interface PolliongResult {
42
41
  success: boolean;
43
- transaction: PollingResponse;
42
+ transaction: IPollingResponse;
44
43
  }
45
44
  export interface SDKOptions {
46
45
  pollInterval?: number;
@@ -50,6 +49,7 @@ export interface SDKOptions {
50
49
  }
51
50
  export declare class MMPaySDK {
52
51
  private POLL_INTERVAL_MS;
52
+ private tokenKey;
53
53
  private publishableKey;
54
54
  private baseUrl;
55
55
  private merchantName;
@@ -68,29 +68,45 @@ export declare class MMPaySDK {
68
68
  * @returns
69
69
  */
70
70
  private _callApi;
71
+ /**
72
+ * createTokenRequest
73
+ * @param {ICreateTokenRequest} payload
74
+ * @param {number} payload.amount
75
+ * @param {string} payload.currency
76
+ * @param {string} payload.orderId
77
+ * @param {string} payload.nonce
78
+ * @param {string} payload.callbackUrl
79
+ * @returns {Promise<ICreateTokenResponse>}
80
+ */
81
+ createTokenRequest(payload: ICreateTokenRequest): Promise<ICreateTokenResponse>;
71
82
  /**
72
83
  * createPaymentRequest
73
- * @param {PaymentData} payload
74
- * @returns
84
+ * @param {ICreatePaymentRequest} payload
85
+ * @param {number} payload.amount
86
+ * @param {string} payload.currency
87
+ * @param {string} payload.orderId
88
+ * @param {string} payload.nonce
89
+ * @param {string} payload.callbackUrl
90
+ * @returns {Promise<ICreatePaymentResponse>}
91
+ */
92
+ createPaymentRequest(payload: ICreatePaymentRequest): Promise<ICreatePaymentResponse>;
93
+ /**
94
+ * showPaymentModal
95
+ * @param {CreatePaymentRequest} payload
96
+ * @param {Function} onComplete
75
97
  */
76
- createPaymentRequest(payload: PaymentData): Promise<CreatePaymentResponse>;
98
+ showPaymentModal(payload: ICreatePaymentRequest, onComplete: (result: PolliongResult) => void): Promise<void>;
77
99
  /**
78
100
  * _createAndRenderModal
79
101
  * @param {string} contentHtml
80
- * @param isTerminal
102
+ * @param {boolean} isTerminal
81
103
  * @returns
82
104
  */
83
105
  private _createAndRenderModal;
84
- /**
85
- * showPaymentModal
86
- * @param {PaymentData} payload
87
- * @param {Function} onComplete
88
- */
89
- showPaymentModal(payload: PaymentData, onComplete: (result: PolliongResult) => void): Promise<void>;
90
106
  /**
91
107
  * _renderQrModalContent
92
- * @param {CreatePaymentResponse} apiResponse
93
- * @param {PaymentData} payload
108
+ * @param {ICreatePaymentResponse} apiResponse
109
+ * @param {CreatePaymentRequest} payload
94
110
  * @param {string} merchantName
95
111
  */
96
112
  private _renderQrModalContent;
@@ -122,7 +138,12 @@ export declare class MMPaySDK {
122
138
  private _injectQrScript;
123
139
  /**
124
140
  * _startPolling
125
- * @param {string} _id
141
+ * @param {IPollingRequest} payload
142
+ * @param {number} payload.amount
143
+ * @param {string} payload.currency
144
+ * @param {string} payload.orderId
145
+ * @param {string} payload.nonce
146
+ * @param {string} payload.callbackUrl
126
147
  * @param {Function} onComplete
127
148
  */
128
149
  private _startPolling;
package/dist/cjs/index.js CHANGED
@@ -26,12 +26,20 @@ class MMPaySDK {
26
26
  * @returns
27
27
  */
28
28
  async _callApi(endpoint, data = {}) {
29
+ let config = {
30
+ 'Content-Type': 'application/json',
31
+ 'Authorization': `Bearer ${this.publishableKey}`
32
+ };
33
+ if (this.tokenKey) {
34
+ config = {
35
+ 'Content-Type': 'application/json',
36
+ 'Authorization': `Bearer ${this.publishableKey}`,
37
+ 'X-MMPay-Btoken': `${this.tokenKey}`
38
+ };
39
+ }
29
40
  const response = await fetch(`${this.baseUrl}${endpoint}`, {
30
41
  method: 'POST',
31
- headers: {
32
- 'Content-Type': 'application/json',
33
- 'Authorization': `Bearer ${this.publishableKey}`
34
- },
42
+ headers: config,
35
43
  body: JSON.stringify(data)
36
44
  });
37
45
  if (!response.ok) {
@@ -40,10 +48,37 @@ class MMPaySDK {
40
48
  }
41
49
  return response.json();
42
50
  }
51
+ /**
52
+ * createTokenRequest
53
+ * @param {ICreateTokenRequest} payload
54
+ * @param {number} payload.amount
55
+ * @param {string} payload.currency
56
+ * @param {string} payload.orderId
57
+ * @param {string} payload.nonce
58
+ * @param {string} payload.callbackUrl
59
+ * @returns {Promise<ICreateTokenResponse>}
60
+ */
61
+ async createTokenRequest(payload) {
62
+ try {
63
+ const endpoint = this.environment === 'sandbox'
64
+ ? '/xpayments/sandbox-token-request'
65
+ : '/xpayments/production-token-request';
66
+ return await this._callApi(endpoint, payload);
67
+ }
68
+ catch (error) {
69
+ console.error("Token request failed:", error);
70
+ throw error;
71
+ }
72
+ }
43
73
  /**
44
74
  * createPaymentRequest
45
- * @param {PaymentData} payload
46
- * @returns
75
+ * @param {ICreatePaymentRequest} payload
76
+ * @param {number} payload.amount
77
+ * @param {string} payload.currency
78
+ * @param {string} payload.orderId
79
+ * @param {string} payload.nonce
80
+ * @param {string} payload.callbackUrl
81
+ * @returns {Promise<ICreatePaymentResponse>}
47
82
  */
48
83
  async createPaymentRequest(payload) {
49
84
  try {
@@ -57,10 +92,39 @@ class MMPaySDK {
57
92
  throw error;
58
93
  }
59
94
  }
95
+ /**
96
+ * showPaymentModal
97
+ * @param {CreatePaymentRequest} payload
98
+ * @param {Function} onComplete
99
+ */
100
+ async showPaymentModal(payload, onComplete) {
101
+ const initialContent = `<div class="mmpay-overlay-content"><div style="text-align: center; color: #fff;">ငွေပေးချေမှု စတင်နေသည်...</div></div>`;
102
+ this._createAndRenderModal(initialContent, false);
103
+ this.onCompleteCallback = onComplete;
104
+ try {
105
+ payload.nonce = new Date().getTime().toString() + '_mmp';
106
+ const tokenResponse = await this.createTokenRequest(payload);
107
+ this.tokenKey = tokenResponse.token;
108
+ const apiResponse = await this.createPaymentRequest(payload);
109
+ if (apiResponse && apiResponse.qr && apiResponse.transactionRefId) {
110
+ this.pendingApiResponse = apiResponse;
111
+ this.pendingPaymentPayload = payload;
112
+ this._renderQrModalContent(apiResponse, payload, this.merchantName);
113
+ this._startPolling(payload, onComplete);
114
+ }
115
+ else {
116
+ this._showTerminalMessage(apiResponse.orderId || 'N/A', 'FAILED', 'ငွေပေးချေမှု စတင်ရန် မအောင်မြင်ပါ။ QR ဒေတာ မရရှိပါ။');
117
+ }
118
+ }
119
+ catch (error) {
120
+ this.tokenKey = null;
121
+ this._showTerminalMessage(payload.orderId || 'N/A', 'FAILED', 'ငွေပေးချေမှု စတင်စဉ် အမှားအယွင်း ဖြစ်ပွားသည်။ ကွန်ဆိုးလ်တွင် ကြည့်ပါ။');
122
+ }
123
+ }
60
124
  /**
61
125
  * _createAndRenderModal
62
126
  * @param {string} contentHtml
63
- * @param isTerminal
127
+ * @param {boolean} isTerminal
64
128
  * @returns
65
129
  */
66
130
  _createAndRenderModal(contentHtml, isTerminal = false) {
@@ -172,36 +236,10 @@ class MMPaySDK {
172
236
  document.body.style.overflow = 'hidden'; // FIX: Prevent body scroll when modal is open
173
237
  return overlay;
174
238
  }
175
- /**
176
- * showPaymentModal
177
- * @param {PaymentData} payload
178
- * @param {Function} onComplete
179
- */
180
- async showPaymentModal(payload, onComplete) {
181
- const initialContent = `<div class="mmpay-overlay-content"><div style="text-align: center; color: #fff;">ငွေပေးချေမှု စတင်နေသည်...</div></div>`;
182
- this._createAndRenderModal(initialContent, false);
183
- this.onCompleteCallback = onComplete;
184
- try {
185
- const apiResponse = await this.createPaymentRequest(payload);
186
- if (apiResponse && apiResponse.qr && apiResponse.transactionId) {
187
- this.pendingApiResponse = apiResponse;
188
- this.pendingPaymentPayload = payload;
189
- this._renderQrModalContent(apiResponse, payload, this.merchantName);
190
- this._startPolling(apiResponse._id, onComplete);
191
- }
192
- else {
193
- this._showTerminalMessage(apiResponse.orderId || 'N/A', 'FAILED', 'ငွေပေးချေမှု စတင်ရန် မအောင်မြင်ပါ။ QR ဒေတာ မရရှိပါ။');
194
- }
195
- }
196
- catch (error) {
197
- // Myanmar translation for "Error during payment initiation. See console."
198
- this._showTerminalMessage(payload.orderId || 'N/A', 'FAILED', 'ငွေပေးချေမှု စတင်စဉ် အမှားအယွင်း ဖြစ်ပွားသည်။ ကွန်ဆိုးလ်တွင် ကြည့်ပါ။');
199
- }
200
- }
201
239
  /**
202
240
  * _renderQrModalContent
203
- * @param {CreatePaymentResponse} apiResponse
204
- * @param {PaymentData} payload
241
+ * @param {ICreatePaymentResponse} apiResponse
242
+ * @param {CreatePaymentRequest} payload
205
243
  * @param {string} merchantName
206
244
  */
207
245
  _renderQrModalContent(apiResponse, payload, merchantName) {
@@ -273,7 +311,7 @@ class MMPaySDK {
273
311
  <span class="mmpay-text-myanmar">မှာယူမှုနံပါတ်:</span> <strong>${apiResponse.orderId}</strong>
274
312
  </div>
275
313
  <div class="mmpay-detail">
276
- <span class="mmpay-text-myanmar">ငွေပေးငွေယူနံပါတ်:</span> <strong>${apiResponse.transactionId}</strong>
314
+ <span class="mmpay-text-myanmar">ငွေပေးငွေယူနံပါတ်:</span> <strong>${apiResponse.transactionRefId}</strong>
277
315
  </div>
278
316
 
279
317
  <p class="mmpay-warning mmpay-text-myanmar">
@@ -428,10 +466,15 @@ class MMPaySDK {
428
466
  }
429
467
  /**
430
468
  * _startPolling
431
- * @param {string} _id
469
+ * @param {IPollingRequest} payload
470
+ * @param {number} payload.amount
471
+ * @param {string} payload.currency
472
+ * @param {string} payload.orderId
473
+ * @param {string} payload.nonce
474
+ * @param {string} payload.callbackUrl
432
475
  * @param {Function} onComplete
433
476
  */
434
- async _startPolling(_id, onComplete) {
477
+ async _startPolling(payload, onComplete) {
435
478
  if (this.pollIntervalId !== undefined) {
436
479
  window.clearInterval(this.pollIntervalId);
437
480
  }
@@ -440,7 +483,7 @@ class MMPaySDK {
440
483
  const endpoint = this.environment === 'sandbox'
441
484
  ? '/xpayments/sandbox-payment-polling'
442
485
  : '/xpayments/production-payment-polling';
443
- const response = await this._callApi(endpoint, { _id: _id });
486
+ const response = await this._callApi(endpoint, payload);
444
487
  const status = (response.status || '').toUpperCase();
445
488
  if (status === 'SUCCESS' || status === 'FAILED' || status === 'EXPIRED') {
446
489
  window.clearInterval(this.pollIntervalId);
@@ -451,6 +494,7 @@ class MMPaySDK {
451
494
  `ငွေပေးချေမှု ${status === 'FAILED' ? 'မအောင်မြင်ပါ' : 'သက်တမ်းကုန်သွားပါပြီ'}.`;
452
495
  this._showTerminalMessage(response.orderId || 'N/A', status, message);
453
496
  if (onComplete) {
497
+ this.tokenKey = null;
454
498
  onComplete({ success: success, transaction: response });
455
499
  }
456
500
  return;
@@ -1,46 +1,45 @@
1
- export interface PaymentData {
1
+ export interface ICreatePaymentRequest {
2
2
  amount: number;
3
3
  currency: string;
4
4
  orderId: string;
5
5
  callbackUrl?: string;
6
+ nonce?: string;
6
7
  }
7
- export interface CreatePaymentResponse {
8
+ export interface ICreatePaymentResponse {
8
9
  _id: string;
9
10
  amount: number;
10
11
  orderId: string;
11
12
  currency: string;
12
- transactionId: string;
13
+ transactionRefId: string;
13
14
  qr: string;
14
15
  url: string;
15
16
  }
16
- export interface PollingResponse {
17
- _id: string;
18
- appId: string;
17
+ export interface ICreateTokenRequest {
18
+ amount: number;
19
+ currency: string;
20
+ orderId: string;
21
+ callbackUrl?: string;
22
+ nonce?: string;
23
+ }
24
+ export interface ICreateTokenResponse {
19
25
  orderId: string;
26
+ token: string;
27
+ }
28
+ export interface IPollingRequest {
20
29
  amount: number;
21
30
  currency: string;
22
- method?: string;
23
- vendor?: string;
31
+ orderId: string;
24
32
  callbackUrl?: string;
25
- callbackUrlStatus?: 'PENDING' | 'SUCCESS' | 'FAILED';
26
- callbackAt?: Date;
27
- disbursementStatus?: 'NONE' | 'PENDING' | 'COMPLETED' | 'FAILED' | 'CANCELLED';
28
- disburseAt?: Date;
29
- items: {
30
- name: string;
31
- amount: number;
32
- quantity: number;
33
- }[];
34
- merchantId: string;
33
+ nonce?: string;
34
+ }
35
+ export interface IPollingResponse {
36
+ orderId: string;
37
+ transactionRefId: string;
35
38
  status: 'PENDING' | 'SUCCESS' | 'FAILED' | 'EXPIRED';
36
- createdAt: Date;
37
- transactionRefId?: string;
38
- qr?: string;
39
- redirectUrl?: string;
40
39
  }
41
40
  export interface PolliongResult {
42
41
  success: boolean;
43
- transaction: PollingResponse;
42
+ transaction: IPollingResponse;
44
43
  }
45
44
  export interface SDKOptions {
46
45
  pollInterval?: number;
@@ -50,6 +49,7 @@ export interface SDKOptions {
50
49
  }
51
50
  export declare class MMPaySDK {
52
51
  private POLL_INTERVAL_MS;
52
+ private tokenKey;
53
53
  private publishableKey;
54
54
  private baseUrl;
55
55
  private merchantName;
@@ -68,29 +68,45 @@ export declare class MMPaySDK {
68
68
  * @returns
69
69
  */
70
70
  private _callApi;
71
+ /**
72
+ * createTokenRequest
73
+ * @param {ICreateTokenRequest} payload
74
+ * @param {number} payload.amount
75
+ * @param {string} payload.currency
76
+ * @param {string} payload.orderId
77
+ * @param {string} payload.nonce
78
+ * @param {string} payload.callbackUrl
79
+ * @returns {Promise<ICreateTokenResponse>}
80
+ */
81
+ createTokenRequest(payload: ICreateTokenRequest): Promise<ICreateTokenResponse>;
71
82
  /**
72
83
  * createPaymentRequest
73
- * @param {PaymentData} payload
74
- * @returns
84
+ * @param {ICreatePaymentRequest} payload
85
+ * @param {number} payload.amount
86
+ * @param {string} payload.currency
87
+ * @param {string} payload.orderId
88
+ * @param {string} payload.nonce
89
+ * @param {string} payload.callbackUrl
90
+ * @returns {Promise<ICreatePaymentResponse>}
91
+ */
92
+ createPaymentRequest(payload: ICreatePaymentRequest): Promise<ICreatePaymentResponse>;
93
+ /**
94
+ * showPaymentModal
95
+ * @param {CreatePaymentRequest} payload
96
+ * @param {Function} onComplete
75
97
  */
76
- createPaymentRequest(payload: PaymentData): Promise<CreatePaymentResponse>;
98
+ showPaymentModal(payload: ICreatePaymentRequest, onComplete: (result: PolliongResult) => void): Promise<void>;
77
99
  /**
78
100
  * _createAndRenderModal
79
101
  * @param {string} contentHtml
80
- * @param isTerminal
102
+ * @param {boolean} isTerminal
81
103
  * @returns
82
104
  */
83
105
  private _createAndRenderModal;
84
- /**
85
- * showPaymentModal
86
- * @param {PaymentData} payload
87
- * @param {Function} onComplete
88
- */
89
- showPaymentModal(payload: PaymentData, onComplete: (result: PolliongResult) => void): Promise<void>;
90
106
  /**
91
107
  * _renderQrModalContent
92
- * @param {CreatePaymentResponse} apiResponse
93
- * @param {PaymentData} payload
108
+ * @param {ICreatePaymentResponse} apiResponse
109
+ * @param {CreatePaymentRequest} payload
94
110
  * @param {string} merchantName
95
111
  */
96
112
  private _renderQrModalContent;
@@ -122,7 +138,12 @@ export declare class MMPaySDK {
122
138
  private _injectQrScript;
123
139
  /**
124
140
  * _startPolling
125
- * @param {string} _id
141
+ * @param {IPollingRequest} payload
142
+ * @param {number} payload.amount
143
+ * @param {string} payload.currency
144
+ * @param {string} payload.orderId
145
+ * @param {string} payload.nonce
146
+ * @param {string} payload.callbackUrl
126
147
  * @param {Function} onComplete
127
148
  */
128
149
  private _startPolling;
package/dist/esm/index.js CHANGED
@@ -23,12 +23,20 @@ export class MMPaySDK {
23
23
  * @returns
24
24
  */
25
25
  async _callApi(endpoint, data = {}) {
26
+ let config = {
27
+ 'Content-Type': 'application/json',
28
+ 'Authorization': `Bearer ${this.publishableKey}`
29
+ };
30
+ if (this.tokenKey) {
31
+ config = {
32
+ 'Content-Type': 'application/json',
33
+ 'Authorization': `Bearer ${this.publishableKey}`,
34
+ 'X-MMPay-Btoken': `${this.tokenKey}`
35
+ };
36
+ }
26
37
  const response = await fetch(`${this.baseUrl}${endpoint}`, {
27
38
  method: 'POST',
28
- headers: {
29
- 'Content-Type': 'application/json',
30
- 'Authorization': `Bearer ${this.publishableKey}`
31
- },
39
+ headers: config,
32
40
  body: JSON.stringify(data)
33
41
  });
34
42
  if (!response.ok) {
@@ -37,10 +45,37 @@ export class MMPaySDK {
37
45
  }
38
46
  return response.json();
39
47
  }
48
+ /**
49
+ * createTokenRequest
50
+ * @param {ICreateTokenRequest} payload
51
+ * @param {number} payload.amount
52
+ * @param {string} payload.currency
53
+ * @param {string} payload.orderId
54
+ * @param {string} payload.nonce
55
+ * @param {string} payload.callbackUrl
56
+ * @returns {Promise<ICreateTokenResponse>}
57
+ */
58
+ async createTokenRequest(payload) {
59
+ try {
60
+ const endpoint = this.environment === 'sandbox'
61
+ ? '/xpayments/sandbox-token-request'
62
+ : '/xpayments/production-token-request';
63
+ return await this._callApi(endpoint, payload);
64
+ }
65
+ catch (error) {
66
+ console.error("Token request failed:", error);
67
+ throw error;
68
+ }
69
+ }
40
70
  /**
41
71
  * createPaymentRequest
42
- * @param {PaymentData} payload
43
- * @returns
72
+ * @param {ICreatePaymentRequest} payload
73
+ * @param {number} payload.amount
74
+ * @param {string} payload.currency
75
+ * @param {string} payload.orderId
76
+ * @param {string} payload.nonce
77
+ * @param {string} payload.callbackUrl
78
+ * @returns {Promise<ICreatePaymentResponse>}
44
79
  */
45
80
  async createPaymentRequest(payload) {
46
81
  try {
@@ -54,10 +89,39 @@ export class MMPaySDK {
54
89
  throw error;
55
90
  }
56
91
  }
92
+ /**
93
+ * showPaymentModal
94
+ * @param {CreatePaymentRequest} payload
95
+ * @param {Function} onComplete
96
+ */
97
+ async showPaymentModal(payload, onComplete) {
98
+ const initialContent = `<div class="mmpay-overlay-content"><div style="text-align: center; color: #fff;">ငွေပေးချေမှု စတင်နေသည်...</div></div>`;
99
+ this._createAndRenderModal(initialContent, false);
100
+ this.onCompleteCallback = onComplete;
101
+ try {
102
+ payload.nonce = new Date().getTime().toString() + '_mmp';
103
+ const tokenResponse = await this.createTokenRequest(payload);
104
+ this.tokenKey = tokenResponse.token;
105
+ const apiResponse = await this.createPaymentRequest(payload);
106
+ if (apiResponse && apiResponse.qr && apiResponse.transactionRefId) {
107
+ this.pendingApiResponse = apiResponse;
108
+ this.pendingPaymentPayload = payload;
109
+ this._renderQrModalContent(apiResponse, payload, this.merchantName);
110
+ this._startPolling(payload, onComplete);
111
+ }
112
+ else {
113
+ this._showTerminalMessage(apiResponse.orderId || 'N/A', 'FAILED', 'ငွေပေးချေမှု စတင်ရန် မအောင်မြင်ပါ။ QR ဒေတာ မရရှိပါ။');
114
+ }
115
+ }
116
+ catch (error) {
117
+ this.tokenKey = null;
118
+ this._showTerminalMessage(payload.orderId || 'N/A', 'FAILED', 'ငွေပေးချေမှု စတင်စဉ် အမှားအယွင်း ဖြစ်ပွားသည်။ ကွန်ဆိုးလ်တွင် ကြည့်ပါ။');
119
+ }
120
+ }
57
121
  /**
58
122
  * _createAndRenderModal
59
123
  * @param {string} contentHtml
60
- * @param isTerminal
124
+ * @param {boolean} isTerminal
61
125
  * @returns
62
126
  */
63
127
  _createAndRenderModal(contentHtml, isTerminal = false) {
@@ -169,36 +233,10 @@ export class MMPaySDK {
169
233
  document.body.style.overflow = 'hidden'; // FIX: Prevent body scroll when modal is open
170
234
  return overlay;
171
235
  }
172
- /**
173
- * showPaymentModal
174
- * @param {PaymentData} payload
175
- * @param {Function} onComplete
176
- */
177
- async showPaymentModal(payload, onComplete) {
178
- const initialContent = `<div class="mmpay-overlay-content"><div style="text-align: center; color: #fff;">ငွေပေးချေမှု စတင်နေသည်...</div></div>`;
179
- this._createAndRenderModal(initialContent, false);
180
- this.onCompleteCallback = onComplete;
181
- try {
182
- const apiResponse = await this.createPaymentRequest(payload);
183
- if (apiResponse && apiResponse.qr && apiResponse.transactionId) {
184
- this.pendingApiResponse = apiResponse;
185
- this.pendingPaymentPayload = payload;
186
- this._renderQrModalContent(apiResponse, payload, this.merchantName);
187
- this._startPolling(apiResponse._id, onComplete);
188
- }
189
- else {
190
- this._showTerminalMessage(apiResponse.orderId || 'N/A', 'FAILED', 'ငွေပေးချေမှု စတင်ရန် မအောင်မြင်ပါ။ QR ဒေတာ မရရှိပါ။');
191
- }
192
- }
193
- catch (error) {
194
- // Myanmar translation for "Error during payment initiation. See console."
195
- this._showTerminalMessage(payload.orderId || 'N/A', 'FAILED', 'ငွေပေးချေမှု စတင်စဉ် အမှားအယွင်း ဖြစ်ပွားသည်။ ကွန်ဆိုးလ်တွင် ကြည့်ပါ။');
196
- }
197
- }
198
236
  /**
199
237
  * _renderQrModalContent
200
- * @param {CreatePaymentResponse} apiResponse
201
- * @param {PaymentData} payload
238
+ * @param {ICreatePaymentResponse} apiResponse
239
+ * @param {CreatePaymentRequest} payload
202
240
  * @param {string} merchantName
203
241
  */
204
242
  _renderQrModalContent(apiResponse, payload, merchantName) {
@@ -270,7 +308,7 @@ export class MMPaySDK {
270
308
  <span class="mmpay-text-myanmar">မှာယူမှုနံပါတ်:</span> <strong>${apiResponse.orderId}</strong>
271
309
  </div>
272
310
  <div class="mmpay-detail">
273
- <span class="mmpay-text-myanmar">ငွေပေးငွေယူနံပါတ်:</span> <strong>${apiResponse.transactionId}</strong>
311
+ <span class="mmpay-text-myanmar">ငွေပေးငွေယူနံပါတ်:</span> <strong>${apiResponse.transactionRefId}</strong>
274
312
  </div>
275
313
 
276
314
  <p class="mmpay-warning mmpay-text-myanmar">
@@ -425,10 +463,15 @@ export class MMPaySDK {
425
463
  }
426
464
  /**
427
465
  * _startPolling
428
- * @param {string} _id
466
+ * @param {IPollingRequest} payload
467
+ * @param {number} payload.amount
468
+ * @param {string} payload.currency
469
+ * @param {string} payload.orderId
470
+ * @param {string} payload.nonce
471
+ * @param {string} payload.callbackUrl
429
472
  * @param {Function} onComplete
430
473
  */
431
- async _startPolling(_id, onComplete) {
474
+ async _startPolling(payload, onComplete) {
432
475
  if (this.pollIntervalId !== undefined) {
433
476
  window.clearInterval(this.pollIntervalId);
434
477
  }
@@ -437,7 +480,7 @@ export class MMPaySDK {
437
480
  const endpoint = this.environment === 'sandbox'
438
481
  ? '/xpayments/sandbox-payment-polling'
439
482
  : '/xpayments/production-payment-polling';
440
- const response = await this._callApi(endpoint, { _id: _id });
483
+ const response = await this._callApi(endpoint, payload);
441
484
  const status = (response.status || '').toUpperCase();
442
485
  if (status === 'SUCCESS' || status === 'FAILED' || status === 'EXPIRED') {
443
486
  window.clearInterval(this.pollIntervalId);
@@ -448,6 +491,7 @@ export class MMPaySDK {
448
491
  `ငွေပေးချေမှု ${status === 'FAILED' ? 'မအောင်မြင်ပါ' : 'သက်တမ်းကုန်သွားပါပြီ'}.`;
449
492
  this._showTerminalMessage(response.orderId || 'N/A', status, message);
450
493
  if (onComplete) {
494
+ this.tokenKey = null;
451
495
  onComplete({ success: success, transaction: response });
452
496
  }
453
497
  return;
package/dist/mmpay-sdk.js CHANGED
@@ -29,12 +29,20 @@
29
29
  * @returns
30
30
  */
31
31
  async _callApi(endpoint, data = {}) {
32
+ let config = {
33
+ 'Content-Type': 'application/json',
34
+ 'Authorization': `Bearer ${this.publishableKey}`
35
+ };
36
+ if (this.tokenKey) {
37
+ config = {
38
+ 'Content-Type': 'application/json',
39
+ 'Authorization': `Bearer ${this.publishableKey}`,
40
+ 'X-MMPay-Btoken': `${this.tokenKey}`
41
+ };
42
+ }
32
43
  const response = await fetch(`${this.baseUrl}${endpoint}`, {
33
44
  method: 'POST',
34
- headers: {
35
- 'Content-Type': 'application/json',
36
- 'Authorization': `Bearer ${this.publishableKey}`
37
- },
45
+ headers: config,
38
46
  body: JSON.stringify(data)
39
47
  });
40
48
  if (!response.ok) {
@@ -43,10 +51,37 @@
43
51
  }
44
52
  return response.json();
45
53
  }
54
+ /**
55
+ * createTokenRequest
56
+ * @param {ICreateTokenRequest} payload
57
+ * @param {number} payload.amount
58
+ * @param {string} payload.currency
59
+ * @param {string} payload.orderId
60
+ * @param {string} payload.nonce
61
+ * @param {string} payload.callbackUrl
62
+ * @returns {Promise<ICreateTokenResponse>}
63
+ */
64
+ async createTokenRequest(payload) {
65
+ try {
66
+ const endpoint = this.environment === 'sandbox'
67
+ ? '/xpayments/sandbox-token-request'
68
+ : '/xpayments/production-token-request';
69
+ return await this._callApi(endpoint, payload);
70
+ }
71
+ catch (error) {
72
+ console.error("Token request failed:", error);
73
+ throw error;
74
+ }
75
+ }
46
76
  /**
47
77
  * createPaymentRequest
48
- * @param {PaymentData} payload
49
- * @returns
78
+ * @param {ICreatePaymentRequest} payload
79
+ * @param {number} payload.amount
80
+ * @param {string} payload.currency
81
+ * @param {string} payload.orderId
82
+ * @param {string} payload.nonce
83
+ * @param {string} payload.callbackUrl
84
+ * @returns {Promise<ICreatePaymentResponse>}
50
85
  */
51
86
  async createPaymentRequest(payload) {
52
87
  try {
@@ -60,10 +95,39 @@
60
95
  throw error;
61
96
  }
62
97
  }
98
+ /**
99
+ * showPaymentModal
100
+ * @param {CreatePaymentRequest} payload
101
+ * @param {Function} onComplete
102
+ */
103
+ async showPaymentModal(payload, onComplete) {
104
+ const initialContent = `<div class="mmpay-overlay-content"><div style="text-align: center; color: #fff;">ငွေပေးချေမှု စတင်နေသည်...</div></div>`;
105
+ this._createAndRenderModal(initialContent, false);
106
+ this.onCompleteCallback = onComplete;
107
+ try {
108
+ payload.nonce = new Date().getTime().toString() + '_mmp';
109
+ const tokenResponse = await this.createTokenRequest(payload);
110
+ this.tokenKey = tokenResponse.token;
111
+ const apiResponse = await this.createPaymentRequest(payload);
112
+ if (apiResponse && apiResponse.qr && apiResponse.transactionRefId) {
113
+ this.pendingApiResponse = apiResponse;
114
+ this.pendingPaymentPayload = payload;
115
+ this._renderQrModalContent(apiResponse, payload, this.merchantName);
116
+ this._startPolling(payload, onComplete);
117
+ }
118
+ else {
119
+ this._showTerminalMessage(apiResponse.orderId || 'N/A', 'FAILED', 'ငွေပေးချေမှု စတင်ရန် မအောင်မြင်ပါ။ QR ဒေတာ မရရှိပါ။');
120
+ }
121
+ }
122
+ catch (error) {
123
+ this.tokenKey = null;
124
+ this._showTerminalMessage(payload.orderId || 'N/A', 'FAILED', 'ငွေပေးချေမှု စတင်စဉ် အမှားအယွင်း ဖြစ်ပွားသည်။ ကွန်ဆိုးလ်တွင် ကြည့်ပါ။');
125
+ }
126
+ }
63
127
  /**
64
128
  * _createAndRenderModal
65
129
  * @param {string} contentHtml
66
- * @param isTerminal
130
+ * @param {boolean} isTerminal
67
131
  * @returns
68
132
  */
69
133
  _createAndRenderModal(contentHtml, isTerminal = false) {
@@ -175,36 +239,10 @@
175
239
  document.body.style.overflow = 'hidden'; // FIX: Prevent body scroll when modal is open
176
240
  return overlay;
177
241
  }
178
- /**
179
- * showPaymentModal
180
- * @param {PaymentData} payload
181
- * @param {Function} onComplete
182
- */
183
- async showPaymentModal(payload, onComplete) {
184
- const initialContent = `<div class="mmpay-overlay-content"><div style="text-align: center; color: #fff;">ငွေပေးချေမှု စတင်နေသည်...</div></div>`;
185
- this._createAndRenderModal(initialContent, false);
186
- this.onCompleteCallback = onComplete;
187
- try {
188
- const apiResponse = await this.createPaymentRequest(payload);
189
- if (apiResponse && apiResponse.qr && apiResponse.transactionId) {
190
- this.pendingApiResponse = apiResponse;
191
- this.pendingPaymentPayload = payload;
192
- this._renderQrModalContent(apiResponse, payload, this.merchantName);
193
- this._startPolling(apiResponse._id, onComplete);
194
- }
195
- else {
196
- this._showTerminalMessage(apiResponse.orderId || 'N/A', 'FAILED', 'ငွေပေးချေမှု စတင်ရန် မအောင်မြင်ပါ။ QR ဒေတာ မရရှိပါ။');
197
- }
198
- }
199
- catch (error) {
200
- // Myanmar translation for "Error during payment initiation. See console."
201
- this._showTerminalMessage(payload.orderId || 'N/A', 'FAILED', 'ငွေပေးချေမှု စတင်စဉ် အမှားအယွင်း ဖြစ်ပွားသည်။ ကွန်ဆိုးလ်တွင် ကြည့်ပါ။');
202
- }
203
- }
204
242
  /**
205
243
  * _renderQrModalContent
206
- * @param {CreatePaymentResponse} apiResponse
207
- * @param {PaymentData} payload
244
+ * @param {ICreatePaymentResponse} apiResponse
245
+ * @param {CreatePaymentRequest} payload
208
246
  * @param {string} merchantName
209
247
  */
210
248
  _renderQrModalContent(apiResponse, payload, merchantName) {
@@ -276,7 +314,7 @@
276
314
  <span class="mmpay-text-myanmar">မှာယူမှုနံပါတ်:</span> <strong>${apiResponse.orderId}</strong>
277
315
  </div>
278
316
  <div class="mmpay-detail">
279
- <span class="mmpay-text-myanmar">ငွေပေးငွေယူနံပါတ်:</span> <strong>${apiResponse.transactionId}</strong>
317
+ <span class="mmpay-text-myanmar">ငွေပေးငွေယူနံပါတ်:</span> <strong>${apiResponse.transactionRefId}</strong>
280
318
  </div>
281
319
 
282
320
  <p class="mmpay-warning mmpay-text-myanmar">
@@ -431,10 +469,15 @@
431
469
  }
432
470
  /**
433
471
  * _startPolling
434
- * @param {string} _id
472
+ * @param {IPollingRequest} payload
473
+ * @param {number} payload.amount
474
+ * @param {string} payload.currency
475
+ * @param {string} payload.orderId
476
+ * @param {string} payload.nonce
477
+ * @param {string} payload.callbackUrl
435
478
  * @param {Function} onComplete
436
479
  */
437
- async _startPolling(_id, onComplete) {
480
+ async _startPolling(payload, onComplete) {
438
481
  if (this.pollIntervalId !== undefined) {
439
482
  window.clearInterval(this.pollIntervalId);
440
483
  }
@@ -443,7 +486,7 @@
443
486
  const endpoint = this.environment === 'sandbox'
444
487
  ? '/xpayments/sandbox-payment-polling'
445
488
  : '/xpayments/production-payment-polling';
446
- const response = await this._callApi(endpoint, { _id: _id });
489
+ const response = await this._callApi(endpoint, payload);
447
490
  const status = (response.status || '').toUpperCase();
448
491
  if (status === 'SUCCESS' || status === 'FAILED' || status === 'EXPIRED') {
449
492
  window.clearInterval(this.pollIntervalId);
@@ -454,6 +497,7 @@
454
497
  `ငွေပေးချေမှု ${status === 'FAILED' ? 'မအောင်မြင်ပါ' : 'သက်တမ်းကုန်သွားပါပြီ'}.`;
455
498
  this._showTerminalMessage(response.orderId || 'N/A', status, message);
456
499
  if (onComplete) {
500
+ this.tokenKey = null;
457
501
  onComplete({ success: success, transaction: response });
458
502
  }
459
503
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"mmpay-sdk.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"mmpay-sdk.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mmpay-browser-sdk",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "JavaScript SDK for integrating the MMQR Merchant and Redirect payment gateway",
5
5
  "keywords": [
6
6
  "MMQR",
package/src/index.ts CHANGED
@@ -1,42 +1,45 @@
1
- export interface PaymentData {
1
+ export interface ICreatePaymentRequest {
2
2
  amount: number;
3
3
  currency: string;
4
4
  orderId: string;
5
5
  callbackUrl?: string;
6
+ nonce?: string;
6
7
  }
7
- export interface CreatePaymentResponse {
8
+ export interface ICreatePaymentResponse {
8
9
  _id: string;
9
10
  amount: number;
10
11
  orderId: string;
11
12
  currency: string;
12
- transactionId: string;
13
+ transactionRefId: string;
13
14
  qr: string;
14
15
  url: string;
15
16
  }
16
- export interface PollingResponse {
17
- _id: string;
18
- appId: string;
17
+ export interface ICreateTokenRequest {
18
+ amount: number;
19
+ currency: string;
19
20
  orderId: string;
21
+ callbackUrl?: string;
22
+ nonce?: string;
23
+ }
24
+ export interface ICreateTokenResponse {
25
+ orderId: string;
26
+ token: string;
27
+ }
28
+ export interface IPollingRequest {
20
29
  amount: number;
21
30
  currency: string;
22
- method?: string;
23
- vendor?: string;
31
+ orderId: string;
24
32
  callbackUrl?: string;
25
- callbackUrlStatus?: 'PENDING' | 'SUCCESS' | 'FAILED';
26
- callbackAt?: Date;
27
- disbursementStatus?: 'NONE' | 'PENDING' | 'COMPLETED' | 'FAILED' | 'CANCELLED';
28
- disburseAt?: Date;
29
- items: {name: string, amount: number, quantity: number}[];
30
- merchantId: string;
33
+ nonce?: string;
34
+ }
35
+ export interface IPollingResponse {
36
+ orderId: string;
37
+ transactionRefId: string;
31
38
  status: 'PENDING' | 'SUCCESS' | 'FAILED' | 'EXPIRED';
32
- createdAt: Date;
33
- transactionRefId?: string;
34
- qr?: string;
35
- redirectUrl?: string;
36
39
  }
37
40
  export interface PolliongResult {
38
41
  success: boolean;
39
- transaction: PollingResponse;
42
+ transaction: IPollingResponse;
40
43
  }
41
44
  export interface SDKOptions {
42
45
  pollInterval?: number;
@@ -57,6 +60,7 @@ declare const window: Window & {
57
60
  export class MMPaySDK {
58
61
 
59
62
  private POLL_INTERVAL_MS: number;
63
+ private tokenKey: string;
60
64
  private publishableKey: string;
61
65
  private baseUrl: string;
62
66
  private merchantName: string;
@@ -66,8 +70,8 @@ export class MMPaySDK {
66
70
  private overlayElement: HTMLDivElement | null = null;
67
71
 
68
72
  // Properties to store pending data for re-rendering after cancel attempt
69
- private pendingApiResponse: CreatePaymentResponse | null = null;
70
- private pendingPaymentPayload: PaymentData | null = null;
73
+ private pendingApiResponse: ICreatePaymentResponse | null = null;
74
+ private pendingPaymentPayload: ICreatePaymentRequest | null = null;
71
75
 
72
76
  private readonly QR_SIZE: number = 300;
73
77
 
@@ -88,12 +92,20 @@ export class MMPaySDK {
88
92
  * @returns
89
93
  */
90
94
  private async _callApi<T>(endpoint: string, data: object = {}): Promise<T> {
95
+ let config: any = {
96
+ 'Content-Type': 'application/json',
97
+ 'Authorization': `Bearer ${this.publishableKey}`
98
+ }
99
+ if (this.tokenKey) {
100
+ config = {
101
+ 'Content-Type': 'application/json',
102
+ 'Authorization': `Bearer ${this.publishableKey}`,
103
+ 'X-MMPay-Btoken': `${this.tokenKey}`
104
+ }
105
+ }
91
106
  const response = await fetch(`${this.baseUrl}${endpoint}`, {
92
107
  method: 'POST',
93
- headers: {
94
- 'Content-Type': 'application/json',
95
- 'Authorization': `Bearer ${this.publishableKey}`
96
- },
108
+ headers: config,
97
109
  body: JSON.stringify(data)
98
110
  });
99
111
  if (!response.ok) {
@@ -102,27 +114,82 @@ export class MMPaySDK {
102
114
  }
103
115
  return response.json() as Promise<T>;
104
116
  }
117
+ /**
118
+ * createTokenRequest
119
+ * @param {ICreateTokenRequest} payload
120
+ * @param {number} payload.amount
121
+ * @param {string} payload.currency
122
+ * @param {string} payload.orderId
123
+ * @param {string} payload.nonce
124
+ * @param {string} payload.callbackUrl
125
+ * @returns {Promise<ICreateTokenResponse>}
126
+ */
127
+ async createTokenRequest(payload: ICreateTokenRequest): Promise<ICreateTokenResponse> {
128
+ try {
129
+ const endpoint = this.environment === 'sandbox'
130
+ ? '/xpayments/sandbox-token-request'
131
+ : '/xpayments/production-token-request';
132
+ return await this._callApi<ICreateTokenResponse>(endpoint, payload);
133
+ } catch (error) {
134
+ console.error("Token request failed:", error);
135
+ throw error;
136
+ }
137
+ }
105
138
  /**
106
139
  * createPaymentRequest
107
- * @param {PaymentData} payload
108
- * @returns
140
+ * @param {ICreatePaymentRequest} payload
141
+ * @param {number} payload.amount
142
+ * @param {string} payload.currency
143
+ * @param {string} payload.orderId
144
+ * @param {string} payload.nonce
145
+ * @param {string} payload.callbackUrl
146
+ * @returns {Promise<ICreatePaymentResponse>}
109
147
  */
110
- async createPaymentRequest(payload: PaymentData): Promise<CreatePaymentResponse> {
148
+ async createPaymentRequest(payload: ICreatePaymentRequest): Promise<ICreatePaymentResponse> {
111
149
  try {
112
150
  const endpoint = this.environment === 'sandbox'
113
151
  ? '/xpayments/sandbox-payment-create'
114
152
  : '/xpayments/production-payment-create';
115
-
116
- return await this._callApi<CreatePaymentResponse>(endpoint, payload);
153
+ return await this._callApi<ICreatePaymentResponse>(endpoint, payload);
117
154
  } catch (error) {
118
155
  console.error("Payment request failed:", error);
119
156
  throw error;
120
157
  }
121
158
  }
159
+ /**
160
+ * showPaymentModal
161
+ * @param {CreatePaymentRequest} payload
162
+ * @param {Function} onComplete
163
+ */
164
+ public async showPaymentModal(
165
+ payload: ICreatePaymentRequest,
166
+ onComplete: (result: PolliongResult) => void
167
+ ): Promise<void> {
168
+ const initialContent = `<div class="mmpay-overlay-content"><div style="text-align: center; color: #fff;">ငွေပေးချေမှု စတင်နေသည်...</div></div>`;
169
+ this._createAndRenderModal(initialContent, false);
170
+ this.onCompleteCallback = onComplete;
171
+ try {
172
+ payload.nonce = new Date().getTime().toString() + '_mmp';
173
+ const tokenResponse = await this.createTokenRequest(payload);
174
+ this.tokenKey = tokenResponse.token as string;
175
+ const apiResponse = await this.createPaymentRequest(payload);
176
+ if (apiResponse && apiResponse.qr && apiResponse.transactionRefId) {
177
+ this.pendingApiResponse = apiResponse;
178
+ this.pendingPaymentPayload = payload;
179
+ this._renderQrModalContent(apiResponse, payload, this.merchantName);
180
+ this._startPolling(payload, onComplete);
181
+ } else {
182
+ this._showTerminalMessage(apiResponse.orderId || 'N/A', 'FAILED', 'ငွေပေးချေမှု စတင်ရန် မအောင်မြင်ပါ။ QR ဒေတာ မရရှိပါ။');
183
+ }
184
+ } catch (error) {
185
+ this.tokenKey = null;
186
+ this._showTerminalMessage(payload.orderId || 'N/A', 'FAILED', 'ငွေပေးချေမှု စတင်စဉ် အမှားအယွင်း ဖြစ်ပွားသည်။ ကွန်ဆိုးလ်တွင် ကြည့်ပါ။');
187
+ }
188
+ }
122
189
  /**
123
190
  * _createAndRenderModal
124
191
  * @param {string} contentHtml
125
- * @param isTerminal
192
+ * @param {boolean} isTerminal
126
193
  * @returns
127
194
  */
128
195
  private _createAndRenderModal(contentHtml: string, isTerminal: boolean = false): HTMLDivElement {
@@ -233,40 +300,13 @@ export class MMPaySDK {
233
300
  document.body.style.overflow = 'hidden'; // FIX: Prevent body scroll when modal is open
234
301
  return overlay;
235
302
  }
236
- /**
237
- * showPaymentModal
238
- * @param {PaymentData} payload
239
- * @param {Function} onComplete
240
- */
241
- public async showPaymentModal(
242
- payload: PaymentData,
243
- onComplete: (result: PolliongResult) => void
244
- ): Promise<void> {
245
- const initialContent = `<div class="mmpay-overlay-content"><div style="text-align: center; color: #fff;">ငွေပေးချေမှု စတင်နေသည်...</div></div>`;
246
- this._createAndRenderModal(initialContent, false);
247
- this.onCompleteCallback = onComplete;
248
- try {
249
- const apiResponse = await this.createPaymentRequest(payload);
250
- if (apiResponse && apiResponse.qr && apiResponse.transactionId) {
251
- this.pendingApiResponse = apiResponse;
252
- this.pendingPaymentPayload = payload;
253
- this._renderQrModalContent(apiResponse, payload, this.merchantName);
254
- this._startPolling(apiResponse._id, onComplete);
255
- } else {
256
- this._showTerminalMessage(apiResponse.orderId || 'N/A', 'FAILED', 'ငွေပေးချေမှု စတင်ရန် မအောင်မြင်ပါ။ QR ဒေတာ မရရှိပါ။');
257
- }
258
- } catch (error) {
259
- // Myanmar translation for "Error during payment initiation. See console."
260
- this._showTerminalMessage(payload.orderId || 'N/A', 'FAILED', 'ငွေပေးချေမှု စတင်စဉ် အမှားအယွင်း ဖြစ်ပွားသည်။ ကွန်ဆိုးလ်တွင် ကြည့်ပါ။');
261
- }
262
- }
263
303
  /**
264
304
  * _renderQrModalContent
265
- * @param {CreatePaymentResponse} apiResponse
266
- * @param {PaymentData} payload
305
+ * @param {ICreatePaymentResponse} apiResponse
306
+ * @param {CreatePaymentRequest} payload
267
307
  * @param {string} merchantName
268
308
  */
269
- private _renderQrModalContent(apiResponse: CreatePaymentResponse, payload: PaymentData, merchantName: string): void {
309
+ private _renderQrModalContent(apiResponse: ICreatePaymentResponse, payload: ICreatePaymentRequest, merchantName: string): void {
270
310
  const qrData = apiResponse.qr;
271
311
  const amountDisplay = `${apiResponse.amount.toFixed(2)} ${apiResponse.currency}`;
272
312
  const qrCanvasId = 'mmpayQrCanvas';
@@ -333,7 +373,7 @@ export class MMPaySDK {
333
373
  <span class="mmpay-text-myanmar">မှာယူမှုနံပါတ်:</span> <strong>${apiResponse.orderId}</strong>
334
374
  </div>
335
375
  <div class="mmpay-detail">
336
- <span class="mmpay-text-myanmar">ငွေပေးငွေယူနံပါတ်:</span> <strong>${apiResponse.transactionId}</strong>
376
+ <span class="mmpay-text-myanmar">ငွေပေးငွေယူနံပါတ်:</span> <strong>${apiResponse.transactionRefId}</strong>
337
377
  </div>
338
378
 
339
379
  <p class="mmpay-warning mmpay-text-myanmar">
@@ -486,10 +526,15 @@ export class MMPaySDK {
486
526
  }
487
527
  /**
488
528
  * _startPolling
489
- * @param {string} _id
529
+ * @param {IPollingRequest} payload
530
+ * @param {number} payload.amount
531
+ * @param {string} payload.currency
532
+ * @param {string} payload.orderId
533
+ * @param {string} payload.nonce
534
+ * @param {string} payload.callbackUrl
490
535
  * @param {Function} onComplete
491
536
  */
492
- private async _startPolling(_id: string, onComplete: (result: PolliongResult) => void): Promise<void> {
537
+ private async _startPolling(payload: IPollingRequest, onComplete: (result: PolliongResult) => void): Promise<void> {
493
538
  if (this.pollIntervalId !== undefined) {
494
539
  window.clearInterval(this.pollIntervalId);
495
540
  }
@@ -499,7 +544,7 @@ export class MMPaySDK {
499
544
  ? '/xpayments/sandbox-payment-polling'
500
545
  : '/xpayments/production-payment-polling';
501
546
 
502
- const response = await this._callApi<PollingResponse>(endpoint, {_id: _id});
547
+ const response = await this._callApi<IPollingResponse>(endpoint, payload);
503
548
  const status = (response.status || '').toUpperCase();
504
549
  if (status === 'SUCCESS' || status === 'FAILED' || status === 'EXPIRED') {
505
550
  window.clearInterval(this.pollIntervalId);
@@ -512,7 +557,8 @@ export class MMPaySDK {
512
557
  this._showTerminalMessage(response.orderId || 'N/A', status as 'SUCCESS' | 'FAILED' | 'EXPIRED', message);
513
558
 
514
559
  if (onComplete) {
515
- onComplete({success: success, transaction: response as PollingResponse});
560
+ this.tokenKey = null;
561
+ onComplete({success: success, transaction: response as IPollingResponse});
516
562
  }
517
563
  return;
518
564
  }
package/test/home.html CHANGED
@@ -1,4 +1,5 @@
1
1
  <html lang="en">
2
+
2
3
  <head>
3
4
  <meta charset="UTF-8">
4
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
@@ -12,6 +13,7 @@
12
13
  display: flex;
13
14
  justify-content: center;
14
15
  }
16
+
15
17
  .container {
16
18
  display: flex;
17
19
  flex-direction: column;
@@ -19,12 +21,15 @@
19
21
  max-width: 1000px;
20
22
  width: 100%;
21
23
  }
24
+
22
25
  @media (min-width: 768px) {
23
26
  .container {
24
27
  flex-direction: row;
25
28
  }
26
29
  }
27
- .order-summary, .payment-area {
30
+
31
+ .order-summary,
32
+ .payment-area {
28
33
  background-color: #ffffff;
29
34
  padding: 25px;
30
35
  border-radius: 10px;
@@ -32,6 +37,7 @@
32
37
  flex: 1;
33
38
  min-height: 450px;
34
39
  }
40
+
35
41
  h2 {
36
42
  color: #2c3e50;
37
43
  border-bottom: 2px solid #ecf0f1;
@@ -40,6 +46,7 @@
40
46
  font-size: 1.5rem;
41
47
  font-weight: 700;
42
48
  }
49
+
43
50
  .item-list div {
44
51
  display: flex;
45
52
  justify-content: space-between;
@@ -47,9 +54,11 @@
47
54
  border-bottom: 1px dashed #ecf0f1;
48
55
  color: #7f8c8d;
49
56
  }
57
+
50
58
  .item-list div:last-child {
51
59
  border-bottom: none;
52
60
  }
61
+
53
62
  .total {
54
63
  margin-top: 20px;
55
64
  padding-top: 15px;
@@ -60,6 +69,7 @@
60
69
  display: flex;
61
70
  justify-content: space-between;
62
71
  }
72
+
63
73
  .checkout-button {
64
74
  width: 100%;
65
75
  background-color: #2ecc71;
@@ -74,10 +84,12 @@
74
84
  margin-top: 20px;
75
85
  box-shadow: 0 2px 5px rgba(46, 204, 113, 0.4);
76
86
  }
87
+
77
88
  .checkout-button:hover {
78
89
  background-color: #27ae60;
79
90
  box-shadow: 0 4px 8px rgba(39, 174, 96, 0.6);
80
91
  }
92
+
81
93
  .payment-status {
82
94
  margin-top: 20px;
83
95
  padding: 15px;
@@ -89,10 +101,19 @@
89
101
  max-height: 200px;
90
102
  overflow-y: auto;
91
103
  }
92
- .success { color: #28a745; font-weight: bold; }
93
- .failure { color: #dc3545; font-weight: bold; }
104
+
105
+ .success {
106
+ color: #28a745;
107
+ font-weight: bold;
108
+ }
109
+
110
+ .failure {
111
+ color: #dc3545;
112
+ font-weight: bold;
113
+ }
94
114
  </style>
95
115
  </head>
116
+
96
117
  <body>
97
118
 
98
119
  <div class="container">
@@ -115,7 +136,8 @@
115
136
  <div class="payment-area">
116
137
  <h2>💳 Payment Details</h2>
117
138
  <div id="payment-container">
118
- <p style="color: #6c757d; padding: 20px;">Click the "Pay Securely" button to initialize the transaction and display the MMPay QR code.</p>
139
+ <p style="color: #6c757d; padding: 20px;">Click the "Pay Securely" button to initialize the transaction
140
+ and display the MMPay QR code.</p>
119
141
  </div>
120
142
  <div class="payment-status" id="result-container">
121
143
  Awaiting transaction polling result...
@@ -123,9 +145,26 @@
123
145
  </div>
124
146
  </div>
125
147
 
126
- <!-- The external SDK file is loaded here -->
127
- <!-- <script src="../dist/mmpay-sdk.js"></script> -->
128
- <script src="https://cdn.jsdelivr.net/npm/mmpay-browser-sdk@latest/mmpay-browser-sdk/master/dist/mmpay-sdk.js"></script>
148
+ <script src="../dist/mmpay-sdk.js"></script>
149
+ <!-- <script src="https://cdn.jsdelivr.net/npm/mmpay-browser-sdk@latest/dist/mmpay-sdk.js"></script> -->
150
+ <!-- <script>
151
+ const PUBLISHABLE_KEY = 'pk_test_504013d7294ea1f6ecf4a2a0d38c31e0788286ef1b8ccacecf2a9b2809e23341';
152
+ const sdk = new MMPaySDK(PUBLISHABLE_KEY, {
153
+ baseUrl: 'https://supapay.ecgedms.com',
154
+ environment: 'sandbox',
155
+ merchantName: 'Fastify E-Shop',
156
+ pollInterval: 5000
157
+ });
158
+ await sdk.showPaymentModal({
159
+ amount: parseFloat(finalAmount.toFixed(2)),
160
+ currency: mockOrder.currency,
161
+ orderId: 'FSTY' + Date.now(),
162
+ callbackUrl: 'https://your.backend.com/api/mmpay/webhook'
163
+ },(result) => {
164
+ const resultContainer = document.getElementById(RESULT_CONTAINER_ID);
165
+ // DO your logic
166
+ });
167
+ </script> -->
129
168
 
130
169
  <!-- Client-Side Application Logic -->
131
170
  <script>
@@ -217,16 +256,8 @@
217
256
  currency: mockOrder.currency,
218
257
  orderId: 'FSTY' + Date.now(),
219
258
  callbackUrl: 'https://your-fastify-backend.com/api/mmpay/webhook'
220
- },(result) => {
221
- const resultContainer = document.getElementById(RESULT_CONTAINER_ID);
222
- document.getElementById(PAY_BUTTON_ID).disabled = false;
223
- if (result.success) {
224
- resultContainer.innerHTML = '<span class="success">✅ PAYMENT SUCCESSFUL!</span><br><br>' + JSON.stringify(result.transaction, null, 2);
225
- document.getElementById(CONTAINER_ID).innerHTML = '<div style="color: #2ecc71; font-size: 1.5rem; font-weight: bold; padding: 50px 0;">Transaction Complete! Thank you for your order!</div>';
226
- } else {
227
- resultContainer.innerHTML = '<span class="failure">❌ PAYMENT FAILED / EXPIRED.</span><br><br>' + JSON.stringify(result.transaction, null, 2);
228
- document.getElementById(CONTAINER_ID).innerHTML = '<div style="color: #e74c3c; font-size: 1.5rem; font-weight: bold; padding: 50px 0;">Transaction Failed. Please try again.</div>';
229
- }
259
+ }, (result) => {
260
+
230
261
  });
231
262
 
232
263
  } catch (error) {
@@ -240,4 +271,5 @@
240
271
  window.onload = renderOrderSummary;
241
272
  </script>
242
273
  </body>
274
+
243
275
  </html>