@mygigsters/card-sdk 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,518 @@
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const p=require("airwallex-payment-elements");class g{constructor(t){this.baseUrl=t.replace(/\/+$/,"")}async _post(t,e,i=null,o={}){const s={"Content-Type":"application/json",...o};i&&(s.Authorization=i.startsWith("Basic ")||i.startsWith("Bearer ")?i:`Bearer ${i}`);const r=await fetch(`${this.baseUrl}/api/v1${t}`,{method:"POST",headers:s,body:JSON.stringify(e)}),c=await r.text();let n=null;if(c&&c.trim().length>0)try{n=JSON.parse(c)}catch{n=null}if(!r.ok){const l=n&&(n.message||n.error)||c||r.statusText||`HTTP ${r.status}`;throw new Error(l)}return n??{}}async authenticate(t,e){const i=btoa(`${t}:${e}`),o=await fetch(`${this.baseUrl}/api/v1/sdk-initialization`,{method:"POST",headers:{"Content-Type":"application/json","x-api-version":"1.1",Authorization:`Basic ${i}`}}),s=await o.text();let r=null;if(s&&s.trim().length>0)try{r=JSON.parse(s)}catch{r=null}if(!o.ok){const c=r&&(r.message||r.error)||s||o.statusText||`HTTP ${o.status}`;throw new Error(c)}if(!r?.success||!r?.data?.token)throw new Error("Authentication failed: Unexpected response from server");return{token:r.data.token,clientId:r.data.clientId,expiresIn:r.data.expiresIn,tokenType:r.data.tokenType,paymentsIndia:r.data.paymentsIndia||!1}}async getClientSecret(t,e,i=null){console.log("🔐 CardAPI.getClientSecret()",{customerId:t,accountId:e,hasToken:!!i});const o=await this._post("/customer/client-secret",{customerId:t,accountId:e},i),s=o.client_secret||o.clientSecret||o?.data?.client_secret||o?.data?.clientSecret;if(!s)throw new Error("Failed to retrieve client secret from server");return{clientSecret:s}}async saveConsent(t,e,i=null){return this._post("/customer/save-consent",{customerId:t,paymentConsentId:e},i)}}const m={close:`<svg width="18" height="18" fill="none" stroke="currentColor" viewBox="0 0 24 24">
2
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.2" d="M6 18L18 6M6 6l12 12"/>
3
+ </svg>`,check:`<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
4
+ <path stroke-linecap="round" stroke-linejoin="round" d="M20 6L9 17l-5-5"/>
5
+ </svg>`};class b{constructor(t,e){this.shadowRoot=t,this.callbacks=e,this.state={loading:!0,cardLoaded:!1,cardComplete:!1,submitting:!1,error:"",success:!1},this._cardMounted=!1}_getContainer(){let t=this.shadowRoot.querySelector("#mc-sdk-root");if(!t){t=document.createElement("div"),t.id="mc-sdk-root";const e=this.shadowRoot.querySelector("#mc-theme-container");e?e.appendChild(t):this.shadowRoot.appendChild(t)}return t}render(){this.state.loading=!0;const t=this._getContainer();t.innerHTML=`
6
+ <div class="mc-backdrop" id="mc-backdrop">
7
+ <div class="mc-modal" id="mc-modal">
8
+ <button class="mc-close-btn" aria-label="Close" id="mc-close-btn" type="button">${m.close}</button>
9
+
10
+ <div class="mc-header">
11
+ <h1 class="mc-title">Card Details</h1>
12
+ <p class="mc-subtitle">Please enter your card details</p>
13
+ </div>
14
+
15
+ <div class="mc-body">
16
+ <!-- Error banner (initially hidden) -->
17
+ <div class="mc-error-banner" style="display:none;" id="mc-error-banner"></div>
18
+
19
+ <!-- Loading spinner (shown initially) -->
20
+ <div class="mc-loading" id="mc-loading">
21
+ <div class="mc-spinner"></div>
22
+ <span class="mc-loading-text">Loading payment form...</span>
23
+ </div>
24
+
25
+ <!-- Card wrapper (hidden until Airwallex loads) -->
26
+ <div class="mc-card-wrapper" id="mc-card-wrapper" style="display:none;">
27
+ <div id="card-root"></div>
28
+ </div>
29
+
30
+ <!-- Submit button (hidden until Airwallex loads) -->
31
+ <button class="mc-submit-btn" id="mc-submit-btn" disabled style="display:none;" type="button">
32
+ Submit
33
+ </button>
34
+ </div>
35
+
36
+ <div class="mc-powered-by">
37
+ Powered by <a href="https://mygigsters.com.au" target="_blank" rel="noopener">MyGigsters</a>
38
+ </div>
39
+ </div>
40
+ </div>
41
+ `,this._attachListeners()}_attachListeners(){this.shadowRoot.querySelectorAll(".mc-close-btn, #mc-close-btn").forEach(o=>{o.addEventListener("click",s=>{s.preventDefault(),s.stopPropagation(),this.callbacks.onClose()})});const e=this.shadowRoot.querySelector("#mc-backdrop")||this.shadowRoot.querySelector(".mc-backdrop");e&&e.addEventListener("click",o=>{o.target===e&&(o.preventDefault(),o.stopPropagation(),this.callbacks.onClose())});const i=this.shadowRoot.querySelector("#mc-submit-btn");i&&i.addEventListener("click",o=>{o.preventDefault(),o.stopPropagation(),this.callbacks.onSubmit()}),this.shadowRoot.addEventListener("click",o=>{const s=o.target;s&&(s.closest(".mc-close-btn")||s.closest("#mc-close-btn"))&&(o.preventDefault(),o.stopPropagation(),this.callbacks.onClose())})}setCardLoaded(){this.state.cardLoaded=!0,this.state.loading=!1;const t=this.shadowRoot.querySelector("#mc-loading"),e=this.shadowRoot.querySelector("#mc-card-wrapper"),i=this.shadowRoot.querySelector("#mc-submit-btn");t&&(t.style.display="none"),e&&(e.style.display="block"),i&&(i.style.display="flex")}markCardMounted(){this._cardMounted=!0}setCardComplete(t){this.state.cardComplete=t;const e=this.shadowRoot.querySelector("#mc-submit-btn");e&&(e.disabled=!t||this.state.submitting)}setSubmitting(t){this.state.submitting=t;const e=this.shadowRoot.querySelector("#mc-submit-btn");e&&(e.disabled=t||!this.state.cardComplete,e.innerHTML=t?'<span class="mc-btn-inner"><div class="mc-spinner mc-spinner-sm"></div>Saving...</span>':"Submit")}setError(t){this.state.error=t;const e=this.shadowRoot.querySelector("#mc-error-banner");e&&(t?(e.textContent=t,e.style.display="block"):(e.textContent="",e.style.display="none"))}showInitError(t){this.state.loading=!1,this.state.error=t;const e=this.shadowRoot.querySelector("#mc-loading");e&&(e.innerHTML=`
42
+ <div style="text-align:center; padding: 12px 0;">
43
+ <p style="color:#ef4444; font-size:14px; font-weight:600; margin-bottom:8px;">${this._escapeHtml(t)}</p>
44
+ <p style="color:#94a3b8; font-size:13px;">Please check your configuration credentials and try again.</p>
45
+ </div>
46
+ `)}showSuccess(t){this.state.success=!0;const e=this.shadowRoot.querySelector(".mc-modal");e&&(e.innerHTML=`
47
+ <button class="mc-close-btn" aria-label="Close" id="mc-close-btn" type="button">${m.close}</button>
48
+
49
+ <div class="mc-body">
50
+ <div class="mc-success-wrap">
51
+ <div class="mc-success-icon">${m.check}</div>
52
+ <h2 class="mc-success-title">Card Saved Successfully</h2>
53
+ <p class="mc-success-sub">Your card details have been securely tokenized and saved.</p>
54
+ <button class="mc-done-btn" id="mc-done-btn" type="button">Done</button>
55
+ </div>
56
+ </div>
57
+
58
+ <div class="mc-powered-by">
59
+ Powered by <a href="https://mygigsters.com.au" target="_blank" rel="noopener">MyGigsters</a>
60
+ </div>
61
+ `,e.querySelectorAll(".mc-close-btn, #mc-close-btn").forEach(i=>{i.addEventListener("click",o=>{o.preventDefault(),o.stopPropagation(),this.callbacks.onClose()})}),e.querySelector("#mc-done-btn")?.addEventListener("click",i=>{i.preventDefault(),i.stopPropagation(),this.callbacks.onClose()}))}_escapeHtml(t){const e=document.createElement("div");return e.textContent=t,e.innerHTML}destroy(){const t=this.shadowRoot.querySelector("#mc-sdk-root");t&&(t.innerHTML=""),this._cardMounted=!1}}const y=`
62
+ /* ── Reset inside shadow DOM ───────────────────────────────────────────────── */
63
+ *, *::before, *::after {
64
+ box-sizing: border-box;
65
+ margin: 0;
66
+ padding: 0;
67
+ }
68
+
69
+ :host {
70
+ display: block !important;
71
+ position: fixed !important;
72
+ top: 0 !important;
73
+ left: 0 !important;
74
+ right: 0 !important;
75
+ bottom: 0 !important;
76
+ width: 100vw !important;
77
+ height: 100vh !important;
78
+ z-index: 2147483647 !important;
79
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
80
+ font-size: 14px;
81
+ color: #e5e7eb;
82
+ line-height: 1.5;
83
+ pointer-events: auto !important;
84
+ }
85
+
86
+ #mc-theme-container, #mc-sdk-root {
87
+ width: 100%;
88
+ height: 100%;
89
+ position: fixed;
90
+ top: 0;
91
+ left: 0;
92
+ }
93
+
94
+ /* ══════════════════════════════════════════════════════════════════════════════
95
+ DARK THEME (DEFAULT)
96
+ ══════════════════════════════════════════════════════════════════════════════ */
97
+
98
+ /* ── Backdrop ──────────────────────────────────────────────────────────────── */
99
+ .mc-backdrop {
100
+ position: fixed;
101
+ top: 0;
102
+ left: 0;
103
+ right: 0;
104
+ bottom: 0;
105
+ width: 100vw;
106
+ height: 100vh;
107
+ background: rgba(0, 0, 0, 0.75);
108
+ backdrop-filter: blur(5px);
109
+ -webkit-backdrop-filter: blur(5px);
110
+ display: flex;
111
+ align-items: center;
112
+ justify-content: center;
113
+ z-index: 2147483647;
114
+ padding: 16px;
115
+ box-sizing: border-box;
116
+ animation: mc-fade-in 0.2s ease;
117
+ }
118
+
119
+ /* ── Modal ──────────────────────────────────────────────────────────────────── */
120
+ .mc-modal {
121
+ background: #111827;
122
+ border: 1px solid rgba(255, 255, 255, 0.12);
123
+ border-radius: 16px;
124
+ width: 100%;
125
+ max-width: 460px;
126
+ box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.8), 0 0 0 1px rgba(255, 255, 255, 0.05);
127
+ overflow: hidden;
128
+ animation: mc-modal-in 0.25s cubic-bezier(0.16, 1, 0.3, 1);
129
+ position: relative;
130
+ display: flex;
131
+ flex-direction: column;
132
+ color: #ffffff;
133
+ }
134
+
135
+ /* ── Close button ──────────────────────────────────────────────────────────── */
136
+ .mc-close-btn {
137
+ position: absolute;
138
+ top: 16px;
139
+ right: 16px;
140
+ background: rgba(255, 255, 255, 0.08);
141
+ border: 1px solid rgba(255, 255, 255, 0.08);
142
+ border-radius: 8px;
143
+ width: 32px;
144
+ height: 32px;
145
+ display: flex;
146
+ align-items: center;
147
+ justify-content: center;
148
+ cursor: pointer !important;
149
+ color: #94a3b8;
150
+ transition: all 0.15s ease;
151
+ padding: 0;
152
+ line-height: 0;
153
+ z-index: 100;
154
+ outline: none;
155
+ pointer-events: auto !important;
156
+ user-select: none;
157
+ }
158
+
159
+ .mc-close-btn svg,
160
+ .mc-close-btn path {
161
+ pointer-events: none !important;
162
+ }
163
+
164
+ .mc-close-btn:hover {
165
+ background: rgba(255, 255, 255, 0.18);
166
+ color: #ffffff;
167
+ transform: scale(1.05);
168
+ }
169
+
170
+ .mc-close-btn:active {
171
+ transform: scale(0.95);
172
+ }
173
+
174
+ /* ── Header ────────────────────────────────────────────────────────────────── */
175
+ .mc-header {
176
+ text-align: center;
177
+ padding: 28px 24px 0;
178
+ }
179
+
180
+ .mc-title {
181
+ font-size: 22px;
182
+ font-weight: 700;
183
+ color: #ffffff;
184
+ margin: 0 0 6px;
185
+ line-height: 1.2;
186
+ }
187
+
188
+ .mc-subtitle {
189
+ font-size: 14px;
190
+ color: #94a3b8;
191
+ margin: 0;
192
+ font-weight: 400;
193
+ }
194
+
195
+ /* ── Body ──────────────────────────────────────────────────────────────────── */
196
+ .mc-body {
197
+ padding: 20px 24px 24px;
198
+ flex: 1;
199
+ }
200
+
201
+ /* ── Card mount area ───────────────────────────────────────────────────────── */
202
+ .mc-card-wrapper {
203
+ background: #1f2937;
204
+ border: 1px solid rgba(255, 255, 255, 0.12);
205
+ border-radius: 10px;
206
+ padding: 14px 16px;
207
+ margin-bottom: 20px;
208
+ min-height: 48px;
209
+ transition: border-color 0.2s, box-shadow 0.2s;
210
+ }
211
+
212
+ .mc-card-wrapper:focus-within {
213
+ border-color: #6366f1;
214
+ box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.25);
215
+ }
216
+
217
+ #card-root {
218
+ margin: 0;
219
+ padding: 0;
220
+ min-height: 40px;
221
+ width: 100%;
222
+ }
223
+
224
+ #card-root iframe {
225
+ display: block !important;
226
+ margin: 0 !important;
227
+ padding: 0 !important;
228
+ width: 100% !important;
229
+ border: none !important;
230
+ }
231
+
232
+ /* ── Loading state ─────────────────────────────────────────────────────────── */
233
+ .mc-loading {
234
+ display: flex;
235
+ flex-direction: column;
236
+ align-items: center;
237
+ justify-content: center;
238
+ padding: 32px 20px;
239
+ gap: 12px;
240
+ }
241
+
242
+ .mc-loading-text {
243
+ font-size: 13.5px;
244
+ color: #94a3b8;
245
+ font-weight: 500;
246
+ }
247
+
248
+ /* ── Spinner ────────────────────────────────────────────────────────────────── */
249
+ .mc-spinner {
250
+ width: 32px;
251
+ height: 32px;
252
+ border: 3px solid rgba(255, 255, 255, 0.15);
253
+ border-top-color: #6366f1;
254
+ border-radius: 50%;
255
+ animation: mc-spin 0.7s linear infinite;
256
+ flex-shrink: 0;
257
+ }
258
+
259
+ .mc-spinner-sm {
260
+ width: 16px;
261
+ height: 16px;
262
+ border-width: 2px;
263
+ border-color: rgba(255, 255, 255, 0.3);
264
+ border-top-color: #fff;
265
+ }
266
+
267
+ @keyframes mc-spin {
268
+ to {
269
+ transform: rotate(360deg);
270
+ }
271
+ }
272
+
273
+ /* ── Submit button ─────────────────────────────────────────────────────────── */
274
+ .mc-submit-btn {
275
+ width: 100%;
276
+ padding: 13px 24px;
277
+ background: #6366f1;
278
+ color: #ffffff;
279
+ border: none;
280
+ border-radius: 9px;
281
+ font-size: 15px;
282
+ font-weight: 600;
283
+ cursor: pointer;
284
+ font-family: inherit;
285
+ transition: all 0.2s ease;
286
+ display: flex;
287
+ align-items: center;
288
+ justify-content: center;
289
+ gap: 8px;
290
+ box-shadow: 0 4px 12px rgba(99, 102, 241, 0.35);
291
+ outline: none;
292
+ }
293
+
294
+ .mc-submit-btn:hover:not(:disabled) {
295
+ background: #4f46e5;
296
+ box-shadow: 0 6px 16px rgba(99, 102, 241, 0.45);
297
+ transform: translateY(-1px);
298
+ }
299
+
300
+ .mc-submit-btn:active:not(:disabled) {
301
+ transform: translateY(0);
302
+ }
303
+
304
+ .mc-submit-btn:disabled {
305
+ opacity: 0.55;
306
+ cursor: not-allowed;
307
+ transform: none;
308
+ box-shadow: none;
309
+ }
310
+
311
+ .mc-btn-inner {
312
+ display: flex;
313
+ align-items: center;
314
+ justify-content: center;
315
+ gap: 8px;
316
+ }
317
+
318
+ /* ── Error banner ──────────────────────────────────────────────────────────── */
319
+ .mc-error-banner {
320
+ background: rgba(239, 68, 68, 0.12);
321
+ border: 1px solid rgba(239, 68, 68, 0.3);
322
+ border-radius: 8px;
323
+ padding: 10px 14px;
324
+ margin-bottom: 16px;
325
+ font-size: 13px;
326
+ color: #fca5a5;
327
+ line-height: 1.4;
328
+ animation: mc-fade-in 0.2s ease;
329
+ }
330
+
331
+ /* ── Success state ─────────────────────────────────────────────────────────── */
332
+ .mc-success-wrap {
333
+ text-align: center;
334
+ padding: 30px 20px 16px;
335
+ animation: mc-fade-in 0.3s ease;
336
+ }
337
+
338
+ .mc-success-icon {
339
+ width: 56px;
340
+ height: 56px;
341
+ border-radius: 50%;
342
+ background: rgba(34, 197, 94, 0.15);
343
+ border: 2px solid rgba(34, 197, 94, 0.4);
344
+ display: flex;
345
+ align-items: center;
346
+ justify-content: center;
347
+ margin: 0 auto 16px;
348
+ }
349
+
350
+ .mc-success-icon svg {
351
+ width: 28px;
352
+ height: 28px;
353
+ color: #22c55e;
354
+ }
355
+
356
+ .mc-success-title {
357
+ font-size: 20px;
358
+ font-weight: 700;
359
+ color: #f8fafc;
360
+ margin: 0 0 6px;
361
+ }
362
+
363
+ .mc-success-sub {
364
+ font-size: 13.5px;
365
+ color: #94a3b8;
366
+ margin: 0 0 24px;
367
+ }
368
+
369
+ .mc-done-btn {
370
+ display: inline-flex;
371
+ align-items: center;
372
+ justify-content: center;
373
+ padding: 11px 36px;
374
+ background: #6366f1;
375
+ color: #fff;
376
+ border: none;
377
+ border-radius: 8px;
378
+ font-size: 14px;
379
+ font-weight: 600;
380
+ cursor: pointer;
381
+ font-family: inherit;
382
+ transition: all 0.2s ease;
383
+ box-shadow: 0 4px 12px rgba(99, 102, 241, 0.35);
384
+ }
385
+
386
+ .mc-done-btn:hover {
387
+ background: #4f46e5;
388
+ transform: translateY(-1px);
389
+ }
390
+
391
+ /* ── Powered by ────────────────────────────────────────────────────────────── */
392
+ .mc-powered-by {
393
+ text-align: center;
394
+ padding: 8px 0 16px;
395
+ font-size: 11.5px;
396
+ color: #64748b;
397
+ }
398
+
399
+ .mc-powered-by a {
400
+ color: #94a3b8;
401
+ text-decoration: none;
402
+ font-weight: 600;
403
+ transition: color 0.15s ease;
404
+ }
405
+
406
+ .mc-powered-by a:hover {
407
+ color: #818cf8;
408
+ }
409
+
410
+ /* ── Animations ────────────────────────────────────────────────────────────── */
411
+ @keyframes mc-modal-in {
412
+ from {
413
+ opacity: 0;
414
+ transform: translateY(12px) scale(0.97);
415
+ }
416
+ to {
417
+ opacity: 1;
418
+ transform: translateY(0) scale(1);
419
+ }
420
+ }
421
+
422
+ @keyframes mc-fade-in {
423
+ from { opacity: 0; }
424
+ to { opacity: 1; }
425
+ }
426
+
427
+ /* ══════════════════════════════════════════════════════════════════════════════
428
+ LIGHT THEME (High Contrast & Clean)
429
+ ══════════════════════════════════════════════════════════════════════════════ */
430
+
431
+ [data-theme='light'] .mc-backdrop {
432
+ background: rgba(15, 23, 42, 0.45);
433
+ backdrop-filter: blur(5px);
434
+ -webkit-backdrop-filter: blur(5px);
435
+ }
436
+
437
+ [data-theme='light'] .mc-modal {
438
+ background: #ffffff;
439
+ border: 1px solid #e2e8f0;
440
+ color: #0f172a;
441
+ box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.12), 0 8px 10px -6px rgba(0, 0, 0, 0.06);
442
+ }
443
+
444
+ [data-theme='light'] .mc-close-btn {
445
+ background: #f1f5f9;
446
+ border: 1px solid #e2e8f0;
447
+ color: #64748b;
448
+ }
449
+
450
+ [data-theme='light'] .mc-close-btn:hover {
451
+ background: #e2e8f0;
452
+ color: #0f172a;
453
+ }
454
+
455
+ [data-theme='light'] .mc-title {
456
+ color: #0f172a;
457
+ }
458
+
459
+ [data-theme='light'] .mc-subtitle {
460
+ color: #64748b;
461
+ }
462
+
463
+ /* ── Light: Card area ─────────────────────────────────────────────────────── */
464
+ [data-theme='light'] .mc-card-wrapper {
465
+ background: #ffffff;
466
+ border: 1.5px solid #cbd5e1;
467
+ box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
468
+ }
469
+
470
+ [data-theme='light'] .mc-card-wrapper:focus-within {
471
+ border-color: #6366f1;
472
+ box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.15);
473
+ }
474
+
475
+ [data-theme='light'] .mc-loading-text {
476
+ color: #64748b;
477
+ }
478
+
479
+ [data-theme='light'] .mc-spinner {
480
+ border-color: rgba(99, 102, 241, 0.2);
481
+ border-top-color: #6366f1;
482
+ }
483
+
484
+ [data-theme='light'] .mc-error-banner {
485
+ background: #fef2f2;
486
+ border-color: #fecaca;
487
+ color: #dc2626;
488
+ }
489
+
490
+ [data-theme='light'] .mc-success-icon {
491
+ background: #f0fdf4;
492
+ border-color: #bbf7d0;
493
+ }
494
+
495
+ [data-theme='light'] .mc-success-icon svg {
496
+ color: #16a34a;
497
+ }
498
+
499
+ [data-theme='light'] .mc-success-title {
500
+ color: #0f172a;
501
+ }
502
+
503
+ [data-theme='light'] .mc-success-sub {
504
+ color: #64748b;
505
+ }
506
+
507
+ [data-theme='light'] .mc-powered-by {
508
+ color: #94a3b8;
509
+ }
510
+
511
+ [data-theme='light'] .mc-powered-by a {
512
+ color: #6366f1;
513
+ }
514
+
515
+ [data-theme='light'] .mc-powered-by a:hover {
516
+ color: #4f46e5;
517
+ }
518
+ `,f={dev:"http://3.108.128.110:5000",demo:"https://qa-payments.mygigsters.com.au",prod:"https://prod-payments.mygigsters.com.au"},w={dev:"demo",demo:"demo",prod:"prod"};class h{constructor(){this.config=null,this.api=null,this.renderer=null,this.host=null,this.shadowRoot=null,this.cardElement=null,this.clientSecret=null,this.authToken=null,this.tokenExpiresAt=null,this.airwallexClientId=null,this.isInitialized=!1,this.isSubmitting=!1,this._handleKeyDown=this._handleKeyDown.bind(this)}async init(t){try{if(!t)throw new Error("Configuration object is required for MygigstersCard.init()");if(!t.apiKey)throw new Error("apiKey is required");if(!t.apiSecret)throw new Error("apiSecret is required");if(!t.customerId)throw new Error("customerId is required");const e=t.myGigsterId||t.accountId;if(!e)throw new Error("myGigsterId is required");if(!t.containerId)throw new Error("containerId is required");if(!document.getElementById(t.containerId))throw new Error(`Container element with ID '${t.containerId}' not found`);let o=t.env||"demo";if(o==="qa"&&(o="demo"),!f[o])throw new Error(`Unknown env "${o}". Use "dev", "demo", or "prod".`);const s=t.baseUrl||f[o];this.config={mode:"dark",onSuccess:()=>{},onError:l=>console.error("MyGigsters Card SDK Error:",l),onClose:()=>{},...t,myGigsterId:e,accountId:e,env:o,baseUrl:s};const r=document.getElementById("mygigsters-card-sdk-host");r?.parentNode&&r.parentNode.removeChild(r),this.api=new g(this.config.baseUrl),this.host=document.createElement("div"),this.host.id="mygigsters-card-sdk-host",this.host.style.cssText="display:block;position:fixed;top:0;left:0;right:0;bottom:0;width:100vw;height:100vh;z-index:2147483647;pointer-events:auto;",this.shadowRoot=this.host.attachShadow({mode:"closed"});const c=document.createElement("style");c.textContent=y,this.shadowRoot.appendChild(c);const n=document.createElement("div");n.id="mc-theme-container",n.setAttribute("data-theme",this.config.mode==="light"?"light":"dark"),this.shadowRoot.appendChild(n),document.body.appendChild(this.host),this.renderer=new b(this.shadowRoot,{onClose:()=>this.handleClose(),onSubmit:()=>this.handleSubmit()}),this.renderer.render(),this.isInitialized=!0,this.show(),window.addEventListener("keydown",this._handleKeyDown),await this.authenticate(),await this._initializeCard()}catch(e){throw this.renderer&&this.renderer.showInitError(e.message||"Initialization failed"),this.config?.onError&&this.config.onError(e),e}}_handleKeyDown(t){t.key==="Escape"&&this.isInitialized&&this.handleClose()}async authenticate(){try{console.info(`[MyGigsters Card SDK] Authenticating in "${this.config.env}" mode → ${this.config.baseUrl}`);const t=await this.api.authenticate(this.config.apiKey,this.config.apiSecret);this.authToken=t.token,this.airwallexClientId=t.clientId,t.expiresIn&&(this.tokenExpiresAt=Date.now()+t.expiresIn*1e3),console.info("[MyGigsters Card SDK] Authentication successful."),(this.config.env==="demo"||this.config.env==="dev")&&console.info(`â„šī¸ Connected to [${this.config.env.toUpperCase()}] backend.`)}catch(t){const e=t.message||"";throw e.includes("401")||e.toLowerCase().includes("unauthorized")?new Error("Invalid API credentials: Please check your apiKey and apiSecret."):new Error(`Authentication failed: ${e}`)}}handleClose(){const t=this.config?.onClose;if(this.destroy(),t)try{t()}catch(e){console.error("Error in onClose callback:",e)}}async handleSubmit(){if(!this.isSubmitting&&this.renderer.state.cardComplete){this.isSubmitting=!0,this.renderer.setSubmitting(!0),this.renderer.setError("");try{const e=(await p.createPaymentConsent({customer_id:this.config.customerId,client_secret:this.clientSecret,currency:"AUD",element:this.cardElement,requires_cvc:!1,next_triggered_by:"merchant"})).payment_consent_id;if(!e)throw new Error("Failed to create payment consent from card element");const i=this.config.apiKey&&this.config.apiSecret?`Basic ${btoa(`${this.config.apiKey}:${this.config.apiSecret}`)}`:this.authToken?`Bearer ${this.authToken}`:null,s={...await this.api.saveConsent(this.config.customerId,e,i),paymentConsentId:e,customerId:this.config.customerId,myGigsterId:this.config.myGigsterId,accountId:this.config.accountId,timestamp:new Date().toISOString(),event:"card.saved"};this.renderer.showSuccess(s),this.config?.onSuccess&&this.config.onSuccess(s)}catch(t){const e=t.message||"Payment could not be completed. Please check your card details and try again.";this.renderer.setError(e),this.renderer.setSubmitting(!1),this.config?.onError&&this.config.onError(t)}finally{this.isSubmitting=!1}}}async _initializeCard(){try{const t=this.config.apiKey&&this.config.apiSecret?`Basic ${btoa(`${this.config.apiKey}:${this.config.apiSecret}`)}`:this.authToken?`Bearer ${this.authToken}`:null,{clientSecret:e}=await this.api.getClientSecret(this.config.customerId,this.config.accountId,t);this.clientSecret=e,await p.loadAirwallex();const i={env:w[this.config.env]||"demo",origin:window.location.origin};this.airwallexClientId&&(i.clientId=this.airwallexClientId),p.init(i);const o=this.config.mode==="light",s={color:o?"#0f172a":"#ffffff",fontSize:"15px",fontFamily:'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',"::placeholder":{color:o?"#94a3b8":"rgba(255, 255, 255, 0.45)",fontSize:"15px"}},r=p.createElement("card",{style:{base:s}});this.cardElement=r,this.renderer.setCardLoaded(),await new Promise(n=>setTimeout(n,0));const c=this.shadowRoot.querySelector("#card-root");if(!c)throw new Error("Card mount point not found");try{r.mount(c)}catch{r.mount("#card-root")}this.renderer.markCardMounted(),r.on("change",n=>{const l=n?.detail?.complete||!1;this.renderer.setCardComplete(l)})}catch(t){const e=t.message||"Failed to load card elements";this.renderer.showInitError(e),this.config?.onError&&this.config.onError(t)}}show(){if(!this.isInitialized)throw new Error("SDK not initialized. Call init() first.");this.host&&(this.host.style.display="block",this.host.style.width="100vw",this.host.style.height="100vh",this.host.style.pointerEvents="auto")}hide(){this.host&&(this.host.style.display="none",this.host.style.width="0",this.host.style.height="0",this.host.style.pointerEvents="none")}setTheme(t){if(!this.shadowRoot)return;const e=this.shadowRoot.querySelector("#mc-theme-container");e&&e.setAttribute("data-theme",t==="light"?"light":"dark"),this.config&&(this.config.mode=t)}destroy(){if(window.removeEventListener("keydown",this._handleKeyDown),this.cardElement)try{this.cardElement.unmount()}catch{}this.renderer&&this.renderer.destroy(),this.host?.parentNode&&this.host.parentNode.removeChild(this.host);const t=document.getElementById("mygigsters-card-sdk-host");t?.parentNode&&t.parentNode.removeChild(t),this.isInitialized=!1,this.isSubmitting=!1,this.config=null,this.api=null,this.renderer=null,this.host=null,this.shadowRoot=null,this.cardElement=null,this.clientSecret=null,this.authToken=null,this.tokenExpiresAt=null,this.airwallexClientId=null}}let a=null;const u={init:async d=>(a&&(a.destroy(),a=null),a=new h,await a.init(d),a),show:()=>{a?.show()},hide:()=>{a?.hide()},destroy:()=>{a&&(a.destroy(),a=null)},setTheme:d=>{a?.setTheme(d)},getInstance:()=>a};typeof window<"u"&&(window.MygigstersCard=u,window.MygigstersCardSDK=h,document.addEventListener("DOMContentLoaded",()=>{const d=document.querySelector('script[data-mygigsters-config][src*="card-sdk"]');if(d)try{const t=JSON.parse(d.dataset.mygigstersConfig);window.MygigstersCard.init(t).catch(e=>{console.error("MyGigsters Card SDK auto-init failed:",e)})}catch(t){console.error("Failed to parse MyGigsters Card SDK config:",t)}}));typeof window<"u"&&(window.MygigstersCard=u,window.MygigstersCardSDK=h);exports.MygigstersCard=u;exports.MygigstersCardSDK=h;exports.default=h;