@mygigsters/card-sdk 1.0.1 → 1.0.3
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 +519 -646
- package/cdn/card-sdk-entry.js +1 -1
- package/cdn/card-sdk-entry.js.map +1 -1
- package/dist/index.cjs.js +133 -12
- package/dist/index.d.ts +40 -29
- package/dist/index.esm.js +352 -178
- package/dist/index.umd.js +130 -9
- package/index.d.ts +40 -29
- package/package.json +1 -1
package/dist/index.cjs.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const p=require("airwallex-payment-elements");class
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const p=require("airwallex-payment-elements");class y{constructor(t){this.baseUrl=t.replace(/\/+$/,"")}async _post(t,e,o=null,r={}){const i={"Content-Type":"application/json",...r};o&&(i.Authorization=o.startsWith("Basic ")||o.startsWith("Bearer ")?o:`Bearer ${o}`);const s=await fetch(`${this.baseUrl}/api/v1${t}`,{method:"POST",headers:i,body:JSON.stringify(e)}),n=await s.text();let a=null;if(n&&n.trim().length>0)try{a=JSON.parse(n)}catch{a=null}if(!s.ok){const l=a&&(a.message||a.error)||n||s.statusText||`HTTP ${s.status}`;throw new Error(l)}return a??{}}async _get(t,e=null,o={}){const r={"Content-Type":"application/json",...o};e&&(r.Authorization=e.startsWith("Basic ")||e.startsWith("Bearer ")?e:`Bearer ${e}`);const i=await fetch(`${this.baseUrl}/api/v1${t}`,{method:"GET",headers:r}),s=await i.text();let n=null;if(s&&s.trim().length>0)try{n=JSON.parse(s)}catch{n=null}if(!i.ok){const a=n&&(n.message||n.error)||s||i.statusText||`HTTP ${i.status}`;throw new Error(a)}return n??{}}async getClientSecret(t,e,o=null){console.log("🔐 CardAPI.getClientSecret()",{customerId:t,accountId:e,hasToken:!!o});const r=await this._post("/customer/client-secret",{customerId:t,accountId:e},o),i=r.client_secret||r.clientSecret||r?.data?.client_secret||r?.data?.clientSecret;if(!i)throw new Error("Failed to retrieve client secret from server");return{clientSecret:i}}async saveConsent(t,e,o=null){return this._post("/customer/save-consent",{customerId:t,paymentConsentId:e},o)}async profileDetails(t=null){console.log("👤 CardAPI.profileDetails() calling /client/profile",{hasToken:!!t});let e=null;try{e=await this._get("/client/profile",t)}catch(r){if(r.message&&(r.message.includes("405")||r.message.includes("Method Not Allowed")))e=await this._post("/client/profile",{},t);else throw r}const o=e?.data?.myGigsterId||e?.data?.mygigsterId||e?.accountId;if(!o)throw new Error("Failed to retrieve myGigsterId from profile API response");return{myGigsterId:o,data:e?.data||e,raw:e}}}const f={close:`<svg width="18" height="18" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
2
2
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.2" d="M6 18L18 6M6 6l12 12"/>
|
|
3
3
|
</svg>`,check:`<svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
|
|
4
4
|
<path stroke-linecap="round" stroke-linejoin="round" d="M20 6L9 17l-5-5"/>
|
|
5
|
-
</svg>`};class
|
|
5
|
+
</svg>`};class w{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
6
|
<div class="mc-backdrop" id="mc-backdrop">
|
|
7
7
|
<div class="mc-modal" id="mc-modal">
|
|
8
|
-
<button class="mc-close-btn" aria-label="Close" id="mc-close-btn" type="button">${
|
|
8
|
+
<button class="mc-close-btn" aria-label="Close" id="mc-close-btn" type="button">${f.close}</button>
|
|
9
9
|
|
|
10
10
|
<div class="mc-header">
|
|
11
11
|
<h1 class="mc-title">Card Details</h1>
|
|
@@ -38,17 +38,34 @@
|
|
|
38
38
|
</div>
|
|
39
39
|
</div>
|
|
40
40
|
</div>
|
|
41
|
-
`,this._attachListeners()}_attachListeners(){this.shadowRoot.querySelectorAll(".mc-close-btn, #mc-close-btn").forEach(
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
41
|
+
`,this._attachListeners()}_attachListeners(){this.shadowRoot.querySelectorAll(".mc-close-btn, #mc-close-btn").forEach(r=>{r.addEventListener("click",i=>{i.preventDefault(),i.stopPropagation(),this.callbacks.onClose()})});const e=this.shadowRoot.querySelector("#mc-backdrop")||this.shadowRoot.querySelector(".mc-backdrop");e&&e.addEventListener("click",r=>{r.target===e&&(r.preventDefault(),r.stopPropagation(),this.callbacks.onClose())});const o=this.shadowRoot.querySelector("#mc-submit-btn");o&&o.addEventListener("click",r=>{r.preventDefault(),r.stopPropagation(),this.callbacks.onSubmit()}),this.shadowRoot.addEventListener("click",r=>{const i=r.target;i&&(i.closest(".mc-close-btn")||i.closest("#mc-close-btn")||i.closest(".mc-dismiss-btn")||i.closest("#mc-dismiss-btn"))&&(r.preventDefault(),r.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"),o=this.shadowRoot.querySelector("#mc-submit-btn");t&&(t.style.display="none"),e&&(e.style.display="block"),o&&(o.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,e="Verification Failed"){this.state.loading=!1,this.state.error=t;const o=this.shadowRoot.querySelector(".mc-modal");if(!o)return;o.innerHTML=`
|
|
42
|
+
<button class="mc-close-btn" aria-label="Close" id="mc-close-btn" type="button">${f.close}</button>
|
|
43
|
+
|
|
44
|
+
<div class="mc-body">
|
|
45
|
+
<div class="mc-error-wrap">
|
|
46
|
+
<div class="mc-error-icon">
|
|
47
|
+
<svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2">
|
|
48
|
+
<circle cx="12" cy="12" r="10" stroke="#ef4444"/>
|
|
49
|
+
<line x1="12" y1="8" x2="12" y2="12" stroke="#ef4444"/>
|
|
50
|
+
<line x1="12" y1="16" x2="12.01" y2="16" stroke="#ef4444"/>
|
|
51
|
+
</svg>
|
|
52
|
+
</div>
|
|
53
|
+
<h2 class="mc-error-title">${this._escapeHtml(e)}</h2>
|
|
54
|
+
<div class="mc-error-detail">${this._escapeHtml(t)}</div>
|
|
55
|
+
<p class="mc-error-sub">SDK initialization has been blocked. Please verify your credentials and try again.</p>
|
|
56
|
+
<button class="mc-dismiss-btn" id="mc-dismiss-btn" type="button">Close</button>
|
|
45
57
|
</div>
|
|
46
|
-
|
|
47
|
-
|
|
58
|
+
</div>
|
|
59
|
+
|
|
60
|
+
<div class="mc-powered-by">
|
|
61
|
+
Powered by <a href="https://mygigsters.com.au" target="_blank" rel="noopener">MyGigsters</a>
|
|
62
|
+
</div>
|
|
63
|
+
`,o.querySelectorAll(".mc-close-btn, #mc-close-btn").forEach(i=>{i.addEventListener("click",s=>{s.preventDefault(),s.stopPropagation(),this.callbacks.onClose()})});const r=o.querySelector("#mc-dismiss-btn");r&&r.addEventListener("click",i=>{i.preventDefault(),i.stopPropagation(),this.callbacks.onClose()})}showSuccess(t){this.state.success=!0;const e=this.shadowRoot.querySelector(".mc-modal");e&&(e.innerHTML=`
|
|
64
|
+
<button class="mc-close-btn" aria-label="Close" id="mc-close-btn" type="button">${f.close}</button>
|
|
48
65
|
|
|
49
66
|
<div class="mc-body">
|
|
50
67
|
<div class="mc-success-wrap">
|
|
51
|
-
<div class="mc-success-icon">${
|
|
68
|
+
<div class="mc-success-icon">${f.check}</div>
|
|
52
69
|
<h2 class="mc-success-title">Card Saved Successfully</h2>
|
|
53
70
|
<p class="mc-success-sub">Your card details have been securely tokenized and saved.</p>
|
|
54
71
|
<button class="mc-done-btn" id="mc-done-btn" type="button">Done</button>
|
|
@@ -58,7 +75,7 @@
|
|
|
58
75
|
<div class="mc-powered-by">
|
|
59
76
|
Powered by <a href="https://mygigsters.com.au" target="_blank" rel="noopener">MyGigsters</a>
|
|
60
77
|
</div>
|
|
61
|
-
`,e.querySelectorAll(".mc-close-btn, #mc-close-btn").forEach(
|
|
78
|
+
`,e.querySelectorAll(".mc-close-btn, #mc-close-btn").forEach(o=>{o.addEventListener("click",r=>{r.preventDefault(),r.stopPropagation(),this.callbacks.onClose()})}),e.querySelector("#mc-done-btn")?.addEventListener("click",o=>{o.preventDefault(),o.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 x=`
|
|
62
79
|
/* ── Reset inside shadow DOM ───────────────────────────────────────────────── */
|
|
63
80
|
*, *::before, *::after {
|
|
64
81
|
box-sizing: border-box;
|
|
@@ -328,6 +345,79 @@
|
|
|
328
345
|
animation: mc-fade-in 0.2s ease;
|
|
329
346
|
}
|
|
330
347
|
|
|
348
|
+
/* ── Error state (init / verification failure) ─────────────────────────────── */
|
|
349
|
+
.mc-error-wrap {
|
|
350
|
+
text-align: center;
|
|
351
|
+
padding: 30px 20px 16px;
|
|
352
|
+
animation: mc-fade-in 0.3s ease;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
.mc-error-icon {
|
|
356
|
+
width: 56px;
|
|
357
|
+
height: 56px;
|
|
358
|
+
border-radius: 50%;
|
|
359
|
+
background: rgba(239, 68, 68, 0.15);
|
|
360
|
+
border: 2px solid rgba(239, 68, 68, 0.4);
|
|
361
|
+
display: flex;
|
|
362
|
+
align-items: center;
|
|
363
|
+
justify-content: center;
|
|
364
|
+
margin: 0 auto 16px;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
.mc-error-icon svg {
|
|
368
|
+
width: 28px;
|
|
369
|
+
height: 28px;
|
|
370
|
+
color: #ef4444;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
.mc-error-title {
|
|
374
|
+
font-size: 20px;
|
|
375
|
+
font-weight: 700;
|
|
376
|
+
color: #f8fafc;
|
|
377
|
+
margin: 0 0 8px;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
.mc-error-detail {
|
|
381
|
+
font-size: 13px;
|
|
382
|
+
color: #fca5a5;
|
|
383
|
+
background: rgba(239, 68, 68, 0.1);
|
|
384
|
+
border: 1px solid rgba(239, 68, 68, 0.25);
|
|
385
|
+
border-radius: 8px;
|
|
386
|
+
padding: 10px 14px;
|
|
387
|
+
margin: 0 0 12px;
|
|
388
|
+
word-break: break-word;
|
|
389
|
+
line-height: 1.45;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
.mc-error-sub {
|
|
393
|
+
font-size: 13px;
|
|
394
|
+
color: #94a3b8;
|
|
395
|
+
margin: 0 0 20px;
|
|
396
|
+
line-height: 1.4;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
.mc-dismiss-btn {
|
|
400
|
+
display: inline-flex;
|
|
401
|
+
align-items: center;
|
|
402
|
+
justify-content: center;
|
|
403
|
+
padding: 11px 36px;
|
|
404
|
+
background: #ef4444;
|
|
405
|
+
color: #fff;
|
|
406
|
+
border: none;
|
|
407
|
+
border-radius: 8px;
|
|
408
|
+
font-size: 14px;
|
|
409
|
+
font-weight: 600;
|
|
410
|
+
cursor: pointer;
|
|
411
|
+
font-family: inherit;
|
|
412
|
+
transition: all 0.2s ease;
|
|
413
|
+
box-shadow: 0 4px 12px rgba(239, 68, 68, 0.35);
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
.mc-dismiss-btn:hover {
|
|
417
|
+
background: #dc2626;
|
|
418
|
+
transform: translateY(-1px);
|
|
419
|
+
}
|
|
420
|
+
|
|
331
421
|
/* ── Success state ─────────────────────────────────────────────────────────── */
|
|
332
422
|
.mc-success-wrap {
|
|
333
423
|
text-align: center;
|
|
@@ -487,6 +577,37 @@
|
|
|
487
577
|
color: #dc2626;
|
|
488
578
|
}
|
|
489
579
|
|
|
580
|
+
[data-theme='light'] .mc-error-icon {
|
|
581
|
+
background: #fef2f2;
|
|
582
|
+
border-color: #fecaca;
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
[data-theme='light'] .mc-error-icon svg {
|
|
586
|
+
color: #dc2626;
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
[data-theme='light'] .mc-error-title {
|
|
590
|
+
color: #0f172a;
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
[data-theme='light'] .mc-error-detail {
|
|
594
|
+
background: #fff5f5;
|
|
595
|
+
border-color: #fed7d7;
|
|
596
|
+
color: #c53030;
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
[data-theme='light'] .mc-error-sub {
|
|
600
|
+
color: #64748b;
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
[data-theme='light'] .mc-dismiss-btn {
|
|
604
|
+
background: #dc2626;
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
[data-theme='light'] .mc-dismiss-btn:hover {
|
|
608
|
+
background: #b91c1c;
|
|
609
|
+
}
|
|
610
|
+
|
|
490
611
|
[data-theme='light'] .mc-success-icon {
|
|
491
612
|
background: #f0fdf4;
|
|
492
613
|
border-color: #bbf7d0;
|
|
@@ -515,4 +636,4 @@
|
|
|
515
636
|
[data-theme='light'] .mc-powered-by a:hover {
|
|
516
637
|
color: #4f46e5;
|
|
517
638
|
}
|
|
518
|
-
`,
|
|
639
|
+
`,b={dev:"http://localhost:5000",demo:"https://qa-payments.mygigsters.com.au",prod:"https://prod-payments.mygigsters.com.au"},v={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.token)throw new Error("token is required. Call GET /api/v1/client/me first to get the token, then pass it to MygigstersCard.init()");if(!t.customerId)throw new Error("customerId is required");if(!t.containerId)throw new Error("containerId is required");const e=t.myGigsterId||t.accountId;if(!e)throw new Error("myGigsterId is required. Pass myGigsterId returned by GET /api/v1/client/me");if(!document.getElementById(t.containerId))throw new Error(`Container element with ID '${t.containerId}' not found`);let r=t.env||"demo";if(r==="qa"&&(r="demo"),!b[r])throw new Error(`Unknown env "${r}". Use "dev", "demo", or "prod".`);const i=t.baseUrl||b[r];this.api=new y(i),this.authToken=t.token,this.config={mode:"dark",onSuccess:()=>{},onError:m=>console.error("MyGigsters Card SDK Error:",m),onClose:()=>{},...t,myGigsterId:e,accountId:e,env:r,baseUrl:i};const s=document.getElementById("mygigsters-card-sdk-host");s?.parentNode&&s.parentNode.removeChild(s),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 n=document.createElement("style");n.textContent=x,this.shadowRoot.appendChild(n);const a=document.createElement("div");a.id="mc-theme-container",a.setAttribute("data-theme",this.config.mode==="light"?"light":"dark"),this.shadowRoot.appendChild(a),document.body.appendChild(this.host),this.renderer=new w(this.shadowRoot,{onClose:()=>this.handleClose(),onSubmit:()=>this.handleSubmit()}),this.renderer.render(),this.isInitialized=!0,this.show(),window.addEventListener("keydown",this._handleKeyDown);const l=this.authToken?`Bearer ${this.authToken}`:null;console.info("[MyGigsters Card SDK] Verifying myGigsterId via profileDetails API...");const g=(await this.api.profileDetails(l))?.myGigsterId;if(!g)throw new Error("Verification failed: Profile API response did not contain a valid myGigsterId.");if(String(g).trim()!==String(e).trim()){const m=new Error("Security check failed: The provided myGigsterId does not match the authenticated client profile. SDK initialization blocked.");throw m.code="MYGIGSTER_ID_MISMATCH",m}console.info("[MyGigsters Card SDK] myGigsterId verified successfully."),console.info(`[MyGigsters Card SDK] Initialized in "${r}" mode → ${i}`),await this._initializeCard()}catch(e){if(this.renderer){const o=e.code==="MYGIGSTER_ID_MISMATCH"?"Security Verification Failed":"Initialization Failed";this.renderer.showInitError(e.message||"Initialization failed",o)}throw this.config?.onError&&this.config.onError(e),e}}_handleKeyDown(t){t.key==="Escape"&&this.isInitialized&&this.handleClose()}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 o=this.authToken?`Bearer ${this.authToken}`:null,i={...await this.api.saveConsent(this.config.customerId,e,o),paymentConsentId:e,customerId:this.config.customerId,myGigsterId:this.config.myGigsterId,accountId:this.config.accountId,timestamp:new Date().toISOString(),event:"card.saved"};this.renderer.showSuccess(i),this.config?.onSuccess&&this.config.onSuccess(i)}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.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 o={env:v[this.config.env]||"demo",origin:window.location.origin};this.airwallexClientId&&(o.clientId=this.airwallexClientId),p.init(o);const r=this.config.mode==="light",i={color:r?"#0f172a":"#ffffff",fontSize:"15px",fontFamily:'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',"::placeholder":{color:r?"#94a3b8":"rgba(255, 255, 255, 0.45)",fontSize:"15px"}},s=p.createElement("card",{style:{base:i}});this.cardElement=s,this.renderer.setCardLoaded(),await new Promise(a=>setTimeout(a,0));const n=this.shadowRoot.querySelector("#card-root");if(!n)throw new Error("Card mount point not found");try{s.mount(n)}catch{s.mount("#card-root")}this.renderer.markCardMounted(),s.on("change",a=>{const l=a?.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 c=null;const u={init:async d=>(c&&(c.destroy(),c=null),c=new h,await c.init(d),c),show:()=>{c?.show()},hide:()=>{c?.hide()},destroy:()=>{c&&(c.destroy(),c=null)},setTheme:d=>{c?.setTheme(d)},getInstance:()=>c};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;
|
package/dist/index.d.ts
CHANGED
|
@@ -27,18 +27,11 @@ export interface CardSuccessResponse {
|
|
|
27
27
|
|
|
28
28
|
export interface MygigstersCardConfig {
|
|
29
29
|
/**
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
* Example: "
|
|
30
|
+
* Bearer token obtained by calling GET /api/v1/client/me with your API credentials.
|
|
31
|
+
* Do this ONCE on your server/frontend; never pass apiKey/apiSecret to the SDK.
|
|
32
|
+
* Example: "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
|
|
33
33
|
*/
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Your MyGigsters API Secret.
|
|
38
|
-
* Required for authentication.
|
|
39
|
-
* Example: "HUdxQCCrOFuF9fSkQRbd"
|
|
40
|
-
*/
|
|
41
|
-
apiSecret: string;
|
|
34
|
+
token: string;
|
|
42
35
|
|
|
43
36
|
/**
|
|
44
37
|
* ID of the DOM element container where the SDK is mounted or validated.
|
|
@@ -47,29 +40,29 @@ export interface MygigstersCardConfig {
|
|
|
47
40
|
containerId: string;
|
|
48
41
|
|
|
49
42
|
/**
|
|
50
|
-
* Customer ID for whom the card will be saved.
|
|
43
|
+
* Airwallex Customer ID for whom the card will be saved.
|
|
51
44
|
* Required.
|
|
52
45
|
* Example: "cus_hkdmcdjshhknkk4lc2t"
|
|
53
46
|
*/
|
|
54
47
|
customerId: string;
|
|
55
48
|
|
|
56
49
|
/**
|
|
57
|
-
* MyGigster ID
|
|
50
|
+
* MyGigster ID returned by GET /api/v1/client/me (data.myGigsterId).
|
|
58
51
|
* Either `myGigsterId` or `accountId` is required.
|
|
59
|
-
* Example: "
|
|
52
|
+
* Example: "3943e1fd-b685-4d1f-b537-ce896520c66c"
|
|
60
53
|
*/
|
|
61
54
|
myGigsterId?: string;
|
|
62
55
|
|
|
63
56
|
/**
|
|
64
57
|
* Account ID for whom the payment consent is created (Legacy alias for myGigsterId).
|
|
65
|
-
* Example: "
|
|
58
|
+
* Example: "3943e1fd-b685-4d1f-b537-ce896520c66c"
|
|
66
59
|
*/
|
|
67
60
|
accountId?: string;
|
|
68
61
|
|
|
69
62
|
/**
|
|
70
63
|
* Target environment.
|
|
71
|
-
* - '
|
|
72
|
-
* - '
|
|
64
|
+
* - 'dev': Development server (localhost:5000 for local testing)
|
|
65
|
+
* - 'demo': Demo server / QA (https://qa-payments.mygigsters.com.au) [Default]
|
|
73
66
|
* - 'prod': Production server (https://prod-payments.mygigsters.com.au)
|
|
74
67
|
* @default 'demo'
|
|
75
68
|
*/
|
|
@@ -128,17 +121,26 @@ export class MygigstersCardSDK {
|
|
|
128
121
|
/**
|
|
129
122
|
* Initialize the Card SDK and display the single-step Card Details modal.
|
|
130
123
|
*
|
|
124
|
+
* IMPORTANT: Call GET /api/v1/client/me FIRST (with Basic Auth) to get the token.
|
|
125
|
+
* Then pass that token + myGigsterId here. Never pass apiKey/apiSecret to the SDK.
|
|
126
|
+
*
|
|
131
127
|
* @example
|
|
132
128
|
* ```ts
|
|
129
|
+
* // Step 1: Get token from /client/me once (on your server or frontend)
|
|
130
|
+
* const res = await fetch('http://localhost:5000/api/v1/client/me', {
|
|
131
|
+
* headers: { Authorization: 'Basic ' + btoa('apiKey:apiSecret') }
|
|
132
|
+
* });
|
|
133
|
+
* const { data } = await res.json();
|
|
134
|
+
*
|
|
135
|
+
* // Step 2: Pass token to SDK — no credentials needed again
|
|
133
136
|
* const sdk = new MygigstersCardSDK();
|
|
134
137
|
* await sdk.init({
|
|
135
138
|
* containerId: "card-mount",
|
|
136
|
-
*
|
|
137
|
-
* apiSecret: "HUdxQCCrOFuF9fSkQRbd",
|
|
139
|
+
* token: data.token,
|
|
138
140
|
* customerId: "cus_hkdmcdjshhknkk4lc2t",
|
|
139
|
-
* myGigsterId:
|
|
140
|
-
* env: "
|
|
141
|
-
* mode: "
|
|
141
|
+
* myGigsterId: data.myGigsterId,
|
|
142
|
+
* env: "dev",
|
|
143
|
+
* mode: "dark",
|
|
142
144
|
* onSuccess: (res) => console.log("Card saved!", res),
|
|
143
145
|
* onError: (err) => console.error("Error:", err),
|
|
144
146
|
* onClose: () => console.log("Modal closed")
|
|
@@ -172,18 +174,27 @@ export interface MygigstersCardGlobal {
|
|
|
172
174
|
/**
|
|
173
175
|
* Initialize the singleton Card SDK instance and display the single-step Card Details modal.
|
|
174
176
|
*
|
|
177
|
+
* IMPORTANT: Call GET /api/v1/client/me FIRST (with Basic Auth) to get the token.
|
|
178
|
+
* Then pass that token + myGigsterId here. No apiKey/apiSecret needed in the SDK.
|
|
179
|
+
*
|
|
175
180
|
* @example
|
|
176
181
|
* ```js
|
|
177
|
-
*
|
|
182
|
+
* // Step 1: Call /client/me once to get token
|
|
183
|
+
* const res = await fetch('http://localhost:5000/api/v1/client/me', {
|
|
184
|
+
* headers: { Authorization: 'Basic ' + btoa('apiKey:apiSecret') }
|
|
185
|
+
* });
|
|
186
|
+
* const { data } = await res.json();
|
|
187
|
+
*
|
|
188
|
+
* // Step 2: Pass token + myGigsterId directly — no credentials needed again
|
|
189
|
+
* await MygigstersCard.init({
|
|
178
190
|
* containerId: "card-mount",
|
|
179
|
-
*
|
|
180
|
-
* apiSecret: "HUdxQCCrOFuF9fSkQRbd",
|
|
191
|
+
* token: data.token,
|
|
181
192
|
* customerId: "cus_hkdmcdjshhknkk4lc2t",
|
|
182
|
-
* myGigsterId:
|
|
183
|
-
* env: "
|
|
193
|
+
* myGigsterId: data.myGigsterId,
|
|
194
|
+
* env: "dev",
|
|
184
195
|
* mode: "dark",
|
|
185
|
-
* onSuccess: (res) => console.log("Card saved!", res),
|
|
186
|
-
* onError: (err) => console.error("Error:", err),
|
|
196
|
+
* onSuccess: (res) => console.log("Card saved!", res.paymentConsentId),
|
|
197
|
+
* onError: (err) => console.error("Card SDK Error:", err),
|
|
187
198
|
* onClose: () => console.log("Modal closed")
|
|
188
199
|
* });
|
|
189
200
|
* ```
|