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 +5 -6
- package/dist/index.d.cts +6 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.js +5 -6
- package/dist/recur.umd.js +1 -1
- package/dist/server.cjs +1 -1
- package/dist/server.js +1 -1
- package/package.json +1 -1
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.
|
|
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.
|
|
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.
|
|
3684
|
-
onSuccess?.(result.
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
3678
|
-
onSuccess?.(result.
|
|
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.
|
|
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
package/dist/server.js
CHANGED