recur-tw 0.7.2 → 0.7.5

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 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;
@@ -1263,7 +1262,6 @@ var init_payment_form = __esm({
1263
1262
  margin: 0 0 12px 0;
1264
1263
  }
1265
1264
 
1266
- /* Slot \u6A23\u5F0F - \u9019\u6703\u61C9\u7528\u5230 slotted \u5167\u5BB9 */
1267
1265
  ::slotted(*) {
1268
1266
  display: block;
1269
1267
  }
@@ -1594,12 +1592,16 @@ var init_payment_form = __esm({
1594
1592
  .recur-payuni-iframe {
1595
1593
  height: 36px;
1596
1594
  width: 100%;
1595
+ max-width: 100%;
1596
+ box-sizing: border-box;
1597
1597
  }
1598
1598
 
1599
1599
  .recur-card-row {
1600
1600
  display: grid;
1601
1601
  grid-template-columns: 1fr 1fr;
1602
1602
  gap: 12px;
1603
+ max-width: 100%;
1604
+ box-sizing: border-box;
1603
1605
  }
1604
1606
 
1605
1607
  /* Container needs relative positioning for skeleton overlay */
@@ -1699,6 +1701,7 @@ var init_payment_form = __esm({
1699
1701
  align-items: center;
1700
1702
  justify-content: center;
1701
1703
  gap: 8px;
1704
+ box-sizing: border-box;
1702
1705
  }
1703
1706
 
1704
1707
  .recur-submit-button:hover:not(:disabled) {
@@ -2646,7 +2649,11 @@ function RecurProvider({ children, config: initialConfig = {} }) {
2646
2649
  width: 90%;
2647
2650
  max-height: 90vh;
2648
2651
  overflow-y: auto;
2652
+ overflow-x: hidden;
2649
2653
  position: relative;
2654
+ border-radius: 12px;
2655
+ background: white;
2656
+ box-shadow: 0 4px 24px rgba(0, 0, 0, 0.15);
2650
2657
  `;
2651
2658
  const closeButton = document.createElement("button");
2652
2659
  closeButton.className = "recur-sdk__close-button";
@@ -2684,11 +2691,6 @@ function RecurProvider({ children, config: initialConfig = {} }) {
2684
2691
  loadingContainer = document.createElement("div");
2685
2692
  loadingContainer.id = "recur-modal-loading";
2686
2693
  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
2694
  const skeleton = document.createElement("recur-payment-form-skeleton");
2693
2695
  loadingContainer.appendChild(skeleton);
2694
2696
  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;
@@ -1257,7 +1256,6 @@ var init_payment_form = __esm({
1257
1256
  margin: 0 0 12px 0;
1258
1257
  }
1259
1258
 
1260
- /* Slot \u6A23\u5F0F - \u9019\u6703\u61C9\u7528\u5230 slotted \u5167\u5BB9 */
1261
1259
  ::slotted(*) {
1262
1260
  display: block;
1263
1261
  }
@@ -1588,12 +1586,16 @@ var init_payment_form = __esm({
1588
1586
  .recur-payuni-iframe {
1589
1587
  height: 36px;
1590
1588
  width: 100%;
1589
+ max-width: 100%;
1590
+ box-sizing: border-box;
1591
1591
  }
1592
1592
 
1593
1593
  .recur-card-row {
1594
1594
  display: grid;
1595
1595
  grid-template-columns: 1fr 1fr;
1596
1596
  gap: 12px;
1597
+ max-width: 100%;
1598
+ box-sizing: border-box;
1597
1599
  }
1598
1600
 
1599
1601
  /* Container needs relative positioning for skeleton overlay */
@@ -1693,6 +1695,7 @@ var init_payment_form = __esm({
1693
1695
  align-items: center;
1694
1696
  justify-content: center;
1695
1697
  gap: 8px;
1698
+ box-sizing: border-box;
1696
1699
  }
1697
1700
 
1698
1701
  .recur-submit-button:hover:not(:disabled) {
@@ -2640,7 +2643,11 @@ function RecurProvider({ children, config: initialConfig = {} }) {
2640
2643
  width: 90%;
2641
2644
  max-height: 90vh;
2642
2645
  overflow-y: auto;
2646
+ overflow-x: hidden;
2643
2647
  position: relative;
2648
+ border-radius: 12px;
2649
+ background: white;
2650
+ box-shadow: 0 4px 24px rgba(0, 0, 0, 0.15);
2644
2651
  `;
2645
2652
  const closeButton = document.createElement("button");
2646
2653
  closeButton.className = "recur-sdk__close-button";
@@ -2678,11 +2685,6 @@ function RecurProvider({ children, config: initialConfig = {} }) {
2678
2685
  loadingContainer = document.createElement("div");
2679
2686
  loadingContainer.id = "recur-modal-loading";
2680
2687
  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
2688
  const skeleton = document.createElement("recur-payment-form-skeleton");
2687
2689
  loadingContainer.appendChild(skeleton);
2688
2690
  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:()=>x});var M,g,x,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">
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=x.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=`
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);x=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",x)});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=`
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;
@@ -836,7 +835,6 @@
836
835
  margin: 0 0 12px 0;
837
836
  }
838
837
 
839
- /* Slot \u6A23\u5F0F - \u9019\u6703\u61C9\u7528\u5230 slotted \u5167\u5BB9 */
840
838
  ::slotted(*) {
841
839
  display: block;
842
840
  }
@@ -1097,12 +1095,16 @@
1097
1095
  .recur-payuni-iframe {
1098
1096
  height: 36px;
1099
1097
  width: 100%;
1098
+ max-width: 100%;
1099
+ box-sizing: border-box;
1100
1100
  }
1101
1101
 
1102
1102
  .recur-card-row {
1103
1103
  display: grid;
1104
1104
  grid-template-columns: 1fr 1fr;
1105
1105
  gap: 12px;
1106
+ max-width: 100%;
1107
+ box-sizing: border-box;
1106
1108
  }
1107
1109
 
1108
1110
  /* Container needs relative positioning for skeleton overlay */
@@ -1180,6 +1182,7 @@
1180
1182
  align-items: center;
1181
1183
  justify-content: center;
1182
1184
  gap: 8px;
1185
+ box-sizing: border-box;
1183
1186
  }
1184
1187
 
1185
1188
  .recur-submit-button:hover:not(:disabled) {
@@ -1516,21 +1519,21 @@
1516
1519
  </p>
1517
1520
  </form>
1518
1521
  </div>
1519
- `}async loadPayUniSDK(){return new Promise((e,t)=>{if(window.UniPayment){e();return}let r=document.createElement("script");r.src=this.sdkEnv==="P"?"https://vendor.payuni.com.tw/sdk/uni-payment.js":"https://sandbox-vendor.payuni.com.tw/sdk/uni-payment.js",r.async=!0,r.onload=()=>e(),r.onerror=()=>t(new Error("Failed to load PAYUNi SDK")),document.head.appendChild(r)})}async initPayUniSDK(){if(!this.sdkToken)throw new Error("SDK token not initialized");let e=window.UniPayment;if(!e)throw new Error("PAYUNi SDK not loaded");let t={env:this.sdkEnv,useInst:!1,elements:{CardNo:"recur-card-number",CardExp:"recur-card-exp",CardCvc:"recur-card-cvc"},style:{color:"#111827",errorColor:"#dc2626",fontSize:"14px",fontWeight:"400",lineHeight:"24px"}};this.payuniSDK=e.createSession(this.sdkToken,t),await this.payuniSDK.start(),this.payuniSDK.onUpdate(r=>{let i=r?.status;i&&(this.isFormValid=i.CardNo===!0&&i.CardExp===!0&&i.CardCvc===!0,this.updateSubmitButton())})}updateSubmitButton(){let e=document.getElementById("recur-submit-btn");e&&(e.disabled=!this.isFormValid,e.style.opacity=this.isFormValid?"1":"0.5",e.style.cursor=this.isFormValid?"pointer":"not-allowed")}setupFormSubmit(){let e=document.getElementById("recur-checkout-form");e&&e.addEventListener("submit",async t=>{t.preventDefault(),await this.handleSubmit()})}async handleSubmit(){try{this.showLoading(!0),this.hideError();let e=document.getElementById("recur-email").value,t=document.getElementById("recur-name").value;if(!e||!t)throw new Error("Please fill in all required fields");if(!this.checkoutId)throw new Error("Checkout session not initialized");if(!this.payuniSDK)throw new Error("Payment system not initialized");let r=await this.payuniSDK.getTradeResult();if(r.Status!=="SUCCESS")throw new Error(r.Message||"Card validation failed");let i=r.EncryptInfo||r.creditToken;if(!i)throw console.error("[Recur SDK] Missing payment token. Available fields:",Object.keys(r)),new Error("Missing payment token");let s=this.getBaseUrl(),n=await fetch(`${s}/v1/checkouts/${this.checkoutId}/pay`,{method:"POST",headers:{"Content-Type":"application/json","X-Recur-Publishable-Key":this.config.publishableKey},body:JSON.stringify({creditToken:i,timestamp:r.HashTimestamp||r.timestamp})});if(!n.ok){let u=await n.json().catch(()=>({}));throw new Error(u.error||"Failed to process payment")}let o=await n.json(),l={subscription:{id:o.subscription?.id||o.charge?.id||"",status:o.success?"active":"failed",planId:this.options.planId,planName:"",amount:o.charge?.amount||0,billingPeriod:o.subscription?.billingPeriod||"MONTHLY",trialDays:null},subscriber:{id:"",email:document.getElementById("recur-email")?.value||"",name:document.getElementById("recur-name")?.value||""},nextSteps:{getSdkToken:"",completeSubscription:""}};this.options.onSuccess&&this.options.onSuccess(l),this.showSuccess()}catch(e){this.handleError(e)}finally{this.showLoading(!1)}}showLoading(e){let t=document.getElementById("recur-submit-btn");t&&(t.disabled=e,t.textContent=e?"Processing...":"Subscribe Now")}showError(e){let t=document.getElementById("recur-error");t&&(t.textContent=e,t.style.display="block")}hideError(){let e=document.getElementById("recur-error");e&&(e.style.display="none")}showSuccess(){this.container.innerHTML="";let e=document.createElement("recur-success-message");e.setAttribute("title","Subscription Complete!"),e.setAttribute("message","Thank you for subscribing. You will receive a confirmation email shortly."),this.container.appendChild(e)}handleError(e){let t=e?.message||"An error occurred";this.showError(t);let r={code:"CHECKOUT_ERROR",message:t};this.options.onError&&this.options.onError(r)}};var k=class{constructor(e){a(this,"publishableKey");a(this,"baseUrl");a(this,"embedUrl");a(this,"iframe",null);a(this,"container",null);a(this,"sessionId",null);a(this,"timestamp",null);a(this,"creditToken",null);a(this,"cardToken",null);a(this,"cardTimestamp",null);a(this,"eventHandlers",new Map);typeof e=="string"?(this.publishableKey=e,this.baseUrl=this.getDefaultBaseUrl(),this.embedUrl=this.getDefaultEmbedUrl()):(this.publishableKey=e.publishableKey,this.baseUrl=e.baseUrl||this.getDefaultBaseUrl(),this.embedUrl=e.embedUrl||this.getDefaultEmbedUrl()),window.addEventListener("message",this.handleMessage.bind(this))}async mount(e){let t=typeof e=="string"?document.querySelector(e):e;if(!t)throw new Error(`Container not found: ${e}`);return this.container=t,this.iframe=document.createElement("iframe"),this.iframe.src=`${this.embedUrl}/elements?key=${encodeURIComponent(this.publishableKey)}`,this.iframe.style.cssText=`
1522
+ `}async loadPayUniSDK(){return new Promise((e,t)=>{if(window.UniPayment){e();return}let r=document.createElement("script");r.src=this.sdkEnv==="P"?"https://vendor.payuni.com.tw/sdk/uni-payment.js":"https://sandbox-vendor.payuni.com.tw/sdk/uni-payment.js",r.async=!0,r.onload=()=>e(),r.onerror=()=>t(new Error("Failed to load PAYUNi SDK")),document.head.appendChild(r)})}async initPayUniSDK(){if(!this.sdkToken)throw new Error("SDK token not initialized");let e=window.UniPayment;if(!e)throw new Error("PAYUNi SDK not loaded");let t={env:this.sdkEnv,useInst:!1,elements:{CardNo:"recur-card-number",CardExp:"recur-card-exp",CardCvc:"recur-card-cvc"},style:{color:"#111827",errorColor:"#dc2626",fontSize:"14px",fontWeight:"400",lineHeight:"24px"}};this.payuniSDK=e.createSession(this.sdkToken,t),await this.payuniSDK.start(),this.payuniSDK.onUpdate(r=>{let i=r?.status;i&&(this.isFormValid=i.CardNo===!0&&i.CardExp===!0&&i.CardCvc===!0,this.updateSubmitButton())})}updateSubmitButton(){let e=document.getElementById("recur-submit-btn");e&&(e.disabled=!this.isFormValid,e.style.opacity=this.isFormValid?"1":"0.5",e.style.cursor=this.isFormValid?"pointer":"not-allowed")}setupFormSubmit(){let e=document.getElementById("recur-checkout-form");e&&e.addEventListener("submit",async t=>{t.preventDefault(),await this.handleSubmit()})}async handleSubmit(){try{this.showLoading(!0),this.hideError();let e=document.getElementById("recur-email").value,t=document.getElementById("recur-name").value;if(!e||!t)throw new Error("Please fill in all required fields");if(!this.checkoutId)throw new Error("Checkout session not initialized");if(!this.payuniSDK)throw new Error("Payment system not initialized");let r=await this.payuniSDK.getTradeResult();if(r.Status!=="SUCCESS")throw new Error(r.Message||"Card validation failed");let i=r.EncryptInfo||r.creditToken;if(!i)throw console.error("[Recur SDK] Missing payment token. Available fields:",Object.keys(r)),new Error("Missing payment token");let s=this.getBaseUrl(),n=await fetch(`${s}/v1/checkouts/${this.checkoutId}/pay`,{method:"POST",headers:{"Content-Type":"application/json","X-Recur-Publishable-Key":this.config.publishableKey},body:JSON.stringify({creditToken:i,timestamp:r.HashTimestamp||r.timestamp})});if(!n.ok){let u=await n.json().catch(()=>({}));throw new Error(u.error||"Failed to process payment")}let o=await n.json(),l={subscription:{id:o.subscription?.id||o.charge?.id||"",status:o.success?"active":"failed",planId:this.options.planId,planName:"",amount:o.charge?.amount||0,billingPeriod:o.subscription?.billingPeriod||"MONTHLY",trialDays:null},subscriber:{id:"",email:document.getElementById("recur-email")?.value||"",name:document.getElementById("recur-name")?.value||""},nextSteps:{getSdkToken:"",completeSubscription:""}};this.options.onSuccess&&this.options.onSuccess(l),this.showSuccess()}catch(e){this.handleError(e)}finally{this.showLoading(!1)}}showLoading(e){let t=document.getElementById("recur-submit-btn");t&&(t.disabled=e,t.textContent=e?"Processing...":"Subscribe Now")}showError(e){let t=document.getElementById("recur-error");t&&(t.textContent=e,t.style.display="block")}hideError(){let e=document.getElementById("recur-error");e&&(e.style.display="none")}showSuccess(){this.container.innerHTML="";let e=document.createElement("recur-success-message");e.setAttribute("title","Subscription Complete!"),e.setAttribute("message","Thank you for subscribing. You will receive a confirmation email shortly."),this.container.appendChild(e)}handleError(e){let t=e?.message||"An error occurred";this.showError(t);let r={code:"CHECKOUT_ERROR",message:t};this.options.onError&&this.options.onError(r)}};var k=class{constructor(e){a(this,"publishableKey");a(this,"baseUrl");a(this,"embedUrl");a(this,"iframe",null);a(this,"container",null);a(this,"sessionId",null);a(this,"timestamp",null);a(this,"creditToken",null);a(this,"sdkToken",null);a(this,"cardToken",null);a(this,"cardTimestamp",null);a(this,"eventHandlers",new Map);typeof e=="string"?(this.publishableKey=e,this.baseUrl=this.getDefaultBaseUrl(),this.embedUrl=this.getDefaultEmbedUrl()):(this.publishableKey=e.publishableKey,this.baseUrl=e.baseUrl||this.getDefaultBaseUrl(),this.embedUrl=e.embedUrl||this.getDefaultEmbedUrl()),window.addEventListener("message",this.handleMessage.bind(this))}async mount(e){let t=typeof e=="string"?document.querySelector(e):e;if(!t)throw new Error(`Container not found: ${e}`);return this.container=t,this.iframe=document.createElement("iframe"),this.iframe.src=`${this.embedUrl}/elements?key=${encodeURIComponent(this.publishableKey)}`,this.iframe.style.cssText=`
1520
1523
  width: 100%;
1521
1524
  border: none;
1522
1525
  min-height: 200px;
1523
1526
  display: block;
1524
1527
  user-select: none;
1525
1528
  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 we="https://vendor.payuni.com.tw/sdk/uni-payment.js",xe="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?xe:we,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",`
1529
+ `.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.sdkToken=r.sdkToken,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,productId:e.productId,email:e.email,name:e.name,phone:e.phone,externalCustomerId:e.externalCustomerId,metadata:e.metadata,successUrl:e.successUrl,cancelUrl:e.cancelUrl})}),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.sdkToken=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
1530
  .form-input-focus {
1528
1531
  border-color: var(--ring, hsl(215 16% 47%)) !important;
1529
1532
  outline: 0 !important;
1530
1533
  box-shadow: 0 0 0 3px color-mix(in oklch, var(--ring, hsl(215 16% 47%)) 50%, transparent) !important;
1531
1534
  transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out !important;
1532
1535
  }
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 w=d.creditToken,q=d.sdkTimestamp;if(!w)throw console.error("[Recur SDK] Missing creditToken from checkout for subscription"),new Error("Missing creditToken for subscription payment");F={creditToken:w,timestamp:q||B},console.log("[Recur SDK] Using creditToken from checkout:",w.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 w=await O.json().catch(()=>({}));throw new Error(w.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=`
1536
+ `),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
1537
  position: fixed;
1535
1538
  top: 0;
1536
1539
  left: 0;
@@ -1546,7 +1549,11 @@
1546
1549
  width: 90%;
1547
1550
  max-height: 90vh;
1548
1551
  overflow-y: auto;
1552
+ overflow-x: hidden;
1549
1553
  position: relative;
1554
+ border-radius: 12px;
1555
+ background: white;
1556
+ box-shadow: 0 4px 24px rgba(0, 0, 0, 0.15);
1550
1557
  `;let i=document.createElement("button");i.innerHTML="\u2715",i.style.cssText=`
1551
1558
  position: absolute;
1552
1559
  top: 12px;
@@ -1565,11 +1572,7 @@
1565
1572
  border-radius: 50%;
1566
1573
  z-index: 10;
1567
1574
  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.style.cssText=`
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);})();
1575
+ `,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
1576
  if (typeof window !== "undefined") {
1574
1577
  window.RecurCheckout = RecurCheckout.default;
1575
1578
  window.RecurElements = RecurCheckout.RecurElements;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "recur-tw",
3
- "version": "0.7.2",
3
+ "version": "0.7.5",
4
4
  "description": "React & Vanilla JS SDK for embedding subscription checkout flows (Taiwan / PAYUNi)",
5
5
  "type": "module",
6
6
  "private": false,
@@ -28,14 +28,6 @@
28
28
  "url": "https://github.com/kaikhq/recur.tw/issues"
29
29
  },
30
30
  "homepage": "https://github.com/kaikhq/recur.tw/tree/main/packages/recur-sdk#readme",
31
- "scripts": {
32
- "build": "tsup",
33
- "dev": "tsup --watch",
34
- "lint": "eslint .",
35
- "lint:fix": "eslint . --fix",
36
- "type-check": "tsc --noEmit",
37
- "examples": "npx http-server examples -p 8080 -o"
38
- },
39
31
  "main": "./dist/index.js",
40
32
  "module": "./dist/index.js",
41
33
  "types": "./dist/index.d.ts",
@@ -81,7 +73,6 @@
81
73
  "@types/node": "^20.19.9",
82
74
  "@types/react": "^19.1.9",
83
75
  "@types/react-dom": "^19.1.7",
84
- "@workspace/typescript-config": "workspace:*",
85
76
  "autoprefixer": "^10.4.22",
86
77
  "eslint": "^9",
87
78
  "eslint-plugin-react": "^7.37.5",
@@ -92,6 +83,15 @@
92
83
  "tailwindcss": "^4.1.11",
93
84
  "tsup": "^8.3.5",
94
85
  "typescript": "^5.9.2",
95
- "typescript-eslint": "^8.47.0"
86
+ "typescript-eslint": "^8.47.0",
87
+ "@workspace/typescript-config": "0.0.0"
88
+ },
89
+ "scripts": {
90
+ "build": "tsup",
91
+ "dev": "tsup --watch",
92
+ "lint": "eslint .",
93
+ "lint:fix": "eslint . --fix",
94
+ "type-check": "tsc --noEmit",
95
+ "examples": "npx http-server examples -p 8080 -o"
96
96
  }
97
- }
97
+ }