recur-tw 0.13.2 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -2814,7 +2814,7 @@ function toCamelCase(obj) {
2814
2814
 
2815
2815
  // package.json
2816
2816
  var package_default = {
2817
- version: "0.13.2"};
2817
+ version: "0.13.3"};
2818
2818
  var SDK_VERSION = package_default.version;
2819
2819
  var SDK_TYPE = "react";
2820
2820
  var RecurContext = React.createContext(null);
@@ -3165,8 +3165,7 @@ function RecurProvider({ children, config: initialConfig = {}, customer: custome
3165
3165
  tokenExpired: checkoutResult.sdkTokenExpiresAt,
3166
3166
  creditToken: "",
3167
3167
  // No longer needed - creditHash stored in database
3168
- environment: "SANDBOX"
3169
- // Will be determined by organization settings
3168
+ environment: checkoutResult.livemode ? "PRODUCTION" : "SANDBOX"
3170
3169
  };
3171
3170
  console.log("[Recur SDK] SDK token extracted:", {
3172
3171
  sdkToken: tokenResult.sdkToken.substring(0, 20) + "...",
@@ -3612,7 +3611,7 @@ function RecurProvider({ children, config: initialConfig = {}, customer: custome
3612
3611
  const fetchPlans = React.useCallback(
3613
3612
  async () => {
3614
3613
  const result = await fetchProducts({ type: "SUBSCRIPTION" });
3615
- return { plans: result.products };
3614
+ return { plans: result.data };
3616
3615
  },
3617
3616
  [fetchProducts]
3618
3617
  );
@@ -3680,8 +3679,8 @@ function useProducts(options = {}) {
3680
3679
  setError(null);
3681
3680
  try {
3682
3681
  const result = await fetchProducts({ type });
3683
- setData(result.products);
3684
- onSuccess?.(result.products);
3682
+ setData(result.data);
3683
+ onSuccess?.(result.data);
3685
3684
  } catch (err) {
3686
3685
  const error2 = err instanceof Error ? err : new Error("Failed to fetch products");
3687
3686
  setError(error2);
package/dist/index.d.cts CHANGED
@@ -357,6 +357,11 @@ interface CheckoutResult {
357
357
  * Used internally for subscription credit binding
358
358
  */
359
359
  sdkTimestamp?: number;
360
+ /**
361
+ * Whether this is a live (production) checkout
362
+ * Used to determine PAYUNi SDK environment
363
+ */
364
+ livemode?: boolean;
360
365
  }
361
366
  /**
362
367
  * Payment failure codes from payment provider
@@ -512,7 +517,7 @@ interface Product {
512
517
  displayOrder: number;
513
518
  }
514
519
  interface ProductsResult {
515
- products: Product[];
520
+ data: Product[];
516
521
  }
517
522
  type Plan = Product;
518
523
  interface PlansResult {
package/dist/index.d.ts CHANGED
@@ -357,6 +357,11 @@ interface CheckoutResult {
357
357
  * Used internally for subscription credit binding
358
358
  */
359
359
  sdkTimestamp?: number;
360
+ /**
361
+ * Whether this is a live (production) checkout
362
+ * Used to determine PAYUNi SDK environment
363
+ */
364
+ livemode?: boolean;
360
365
  }
361
366
  /**
362
367
  * Payment failure codes from payment provider
@@ -512,7 +517,7 @@ interface Product {
512
517
  displayOrder: number;
513
518
  }
514
519
  interface ProductsResult {
515
- products: Product[];
520
+ data: Product[];
516
521
  }
517
522
  type Plan = Product;
518
523
  interface PlansResult {
package/dist/index.js CHANGED
@@ -2808,7 +2808,7 @@ function toCamelCase(obj) {
2808
2808
 
2809
2809
  // package.json
2810
2810
  var package_default = {
2811
- version: "0.13.2"};
2811
+ version: "0.13.3"};
2812
2812
  var SDK_VERSION = package_default.version;
2813
2813
  var SDK_TYPE = "react";
2814
2814
  var RecurContext = createContext(null);
@@ -3159,8 +3159,7 @@ function RecurProvider({ children, config: initialConfig = {}, customer: custome
3159
3159
  tokenExpired: checkoutResult.sdkTokenExpiresAt,
3160
3160
  creditToken: "",
3161
3161
  // No longer needed - creditHash stored in database
3162
- environment: "SANDBOX"
3163
- // Will be determined by organization settings
3162
+ environment: checkoutResult.livemode ? "PRODUCTION" : "SANDBOX"
3164
3163
  };
3165
3164
  console.log("[Recur SDK] SDK token extracted:", {
3166
3165
  sdkToken: tokenResult.sdkToken.substring(0, 20) + "...",
@@ -3606,7 +3605,7 @@ function RecurProvider({ children, config: initialConfig = {}, customer: custome
3606
3605
  const fetchPlans = useCallback(
3607
3606
  async () => {
3608
3607
  const result = await fetchProducts({ type: "SUBSCRIPTION" });
3609
- return { plans: result.products };
3608
+ return { plans: result.data };
3610
3609
  },
3611
3610
  [fetchProducts]
3612
3611
  );
@@ -3674,8 +3673,8 @@ function useProducts(options = {}) {
3674
3673
  setError(null);
3675
3674
  try {
3676
3675
  const result = await fetchProducts({ type });
3677
- setData(result.products);
3678
- onSuccess?.(result.products);
3676
+ setData(result.data);
3677
+ onSuccess?.(result.data);
3679
3678
  } catch (err) {
3680
3679
  const error2 = err instanceof Error ? err : new Error("Failed to fetch products");
3681
3680
  setError(error2);
package/dist/recur.umd.js CHANGED
@@ -2101,7 +2101,7 @@
2101
2101
  <path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"/>
2102
2102
  <circle cx="12" cy="7" r="4"/>
2103
2103
  </svg>
2104
- `}setupEventListeners(){let t=this.shadowRoot?.querySelector("button");t&&t.addEventListener("click",this.handleClick)}redirectToPortal(t){let r=this.getAttribute("target");this.dispatchEvent(new CustomEvent("portal-redirect",{detail:{url:t},bubbles:!0,composed:!0})),r==="_blank"?window.open(t,"_blank","noopener,noreferrer"):window.location.href=t}async fetchAndRedirect(t){let r=this.getAttribute("customer-id"),o=this.getAttribute("return-url");this._isLoading=!0,this.render(),this.setupEventListeners();try{let i={};r&&(i.customerId=r),o&&(i.returnUrl=o);let n=await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(i)});if(!n.ok){let u=await n.json().catch(()=>({}));throw new Error(u.error?.message||u.message||`HTTP ${n.status}: Failed to create portal session`)}let a=await n.json(),c=a.url||a.portalUrl;if(!c)throw new Error("Portal URL not found in response");this._isLoading=!1,this.render(),this.setupEventListeners(),this.redirectToPortal(c)}catch(i){this._isLoading=!1,this.render(),this.setupEventListeners(),this.dispatchError(i instanceof Error?i.message:"Failed to create portal session")}}dispatchError(t){console.error("[recur-portal]",t),this.dispatchEvent(new CustomEvent("portal-error",{detail:{message:t},bubbles:!0,composed:!0}))}};typeof window<"u"&&!customElements.get("recur-portal")&&customElements.define("recur-portal",pe)});var Qt={};S(Qt,{RecurCheckout:()=>O,RecurElements:()=>z,create:()=>kt,createElements:()=>$e,default:()=>Zt,init:()=>vt});async function jt(){if(typeof window>"u"){console.warn("[Recur SDK] Cannot register Web Components: window is not defined");return}await Promise.all([Promise.resolve().then(()=>(Le(),Me)),Promise.resolve().then(()=>(He(),Ue)),Promise.resolve().then(()=>(Be(),Ne)),Promise.resolve().then(()=>(Oe(),ze)),Promise.resolve().then(()=>(tt(),et)),Promise.resolve().then(()=>(ot(),rt)),Promise.resolve().then(()=>(pt(),dt)),Promise.resolve().then(()=>(ht(),mt)),Promise.resolve().then(()=>(ft(),gt))]);let e=["recur-loading-spinner","recur-success-message","recur-error-display","recur-skeleton-loader","recur-payment-form-skeleton","recur-toast","recur-toast-container","recur-payment-form","recur-checkout","recur-portal"].filter(t=>!customElements.get(t));e.length>0&&console.warn("[Recur SDK] The following components are not registered:",e)}typeof window<"u"&&jt();function Ft(s){return s.replace(/_([a-z])/g,(e,t)=>t.toUpperCase())}function w(s){if(s==null)return s;if(Array.isArray(s))return s.map(e=>w(e));if(s instanceof Date)return s;if(typeof s=="object"){let e={};for(let[t,r]of Object.entries(s)){let o=Ft(t);e[o]=w(r)}return e}return s}var me={name:"recur-tw",version:"0.13.2",description:"React & Vanilla JS SDK for embedding subscription checkout flows (Taiwan / PAYUNi)",type:"module",private:!1,author:"Recur",license:"Elastic-2.0",keywords:["react","vanilla-js","subscription","checkout","payment","payuni","recurring-billing","taiwan","\u7E41\u9AD4\u4E2D\u6587","sdk","embedded-checkout"],homepage:"https://recur.tw/",bugs:{email:"support@recur.tw"},scripts:{build:"tsup",dev:"tsup --watch",lint:"eslint .","lint:fix":"eslint . --fix","type-check":"tsc --noEmit",examples:"npx http-server . -p 8080 -o /examples/"},main:"./dist/index.js",module:"./dist/index.js",types:"./dist/index.d.ts",exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.js",require:"./dist/index.cjs"},"./server":{types:"./dist/server.d.ts",import:"./dist/server.js",require:"./dist/server.cjs"},"./vanilla":"./dist/recur.umd.js","./checkout":"./dist/checkout.js","./widget":"./dist/widget.js","./package.json":"./package.json"},unpkg:"./dist/recur.umd.js",jsdelivr:"./dist/recur.umd.js",files:["dist","README.md","AGENTS.md","LICENSE"],sideEffects:["src/components/**/*.ts","src/components/**/*.js"],peerDependencies:{react:">=18.0.0","react-dom":">=18.0.0"},peerDependenciesMeta:{react:{optional:!0},"react-dom":{optional:!0}},devDependencies:{"@eslint/js":"^9.39.1","@types/node":"^20.19.9","@types/react":"^19.1.9","@types/react-dom":"^19.1.7","@workspace/typescript-config":"workspace:*",autoprefixer:"^10.4.22",eslint:"^9","eslint-plugin-react":"^7.37.5","eslint-plugin-react-hooks":"^7.0.1",postcss:"^8.5.6",react:"^19.2.1","react-dom":"^19.2.1",tailwindcss:"^4.1.11",tsup:"^8.3.5",typescript:"^5.9.2","typescript-eslint":"^8.47.0"},dependencies:{"lit-html":"^3.3.1"}};var qt=me.version,Yt="vanilla",he=class{constructor(e){l(this,"config");if(!e.publishableKey)throw new Error("publishableKey is required");this.config={baseUrl:"https://api.recur.tw",...e}}getHeaders(){return{"Content-Type":"application/json","X-Recur-Publishable-Key":this.config.publishableKey,"X-Recur-SDK-Type":Yt,"X-Recur-SDK-Version":qt,"X-Recur-Source":typeof window<"u"?window.location.origin:"server"}}async createSubscription(e){let{customerName:t,customerEmail:r}=e,o=e.productId||e.planId,i=e.productSlug;if(!o&&!i)throw new Error("Either productId or productSlug is required");let n={customerName:t,customerEmail:r};o&&(n.productId=o),i&&(n.productSlug=i);let a=await fetch(`${this.config.baseUrl}/v1/subscriptions`,{method:"POST",headers:this.getHeaders(),body:JSON.stringify(n)});if(!a.ok){let u=await a.json().catch(()=>({}));throw{code:u.error||"CHECKOUT_FAILED",message:u.message||"Failed to initiate checkout",details:u}}let c=await a.json();return w(c)}async fetchProducts(e){let t=new URL(`${this.config.baseUrl}/v1/products`);e?.type&&t.searchParams.set("type",e.type);let r=await fetch(t.toString(),{method:"GET",headers:this.getHeaders()});if(!r.ok){let i=await r.json().catch(()=>({}));throw{code:i.error||"FETCH_PRODUCTS_FAILED",message:i.message||"Failed to fetch products",details:i}}let o=await r.json();return w(o)}async fetchPlans(){return{plans:(await this.fetchProducts({type:"SUBSCRIPTION"})).products}}getConfig(){return{...this.config}}};var ge=class{constructor(e,t){l(this,"config");l(this,"options");l(this,"container");l(this,"checkoutId",null);l(this,"sdkToken",null);l(this,"sdkTimestamp",null);l(this,"creditToken",null);l(this,"sdkEnv","S");l(this,"payuniSDK",null);l(this,"isFormValid",!1);if(this.config=e,this.options=t,typeof t.container=="string"){let r=document.querySelector(t.container);if(!r)throw new Error(`Container not found: ${t.container}`);this.container=r}else this.container=t.container}async render(){try{await this.initCheckout(),this.renderHTML(),await this.loadPayUniSDK(),await this.initPayUniSDK(),this.setupFormSubmit()}catch(e){this.handleError(e)}}getBaseUrl(){if(this.config.baseUrl)return this.config.baseUrl;if(typeof window<"u"){let e=window.location.hostname;if(e==="localhost"||e.includes(".test")||e.includes(".local")||e==="127.0.0.1")return`${window.location.protocol}//${window.location.host}/api`}return"https://api.recur.tw"}async initCheckout(){let e=this.getBaseUrl(),t=await fetch(`${e}/v1/checkouts`,{method:"POST",headers:{"Content-Type":"application/json","X-Recur-Publishable-Key":this.config.publishableKey},body:JSON.stringify({productId:this.options.productId||this.options.planId,customerEmail:this.options.customerEmail,customerName:this.options.customerName})});if(!t.ok){let i=await t.json().catch(()=>({}));throw new Error(i.error||"Failed to initialize checkout")}let r=await t.json(),o=w(r);this.checkoutId=o.checkout.id,this.sdkToken=o.sdkToken,this.sdkTimestamp=o.sdkTimestamp||null,this.creditToken=o.creditToken||null,this.sdkEnv=this.config.publishableKey.startsWith("pk_test_")?"S":"P"}renderHTML(){this.container.innerHTML=`
2104
+ `}setupEventListeners(){let t=this.shadowRoot?.querySelector("button");t&&t.addEventListener("click",this.handleClick)}redirectToPortal(t){let r=this.getAttribute("target");this.dispatchEvent(new CustomEvent("portal-redirect",{detail:{url:t},bubbles:!0,composed:!0})),r==="_blank"?window.open(t,"_blank","noopener,noreferrer"):window.location.href=t}async fetchAndRedirect(t){let r=this.getAttribute("customer-id"),o=this.getAttribute("return-url");this._isLoading=!0,this.render(),this.setupEventListeners();try{let i={};r&&(i.customerId=r),o&&(i.returnUrl=o);let n=await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(i)});if(!n.ok){let u=await n.json().catch(()=>({}));throw new Error(u.error?.message||u.message||`HTTP ${n.status}: Failed to create portal session`)}let a=await n.json(),c=a.url||a.portalUrl;if(!c)throw new Error("Portal URL not found in response");this._isLoading=!1,this.render(),this.setupEventListeners(),this.redirectToPortal(c)}catch(i){this._isLoading=!1,this.render(),this.setupEventListeners(),this.dispatchError(i instanceof Error?i.message:"Failed to create portal session")}}dispatchError(t){console.error("[recur-portal]",t),this.dispatchEvent(new CustomEvent("portal-error",{detail:{message:t},bubbles:!0,composed:!0}))}};typeof window<"u"&&!customElements.get("recur-portal")&&customElements.define("recur-portal",pe)});var Qt={};S(Qt,{RecurCheckout:()=>O,RecurElements:()=>z,create:()=>kt,createElements:()=>$e,default:()=>Zt,init:()=>vt});async function jt(){if(typeof window>"u"){console.warn("[Recur SDK] Cannot register Web Components: window is not defined");return}await Promise.all([Promise.resolve().then(()=>(Le(),Me)),Promise.resolve().then(()=>(He(),Ue)),Promise.resolve().then(()=>(Be(),Ne)),Promise.resolve().then(()=>(Oe(),ze)),Promise.resolve().then(()=>(tt(),et)),Promise.resolve().then(()=>(ot(),rt)),Promise.resolve().then(()=>(pt(),dt)),Promise.resolve().then(()=>(ht(),mt)),Promise.resolve().then(()=>(ft(),gt))]);let e=["recur-loading-spinner","recur-success-message","recur-error-display","recur-skeleton-loader","recur-payment-form-skeleton","recur-toast","recur-toast-container","recur-payment-form","recur-checkout","recur-portal"].filter(t=>!customElements.get(t));e.length>0&&console.warn("[Recur SDK] The following components are not registered:",e)}typeof window<"u"&&jt();function Ft(s){return s.replace(/_([a-z])/g,(e,t)=>t.toUpperCase())}function w(s){if(s==null)return s;if(Array.isArray(s))return s.map(e=>w(e));if(s instanceof Date)return s;if(typeof s=="object"){let e={};for(let[t,r]of Object.entries(s)){let o=Ft(t);e[o]=w(r)}return e}return s}var me={name:"recur-tw",version:"0.13.3",description:"React & Vanilla JS SDK for embedding subscription checkout flows (Taiwan / PAYUNi)",type:"module",private:!1,author:"Recur",license:"Elastic-2.0",keywords:["react","vanilla-js","subscription","checkout","payment","payuni","recurring-billing","taiwan","\u7E41\u9AD4\u4E2D\u6587","sdk","embedded-checkout"],homepage:"https://recur.tw/",bugs:{email:"support@recur.tw"},scripts:{build:"tsup",dev:"tsup --watch",lint:"eslint .","lint:fix":"eslint . --fix","type-check":"tsc --noEmit",examples:"npx http-server . -p 8080 -o /examples/"},main:"./dist/index.js",module:"./dist/index.js",types:"./dist/index.d.ts",exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.js",require:"./dist/index.cjs"},"./server":{types:"./dist/server.d.ts",import:"./dist/server.js",require:"./dist/server.cjs"},"./vanilla":"./dist/recur.umd.js","./checkout":"./dist/checkout.js","./widget":"./dist/widget.js","./package.json":"./package.json"},unpkg:"./dist/recur.umd.js",jsdelivr:"./dist/recur.umd.js",files:["dist","README.md","AGENTS.md","LICENSE"],sideEffects:["src/components/**/*.ts","src/components/**/*.js"],peerDependencies:{react:">=18.0.0","react-dom":">=18.0.0"},peerDependenciesMeta:{react:{optional:!0},"react-dom":{optional:!0}},devDependencies:{"@eslint/js":"^9.39.1","@types/node":"^20.19.9","@types/react":"^19.1.9","@types/react-dom":"^19.1.7","@workspace/typescript-config":"workspace:*",autoprefixer:"^10.4.22",eslint:"^9","eslint-plugin-react":"^7.37.5","eslint-plugin-react-hooks":"^7.0.1",postcss:"^8.5.6",react:"^19.2.1","react-dom":"^19.2.1",tailwindcss:"^4.1.11",tsup:"^8.3.5",typescript:"^5.9.2","typescript-eslint":"^8.47.0"},dependencies:{"lit-html":"^3.3.1"}};var qt=me.version,Yt="vanilla",he=class{constructor(e){l(this,"config");if(!e.publishableKey)throw new Error("publishableKey is required");this.config={baseUrl:"https://api.recur.tw",...e}}getHeaders(){return{"Content-Type":"application/json","X-Recur-Publishable-Key":this.config.publishableKey,"X-Recur-SDK-Type":Yt,"X-Recur-SDK-Version":qt,"X-Recur-Source":typeof window<"u"?window.location.origin:"server"}}async createSubscription(e){let{customerName:t,customerEmail:r}=e,o=e.productId||e.planId,i=e.productSlug;if(!o&&!i)throw new Error("Either productId or productSlug is required");let n={customerName:t,customerEmail:r};o&&(n.productId=o),i&&(n.productSlug=i);let a=await fetch(`${this.config.baseUrl}/v1/subscriptions`,{method:"POST",headers:this.getHeaders(),body:JSON.stringify(n)});if(!a.ok){let u=await a.json().catch(()=>({}));throw{code:u.error||"CHECKOUT_FAILED",message:u.message||"Failed to initiate checkout",details:u}}let c=await a.json();return w(c)}async fetchProducts(e){let t=new URL(`${this.config.baseUrl}/v1/products`);e?.type&&t.searchParams.set("type",e.type);let r=await fetch(t.toString(),{method:"GET",headers:this.getHeaders()});if(!r.ok){let i=await r.json().catch(()=>({}));throw{code:i.error||"FETCH_PRODUCTS_FAILED",message:i.message||"Failed to fetch products",details:i}}let o=await r.json();return w(o)}async fetchPlans(){return{plans:(await this.fetchProducts({type:"SUBSCRIPTION"})).data}}getConfig(){return{...this.config}}};var ge=class{constructor(e,t){l(this,"config");l(this,"options");l(this,"container");l(this,"checkoutId",null);l(this,"sdkToken",null);l(this,"sdkTimestamp",null);l(this,"creditToken",null);l(this,"sdkEnv","S");l(this,"payuniSDK",null);l(this,"isFormValid",!1);if(this.config=e,this.options=t,typeof t.container=="string"){let r=document.querySelector(t.container);if(!r)throw new Error(`Container not found: ${t.container}`);this.container=r}else this.container=t.container}async render(){try{await this.initCheckout(),this.renderHTML(),await this.loadPayUniSDK(),await this.initPayUniSDK(),this.setupFormSubmit()}catch(e){this.handleError(e)}}getBaseUrl(){if(this.config.baseUrl)return this.config.baseUrl;if(typeof window<"u"){let e=window.location.hostname;if(e==="localhost"||e.includes(".test")||e.includes(".local")||e==="127.0.0.1")return`${window.location.protocol}//${window.location.host}/api`}return"https://api.recur.tw"}async initCheckout(){let e=this.getBaseUrl(),t=await fetch(`${e}/v1/checkouts`,{method:"POST",headers:{"Content-Type":"application/json","X-Recur-Publishable-Key":this.config.publishableKey},body:JSON.stringify({productId:this.options.productId||this.options.planId,customerEmail:this.options.customerEmail,customerName:this.options.customerName})});if(!t.ok){let i=await t.json().catch(()=>({}));throw new Error(i.error||"Failed to initialize checkout")}let r=await t.json(),o=w(r);this.checkoutId=o.checkout.id,this.sdkToken=o.sdkToken,this.sdkTimestamp=o.sdkTimestamp||null,this.creditToken=o.creditToken||null,this.sdkEnv=o.livemode?"P":"S"}renderHTML(){this.container.innerHTML=`
2105
2105
  <div class="recur-embedded-checkout" style="max-width: 400px; margin: 0 auto; padding: 20px; font-family: system-ui, -apple-system, sans-serif;">
2106
2106
  <div class="recur-checkout-header" style="margin-bottom: 24px;">
2107
2107
  <h2 style="margin: 0 0 8px 0; font-size: 20px; font-weight: 600; color: #111;">Subscribe</h2>
package/dist/server.cjs CHANGED
@@ -24,7 +24,7 @@ var RecurAPIError = class extends Error {
24
24
 
25
25
  // package.json
26
26
  var package_default = {
27
- version: "0.13.2"};
27
+ version: "0.13.3"};
28
28
 
29
29
  // src/server/resources/portal.ts
30
30
  var SDK_VERSION = package_default.version;
package/dist/server.js CHANGED
@@ -22,7 +22,7 @@ var RecurAPIError = class extends Error {
22
22
 
23
23
  // package.json
24
24
  var package_default = {
25
- version: "0.13.2"};
25
+ version: "0.13.3"};
26
26
 
27
27
  // src/server/resources/portal.ts
28
28
  var SDK_VERSION = package_default.version;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "recur-tw",
3
- "version": "0.13.2",
3
+ "version": "0.14.0",
4
4
  "description": "React & Vanilla JS SDK for embedding subscription checkout flows (Taiwan / PAYUNi)",
5
5
  "type": "module",
6
6
  "private": false,