recur-tw 0.7.2 → 0.7.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +9 -6
- package/dist/index.js +9 -6
- package/dist/recur.umd.js +15 -11
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1220,7 +1220,6 @@ var init_payment_form = __esm({
|
|
|
1220
1220
|
render() {
|
|
1221
1221
|
this.shadowRoot.innerHTML = `
|
|
1222
1222
|
<style>
|
|
1223
|
-
/* \u9019\u4E9B\u6A23\u5F0F\u88AB\u9694\u96E2\u5728 Shadow DOM \u5167\uFF0C\u4E0D\u6703\u5F71\u97FF\u5916\u90E8 */
|
|
1224
1223
|
:host {
|
|
1225
1224
|
display: block;
|
|
1226
1225
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
@@ -1594,12 +1593,16 @@ var init_payment_form = __esm({
|
|
|
1594
1593
|
.recur-payuni-iframe {
|
|
1595
1594
|
height: 36px;
|
|
1596
1595
|
width: 100%;
|
|
1596
|
+
max-width: 100%;
|
|
1597
|
+
box-sizing: border-box;
|
|
1597
1598
|
}
|
|
1598
1599
|
|
|
1599
1600
|
.recur-card-row {
|
|
1600
1601
|
display: grid;
|
|
1601
1602
|
grid-template-columns: 1fr 1fr;
|
|
1602
1603
|
gap: 12px;
|
|
1604
|
+
max-width: 100%;
|
|
1605
|
+
box-sizing: border-box;
|
|
1603
1606
|
}
|
|
1604
1607
|
|
|
1605
1608
|
/* Container needs relative positioning for skeleton overlay */
|
|
@@ -1699,6 +1702,7 @@ var init_payment_form = __esm({
|
|
|
1699
1702
|
align-items: center;
|
|
1700
1703
|
justify-content: center;
|
|
1701
1704
|
gap: 8px;
|
|
1705
|
+
box-sizing: border-box;
|
|
1702
1706
|
}
|
|
1703
1707
|
|
|
1704
1708
|
.recur-submit-button:hover:not(:disabled) {
|
|
@@ -2646,7 +2650,11 @@ function RecurProvider({ children, config: initialConfig = {} }) {
|
|
|
2646
2650
|
width: 90%;
|
|
2647
2651
|
max-height: 90vh;
|
|
2648
2652
|
overflow-y: auto;
|
|
2653
|
+
overflow-x: hidden;
|
|
2649
2654
|
position: relative;
|
|
2655
|
+
border-radius: 12px;
|
|
2656
|
+
background: white;
|
|
2657
|
+
box-shadow: 0 4px 24px rgba(0, 0, 0, 0.15);
|
|
2650
2658
|
`;
|
|
2651
2659
|
const closeButton = document.createElement("button");
|
|
2652
2660
|
closeButton.className = "recur-sdk__close-button";
|
|
@@ -2684,11 +2692,6 @@ function RecurProvider({ children, config: initialConfig = {} }) {
|
|
|
2684
2692
|
loadingContainer = document.createElement("div");
|
|
2685
2693
|
loadingContainer.id = "recur-modal-loading";
|
|
2686
2694
|
loadingContainer.className = "recur-sdk__loading-container";
|
|
2687
|
-
loadingContainer.style.cssText = `
|
|
2688
|
-
background: white;
|
|
2689
|
-
border-radius: 12px;
|
|
2690
|
-
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
2691
|
-
`;
|
|
2692
2695
|
const skeleton = document.createElement("recur-payment-form-skeleton");
|
|
2693
2696
|
loadingContainer.appendChild(skeleton);
|
|
2694
2697
|
modalContent.appendChild(closeButton);
|
package/dist/index.js
CHANGED
|
@@ -1214,7 +1214,6 @@ var init_payment_form = __esm({
|
|
|
1214
1214
|
render() {
|
|
1215
1215
|
this.shadowRoot.innerHTML = `
|
|
1216
1216
|
<style>
|
|
1217
|
-
/* \u9019\u4E9B\u6A23\u5F0F\u88AB\u9694\u96E2\u5728 Shadow DOM \u5167\uFF0C\u4E0D\u6703\u5F71\u97FF\u5916\u90E8 */
|
|
1218
1217
|
:host {
|
|
1219
1218
|
display: block;
|
|
1220
1219
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
@@ -1588,12 +1587,16 @@ var init_payment_form = __esm({
|
|
|
1588
1587
|
.recur-payuni-iframe {
|
|
1589
1588
|
height: 36px;
|
|
1590
1589
|
width: 100%;
|
|
1590
|
+
max-width: 100%;
|
|
1591
|
+
box-sizing: border-box;
|
|
1591
1592
|
}
|
|
1592
1593
|
|
|
1593
1594
|
.recur-card-row {
|
|
1594
1595
|
display: grid;
|
|
1595
1596
|
grid-template-columns: 1fr 1fr;
|
|
1596
1597
|
gap: 12px;
|
|
1598
|
+
max-width: 100%;
|
|
1599
|
+
box-sizing: border-box;
|
|
1597
1600
|
}
|
|
1598
1601
|
|
|
1599
1602
|
/* Container needs relative positioning for skeleton overlay */
|
|
@@ -1693,6 +1696,7 @@ var init_payment_form = __esm({
|
|
|
1693
1696
|
align-items: center;
|
|
1694
1697
|
justify-content: center;
|
|
1695
1698
|
gap: 8px;
|
|
1699
|
+
box-sizing: border-box;
|
|
1696
1700
|
}
|
|
1697
1701
|
|
|
1698
1702
|
.recur-submit-button:hover:not(:disabled) {
|
|
@@ -2640,7 +2644,11 @@ function RecurProvider({ children, config: initialConfig = {} }) {
|
|
|
2640
2644
|
width: 90%;
|
|
2641
2645
|
max-height: 90vh;
|
|
2642
2646
|
overflow-y: auto;
|
|
2647
|
+
overflow-x: hidden;
|
|
2643
2648
|
position: relative;
|
|
2649
|
+
border-radius: 12px;
|
|
2650
|
+
background: white;
|
|
2651
|
+
box-shadow: 0 4px 24px rgba(0, 0, 0, 0.15);
|
|
2644
2652
|
`;
|
|
2645
2653
|
const closeButton = document.createElement("button");
|
|
2646
2654
|
closeButton.className = "recur-sdk__close-button";
|
|
@@ -2678,11 +2686,6 @@ function RecurProvider({ children, config: initialConfig = {} }) {
|
|
|
2678
2686
|
loadingContainer = document.createElement("div");
|
|
2679
2687
|
loadingContainer.id = "recur-modal-loading";
|
|
2680
2688
|
loadingContainer.className = "recur-sdk__loading-container";
|
|
2681
|
-
loadingContainer.style.cssText = `
|
|
2682
|
-
background: white;
|
|
2683
|
-
border-radius: 12px;
|
|
2684
|
-
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
2685
|
-
`;
|
|
2686
2689
|
const skeleton = document.createElement("recur-payment-form-skeleton");
|
|
2687
2690
|
loadingContainer.appendChild(skeleton);
|
|
2688
2691
|
modalContent.appendChild(closeButton);
|
package/dist/recur.umd.js
CHANGED
|
@@ -644,7 +644,7 @@
|
|
|
644
644
|
<p class="security-text">\u60A8\u7684\u4ED8\u6B3E\u8CC7\u8A0A\u7D93\u904E\u52A0\u5BC6\u4FDD\u8B77</p>
|
|
645
645
|
</div>
|
|
646
646
|
</div>
|
|
647
|
-
`}};typeof window<"u"&&!customElements.get("recur-payment-form-skeleton")&&customElements.define("recur-payment-form-skeleton",L)});var re={};f(re,{RecurToast:()=>M,RecurToastContainer:()=>
|
|
647
|
+
`}};typeof window<"u"&&!customElements.get("recur-payment-form-skeleton")&&customElements.define("recur-payment-form-skeleton",L)});var re={};f(re,{RecurToast:()=>M,RecurToastContainer:()=>w});var M,g,w,ie=b(()=>{"use strict";M=class extends HTMLElement{static get observedAttributes(){return["message","type","duration"]}constructor(){super(),this.attachShadow({mode:"open"})}connectedCallback(){this.render(),this.setupAutoDismiss()}get message(){return this.getAttribute("message")||"Notification"}get type(){let e=this.getAttribute("type");return e==="success"||e==="error"?e:"info"}get duration(){let e=this.getAttribute("duration");return e?parseInt(e,10):5e3}setupAutoDismiss(){let e=this.duration;e>0&&setTimeout(()=>this.dismiss(),e)}dismiss(){this.style.animation="recur-toast-slide-out 0.3s ease-in-out",setTimeout(()=>this.remove(),300)}getTypeIcon(){switch(this.type){case"success":return`<svg width="20" height="20" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
648
648
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
|
|
649
649
|
</svg>`;case"error":return`<svg width="20" height="20" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
650
650
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
|
|
@@ -764,7 +764,7 @@
|
|
|
764
764
|
</svg>
|
|
765
765
|
</button>
|
|
766
766
|
</div>
|
|
767
|
-
`,this.shadowRoot.querySelector(".toast-close")?.addEventListener("click",i=>{i.stopPropagation(),this.dismiss()}),this.shadowRoot.querySelector(".toast")?.addEventListener("click",()=>this.dismiss())}static show(e,t="info",r=5e3){let i=
|
|
767
|
+
`,this.shadowRoot.querySelector(".toast-close")?.addEventListener("click",i=>{i.stopPropagation(),this.dismiss()}),this.shadowRoot.querySelector(".toast")?.addEventListener("click",()=>this.dismiss())}static show(e,t="info",r=5e3){let i=w.getInstance(),s=document.createElement("recur-toast");return s.setAttribute("message",e),s.setAttribute("type",t),s.setAttribute("duration",r.toString()),i.appendChild(s),s}},g=class g extends HTMLElement{constructor(){super(),this.attachShadow({mode:"open"})}connectedCallback(){this.render()}render(){this.shadowRoot.innerHTML=`
|
|
768
768
|
<style>
|
|
769
769
|
:host {
|
|
770
770
|
position: fixed;
|
|
@@ -791,9 +791,8 @@
|
|
|
791
791
|
</style>
|
|
792
792
|
|
|
793
793
|
<slot></slot>
|
|
794
|
-
`}static getInstance(){return g.instance||(g.instance=document.querySelector("recur-toast-container"),g.instance||(g.instance=document.createElement("recur-toast-container"),document.body.appendChild(g.instance))),g.instance}};a(g,"instance",null);
|
|
794
|
+
`}static getInstance(){return g.instance||(g.instance=document.querySelector("recur-toast-container"),g.instance||(g.instance=document.createElement("recur-toast-container"),document.body.appendChild(g.instance))),g.instance}};a(g,"instance",null);w=g;typeof window<"u"&&!customElements.get("recur-toast")&&customElements.define("recur-toast",M);typeof window<"u"&&!customElements.get("recur-toast-container")&&customElements.define("recur-toast-container",w)});var se={};f(se,{RecurPaymentForm:()=>U});var U,oe=b(()=>{"use strict";U=class extends HTMLElement{constructor(){super();a(this,"containerId");a(this,"customStyles");a(this,"_isInitializing",!1);a(this,"_initializationAborted",!1);this.containerId=this.getAttribute("container-id")||`recur-${Date.now()}`,this.customStyles=this.getAttribute("custom-styles")||"",this.attachShadow({mode:"open"})}connectedCallback(){this.render()}disconnectedCallback(){console.log("[PaymentForm] Component disconnected, cleaning up..."),this._initializationAborted=!0,this._paymentSession=null;let t=document.getElementById(`${this.containerId}-submit-btn`);if(t){let r=t.cloneNode(!0);t.parentNode?.replaceChild(r,t)}}static get observedAttributes(){return["custom-styles","customer-name","customer-email","plan-name","amount","billing-period"]}attributeChangedCallback(t,r,i){t==="custom-styles"&&r!==i?(this.customStyles=i||"",this.updateCustomStyles()):r!==i&&this.updateCustomerInfoSection()}render(){this.shadowRoot.innerHTML=`
|
|
795
795
|
<style>
|
|
796
|
-
/* \u9019\u4E9B\u6A23\u5F0F\u88AB\u9694\u96E2\u5728 Shadow DOM \u5167\uFF0C\u4E0D\u6703\u5F71\u97FF\u5916\u90E8 */
|
|
797
796
|
:host {
|
|
798
797
|
display: block;
|
|
799
798
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
@@ -1097,12 +1096,16 @@
|
|
|
1097
1096
|
.recur-payuni-iframe {
|
|
1098
1097
|
height: 36px;
|
|
1099
1098
|
width: 100%;
|
|
1099
|
+
max-width: 100%;
|
|
1100
|
+
box-sizing: border-box;
|
|
1100
1101
|
}
|
|
1101
1102
|
|
|
1102
1103
|
.recur-card-row {
|
|
1103
1104
|
display: grid;
|
|
1104
1105
|
grid-template-columns: 1fr 1fr;
|
|
1105
1106
|
gap: 12px;
|
|
1107
|
+
max-width: 100%;
|
|
1108
|
+
box-sizing: border-box;
|
|
1106
1109
|
}
|
|
1107
1110
|
|
|
1108
1111
|
/* Container needs relative positioning for skeleton overlay */
|
|
@@ -1180,6 +1183,7 @@
|
|
|
1180
1183
|
align-items: center;
|
|
1181
1184
|
justify-content: center;
|
|
1182
1185
|
gap: 8px;
|
|
1186
|
+
box-sizing: border-box;
|
|
1183
1187
|
}
|
|
1184
1188
|
|
|
1185
1189
|
.recur-submit-button:hover:not(:disabled) {
|
|
@@ -1523,14 +1527,14 @@
|
|
|
1523
1527
|
display: block;
|
|
1524
1528
|
user-select: none;
|
|
1525
1529
|
transition: height 0.35s ease, opacity 0.4s ease 0.1s;
|
|
1526
|
-
`.replace(/\s+/g," ").trim(),this.iframe.allow="payment *",this.iframe.setAttribute("title","Secure payment input frame"),this.iframe.setAttribute("role","presentation"),this.iframe.setAttribute("scrolling","no"),this.iframe.setAttribute("frameBorder","0"),this.container.innerHTML="",this.container.appendChild(this.iframe),new Promise((r,i)=>{let s=setTimeout(()=>{i(new Error("Elements initialization timeout"))},3e4),n=()=>{clearTimeout(s),this.off("ready",n),r()},o=l=>{clearTimeout(s),this.off("error",o),i(new Error(l.message||"Elements initialization failed"))};this.on("ready",n),this.on("error",o)})}on(e,t){this.eventHandlers.has(e)||this.eventHandlers.set(e,new Set),this.eventHandlers.get(e).add(t)}off(e,t){let r=this.eventHandlers.get(e);r&&r.delete(t)}emit(e,t){let r=this.eventHandlers.get(e);r&&r.forEach(i=>i(t))}handleMessage(e){if(!this.isValidOrigin(e.origin))return;let{type:t,data:r}=e.data||{};switch(t){case"RECUR_ELEMENTS_READY":this.sessionId=r.sessionId,this.timestamp=r.timestamp,this.creditToken=r.creditToken,this.emit("ready",r);break;case"RECUR_CARD_VALID":this.emit("change",{valid:r.valid});break;case"RECUR_CARD_TOKENIZED":this.cardToken=r.cardToken,this.cardTimestamp=r.timestamp,this.emit("tokenized",r);break;case"RECUR_PAYMENT_ERROR":this.emit("error",r);break;case"RECUR_RESIZE":this.iframe&&r?.height&&(this.iframe.style.height=`${r.height}px`);break}}isValidOrigin(e){try{let t=new URL(this.embedUrl).origin;return e===t}catch{return!1}}async tokenize(){if(!this.iframe||!this.iframe.contentWindow)throw new Error("Elements not mounted");let e=new URL(this.embedUrl).origin;return this.iframe.contentWindow.postMessage({type:"RECUR_TOKENIZE"},e),new Promise((t,r)=>{let i=setTimeout(()=>{r(new Error("Tokenization timeout"))},6e4),s=o=>{clearTimeout(i),this.off("tokenized",s),t(o)},n=o=>{clearTimeout(i),this.off("error",n),r(new Error(o.message||"Tokenization failed"))};this.on("tokenized",s),this.on("error",n)})}async confirmPayment(e){if(!this.sessionId||!this.cardToken)throw new Error("Card not tokenized. Call tokenize() first.");let t=await fetch(`${this.baseUrl}/api/v1/elements/confirm`,{method:"POST",headers:{"Content-Type":"application/json","X-Recur-Publishable-Key":this.publishableKey},body:JSON.stringify({sessionId:this.sessionId,sdkToken:this.cardToken,timestamp:this.cardTimestamp,creditToken:this.creditToken,productId:e.productId,email:e.email,name:e.name,metadata:e.metadata})}),r=await t.json();return t.ok?r:{status:"failed",message:r.error||r.message||"Payment failed",canRetry:r.canRetry??!0}}getDefaultBaseUrl(){if(typeof window>"u")return"https://app.recur.tw";let e=window.location.hostname;return e==="localhost"||e.includes(".test")||e.includes(".local")||e==="127.0.0.1"?`${window.location.protocol}//${e}:3000`:"https://app.recur.tw"}getDefaultEmbedUrl(){if(typeof window>"u")return"https://embed.recur.tw";let e=window.location.hostname;return e==="localhost"||e.includes(".test")||e.includes(".local")||e==="127.0.0.1"?`${window.location.protocol}//${e}:3002`:"https://embed.recur.tw"}destroy(){this.iframe&&this.iframe.parentNode&&this.iframe.parentNode.removeChild(this.iframe),this.iframe=null,this.container=null,this.sessionId=null,this.timestamp=null,this.creditToken=null,this.cardToken=null,this.cardTimestamp=null,this.eventHandlers.clear(),window.removeEventListener("message",this.handleMessage.bind(this))}};function K(c){return new k(c)}var
|
|
1530
|
+
`.replace(/\s+/g," ").trim(),this.iframe.allow="payment *",this.iframe.setAttribute("title","Secure payment input frame"),this.iframe.setAttribute("role","presentation"),this.iframe.setAttribute("scrolling","no"),this.iframe.setAttribute("frameBorder","0"),this.container.innerHTML="",this.container.appendChild(this.iframe),new Promise((r,i)=>{let s=setTimeout(()=>{i(new Error("Elements initialization timeout"))},3e4),n=()=>{clearTimeout(s),this.off("ready",n),r()},o=l=>{clearTimeout(s),this.off("error",o),i(new Error(l.message||"Elements initialization failed"))};this.on("ready",n),this.on("error",o)})}on(e,t){this.eventHandlers.has(e)||this.eventHandlers.set(e,new Set),this.eventHandlers.get(e).add(t)}off(e,t){let r=this.eventHandlers.get(e);r&&r.delete(t)}emit(e,t){let r=this.eventHandlers.get(e);r&&r.forEach(i=>i(t))}handleMessage(e){if(!this.isValidOrigin(e.origin))return;let{type:t,data:r}=e.data||{};switch(t){case"RECUR_ELEMENTS_READY":this.sessionId=r.sessionId,this.timestamp=r.timestamp,this.creditToken=r.creditToken,this.emit("ready",r);break;case"RECUR_CARD_VALID":this.emit("change",{valid:r.valid});break;case"RECUR_CARD_TOKENIZED":this.cardToken=r.cardToken,this.cardTimestamp=r.timestamp,this.emit("tokenized",r);break;case"RECUR_PAYMENT_ERROR":this.emit("error",r);break;case"RECUR_RESIZE":this.iframe&&r?.height&&(this.iframe.style.height=`${r.height}px`);break}}isValidOrigin(e){try{let t=new URL(this.embedUrl).origin;return e===t}catch{return!1}}async tokenize(){if(!this.iframe||!this.iframe.contentWindow)throw new Error("Elements not mounted");let e=new URL(this.embedUrl).origin;return this.iframe.contentWindow.postMessage({type:"RECUR_TOKENIZE"},e),new Promise((t,r)=>{let i=setTimeout(()=>{r(new Error("Tokenization timeout"))},6e4),s=o=>{clearTimeout(i),this.off("tokenized",s),t(o)},n=o=>{clearTimeout(i),this.off("error",n),r(new Error(o.message||"Tokenization failed"))};this.on("tokenized",s),this.on("error",n)})}async confirmPayment(e){if(!this.sessionId||!this.cardToken)throw new Error("Card not tokenized. Call tokenize() first.");let t=await fetch(`${this.baseUrl}/api/v1/elements/confirm`,{method:"POST",headers:{"Content-Type":"application/json","X-Recur-Publishable-Key":this.publishableKey},body:JSON.stringify({sessionId:this.sessionId,sdkToken:this.cardToken,timestamp:this.cardTimestamp,creditToken:this.creditToken,productId:e.productId,email:e.email,name:e.name,metadata:e.metadata})}),r=await t.json();return t.ok?r:{status:"failed",message:r.error||r.message||"Payment failed",canRetry:r.canRetry??!0}}getDefaultBaseUrl(){if(typeof window>"u")return"https://app.recur.tw";let e=window.location.hostname;return e==="localhost"||e.includes(".test")||e.includes(".local")||e==="127.0.0.1"?`${window.location.protocol}//${e}:3000`:"https://app.recur.tw"}getDefaultEmbedUrl(){if(typeof window>"u")return"https://embed.recur.tw";let e=window.location.hostname;return e==="localhost"||e.includes(".test")||e.includes(".local")||e==="127.0.0.1"?`${window.location.protocol}//${e}:3002`:"https://embed.recur.tw"}destroy(){this.iframe&&this.iframe.parentNode&&this.iframe.parentNode.removeChild(this.iframe),this.iframe=null,this.container=null,this.sessionId=null,this.timestamp=null,this.creditToken=null,this.cardToken=null,this.cardTimestamp=null,this.eventHandlers.clear(),window.removeEventListener("message",this.handleMessage.bind(this))}};function K(c){return new k(c)}var xe="https://vendor.payuni.com.tw/sdk/uni-payment.js",we="https://sandbox-vendor.payuni.com.tw/sdk/uni-payment.js",de=!1,H=!1,E=null;async function ue(c=!1){return de&&window.UniPayment?Promise.resolve():(H&&E||(H=!0,E=new Promise((e,t)=>{let r=document.createElement("script");r.src=c?we:xe,r.async=!0,r.onload=()=>{de=!0,H=!1,e()},r.onerror=()=>{H=!1,E=null,t(new Error("Failed to load PAYUNi SDK"))},document.head.appendChild(r)})),E)}var S=class{constructor(e){a(this,"core");a(this,"currentModal",null);a(this,"currentIframe",null);a(this,"currentModalOverlay",null);this.core=new D(e)}async fetchProducts(e){return await this.core.fetchProducts(e)}async fetchPlans(){return await this.core.fetchPlans()}async createEmbeddedCheckout(e){let t=this.core.getConfig();await new z(t,e).render()}async redirectToCheckout(e){let t=this.core.getConfig(),r=()=>{if(typeof window<"u"){let l=window.location.hostname;if(l==="localhost"||l.includes(".test")||l.includes(".local")||l==="127.0.0.1")return`${window.location.protocol}//${window.location.host}/api`}return"https://api.recur.tw"},i=t.baseUrl||r();if(!e.productId&&!e.productSlug)throw new Error("Either productId or productSlug is required");let s={successUrl:e.successUrl,cancelUrl:e.cancelUrl};e.productId&&(s.productId=e.productId),e.productSlug&&(s.productSlug=e.productSlug),e.mode&&(s.mode=e.mode),e.customerEmail&&(s.customerEmail=e.customerEmail),e.customerName&&(s.customerName=e.customerName),e.externalCustomerId&&(s.externalCustomerId=e.externalCustomerId);let n=await fetch(`${i}/v1/checkout/sessions`,{method:"POST",headers:{"Content-Type":"application/json","X-Recur-Publishable-Key":t.publishableKey},body:JSON.stringify(s)});if(!n.ok){let l=await n.json().catch(()=>({}));throw new Error(l.error?.message||"Failed to create checkout session")}let o=await n.json();window.location.href=o.url}async createCheckoutSession(e){let t=this.core.getConfig(),r=()=>{if(typeof window<"u"){let o=window.location.hostname;if(o==="localhost"||o.includes(".test")||o.includes(".local")||o==="127.0.0.1")return`${window.location.protocol}//${window.location.host}/api`}return"https://api.recur.tw"},i=t.baseUrl||r();if(!e.productId&&!e.productSlug)throw new Error("Either productId or productSlug is required");let s={successUrl:e.successUrl,cancelUrl:e.cancelUrl};e.productId&&(s.productId=e.productId),e.productSlug&&(s.productSlug=e.productSlug),e.mode&&(s.mode=e.mode),e.customerEmail&&(s.customerEmail=e.customerEmail),e.customerName&&(s.customerName=e.customerName),e.externalCustomerId&&(s.externalCustomerId=e.externalCustomerId);let n=await fetch(`${i}/v1/checkout/sessions`,{method:"POST",headers:{"Content-Type":"application/json","X-Recur-Publishable-Key":t.publishableKey},body:JSON.stringify(s)});if(!n.ok){let o=await n.json().catch(()=>({}));throw new Error(o.error?.message||"Failed to create checkout session")}return n.json()}async checkout(e){let t=this.core.getConfig(),r=null,i=e.productId||e.planId,s=e.productSlug;try{if(console.log("[Recur SDK] Starting checkout flow...",{productId:i,productSlug:s,mode:e.mode}),!i&&!s)throw new Error("Either productId or productSlug is required");if(!t.publishableKey)throw new Error("publishableKey is required");if(!e.customerName)throw new Error("customerName is required");if(!e.customerEmail)throw new Error("customerEmail is required");let n=this.getBaseUrl();console.log("[Recur SDK] Base URL:",n);let o={"Content-Type":"application/json","X-Recur-Publishable-Key":t.publishableKey},l=e.mode||"modal",u=null;if(l==="modal"){let m=this.createModalWithSkeleton(e.onClose);r=m.overlay,u=m.container}else if(l==="iframe"){if(u=this.getEmbeddedContainer(e.container),!u)throw new Error("Container is required for iframe mode");u.innerHTML="";let m=document.createElement("recur-payment-form-skeleton");u.appendChild(m)}console.log("[Recur SDK] Step 1: Creating checkout session...");let y={customerName:e.customerName,customerEmail:e.customerEmail};i&&(y.productId=i),s&&(y.productSlug=s),e.externalCustomerId&&(y.externalCustomerId=e.externalCustomerId);let $=await fetch(`${n}/v1/checkouts`,{method:"POST",headers:o,body:JSON.stringify(y)});if(!$.ok){let m=await $.json().catch(()=>({}));console.error("[Recur SDK] Failed to create checkout:",m);let N=m.details||m.error||"Failed to create checkout";throw new Error(N)}let d=await $.json();if(console.log("[Recur SDK] Checkout created successfully:",d),e.onSuccess?.(d),l==="redirect"){let m=`https://checkout.recur.tw/${d.checkout.id}`;console.log("[Recur SDK] Redirecting to hosted checkout:",m),window.location.href=m;return}if(console.log("[Recur SDK] Step 2: Extracting SDK token..."),!d.sdkToken)throw new Error("SDK token missing from checkout response");console.log("[Recur SDK] Step 3: Loading PAYUNi SDK...");let j=!0;if(await ue(j),console.log("[Recur SDK] PAYUNi SDK loaded successfully"),!window.UniPayment)throw new Error("PAYUNi SDK failed to load");if(console.log("[Recur SDK] Step 4: Rendering payment form..."),!u)throw new Error("Payment container not available");u.innerHTML="";let p=document.createElement("recur-payment-form");if(p.setAttribute("container-id",u.id||"recur-payment-container"),e.customerName&&p.setAttribute("customer-name",e.customerName),e.customerEmail&&p.setAttribute("customer-email",e.customerEmail),d.plan?.name&&p.setAttribute("plan-name",d.plan.name),d.checkout?.amount&&p.setAttribute("amount",d.checkout.amount.toString()),d.plan?.billingPeriod&&p.setAttribute("billing-period",d.plan.billingPeriod),p.setAttribute("custom-styles",`
|
|
1527
1531
|
.form-input-focus {
|
|
1528
1532
|
border-color: var(--ring, hsl(215 16% 47%)) !important;
|
|
1529
1533
|
outline: 0 !important;
|
|
1530
1534
|
box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring, hsl(215 16% 47%)) 50%, transparent) !important;
|
|
1531
1535
|
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out !important;
|
|
1532
1536
|
}
|
|
1533
|
-
`),u.appendChild(p),await new Promise(m=>setTimeout(m,100)),console.log("[Recur SDK] Step 5: Initializing PAYUNi SDK..."),await p.initializePayment(d.sdkToken,j?"SANDBOX":"PRODUCTION")===null){console.log("[Recur SDK] Initialization aborted");return}console.log("[Recur SDK] PAYUNi SDK initialized successfully"),console.log("[Recur SDK] Step 6: Setting up submit handler..."),p.addEventListener("submit",(async m=>{console.log("[Recur SDK] Form submitted");let N=m,{paymentSession:pe}=N.detail;try{let v=await pe.getTradeResult();console.log("[Recur SDK] Trade result received"),console.log("[Recur SDK] Executing payment...");let B=v.HashTimestamp||v.timestamp,F={};if(d.checkout.productType==="SUBSCRIPTION"){let
|
|
1537
|
+
`),u.appendChild(p),await new Promise(m=>setTimeout(m,100)),console.log("[Recur SDK] Step 5: Initializing PAYUNi SDK..."),await p.initializePayment(d.sdkToken,j?"SANDBOX":"PRODUCTION")===null){console.log("[Recur SDK] Initialization aborted");return}console.log("[Recur SDK] PAYUNi SDK initialized successfully"),console.log("[Recur SDK] Step 6: Setting up submit handler..."),p.addEventListener("submit",(async m=>{console.log("[Recur SDK] Form submitted");let N=m,{paymentSession:pe}=N.detail;try{let v=await pe.getTradeResult();console.log("[Recur SDK] Trade result received"),console.log("[Recur SDK] Executing payment...");let B=v.HashTimestamp||v.timestamp,F={};if(d.checkout.productType==="SUBSCRIPTION"){let x=d.creditToken,q=d.sdkTimestamp;if(!x)throw console.error("[Recur SDK] Missing creditToken from checkout for subscription"),new Error("Missing creditToken for subscription payment");F={creditToken:x,timestamp:q||B},console.log("[Recur SDK] Using creditToken from checkout:",x.substring(0,30)+"..."),console.log("[Recur SDK] Using timestamp:",q?"from checkout (sdkTimestamp)":"from tradeResult")}let O=await fetch(`${n}/v1/checkouts/${d.checkout.id}/pay`,{method:"POST",headers:o,body:JSON.stringify(F)});if(!O.ok){let x=await O.json().catch(()=>({}));throw new Error(x.error||"Failed to execute payment")}let h=await O.json();if(console.log("[Recur SDK] Payment executed:",h),h.requires3D&&h.redirectUrl){console.log("[Recur SDK] 3D verification required"),window.location.href=h.redirectUrl;return}e.onPaymentComplete&&(h.subscription?e.onPaymentComplete({id:h.subscription.id,status:h.subscription.status,planId:d.checkout.productId,amount:d.checkout.amount,billingPeriod:h.subscription.billingPeriod,currentPeriodStart:h.subscription.currentPeriodStart,currentPeriodEnd:h.subscription.currentPeriodEnd}):e.onPaymentComplete({id:h.checkout.id,status:h.checkout.status,planId:d.checkout.productId,amount:d.checkout.amount,billingPeriod:d.checkout.productType})),console.log("[Recur SDK] Checkout flow completed successfully!"),p.resetButton?.(),r&&r.remove()}catch(v){console.error("[Recur SDK] Payment error:",v);let B={code:"PAYMENT_FAILED",message:v instanceof Error?v.message:"Payment failed"};e.onError?.(B),p.resetButton?.()}})),console.log("[Recur SDK] Checkout flow initialized, waiting for user input...")}catch(n){console.error("[Recur SDK] Checkout error:",n),r&&r.remove();let o={code:"CHECKOUT_ERROR",message:n instanceof Error?n.message:"An unknown error occurred"};throw e.onError?.(o),n}}getBaseUrl(){let e=this.core.getConfig();if(e.baseUrl)return e.baseUrl;if(typeof window<"u"){let t=window.location.hostname;if(t==="localhost"||t.includes(".test")||t.includes(".local")||t==="127.0.0.1")return`${window.location.protocol}//${window.location.host}/api`}return"https://api.recur.tw"}createModalWithSkeleton(e){this.closeModal();let t=document.createElement("div");t.id="recur-modal-overlay",t.style.cssText=`
|
|
1534
1538
|
position: fixed;
|
|
1535
1539
|
top: 0;
|
|
1536
1540
|
left: 0;
|
|
@@ -1546,7 +1550,11 @@
|
|
|
1546
1550
|
width: 90%;
|
|
1547
1551
|
max-height: 90vh;
|
|
1548
1552
|
overflow-y: auto;
|
|
1553
|
+
overflow-x: hidden;
|
|
1549
1554
|
position: relative;
|
|
1555
|
+
border-radius: 12px;
|
|
1556
|
+
background: white;
|
|
1557
|
+
box-shadow: 0 4px 24px rgba(0, 0, 0, 0.15);
|
|
1550
1558
|
`;let i=document.createElement("button");i.innerHTML="\u2715",i.style.cssText=`
|
|
1551
1559
|
position: absolute;
|
|
1552
1560
|
top: 12px;
|
|
@@ -1565,11 +1573,7 @@
|
|
|
1565
1573
|
border-radius: 50%;
|
|
1566
1574
|
z-index: 10;
|
|
1567
1575
|
transition: background 0.2s;
|
|
1568
|
-
`,i.onmouseover=()=>{i.style.background="rgba(0, 0, 0, 0.1)"},i.onmouseout=()=>{i.style.background="rgba(0, 0, 0, 0.05)"},i.onclick=()=>{t.remove(),e?.()};let s=document.createElement("div");s.id="recur-modal-payment-container",s.
|
|
1569
|
-
background: white;
|
|
1570
|
-
border-radius: 12px;
|
|
1571
|
-
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
1572
|
-
`;let n=document.createElement("recur-payment-form-skeleton");return s.appendChild(n),r.appendChild(i),r.appendChild(s),t.appendChild(r),document.body.appendChild(t),this.currentModalOverlay=t,{overlay:t,container:s}}getEmbeddedContainer(e){return e?typeof e=="string"?document.getElementById(e)||document.querySelector(e):e:null}closeModal(){this.currentModal&&(this.currentModal.close(),this.currentModal=null),this.currentModalOverlay&&(this.currentModalOverlay.remove(),this.currentModalOverlay=null)}removeIframe(){this.currentIframe&&(this.currentIframe.remove(),this.currentIframe=null)}close(){this.closeModal(),this.removeIframe()}async createPortalSession(e,t){let r=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({customerId:t.customerId,returnUrl:t.returnUrl})});if(!r.ok){let s=await r.json().catch(()=>({}));throw new Error(s.error?.message||s.message||"Failed to create portal session")}let i=await r.json();return{id:i.id,url:i.url||i.portalUrl,expiresAt:i.expiresAt}}async redirectToPortal(e,t){let r=await this.createPortalSession(e,t);window.location.href=r.url}};function me(c){return new S(c)}var Ee={init:me,RecurCheckout:S,RecurElements:k,createElements:K};return ve(Se);})();
|
|
1576
|
+
`,i.onmouseover=()=>{i.style.background="rgba(0, 0, 0, 0.1)"},i.onmouseout=()=>{i.style.background="rgba(0, 0, 0, 0.05)"},i.onclick=()=>{t.remove(),e?.()};let s=document.createElement("div");s.id="recur-modal-payment-container";let n=document.createElement("recur-payment-form-skeleton");return s.appendChild(n),r.appendChild(i),r.appendChild(s),t.appendChild(r),document.body.appendChild(t),this.currentModalOverlay=t,{overlay:t,container:s}}getEmbeddedContainer(e){return e?typeof e=="string"?document.getElementById(e)||document.querySelector(e):e:null}closeModal(){this.currentModal&&(this.currentModal.close(),this.currentModal=null),this.currentModalOverlay&&(this.currentModalOverlay.remove(),this.currentModalOverlay=null)}removeIframe(){this.currentIframe&&(this.currentIframe.remove(),this.currentIframe=null)}close(){this.closeModal(),this.removeIframe()}async createPortalSession(e,t){let r=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({customerId:t.customerId,returnUrl:t.returnUrl})});if(!r.ok){let s=await r.json().catch(()=>({}));throw new Error(s.error?.message||s.message||"Failed to create portal session")}let i=await r.json();return{id:i.id,url:i.url||i.portalUrl,expiresAt:i.expiresAt}}async redirectToPortal(e,t){let r=await this.createPortalSession(e,t);window.location.href=r.url}};function me(c){return new S(c)}var Ee={init:me,RecurCheckout:S,RecurElements:k,createElements:K};return ve(Se);})();
|
|
1573
1577
|
if (typeof window !== "undefined") {
|
|
1574
1578
|
window.RecurCheckout = RecurCheckout.default;
|
|
1575
1579
|
window.RecurElements = RecurCheckout.RecurElements;
|