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 +9 -2
- package/dist/cjs/index.d.ts +18 -112
- package/dist/cjs/index.js +90 -114
- package/dist/esm/index.d.ts +18 -112
- package/dist/esm/index.js +90 -114
- package/dist/mmpay-sdk.js +90 -114
- package/dist/mmpay-sdk.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +125 -142
- package/test/home.html +3 -2
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) {
|
package/dist/cjs/index.d.ts
CHANGED
|
@@ -1,14 +1,24 @@
|
|
|
1
|
-
export interface
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
80
|
+
customMessage: params.customMessage,
|
|
113
81
|
nonce: new Date().getTime().toString() + '_mmp'
|
|
114
82
|
};
|
|
115
83
|
try {
|
|
116
|
-
const tokenResponse = await this._callApiTokenRequest(
|
|
84
|
+
const tokenResponse = await this._callApiTokenRequest(tokenPayload);
|
|
117
85
|
this.tokenKey = tokenResponse.token;
|
|
118
|
-
|
|
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
|
|
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
|
-
|
|
106
|
+
customMessage: params.customMessage,
|
|
143
107
|
nonce: new Date().getTime().toString() + '_mmp'
|
|
144
108
|
};
|
|
145
109
|
try {
|
|
146
|
-
const tokenResponse = await this._callApiTokenRequest(
|
|
110
|
+
const tokenResponse = await this._callApiTokenRequest(tokenPayload);
|
|
147
111
|
this.tokenKey = tokenResponse.token;
|
|
148
|
-
const apiResponse = await this._callApiPaymentRequest(
|
|
112
|
+
const apiResponse = await this._callApiPaymentRequest(paymentPayload);
|
|
149
113
|
if (apiResponse && apiResponse.qr && apiResponse.transactionRefId) {
|
|
150
114
|
this.pendingApiResponse = apiResponse;
|
|
151
|
-
this.pendingPaymentPayload =
|
|
152
|
-
this._renderQrModalContent(apiResponse,
|
|
153
|
-
this._startPolling(
|
|
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(
|
|
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';
|
|
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';
|
|
378
|
-
const failureColor = '#ef4444';
|
|
379
|
-
const expiredColor = '#f59e0b';
|
|
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);
|
|
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);
|
|
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;
|