@mmpay/browser 0.0.0-stage → 1.3.1
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/.vscode/settings.json +33 -0
- package/README.md +489 -2
- package/dist/cjs/index.js +1770 -0
- package/dist/esm/api.d.ts +26 -0
- package/dist/esm/deprecated/api.d.ts +12 -0
- package/dist/esm/deprecated/showPaymentModal.d.ts +6 -0
- package/dist/esm/functions/api.d.ts +12 -0
- package/dist/esm/functions/showPaymentModal.d.ts +2 -0
- package/dist/esm/i18n.d.ts +13 -0
- package/dist/esm/index.d.ts +65 -0
- package/dist/esm/index.js +1768 -0
- package/dist/esm/logo.d.ts +5 -0
- package/dist/esm/stream.d.ts +46 -0
- package/dist/esm/styles.d.ts +5 -0
- package/dist/esm/templates.d.ts +6 -0
- package/dist/esm/types.d.ts +101 -0
- package/dist/esm/ui.d.ts +85 -0
- package/dist/mmpay-sdk.js +1776 -0
- package/package.json +45 -4
- package/rollup.config.ts +33 -0
- package/src/api.ts +121 -0
- package/src/i18n.ts +112 -0
- package/src/index.ts +490 -0
- package/src/logo.ts +5 -0
- package/src/stream.ts +214 -0
- package/src/styles.ts +206 -0
- package/src/types.ts +117 -0
- package/src/ui.ts +715 -0
- package/test/index.html +476 -0
- package/tsconfig.json +15 -0
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MyanMyanPay logo (256px PNG from myanmyanpay.com/mmp-logo.png), embedded so
|
|
3
|
+
* the loading screen shows it instantly instead of waiting on another request.
|
|
4
|
+
*/
|
|
5
|
+
export declare const MMPAY_LOGO_DATA_URI = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAMAAABrrFhUAAAAHlBMVEX///8AAAADAwNFRUVjY2NTU1MuLi7n5+e9vb2BgYFUuDMdAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAE90lEQVR4nO2d2XbCMAxE5yokhf//4R5atrCEYIckMLoPfeiJVTPIrm3JijBHmCPMEeYIc4Q5whxhjjBHmCPMEeYIc4Q5whxhjjBHmCPMEeYIc4Q5whxhjjBHmCPMEeYIc4Q5whxhjjBHmCPMEeYIc4Q5whxhjjBHmCPMEeYIc4Q5whxhjjBHmCPMEeYIc4Q5whxhjjBHle2jlLcZmlWAqPjzvaY1dmI5AYLomjK6uPzQkxmaV4Cg2aqUbXdpqqsyFMsIEDQ/xd2Wfk4dD7ppDM0sAFH+te3Zni1NZmhOAYKuqtunb67SASTVuIAqBGjquq3mKMBEhlKAEkQp6QHkEFDOAQd249dx3W5oEqwytOAc0IzuQdAOCfCKoZJWbxRgLMMCtC8YWpkAuHsAh98+/MJeFOC5oTUKEIPPvyDAGEMrFCCIpr1Pc9i2jxNglKEVCsDm8a7mp2W0ADFoaHN4ZnUCBBsN0f4/9FyAZ4b+FFifAEEM72p/YrQHjDK0PgHawW7fPvVAgOebjOun1iLA5km/N2MFGGcoBVB6wIEcAsTCh6Kd4xzA+Vj871z6st9td6atEWDI0OICxKkLN8uX8zn1pZ8UCDBkaHEBOISGtqf162W/T5u3WgEeGlpeAPYxzfYYnTT0AHp7V0sB2HvoqYeWApxJAUgPUA6BAzkH4LEO6JFzAPeX8JsaD9iseS9wheFusE8KQHqA/IZAxClX19IDovez8YoL7InNdrttjwKYRYY4HQpubw8EBkJ6XxMbJDimKe2OHRgT1B2VHzBs6FGreQWIc4rvn0/+n440m/u8lh8AIwwtL0Bzs/tzzxDBPkfIOUtsLJkn2H6jB+wepHTdy/IazhV+lBx2hzXlCpeRN0aISZVMDyhBlJJDAPs5oPO+N8iEFz4/8uYolWPg4u5w1N0drvknwEpuj9cZik+sH0C/25MZmlUAav50//Mv1AmyhogwR5gjzBHmqLL96KOwm6Oxdxl6EVW1dv83GOYLoZhqKRyfuRSOyTZDlRWZltsMba23wzHhgUidoSyk1OSpcCwyBJpKz824ABkY4UsiQ7tm/uDoraEFBWjcw+NNJkgE7h7A4bdPtu1ZSIk3pMktX1O0OX6U+RIlLzKKj3maKxBgMyLDdYJCSo8ydRcWIGZNlr7J1V5cgJg3Xf6vZXvO1rcrpLTn+YT5xYWUrm/seAowASpumQKQHqAcAiPqH23eU0hp3XNA9/4iKqsX4N0FFFYvAO4ewP1+pwCkByiHwHRzwJIpMrH8HLDe3WA3iwC9an6G64D4TyypSxDhcz3gqqLnugRo319U9bqm67oEmKWISr+qr6EAzbWhFKAEUUp6ADkE1B+6ZoWUorD+0dcUUop8yUrz4mt24stfs0O+aIm/r+YeJRkizwyt0AOwzxFyzhIbSxZSar/RA3bN/C9dXVWucBmZLs/XpMuXkQKQHsBHD4GurttZSInPvjlK7ZXfi7vDdYWUqm5Pq7zpvuMTFVKKOkPLhMb4j04WXfpvun5Ms6YQwWLB0T0V0fl+04rPUJkhoKrW9jVEvgBhjjBHmCPMEeYIc4Q5whxhjjBHmCPMEeYIc4Q5whxhjjBHmCPMEeYIc4Q5whxhjjBHmCPMEeYIc4Q5whxhjjBHmCPMEeYIc4Q5whxhjjBHmCPMEeYIc4Q5whxhjjBHmCPMEeYIc1IAzPkF8CT7lTTnMu0AAAAASUVORK5CYII=";
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { MMPayAPI } from './api';
|
|
2
|
+
import { IPollingRequest, IPollingResponse, MMPayTransport } from './types';
|
|
3
|
+
export type ConnectionState = 'live' | 'reconnecting';
|
|
4
|
+
interface WatcherOptions {
|
|
5
|
+
transport: MMPayTransport;
|
|
6
|
+
pollInterval: number;
|
|
7
|
+
onStatus: (response: IPollingResponse) => void;
|
|
8
|
+
onConnectionChange?: (state: ConnectionState) => void;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Watches one payment until the owner calls `stop()`.
|
|
12
|
+
*
|
|
13
|
+
* Status is pushed over a WebSocket. If a socket cannot be established or keeps
|
|
14
|
+
* dropping (old server, blocking proxy), the watcher quietly degrades to the
|
|
15
|
+
* HTTP polling endpoint, so a payment is never left unobserved.
|
|
16
|
+
*/
|
|
17
|
+
export declare class PaymentStatusWatcher {
|
|
18
|
+
private api;
|
|
19
|
+
private payload;
|
|
20
|
+
private options;
|
|
21
|
+
private socket;
|
|
22
|
+
private stopped;
|
|
23
|
+
private connecting;
|
|
24
|
+
private usingPolling;
|
|
25
|
+
private socketFailures;
|
|
26
|
+
private pollIntervalId;
|
|
27
|
+
private reconnectTimeoutId;
|
|
28
|
+
private silenceTimeoutId;
|
|
29
|
+
private readonly onWake;
|
|
30
|
+
private readonly onVisibility;
|
|
31
|
+
constructor(api: MMPayAPI, payload: IPollingRequest, options: WatcherOptions);
|
|
32
|
+
start(): void;
|
|
33
|
+
stop(): void;
|
|
34
|
+
private checkNow;
|
|
35
|
+
private wake;
|
|
36
|
+
private connect;
|
|
37
|
+
private parseMessage;
|
|
38
|
+
private isOwnStatus;
|
|
39
|
+
private handleSocketFailure;
|
|
40
|
+
private armSilenceTimer;
|
|
41
|
+
private startPolling;
|
|
42
|
+
private closeSocket;
|
|
43
|
+
private discard;
|
|
44
|
+
private notifyConnection;
|
|
45
|
+
}
|
|
46
|
+
export {};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Styles live inside the modal's shadow root, so the merchant page's CSS
|
|
3
|
+
* cannot restyle the payment modal and these rules cannot leak out.
|
|
4
|
+
*/
|
|
5
|
+
export declare const MMPAY_STYLES = "\n.mmp-root, .mmp-root *, .mmp-root *::before, .mmp-root *::after { box-sizing: border-box; }\n.mmp-root {\n --mmp-card: #ffffff;\n --mmp-text: #1d1d1f;\n --mmp-sub: #6e6e73;\n --mmp-border: rgba(0, 0, 0, 0.08);\n --mmp-chip: #f2f2f5;\n --mmp-chip-active: #ffffff;\n --mmp-chip-hover: #e5e5ea;\n --mmp-panel: #f7f7f9;\n --mmp-skeleton: #e9e9ee;\n --mmp-skeleton-shine: #f6f6f9;\n --mmp-accent: #2c2c2e;\n --mmp-accent-text: #ffffff;\n --mmp-success: #1f9d55;\n --mmp-success-bg: #e6f6ec;\n --mmp-danger: #d93025;\n --mmp-danger-bg: #fce8e6;\n --mmp-warn: #c26a00;\n --mmp-warn-bg: #fff3e0;\n --mmp-card-blur: none;\n position: absolute; top: 0; right: 0; bottom: 0; left: 0;\n display: flex; align-items: center; justify-content: center;\n padding: 16px; overflow-y: auto;\n background: rgba(0, 0, 0, 0.45);\n -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);\n font-family: -apple-system, BlinkMacSystemFont, \"SF Pro Text\", \"Segoe UI\", Roboto, Helvetica, Arial, \"Padauk\", \"Myanmar Text\", \"Noto Sans Myanmar\", sans-serif;\n font-size: 16px; line-height: 1.4; font-weight: 400; font-style: normal;\n letter-spacing: normal; text-align: center; text-transform: none; white-space: normal;\n color: var(--mmp-text); direction: ltr;\n -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: 100%;\n animation: mmp-fade 0.2s ease;\n}\n.mmp-root.mmp-dark {\n --mmp-card: #1c1c1e;\n --mmp-text: #f5f5f7;\n --mmp-sub: rgba(235, 235, 245, 0.62);\n --mmp-border: rgba(255, 255, 255, 0.12);\n --mmp-chip: #2c2c2e;\n --mmp-chip-active: #636366;\n --mmp-chip-hover: #3a3a3c;\n --mmp-panel: #2c2c2e;\n --mmp-skeleton: #2c2c2e;\n --mmp-skeleton-shine: #3a3a3c;\n --mmp-accent: #ffffff;\n --mmp-accent-text: #000000;\n --mmp-success: #34c759;\n --mmp-success-bg: rgba(52, 199, 89, 0.18);\n --mmp-danger: #ff6259;\n --mmp-danger-bg: rgba(255, 69, 58, 0.18);\n --mmp-warn: #ffa733;\n --mmp-warn-bg: rgba(255, 149, 0, 0.18);\n}\n.mmp-root.mmp-translucent { --mmp-card: rgba(255, 255, 255, 0.78); --mmp-card-blur: blur(20px); }\n.mmp-root.mmp-dark.mmp-translucent { --mmp-card: rgba(28, 28, 30, 0.78); }\n.mmp-root[data-lang=\"mm\"] { line-height: 1.75; }\n\n.mmp-card {\n position: relative; display: flex; flex-direction: column;\n width: 100%; max-width: 372px; max-height: 100%; margin: auto;\n overflow-x: hidden; overflow-y: auto;\n background: var(--mmp-card);\n -webkit-backdrop-filter: var(--mmp-card-blur); backdrop-filter: var(--mmp-card-blur);\n border-radius: 24px;\n box-shadow: 0 24px 60px rgba(0, 0, 0, 0.22), 0 0 0 1px var(--mmp-border);\n outline: none;\n animation: mmp-rise 0.35s cubic-bezier(0.2, 0.8, 0.2, 1);\n}\n.mmp-topbar { display: flex; align-items: center; justify-content: space-between; padding: 14px 14px 0 14px; flex-shrink: 0; }\n.mmp-lang { display: inline-flex; gap: 2px; padding: 3px; background: var(--mmp-chip); border: 1px solid var(--mmp-border); border-radius: 11px; }\n.mmp-lang button {\n margin: 0; padding: 5px 11px; min-width: 40px; border: none; border-radius: 8px; background: transparent;\n font: inherit; font-size: 12px; font-weight: 600; line-height: 1.5; color: var(--mmp-sub); cursor: pointer;\n transition: background 0.2s ease, color 0.2s ease;\n}\n.mmp-lang button[aria-pressed=\"true\"] { background: var(--mmp-chip-active); color: var(--mmp-text); box-shadow: 0 1px 4px rgba(0, 0, 0, 0.12); }\n.mmp-close {\n display: flex; align-items: center; justify-content: center; width: 34px; height: 34px; margin: 0; padding: 0;\n border: none; border-radius: 50%; background: var(--mmp-chip); color: var(--mmp-sub); cursor: pointer;\n transition: background 0.2s ease, color 0.2s ease;\n}\n.mmp-close:hover { background: var(--mmp-chip-hover); color: var(--mmp-text); }\n.mmp-close[hidden] { display: flex; visibility: hidden; }\n.mmp-root button:focus-visible { outline: 2px solid var(--mmp-text); outline-offset: 2px; }\n\n.mmp-screen { display: flex; flex-direction: column; align-items: center; padding: 6px 22px 22px 22px; animation: mmp-screen-in 0.28s ease; }\n.mmp-brand { display: flex; align-items: center; justify-content: center; height: 36px; margin-bottom: 10px; }\n.mmp-brand img { display: block; height: 36px; width: auto; max-width: 160px; object-fit: contain; }\n.mmp-merchant { max-width: 100%; font-size: 15px; font-weight: 500; color: var(--mmp-sub); overflow-wrap: anywhere; }\n.mmp-amount { display: flex; align-items: baseline; justify-content: center; gap: 6px; min-height: 36px; margin: 2px 0 14px 0; }\n.mmp-amount-value { font-size: 30px; font-weight: 700; line-height: 1.2; letter-spacing: -0.5px; font-variant-numeric: tabular-nums; }\n.mmp-amount-currency { font-size: 14px; font-weight: 600; letter-spacing: 0.5px; color: var(--mmp-sub); }\n\n.mmp-qr {\n position: relative; display: flex; align-items: center; justify-content: center; flex-shrink: 0;\n width: 228px; height: 228px; padding: 12px; background: #ffffff; border-radius: 18px;\n border: 1px solid var(--mmp-border); box-shadow: 0 8px 24px rgba(0, 0, 0, 0.06); overflow: hidden;\n}\n.mmp-qr canvas { display: block; width: 100% !important; height: 100% !important; animation: mmp-qr-in 0.4s cubic-bezier(0.2, 0.8, 0.2, 1); }\n.mmp-qr-placeholder { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 22px; width: 100%; height: 100%; }\n.mmp-loader-logo { display: block; width: 88px; height: 88px; border-radius: 22px; box-shadow: 0 10px 24px rgba(0, 0, 0, 0.18); animation: mmp-pulse 2.2s ease-in-out infinite; }\n.mmp-loader-track { position: relative; width: 120px; height: 3px; border-radius: 3px; background: #ececf1; overflow: hidden; }\n.mmp-loader-bar { position: absolute; top: 0; bottom: 0; left: 0; width: 40%; border-radius: 3px; background: #1d1d1f; animation: mmp-sweep 1.2s cubic-bezier(0.4, 0, 0.2, 1) infinite; }\n.mmp-qr-error { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; padding: 8px; font-size: 13px; color: #6e6e73; }\n.mmp-qr-error button {\n margin: 0; padding: 7px 14px; border: 1px solid #d2d2d7; border-radius: 10px; background: #ffffff;\n font: inherit; font-size: 13px; font-weight: 600; color: #1d1d1f; cursor: pointer;\n}\n\n.mmp-caption { min-height: 44px; margin: 14px 0 0 0; display: flex; flex-direction: column; align-items: center; justify-content: center; }\n.mmp-caption-title { font-size: 15px; font-weight: 600; }\n.mmp-caption-title::after { content: \"\"; display: inline-block; width: 1.2em; text-align: left; animation: mmp-ellipsis 1.4s steps(4, end) infinite; }\n.mmp-caption-sub { font-size: 13px; color: var(--mmp-sub); }\n.mmp-hint { font-size: 13px; color: var(--mmp-sub); }\n\n.mmp-status-row { display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: 8px; margin: 10px 0 14px 0; }\n.mmp-waiting, .mmp-timer {\n display: inline-flex; align-items: center; gap: 7px; padding: 5px 11px; border-radius: 999px;\n font-size: 13px; font-weight: 600; background: var(--mmp-panel); border: 1px solid var(--mmp-border); color: var(--mmp-sub);\n}\n.mmp-dot { position: relative; width: 8px; height: 8px; border-radius: 50%; background: var(--mmp-success); flex-shrink: 0; }\n.mmp-dot::after { content: \"\"; position: absolute; top: 0; right: 0; bottom: 0; left: 0; border-radius: 50%; background: inherit; animation: mmp-ping 1.6s ease-out infinite; }\n.mmp-waiting[data-state=\"reconnecting\"] .mmp-dot { background: var(--mmp-warn); }\n.mmp-timer { font-variant-numeric: tabular-nums; color: var(--mmp-text); }\n.mmp-timer svg { width: 13px; height: 13px; fill: currentColor; }\n.mmp-timer[data-urgent=\"true\"] { color: var(--mmp-danger); background: var(--mmp-danger-bg); border-color: transparent; }\n\n.mmp-details { width: 100%; padding: 12px 14px; margin-bottom: 14px; background: var(--mmp-panel); border: 1px solid var(--mmp-border); border-radius: 14px; }\n.mmp-detail { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 24px; font-size: 13px; color: var(--mmp-sub); }\n.mmp-detail + .mmp-detail { margin-top: 6px; }\n.mmp-detail > span:first-child { flex-shrink: 0; text-align: left; }\n.mmp-detail strong { font-weight: 600; color: var(--mmp-text); text-align: right; overflow-wrap: anywhere; font-variant-numeric: tabular-nums; }\n.mmp-skeleton {\n display: inline-block; height: 14px; border-radius: 7px;\n background: linear-gradient(90deg, var(--mmp-skeleton) 25%, var(--mmp-skeleton-shine) 50%, var(--mmp-skeleton) 75%);\n background-size: 200% 100%; animation: mmp-shimmer 1.4s linear infinite;\n}\n\n.mmp-btn {\n display: flex; align-items: center; justify-content: center; gap: 8px; width: 100%; min-height: 50px; margin: 0; padding: 12px 20px;\n border: 1px solid transparent; border-radius: 14px; background: var(--mmp-accent); color: var(--mmp-accent-text);\n font: inherit; font-size: 16px; font-weight: 600; cursor: pointer; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.14);\n transition: transform 0.15s ease, filter 0.2s ease, opacity 0.2s ease;\n}\n.mmp-btn:hover { filter: brightness(1.08); }\n.mmp-btn:active { transform: scale(0.98); }\n.mmp-btn:disabled { opacity: 0.45; cursor: default; filter: none; transform: none; box-shadow: none; }\n.mmp-btn svg { width: 18px; height: 18px; flex-shrink: 0; }\n.mmp-btn-secondary { background: transparent; color: var(--mmp-text); border-color: var(--mmp-border); box-shadow: none; }\n.mmp-btn-secondary:hover { background: var(--mmp-chip); filter: none; }\n.mmp-btn-danger { background: var(--mmp-danger-bg); color: var(--mmp-danger); box-shadow: none; }\n.mmp-btn[data-busy=\"true\"]::before {\n content: \"\"; width: 16px; height: 16px; border-radius: 50%; border: 2px solid currentColor; border-right-color: transparent;\n animation: mmp-spin 0.7s linear infinite;\n}\n.mmp-powered { margin-top: 12px; font-size: 12px; font-weight: 500; color: var(--mmp-sub); }\n\n.mmp-sheet {\n position: absolute; top: 52px; right: 0; bottom: 0; left: 0; z-index: 2;\n display: flex; flex-direction: column; align-items: center; justify-content: center;\n padding: 12px 22px 24px 22px; background: var(--mmp-card); border-radius: 0 0 24px 24px; overflow-y: auto;\n animation: mmp-sheet-in 0.26s cubic-bezier(0.2, 0.8, 0.2, 1);\n}\n.mmp-root.mmp-translucent .mmp-sheet { -webkit-backdrop-filter: blur(24px); backdrop-filter: blur(24px); }\n.mmp-icon { display: flex; align-items: center; justify-content: center; width: 72px; height: 72px; margin: 10px auto 18px auto; border-radius: 50%; flex-shrink: 0; animation: mmp-pop 0.45s cubic-bezier(0.2, 1.4, 0.4, 1); }\n.mmp-icon svg { width: 36px; height: 36px; fill: none; stroke: currentColor; stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; }\n.mmp-icon svg path { stroke-dasharray: 60; stroke-dashoffset: 60; animation: mmp-draw 0.5s 0.2s ease forwards; }\n.mmp-icon[data-tone=\"success\"] { background: var(--mmp-success-bg); color: var(--mmp-success); }\n.mmp-icon[data-tone=\"danger\"] { background: var(--mmp-danger-bg); color: var(--mmp-danger); }\n.mmp-icon[data-tone=\"warn\"] { background: var(--mmp-warn-bg); color: var(--mmp-warn); }\n.mmp-title { margin: 0 0 10px 0; font-size: 22px; font-weight: 700; line-height: inherit; color: var(--mmp-text); }\n.mmp-pill { display: inline-block; max-width: 100%; padding: 6px 12px; margin-bottom: 14px; background: var(--mmp-panel); border: 1px solid var(--mmp-border); border-radius: 10px; font-size: 13px; font-weight: 600; color: var(--mmp-sub); overflow-wrap: anywhere; }\n.mmp-text { margin: 0 0 6px 0; font-size: 15px; color: var(--mmp-sub); overflow-wrap: anywhere; }\n.mmp-detail-text { max-width: 100%; max-height: 84px; margin: 4px 0 0 0; overflow-y: auto; font-size: 12px; line-height: 1.4; color: var(--mmp-sub); opacity: 0.85; overflow-wrap: anywhere; }\n.mmp-actions { display: flex; flex-direction: column; gap: 10px; width: 100%; margin-top: 18px; }\n\n@keyframes mmp-fade { from { opacity: 0; } to { opacity: 1; } }\n@keyframes mmp-rise { from { opacity: 0; transform: translateY(18px) scale(0.97); } to { opacity: 1; transform: none; } }\n@keyframes mmp-screen-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }\n@keyframes mmp-sheet-in { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }\n@keyframes mmp-qr-in { from { opacity: 0; transform: scale(0.94); } to { opacity: 1; transform: none; } }\n@keyframes mmp-pulse { 0%, 100% { opacity: 0.88; transform: scale(1); } 50% { opacity: 1; transform: scale(1.05); } }\n@keyframes mmp-sweep { 0% { transform: translateX(-110%); } 100% { transform: translateX(260%); } }\n@keyframes mmp-shimmer { from { background-position: 200% 0; } to { background-position: -200% 0; } }\n@keyframes mmp-ping { 0% { transform: scale(1); opacity: 0.7; } 100% { transform: scale(2.6); opacity: 0; } }\n@keyframes mmp-spin { to { transform: rotate(360deg); } }\n@keyframes mmp-pop { from { opacity: 0; transform: scale(0.6); } to { opacity: 1; transform: none; } }\n@keyframes mmp-draw { to { stroke-dashoffset: 0; } }\n@keyframes mmp-ellipsis { 0% { content: \"\"; } 25% { content: \".\"; } 50% { content: \"..\"; } 75% { content: \"...\"; } }\n\n@media (max-width: 380px) {\n .mmp-root { padding: 10px; }\n .mmp-screen { padding: 6px 16px 18px 16px; }\n .mmp-qr { width: 204px; height: 204px; }\n}\n@media (prefers-reduced-motion: reduce) {\n .mmp-root, .mmp-root *, .mmp-root *::before, .mmp-root *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; }\n .mmp-icon svg path { stroke-dashoffset: 0; }\n .mmp-loader-bar { width: 100%; opacity: 0.25; }\n}\n";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { IDesignOptions } from './types';
|
|
2
|
+
export declare function _getContentCancelModal(design?: IDesignOptions): string;
|
|
3
|
+
export declare function _getContentCoreCss(design?: IDesignOptions): string;
|
|
4
|
+
export declare function _getContentQRDisplay(qrContainerId: string, merchantName: string, formattedAmount: string, apiResponse: any, design?: IDesignOptions): string;
|
|
5
|
+
export declare function _getContentAfterModal(status: 'SUCCESS' | 'FAILED' | 'EXPIRED' | 'CANCELLED', orderId: string, messageHtml: string, design?: IDesignOptions): string;
|
|
6
|
+
export declare function _getPreloadScreen(design?: IDesignOptions): string;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
export type MMPayLanguage = 'en' | 'mm';
|
|
2
|
+
export type MMPayTransport = 'auto' | 'websocket' | 'polling';
|
|
3
|
+
export type MMPayTerminalStatus = 'SUCCESS' | 'FAILED' | 'EXPIRED' | 'CANCELLED';
|
|
4
|
+
export interface IDesignOptions {
|
|
5
|
+
mode?: 'light' | 'dark' | 'light-translucent' | 'dark-translucent' | 'auto';
|
|
6
|
+
color?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface SDKOptions {
|
|
9
|
+
baseUrl?: string;
|
|
10
|
+
environment?: 'sandbox' | 'production';
|
|
11
|
+
merchantName?: string;
|
|
12
|
+
/**
|
|
13
|
+
* Interval of the HTTP polling fallback, in milliseconds.
|
|
14
|
+
*/
|
|
15
|
+
pollInterval?: number;
|
|
16
|
+
/**
|
|
17
|
+
* How payment status reaches the browser. `auto` (default) uses a WebSocket
|
|
18
|
+
* and falls back to HTTP polling when a socket cannot be established.
|
|
19
|
+
*/
|
|
20
|
+
transport?: MMPayTransport;
|
|
21
|
+
/**
|
|
22
|
+
* Seconds the shopper has to pay before the modal shows "Expired".
|
|
23
|
+
* Default and maximum: 900 (15 minutes). Minimum: 60.
|
|
24
|
+
*/
|
|
25
|
+
timeoutSeconds?: number;
|
|
26
|
+
/**
|
|
27
|
+
* Language the modal opens in. The shopper can still switch, and their
|
|
28
|
+
* choice is remembered.
|
|
29
|
+
*/
|
|
30
|
+
language?: MMPayLanguage | 'my';
|
|
31
|
+
design?: IDesignOptions;
|
|
32
|
+
}
|
|
33
|
+
export interface ICreateTokenRequestParams {
|
|
34
|
+
amount?: number;
|
|
35
|
+
orderId: string;
|
|
36
|
+
nonce: string;
|
|
37
|
+
}
|
|
38
|
+
export interface ICreateTokenResponse {
|
|
39
|
+
token: string;
|
|
40
|
+
}
|
|
41
|
+
export interface ICreatePaymentRequestParams {
|
|
42
|
+
amount: number;
|
|
43
|
+
orderId: string;
|
|
44
|
+
callbackUrl?: string;
|
|
45
|
+
customMessage?: string;
|
|
46
|
+
nonce: string;
|
|
47
|
+
}
|
|
48
|
+
export interface ICreatePaymentResponse {
|
|
49
|
+
orderId: string;
|
|
50
|
+
amount: number;
|
|
51
|
+
status: 'PENDING' | 'SUCCESS' | 'FAILED' | 'REFUNDED' | 'CANCELLED' | 'EXPIRED';
|
|
52
|
+
currency: string;
|
|
53
|
+
vendorQrRefId: string;
|
|
54
|
+
qr: string;
|
|
55
|
+
createdAt: string;
|
|
56
|
+
}
|
|
57
|
+
export interface IPaymentShowRequestParams {
|
|
58
|
+
orderId: string;
|
|
59
|
+
nonce: string;
|
|
60
|
+
}
|
|
61
|
+
export interface IPaymentShowResponse {
|
|
62
|
+
orderId: string;
|
|
63
|
+
amount: number;
|
|
64
|
+
status: 'PENDING' | 'SUCCESS' | 'FAILED' | 'REFUNDED' | 'CANCELLED' | 'EXPIRED';
|
|
65
|
+
currency: string;
|
|
66
|
+
vendorQrRefId: string;
|
|
67
|
+
qr: string;
|
|
68
|
+
createdAt: string;
|
|
69
|
+
}
|
|
70
|
+
export interface ICancelPaymentRequestParams {
|
|
71
|
+
orderId: string;
|
|
72
|
+
nonce: string;
|
|
73
|
+
}
|
|
74
|
+
export interface ICancelPaymentResponse {
|
|
75
|
+
success: boolean;
|
|
76
|
+
}
|
|
77
|
+
export interface IPollingRequest {
|
|
78
|
+
orderId: string;
|
|
79
|
+
nonce: string;
|
|
80
|
+
}
|
|
81
|
+
export interface IPollingResponse {
|
|
82
|
+
status: 'PENDING' | 'SUCCESS' | 'FAILED' | 'REFUNDED' | 'CANCELLED' | 'EXPIRED';
|
|
83
|
+
vendorQrRefId?: string;
|
|
84
|
+
transactionRefId?: string;
|
|
85
|
+
orderId?: string;
|
|
86
|
+
amount?: number;
|
|
87
|
+
}
|
|
88
|
+
export interface IStreamTicketResponse {
|
|
89
|
+
ticket: string;
|
|
90
|
+
expiresIn: number;
|
|
91
|
+
}
|
|
92
|
+
export interface IModalEventResult {
|
|
93
|
+
success?: boolean;
|
|
94
|
+
created?: boolean;
|
|
95
|
+
cancelled?: boolean;
|
|
96
|
+
expired?: boolean;
|
|
97
|
+
failed?: boolean;
|
|
98
|
+
orderId?: string;
|
|
99
|
+
amount?: number;
|
|
100
|
+
vendorQrRefId?: string;
|
|
101
|
+
}
|
package/dist/esm/ui.d.ts
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { IDesignOptions, MMPayLanguage, MMPayTerminalStatus } from './types';
|
|
2
|
+
export interface MMPayUIHandlers {
|
|
3
|
+
/** The shopper pressed close while a payment is still pending. */
|
|
4
|
+
onCloseRequest: () => void;
|
|
5
|
+
/** The shopper confirmed they want to stop the pending payment. */
|
|
6
|
+
onCancelConfirm: () => void;
|
|
7
|
+
/** The shopper closed a finished (success, failed, expired, cancelled) screen. */
|
|
8
|
+
onDismiss: () => void;
|
|
9
|
+
}
|
|
10
|
+
export interface MMPayPaymentView {
|
|
11
|
+
merchantName: string;
|
|
12
|
+
orderId: string;
|
|
13
|
+
amount?: number;
|
|
14
|
+
vendorQrRefId?: string;
|
|
15
|
+
qr?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface MMPayResultView {
|
|
18
|
+
orderId: string;
|
|
19
|
+
messageKey: string;
|
|
20
|
+
ref?: string;
|
|
21
|
+
detail?: string;
|
|
22
|
+
}
|
|
23
|
+
export declare class MMPayUI {
|
|
24
|
+
private design;
|
|
25
|
+
private language;
|
|
26
|
+
private handlers;
|
|
27
|
+
private mode;
|
|
28
|
+
private host;
|
|
29
|
+
private root;
|
|
30
|
+
private card;
|
|
31
|
+
private screen;
|
|
32
|
+
private sheet;
|
|
33
|
+
private closeButton;
|
|
34
|
+
private frameBindings;
|
|
35
|
+
private screenBindings;
|
|
36
|
+
private sheetBindings;
|
|
37
|
+
private payment;
|
|
38
|
+
private paymentParts;
|
|
39
|
+
private countdownText;
|
|
40
|
+
private timerBadge;
|
|
41
|
+
private waitingBadge;
|
|
42
|
+
private waitingBinding;
|
|
43
|
+
private qrCanvas;
|
|
44
|
+
private previousBodyOverflow;
|
|
45
|
+
private previousFocus;
|
|
46
|
+
private readonly onKeyDown;
|
|
47
|
+
constructor(design: IDesignOptions, preferredLanguage?: string);
|
|
48
|
+
getLanguage(): MMPayLanguage;
|
|
49
|
+
/**
|
|
50
|
+
* The language is state of the UI, not of a screen, so it survives every
|
|
51
|
+
* screen change and is applied to whatever is rendered next.
|
|
52
|
+
*/
|
|
53
|
+
setLanguage(language: string, remember?: boolean): void;
|
|
54
|
+
isOpen(): boolean;
|
|
55
|
+
showLoading(view: MMPayPaymentView, handlers: MMPayUIHandlers): void;
|
|
56
|
+
showQr(view: MMPayPaymentView, handlers: MMPayUIHandlers): void;
|
|
57
|
+
showResult(status: MMPayTerminalStatus, view: MMPayResultView, handlers: MMPayUIHandlers): void;
|
|
58
|
+
showCancelConfirmation(): void;
|
|
59
|
+
hideCancelConfirmation(): void;
|
|
60
|
+
setCancelBusy(busy: boolean): void;
|
|
61
|
+
setCountdown(remainingSeconds: number): void;
|
|
62
|
+
setConnectionState(state: 'live' | 'reconnecting'): void;
|
|
63
|
+
close(): void;
|
|
64
|
+
private mount;
|
|
65
|
+
private renderPaymentScreen;
|
|
66
|
+
private fillPayment;
|
|
67
|
+
private setAmount;
|
|
68
|
+
private showQrPlaceholder;
|
|
69
|
+
private renderQr;
|
|
70
|
+
private downloadQr;
|
|
71
|
+
private handleClick;
|
|
72
|
+
private requestClose;
|
|
73
|
+
private handleKeyDown;
|
|
74
|
+
private swapScreen;
|
|
75
|
+
private removeSheet;
|
|
76
|
+
private setCloseVisible;
|
|
77
|
+
private focusFirst;
|
|
78
|
+
private clear;
|
|
79
|
+
/** Creates a text node holder that is re-translated whenever the language changes. */
|
|
80
|
+
private text;
|
|
81
|
+
private applyBinding;
|
|
82
|
+
private applyLanguage;
|
|
83
|
+
/** Web fonts must be declared in the page itself to be usable inside a shadow root. */
|
|
84
|
+
private ensureFont;
|
|
85
|
+
}
|