@nextblock-cms/ecom 0.22.2 → 0.22.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.cjs +1 -1
- package/index.es.js +31 -31
- package/lib/components/Checkout.cjs +1 -1
- package/lib/components/Checkout.es.js +1 -0
- package/lib/components/SubscriptionSelector.cjs +1 -1
- package/lib/components/SubscriptionSelector.es.js +91 -92
- package/lib/coupon-server.cjs +1 -1
- package/lib/coupon-server.es.js +78 -61
- package/lib/coupons.cjs +1 -1
- package/lib/coupons.d.ts +9 -0
- package/lib/coupons.es.js +11 -2
- package/lib/currency-sync.cjs +1 -1
- package/lib/currency-sync.es.js +1 -1
- package/lib/freemius-coupons.cjs +1 -1
- package/lib/freemius-coupons.es.js +88 -92
- package/lib/freemius-license-claim.cjs +1 -1
- package/lib/freemius-license-claim.d.ts +13 -0
- package/lib/freemius-license-claim.es.js +44 -29
- package/lib/freemius-license.cjs +1 -1
- package/lib/freemius-license.es.js +19 -17
- package/lib/freemius-order-sync.cjs +1 -1
- package/lib/freemius-order-sync.d.ts +44 -0
- package/lib/freemius-order-sync.es.js +164 -77
- package/lib/freemius-pricing-server.cjs +1 -0
- package/lib/freemius-pricing-server.d.ts +65 -0
- package/lib/freemius-pricing-server.es.js +82 -0
- package/lib/freemius-pricing.cjs +1 -0
- package/lib/freemius-pricing.d.ts +53 -0
- package/lib/freemius-pricing.es.js +51 -0
- package/lib/invoice-server.cjs +1 -1
- package/lib/invoice-server.es.js +1 -0
- package/lib/pages/cms/coupons/CouponsPage.cjs +1 -1
- package/lib/pages/cms/coupons/CouponsPage.es.js +1 -0
- package/lib/pages/cms/coupons/EditCouponPage.cjs +1 -1
- package/lib/pages/cms/coupons/EditCouponPage.es.js +1 -0
- package/lib/pages/cms/coupons/actions.cjs +1 -1
- package/lib/pages/cms/coupons/actions.es.js +1 -0
- package/lib/pages/cms/orders/actions.cjs +1 -1
- package/lib/pages/cms/orders/actions.es.js +1 -0
- package/lib/pages/cms/orders/export-actions.cjs +1 -1
- package/lib/pages/cms/orders/export-actions.es.js +1 -0
- package/lib/pages/cms/orders/server-actions.cjs +1 -1
- package/lib/pages/cms/orders/server-actions.es.js +1 -0
- package/lib/pages/cms/products/ProductsPage.cjs +1 -1
- package/lib/pages/cms/products/ProductsPage.es.js +1 -0
- package/lib/pages/cms/products/[id]/edit/EditProductPage.cjs +1 -1
- package/lib/pages/cms/products/[id]/edit/EditProductPage.es.js +1 -0
- package/lib/pages/cms/products/actions.cjs +3 -3
- package/lib/pages/cms/products/actions.d.ts +11 -5
- package/lib/pages/cms/products/actions.es.js +45 -12
- package/lib/pages/cms/products/inventory/actions.cjs +1 -1
- package/lib/pages/cms/products/inventory/actions.es.js +1 -0
- package/lib/pages/cms/products/new/NewProductPage.cjs +1 -1
- package/lib/pages/cms/products/new/NewProductPage.es.js +1 -0
- package/lib/pages/cms/products/server-actions.cjs +1 -1
- package/lib/pages/cms/products/server-actions.es.js +1 -0
- package/lib/pages/cms/shipping/ShippingPage.cjs +1 -1
- package/lib/pages/cms/shipping/ShippingPage.es.js +1 -0
- package/lib/pages/cms/shipping/server-actions.cjs +1 -1
- package/lib/pages/cms/shipping/server-actions.es.js +1 -0
- package/lib/pages/cms/taxes/TaxesPage.cjs +1 -1
- package/lib/pages/cms/taxes/TaxesPage.es.js +1 -0
- package/lib/payment-config.cjs +1 -1
- package/lib/payment-config.es.js +1 -0
- package/lib/providers/freemius.cjs +1 -1
- package/lib/providers/freemius.es.js +200 -187
- package/lib/providers/stripe.cjs +1 -1
- package/lib/providers/stripe.es.js +151 -150
- package/lib/server-actions/coupon-actions.cjs +1 -1
- package/lib/server-actions/coupon-actions.es.js +1 -0
- package/lib/server-actions/customer-actions.d.ts +6 -1
- package/lib/server-actions/require-ecom-role.cjs +1 -1
- package/lib/server-actions/require-ecom-role.es.js +22 -10
- package/lib/server-actions/tax-actions.cjs +1 -1
- package/lib/server-actions/tax-actions.es.js +1 -0
- package/lib/shared-inventory.cjs +1 -1
- package/lib/shared-inventory.es.js +1 -1
- package/lib/stripe/checkout.cjs +1 -1
- package/lib/stripe/checkout.es.js +1 -0
- package/lib/stripe/order-sync.cjs +1 -1
- package/lib/stripe/order-sync.es.js +1 -0
- package/lib/stripe/webhooks.cjs +1 -1
- package/lib/stripe/webhooks.d.ts +10 -0
- package/lib/stripe/webhooks.es.js +23 -10
- package/package.json +4 -4
- package/server.cjs +1 -1
- package/server.es.js +31 -31
|
@@ -1,21 +1,24 @@
|
|
|
1
|
-
import { getDefaultCurrency as e, isSaleWindowActive as t
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import f from "
|
|
10
|
-
import
|
|
1
|
+
import { getDefaultCurrency as e, isSaleWindowActive as t } from "../currency.es.js";
|
|
2
|
+
import { reconcileCouponContextItems as n } from "../coupons.es.js";
|
|
3
|
+
import { FREEMIUS_PRICED_PRODUCT_COLUMNS as r, resolveFreemiusUnitAmount as i } from "../freemius-pricing-server.es.js";
|
|
4
|
+
import { getCouponQuote as a, recordCouponRedemption as o } from "../coupon-server.es.js";
|
|
5
|
+
import { normalizeOrderCustomerDetails as s } from "../customer.es.js";
|
|
6
|
+
import { fillMissingUserProfileCheckoutDetails as c, upsertDefaultUserAddresses as l } from "../customer-addresses.es.js";
|
|
7
|
+
import { hydrateFreemiusEnvFromDb as u } from "../payment-config.es.js";
|
|
8
|
+
import { mintOrderAccessToken as d } from "../order-access-token.es.js";
|
|
9
|
+
import { createInvalidCheckoutItemsError as f, normalizeCheckoutItems as p } from "./checkout-items.es.js";
|
|
10
|
+
import "server-only";
|
|
11
|
+
import { createClient as m } from "@supabase/supabase-js";
|
|
12
|
+
import h from "crypto";
|
|
13
|
+
import { Freemius as g } from "@freemius/sdk";
|
|
11
14
|
//#region src/lib/providers/freemius.ts
|
|
12
|
-
function
|
|
15
|
+
function _(e) {
|
|
13
16
|
let t = process.env[e];
|
|
14
17
|
if (!t) return null;
|
|
15
18
|
let n = t.trim();
|
|
16
19
|
return n.startsWith("\"") && n.endsWith("\"") || n.startsWith("'") && n.endsWith("'") ? n.slice(1, -1).trim() : n;
|
|
17
20
|
}
|
|
18
|
-
function
|
|
21
|
+
function v(e) {
|
|
19
22
|
let t = e?.trim();
|
|
20
23
|
if (!t) return {
|
|
21
24
|
firstName: null,
|
|
@@ -27,39 +30,39 @@ function h(e) {
|
|
|
27
30
|
lastName: r.length > 0 ? r.join(" ") : null
|
|
28
31
|
};
|
|
29
32
|
}
|
|
30
|
-
function
|
|
33
|
+
function y(e) {
|
|
31
34
|
if (e == null || e === "") return 0;
|
|
32
35
|
let t = Number(e);
|
|
33
36
|
return !Number.isFinite(t) || t <= 0 ? 0 : Math.round(t);
|
|
34
37
|
}
|
|
35
|
-
function
|
|
38
|
+
function b(e) {
|
|
36
39
|
return e === !0 || e === 1 || e === "1" || e === "true";
|
|
37
40
|
}
|
|
38
|
-
function
|
|
41
|
+
function x(e, t) {
|
|
39
42
|
let n = e?.[t];
|
|
40
43
|
return Array.isArray(n) ? n : n && typeof n == "object" ? [n] : [];
|
|
41
44
|
}
|
|
42
|
-
function
|
|
45
|
+
function S(e, t) {
|
|
43
46
|
for (let n of t) {
|
|
44
|
-
let t =
|
|
47
|
+
let t = x(e, n);
|
|
45
48
|
if (t.length > 0) return t;
|
|
46
49
|
}
|
|
47
50
|
return Array.isArray(e) ? e : [];
|
|
48
51
|
}
|
|
49
|
-
function
|
|
52
|
+
function C(e) {
|
|
50
53
|
if (e == null || e === "") return null;
|
|
51
54
|
let t = Number(e);
|
|
52
55
|
return Number.isFinite(t) ? t : null;
|
|
53
56
|
}
|
|
54
|
-
function
|
|
57
|
+
function w(e) {
|
|
55
58
|
return e === null ? 0 : e > 5e3 ? (console.warn(`[Freemius Sync] Suspiciously high price detected: ${e}. Assuming it is already in cents.`), Math.round(e)) : Math.round(e * 100);
|
|
56
59
|
}
|
|
57
|
-
function
|
|
60
|
+
function T(e) {
|
|
58
61
|
let t = Number(e);
|
|
59
62
|
return !Number.isFinite(t) || t < 1 ? 1 : Math.round(t);
|
|
60
63
|
}
|
|
61
|
-
function
|
|
62
|
-
let e =
|
|
64
|
+
function E() {
|
|
65
|
+
let e = _("FREEMIUS_CHECKOUT_PRODUCTS_JSON");
|
|
63
66
|
if (!e) return null;
|
|
64
67
|
try {
|
|
65
68
|
let t = JSON.parse(e);
|
|
@@ -68,8 +71,8 @@ function C() {
|
|
|
68
71
|
return console.error("[Freemius Checkout] Failed to parse FREEMIUS_CHECKOUT_PRODUCTS_JSON:", e), null;
|
|
69
72
|
}
|
|
70
73
|
}
|
|
71
|
-
function
|
|
72
|
-
let t =
|
|
74
|
+
function D(e) {
|
|
75
|
+
let t = E(), n = String(e), r = t?.[n], i = _("FREEMIUS_PRODUCT_ID"), a = _("FREEMIUS_ECOMMERCE_SANDBOX_PUBLIC_KEY"), o = _("FREEMIUS_ECOMMERCE_SANDBOX_SECRET_KEY");
|
|
73
76
|
return r?.publicKey ? {
|
|
74
77
|
publicKey: r.publicKey,
|
|
75
78
|
secretKey: r.secretKey ?? null,
|
|
@@ -78,99 +81,109 @@ function w(e) {
|
|
|
78
81
|
} : process.env.FREEMIUS_SANDBOX_ENABLED === "true" && i && i === n && a ? {
|
|
79
82
|
publicKey: a,
|
|
80
83
|
secretKey: o,
|
|
81
|
-
apiKey:
|
|
84
|
+
apiKey: _("FREEMIUS_API_KEY"),
|
|
82
85
|
source: "single-product-sandbox-env"
|
|
83
|
-
} : i && i === n &&
|
|
84
|
-
publicKey:
|
|
85
|
-
secretKey:
|
|
86
|
-
apiKey:
|
|
86
|
+
} : i && i === n && _("FREEMIUS_PUBLIC_KEY") ? {
|
|
87
|
+
publicKey: _("FREEMIUS_PUBLIC_KEY"),
|
|
88
|
+
secretKey: _("FREEMIUS_SECRET_KEY"),
|
|
89
|
+
apiKey: _("FREEMIUS_API_KEY"),
|
|
87
90
|
source: "single-product-env"
|
|
88
91
|
} : {
|
|
89
|
-
publicKey:
|
|
90
|
-
secretKey:
|
|
91
|
-
apiKey:
|
|
92
|
+
publicKey: _("FREEMIUS_PUBLIC_KEY"),
|
|
93
|
+
secretKey: _("FREEMIUS_SECRET_KEY"),
|
|
94
|
+
apiKey: _("FREEMIUS_API_KEY"),
|
|
92
95
|
source: "legacy-env"
|
|
93
96
|
};
|
|
94
97
|
}
|
|
95
|
-
async function
|
|
98
|
+
async function O(e) {
|
|
96
99
|
if (!e.apiKey) throw Error("Missing Freemius API key for SDK sandbox generation.");
|
|
97
|
-
return new
|
|
100
|
+
return new g({
|
|
98
101
|
productId: Number(e.productId),
|
|
99
102
|
apiKey: e.apiKey,
|
|
100
103
|
secretKey: e.secretKey,
|
|
101
104
|
publicKey: e.publicKey
|
|
102
105
|
}).checkout.getSandboxParams();
|
|
103
106
|
}
|
|
104
|
-
var
|
|
107
|
+
var k = class {
|
|
105
108
|
getProviderName() {
|
|
106
109
|
return "Freemius";
|
|
107
110
|
}
|
|
108
|
-
async createCheckoutSession({ items:
|
|
109
|
-
let
|
|
110
|
-
if (!
|
|
111
|
+
async createCheckoutSession({ items: g, customerEmail: b, customerPhone: x, userId: S, billingAddress: C, shippingAddress: w, currencyCode: T, couponCode: E, couponContextItems: k }) {
|
|
112
|
+
let A = process.env.NEXT_PUBLIC_SUPABASE_URL || process.env.SUPABASE_URL, j = process.env.SUPABASE_SERVICE_ROLE_KEY || process.env.SUPABASE_SECRET_KEY;
|
|
113
|
+
if (!A || !j) return {
|
|
111
114
|
error: "Missing Supabase credentials for checkout (Service Key required).",
|
|
112
115
|
url: null
|
|
113
116
|
};
|
|
114
|
-
let
|
|
115
|
-
if (!
|
|
117
|
+
let M = m(A, j);
|
|
118
|
+
if (!g || g.length === 0) return {
|
|
116
119
|
error: "Cart is empty",
|
|
117
120
|
url: null
|
|
118
121
|
};
|
|
119
|
-
if (
|
|
122
|
+
if (g.length !== 1) return {
|
|
120
123
|
error: "Freemius items must be checked out one at a time.",
|
|
121
124
|
url: null
|
|
122
125
|
};
|
|
123
|
-
let
|
|
124
|
-
if (!
|
|
126
|
+
let N = p(g);
|
|
127
|
+
if (!N.ok) return {
|
|
125
128
|
url: null,
|
|
126
|
-
...
|
|
129
|
+
...N.error
|
|
127
130
|
};
|
|
128
|
-
let ee =
|
|
129
|
-
if (
|
|
130
|
-
let e =
|
|
131
|
+
let ee = N.items;
|
|
132
|
+
if (k && k.length > 0) {
|
|
133
|
+
let e = p(k);
|
|
131
134
|
if (!e.ok) return {
|
|
132
135
|
url: null,
|
|
133
136
|
...e.error
|
|
134
137
|
};
|
|
135
|
-
ee = e.items;
|
|
138
|
+
ee = n(N.items, e.items);
|
|
136
139
|
}
|
|
137
|
-
let { data: te, error: ne } = await
|
|
138
|
-
if (ne ||
|
|
140
|
+
let { data: te, error: ne } = await M.from("currencies").select("code, symbol, exchange_rate, is_default, is_active, auto_sync_product_prices, auto_update_exchange_rate, exchange_rate_source, exchange_rate_updated_at, rounding_mode, rounding_increment, rounding_charm_amount").eq("is_active", !0).order("code", { ascending: !0 }), P = te ?? [];
|
|
141
|
+
if (ne || P.length === 0) return {
|
|
139
142
|
error: "Failed to resolve store currencies",
|
|
140
143
|
url: null
|
|
141
144
|
};
|
|
142
|
-
let re = e(
|
|
143
|
-
if (ie || !
|
|
145
|
+
let re = e(P), F = P.find((e) => e.code === (T || "").toUpperCase()) ?? re, I = N.items[0], { data: L, error: ie } = await M.from("products").select(`${r}, title, freemius_plan_id, freemius_product_id, trial_period_days, trial_requires_payment_method`).eq("id", I.product_id).single();
|
|
146
|
+
if (ie || !L) return {
|
|
144
147
|
error: "Product not found",
|
|
145
148
|
url: null
|
|
146
149
|
};
|
|
147
|
-
let
|
|
148
|
-
if (!
|
|
150
|
+
let R = L.freemius_plan_id, z = L.freemius_product_id;
|
|
151
|
+
if (!R || !z) return {
|
|
149
152
|
error: "Product is not configured for Freemius checkout (missing Plan ID or Product ID)",
|
|
150
153
|
url: null
|
|
151
154
|
};
|
|
152
|
-
let
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
155
|
+
let B;
|
|
156
|
+
try {
|
|
157
|
+
B = await i({
|
|
158
|
+
client: M,
|
|
159
|
+
product: L,
|
|
160
|
+
billingCycle: I.billing_cycle,
|
|
161
|
+
currencyCode: F.code,
|
|
162
|
+
currencies: P
|
|
163
|
+
});
|
|
164
|
+
} catch (e) {
|
|
165
|
+
return console.error("Failed to resolve Freemius pricing:", e), {
|
|
166
|
+
error: "Failed to resolve product pricing",
|
|
167
|
+
url: null
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
if (!B.ok) return {
|
|
171
|
+
url: null,
|
|
172
|
+
...f()
|
|
173
|
+
};
|
|
174
|
+
let ae = B.unitAmount, V = B.billingCycle, oe = t({
|
|
175
|
+
saleStartAt: L.sale_start_at,
|
|
176
|
+
saleEndAt: L.sale_end_at
|
|
177
|
+
}), H = ae * I.quantity, U = null, W = 0;
|
|
178
|
+
if (E) {
|
|
179
|
+
let e = await a({
|
|
180
|
+
client: M,
|
|
181
|
+
code: E,
|
|
182
|
+
items: ee.map((e) => e.product_id === L.id ? {
|
|
183
|
+
...e,
|
|
184
|
+
billing_cycle: V ?? void 0
|
|
185
|
+
} : e),
|
|
186
|
+
currencyCode: F.code
|
|
174
187
|
});
|
|
175
188
|
if (!e.success) return {
|
|
176
189
|
error: e.error,
|
|
@@ -178,83 +191,83 @@ var E = class {
|
|
|
178
191
|
errorStatus: 400,
|
|
179
192
|
url: null
|
|
180
193
|
};
|
|
181
|
-
|
|
194
|
+
U = e.quote, W = Math.min(H, U.lineDiscounts.filter((e) => e.product_id === L.id).reduce((e, t) => e + t.discount, 0));
|
|
182
195
|
}
|
|
183
|
-
let
|
|
184
|
-
status:
|
|
185
|
-
total: Math.max(0,
|
|
186
|
-
currency:
|
|
187
|
-
exchange_rate_at_purchase:
|
|
188
|
-
subtotal:
|
|
189
|
-
discount_total:
|
|
190
|
-
coupon_id:
|
|
191
|
-
coupon_code:
|
|
192
|
-
discount_details:
|
|
193
|
-
code:
|
|
194
|
-
discount_type:
|
|
195
|
-
discount_amount:
|
|
196
|
+
let se = y(L.trial_period_days), G = se > 0 ? I.trial_preference ? I.trial_preference : L.trial_requires_payment_method ? "paid" : "free" : null, ce = "pending", K = v(C?.recipient_name ?? null), { data: q, error: le } = await M.from("orders").insert({
|
|
197
|
+
status: ce,
|
|
198
|
+
total: Math.max(0, H - W),
|
|
199
|
+
currency: F.code,
|
|
200
|
+
exchange_rate_at_purchase: F.exchange_rate,
|
|
201
|
+
subtotal: H,
|
|
202
|
+
discount_total: W,
|
|
203
|
+
coupon_id: U?.couponId ?? null,
|
|
204
|
+
coupon_code: U?.code ?? null,
|
|
205
|
+
discount_details: U ? {
|
|
206
|
+
code: U.code,
|
|
207
|
+
discount_type: U.discountType,
|
|
208
|
+
discount_amount: U.discountAmount,
|
|
196
209
|
provider: "freemius",
|
|
197
|
-
provider_discounts:
|
|
198
|
-
line_discounts:
|
|
210
|
+
provider_discounts: U.providerDiscounts,
|
|
211
|
+
line_discounts: U.lineDiscounts,
|
|
199
212
|
final_amount_owned_by: "freemius"
|
|
200
213
|
} : null,
|
|
201
214
|
provider: "freemius",
|
|
202
|
-
freemius_product_id: String(
|
|
203
|
-
freemius_plan_id: String(
|
|
204
|
-
user_id:
|
|
205
|
-
customer_details:
|
|
206
|
-
email:
|
|
207
|
-
phone:
|
|
208
|
-
name:
|
|
209
|
-
billing:
|
|
210
|
-
shipping:
|
|
215
|
+
freemius_product_id: String(z),
|
|
216
|
+
freemius_plan_id: String(R),
|
|
217
|
+
user_id: S || null,
|
|
218
|
+
customer_details: s({
|
|
219
|
+
email: b,
|
|
220
|
+
phone: x,
|
|
221
|
+
name: C?.recipient_name,
|
|
222
|
+
billing: C,
|
|
223
|
+
shipping: w
|
|
211
224
|
})
|
|
212
225
|
}).select("id").single();
|
|
213
|
-
if (
|
|
226
|
+
if (le || !q) return console.error("Failed to create pending order:", le), {
|
|
214
227
|
error: "Failed to initiate order",
|
|
215
228
|
url: null
|
|
216
229
|
};
|
|
217
|
-
let { error:
|
|
218
|
-
order_id:
|
|
219
|
-
product_id:
|
|
220
|
-
quantity:
|
|
230
|
+
let { error: ue } = await M.from("order_items").insert([{
|
|
231
|
+
order_id: q.id,
|
|
232
|
+
product_id: L.id,
|
|
233
|
+
quantity: I.quantity,
|
|
221
234
|
price_at_purchase: ae
|
|
222
235
|
}]);
|
|
223
|
-
if (
|
|
224
|
-
await
|
|
225
|
-
userId:
|
|
226
|
-
billingAddress:
|
|
227
|
-
shippingAddress:
|
|
228
|
-
client:
|
|
229
|
-
}), await
|
|
230
|
-
userId:
|
|
231
|
-
fullName:
|
|
232
|
-
phone:
|
|
233
|
-
client:
|
|
236
|
+
if (ue && console.error("Failed to insert order items:", ue), S) try {
|
|
237
|
+
await l({
|
|
238
|
+
userId: S,
|
|
239
|
+
billingAddress: C,
|
|
240
|
+
shippingAddress: w,
|
|
241
|
+
client: M
|
|
242
|
+
}), await c({
|
|
243
|
+
userId: S,
|
|
244
|
+
fullName: C?.recipient_name ?? w?.recipient_name ?? null,
|
|
245
|
+
phone: x,
|
|
246
|
+
client: M
|
|
234
247
|
});
|
|
235
248
|
} catch (e) {
|
|
236
249
|
console.error("Failed to sync checkout profile defaults before checkout:", e);
|
|
237
250
|
}
|
|
238
|
-
if (
|
|
239
|
-
client:
|
|
240
|
-
quote:
|
|
241
|
-
orderId:
|
|
251
|
+
if (U && !(await o({
|
|
252
|
+
client: M,
|
|
253
|
+
quote: U,
|
|
254
|
+
orderId: q.id,
|
|
242
255
|
provider: "freemius",
|
|
243
|
-
discountTotal:
|
|
244
|
-
userId:
|
|
245
|
-
customerEmail:
|
|
256
|
+
discountTotal: W,
|
|
257
|
+
userId: S,
|
|
258
|
+
customerEmail: b,
|
|
246
259
|
metadata: {
|
|
247
|
-
currency:
|
|
248
|
-
subtotal:
|
|
260
|
+
currency: F.code,
|
|
261
|
+
subtotal: H,
|
|
249
262
|
final_amount_owned_by: "freemius"
|
|
250
263
|
}
|
|
251
|
-
})).success) return await
|
|
264
|
+
})).success) return await M.from("orders").update({ status: "failed" }).eq("id", q.id), {
|
|
252
265
|
url: null,
|
|
253
266
|
error: "Coupon is no longer available.",
|
|
254
267
|
errorKey: "ecommerce.coupon_invalid"
|
|
255
268
|
};
|
|
256
|
-
await
|
|
257
|
-
let J = process.env.FREEMIUS_SANDBOX_ENABLED === "true", Y =
|
|
269
|
+
await u();
|
|
270
|
+
let J = process.env.FREEMIUS_SANDBOX_ENABLED === "true", Y = D(z), X = Y.publicKey, Z = Y.secretKey, de = Y.apiKey;
|
|
258
271
|
if (!X || J && !Z) return console.error("Freemius checkout blocked: missing credentials (PUBLIC_KEY or SECRET_KEY) in CMS → Payments or environment."), {
|
|
259
272
|
error: "This store is not able to take payments right now. Please contact the seller to complete your purchase.",
|
|
260
273
|
errorKey: "ecommerce.checkout_payments_unavailable",
|
|
@@ -262,38 +275,38 @@ var E = class {
|
|
|
262
275
|
url: null
|
|
263
276
|
};
|
|
264
277
|
if (J && Y.source === "legacy-env") {
|
|
265
|
-
let e =
|
|
266
|
-
console.warn(`[Freemius Checkout] Sandbox is enabled for product ${
|
|
278
|
+
let e = _("FREEMIUS_PRODUCT_ID"), t = !!_("FREEMIUS_ECOMMERCE_SANDBOX_PUBLIC_KEY"), n = !!_("FREEMIUS_ECOMMERCE_SANDBOX_SECRET_KEY");
|
|
279
|
+
console.warn(`[Freemius Checkout] Sandbox is enabled for product ${z}, but no product-scoped checkout credentials were selected. Falling back to legacy FREEMIUS_PUBLIC_KEY/FREEMIUS_SECRET_KEY may open live checkout instead of sandbox.`, {
|
|
267
280
|
configuredProductId: e,
|
|
268
|
-
productIdsMatch: e === String(
|
|
281
|
+
productIdsMatch: e === String(z),
|
|
269
282
|
hasSandboxOverridePublicKey: t,
|
|
270
283
|
hasSandboxOverrideSecretKey: n,
|
|
271
|
-
hasCheckoutProductsJson: !!
|
|
284
|
+
hasCheckoutProductsJson: !!_("FREEMIUS_CHECKOUT_PRODUCTS_JSON")
|
|
272
285
|
});
|
|
273
286
|
}
|
|
274
287
|
let Q = !1;
|
|
275
288
|
if (J && Z && X) try {
|
|
276
|
-
Q = await
|
|
277
|
-
productId:
|
|
289
|
+
Q = await O({
|
|
290
|
+
productId: z,
|
|
278
291
|
publicKey: X,
|
|
279
292
|
secretKey: Z,
|
|
280
|
-
apiKey:
|
|
293
|
+
apiKey: de
|
|
281
294
|
});
|
|
282
295
|
} catch (e) {
|
|
283
296
|
console.warn("Freemius Checkout - SDK sandbox generation failed. Falling back to manual token generation.", e, {
|
|
284
297
|
credentialSource: Y.source,
|
|
285
|
-
hasApiKey: !!
|
|
298
|
+
hasApiKey: !!de
|
|
286
299
|
});
|
|
287
|
-
let t = Math.floor(Date.now() / 1e3).toString(), n = `${t}${
|
|
300
|
+
let t = Math.floor(Date.now() / 1e3).toString(), n = `${t}${z}${Z}${X}checkout`;
|
|
288
301
|
Q = {
|
|
289
302
|
ctx: t,
|
|
290
|
-
token:
|
|
303
|
+
token: h.createHash("md5").update(n).digest("hex")
|
|
291
304
|
};
|
|
292
305
|
}
|
|
293
|
-
let $ = new URL(`https://checkout.freemius.com/app/${
|
|
294
|
-
if (J && Z && X ? ($.searchParams.append("sandbox", Q.token), $.searchParams.append("s_ctx_ts", Q.ctx)) : J && $.searchParams.append("sandbox", "true"),
|
|
306
|
+
let $ = new URL(`https://checkout.freemius.com/app/${z}/plan/${R}/`);
|
|
307
|
+
if (J && Z && X ? ($.searchParams.append("sandbox", Q.token), $.searchParams.append("s_ctx_ts", Q.ctx)) : J && $.searchParams.append("sandbox", "true"), b && $.searchParams.append("user_email", b), K.firstName && $.searchParams.append("user_firstname", K.firstName), K.lastName && $.searchParams.append("user_lastname", K.lastName), $.searchParams.append("currency", F.code.toLowerCase()), V && $.searchParams.append("billing_cycle", V), G && $.searchParams.append("trial", G), U) $.searchParams.append("coupon", U.code);
|
|
295
308
|
else if (oe) {
|
|
296
|
-
let { data: e } = await
|
|
309
|
+
let { data: e } = await M.from("product_freemius_sale_coupons").select("freemius_coupon_code, is_active, starts_at, ends_at, sync_status").eq("product_id", L.id).maybeSingle();
|
|
297
310
|
e?.is_active && e.sync_status === "synced" && e.freemius_coupon_code && t({
|
|
298
311
|
saleStartAt: e.starts_at,
|
|
299
312
|
saleEndAt: e.ends_at
|
|
@@ -303,28 +316,28 @@ var E = class {
|
|
|
303
316
|
url: $.toString(),
|
|
304
317
|
customProps: {
|
|
305
318
|
provider: "freemius",
|
|
306
|
-
plugin_id:
|
|
307
|
-
plan_id:
|
|
319
|
+
plugin_id: z,
|
|
320
|
+
plan_id: R,
|
|
308
321
|
public_key: X,
|
|
309
|
-
user_email:
|
|
310
|
-
user_firstname:
|
|
311
|
-
user_lastname:
|
|
322
|
+
user_email: b,
|
|
323
|
+
user_firstname: K.firstName,
|
|
324
|
+
user_lastname: K.lastName,
|
|
312
325
|
credential_source: Y.source,
|
|
313
326
|
sandbox: Q,
|
|
314
|
-
billing_cycle:
|
|
315
|
-
trial:
|
|
316
|
-
trial_period_days:
|
|
317
|
-
trial_requires_payment_method:
|
|
318
|
-
initial_order_status:
|
|
319
|
-
coupon:
|
|
320
|
-
order_id:
|
|
321
|
-
success_token:
|
|
327
|
+
billing_cycle: V,
|
|
328
|
+
trial: G,
|
|
329
|
+
trial_period_days: se,
|
|
330
|
+
trial_requires_payment_method: L.trial_requires_payment_method,
|
|
331
|
+
initial_order_status: ce,
|
|
332
|
+
coupon: U?.code ?? null,
|
|
333
|
+
order_id: q.id,
|
|
334
|
+
success_token: d(q.id)
|
|
322
335
|
}
|
|
323
336
|
};
|
|
324
337
|
}
|
|
325
338
|
};
|
|
326
|
-
async function
|
|
327
|
-
let i = (/* @__PURE__ */ new Date()).toUTCString().replace("GMT", "+0000"), a = `GET\n\n\n${i}\n${e}`, o =
|
|
339
|
+
async function A(e, t, n, r) {
|
|
340
|
+
let i = (/* @__PURE__ */ new Date()).toUTCString().replace("GMT", "+0000"), a = `GET\n\n\n${i}\n${e}`, o = h.createHmac("sha256", r).update(a).digest("hex"), s = `FS ${t}:${n}:${Buffer.from(o).toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "")}`, c = await fetch(`https://api.freemius.com${e}`, { headers: {
|
|
328
341
|
Authorization: s,
|
|
329
342
|
Date: i,
|
|
330
343
|
Accept: "application/json"
|
|
@@ -335,16 +348,16 @@ async function D(e, t, n, r) {
|
|
|
335
348
|
}
|
|
336
349
|
return c.json();
|
|
337
350
|
}
|
|
338
|
-
async function
|
|
339
|
-
let e =
|
|
351
|
+
async function j() {
|
|
352
|
+
let e = _("FREEMIUS_DEVELOPER_ID"), t = _("FREEMIUS_PUBLIC_KEY"), n = _("FREEMIUS_SECRET_KEY"), r = process.env.NEXT_PUBLIC_SUPABASE_URL || process.env.SUPABASE_URL, i = process.env.SUPABASE_SERVICE_ROLE_KEY || process.env.SUPABASE_SECRET_KEY;
|
|
340
353
|
if (!e || !t || !n || !r || !i) throw Error("Missing necessary environment variables for Freemius Sync.");
|
|
341
|
-
let a =
|
|
354
|
+
let a = m(r, i, { auth: {
|
|
342
355
|
autoRefreshToken: !1,
|
|
343
356
|
persistSession: !1
|
|
344
|
-
} }), o = (r) =>
|
|
357
|
+
} }), o = (r) => A(r, e, t, n);
|
|
345
358
|
try {
|
|
346
359
|
console.log(`[Freemius Sync] Fetching all plugins for developer ${e}...`);
|
|
347
|
-
let t =
|
|
360
|
+
let t = S(await o(`/v1/developers/${e}/plugins.json`), ["plugins", "plugin"]);
|
|
348
361
|
console.log(`[Freemius Sync] Found ${t.length} plugins. Syncing plans...`);
|
|
349
362
|
let n = 0, { data: r } = await a.from("languages").select("id").eq("code", "en").single(), i = r?.id;
|
|
350
363
|
if (!i) throw Error("English language not found in database. Cannot sync products.");
|
|
@@ -354,7 +367,7 @@ async function O() {
|
|
|
354
367
|
console.warn("[Freemius Sync] Skipping plugin without an id:", r);
|
|
355
368
|
continue;
|
|
356
369
|
}
|
|
357
|
-
let s = await
|
|
370
|
+
let s = await N(a, e, t, r.title || r.name || `Freemius Product ${t}`, o, i);
|
|
358
371
|
n += s;
|
|
359
372
|
}
|
|
360
373
|
return {
|
|
@@ -365,22 +378,22 @@ async function O() {
|
|
|
365
378
|
throw console.error("[Freemius Sync] Global Error:", e), e;
|
|
366
379
|
}
|
|
367
380
|
}
|
|
368
|
-
async function
|
|
369
|
-
let t =
|
|
381
|
+
async function M(e) {
|
|
382
|
+
let t = _("FREEMIUS_DEVELOPER_ID"), n = _("FREEMIUS_PUBLIC_KEY"), r = _("FREEMIUS_SECRET_KEY"), i = process.env.NEXT_PUBLIC_SUPABASE_URL || process.env.SUPABASE_URL, a = process.env.SUPABASE_SERVICE_ROLE_KEY || process.env.SUPABASE_SECRET_KEY;
|
|
370
383
|
if (!t || !n || !r || !i || !a) throw Error("Missing environment variables for Freemius Sync.");
|
|
371
|
-
let o =
|
|
384
|
+
let o = m(i, a), s = (e) => A(e, t, n, r), { data: c } = await o.from("languages").select("id").eq("code", "en").single(), l = c?.id;
|
|
372
385
|
if (!l) throw Error("English language not found in database. Cannot sync products.");
|
|
373
|
-
let u = await s(`/v1/developers/${t}/plugins/${e}.json`),
|
|
386
|
+
let u = await s(`/v1/developers/${t}/plugins/${e}.json`), d = u.plugin ?? u;
|
|
374
387
|
return {
|
|
375
388
|
success: !0,
|
|
376
|
-
count: await
|
|
389
|
+
count: await N(o, t, e, d.title || d.name || `Freemius Product ${e}`, s, l)
|
|
377
390
|
};
|
|
378
391
|
}
|
|
379
|
-
async function
|
|
392
|
+
async function N(e, t, n, r, i, a) {
|
|
380
393
|
console.log(`[Freemius Sync] Fetching plans for plugin: ${r} (${n})...`);
|
|
381
394
|
let o = 0;
|
|
382
395
|
try {
|
|
383
|
-
let s =
|
|
396
|
+
let s = S(await i(`/v1/developers/${t}/plugins/${n}/plans.json`), ["plans", "plan"]);
|
|
384
397
|
console.log(`[Freemius Sync] Received ${s.length} plans for plugin ${n}.`);
|
|
385
398
|
for (let c of s) {
|
|
386
399
|
let s = c.id?.toString();
|
|
@@ -400,23 +413,23 @@ async function A(e, t, n, r, i, a) {
|
|
|
400
413
|
} catch (e) {
|
|
401
414
|
console.warn(`[Freemius Sync] Could not fetch trial details for plan ${s}:`, e instanceof Error ? e.message : e);
|
|
402
415
|
}
|
|
403
|
-
let f =
|
|
416
|
+
let f = y(d.trial_period), p = f > 0 && b(d.is_require_subscription), m = 0, h = [];
|
|
404
417
|
try {
|
|
405
|
-
if (h =
|
|
418
|
+
if (h = S(await i(`/v1/developers/${t}/plugins/${n}/plans/${s}/pricing.json`), [
|
|
406
419
|
"pricing",
|
|
407
420
|
"prices",
|
|
408
421
|
"pricings"
|
|
409
422
|
]), h.length > 0) {
|
|
410
423
|
let e = h[0];
|
|
411
|
-
m =
|
|
424
|
+
m = w(C(e.annual_price) ?? C(e.monthly_price) ?? C(e.lifetime_price));
|
|
412
425
|
}
|
|
413
426
|
console.log(`[Freemius Sync] Plan: ${u} -> Resolved Price (cents): ${m}`);
|
|
414
427
|
} catch (e) {
|
|
415
428
|
console.warn(`[Freemius Sync] Could not fetch pricing for plan ${s}:`, e instanceof Error ? e.message : e);
|
|
416
429
|
}
|
|
417
|
-
let
|
|
430
|
+
let g = `${r}-${u}`.toLowerCase().replace(/[^\w\s-]/g, "").replace(/[\s_]+/g, "-").replace(/^-+|-+$/g, ""), _ = {
|
|
418
431
|
title: `${r} - ${u}`,
|
|
419
|
-
slug:
|
|
432
|
+
slug: g,
|
|
420
433
|
short_description: c.description || "",
|
|
421
434
|
price: m,
|
|
422
435
|
product_type: "digital",
|
|
@@ -429,13 +442,13 @@ async function A(e, t, n, r, i, a) {
|
|
|
429
442
|
stock: 999,
|
|
430
443
|
sku: `FM-${n}-${s}`,
|
|
431
444
|
language_id: a
|
|
432
|
-
}, { data:
|
|
433
|
-
if (
|
|
434
|
-
console.error(`[Freemius Sync] Error upserting product ${
|
|
445
|
+
}, { data: v, error: x } = await e.from("products").upsert(_, { onConflict: "language_id, sku" }).select();
|
|
446
|
+
if (x || !v || v.length === 0) {
|
|
447
|
+
console.error(`[Freemius Sync] Error upserting product ${_.sku}:`, x);
|
|
435
448
|
continue;
|
|
436
449
|
}
|
|
437
|
-
let E =
|
|
438
|
-
O && console.warn(`[Freemius Sync] Could not check existing local plan for ${
|
|
450
|
+
let E = v[0].id, { data: D, error: O } = await e.from("freemius_plans").select("id").eq("product_id", E).eq("name", l).maybeSingle();
|
|
451
|
+
O && console.warn(`[Freemius Sync] Could not check existing local plan for ${_.sku}:`, O.message || O);
|
|
439
452
|
let k = "";
|
|
440
453
|
if (D) {
|
|
441
454
|
k = D.id;
|
|
@@ -450,15 +463,15 @@ async function A(e, t, n, r, i, a) {
|
|
|
450
463
|
name: l,
|
|
451
464
|
title: u
|
|
452
465
|
}).select("id").single();
|
|
453
|
-
n && console.warn(`[Freemius Sync] Could not insert local plan for ${
|
|
466
|
+
n && console.warn(`[Freemius Sync] Could not insert local plan for ${_.sku}:`, n.message || n), t && (k = t.id);
|
|
454
467
|
}
|
|
455
468
|
if (k && h.length > 0) for (let t of h) {
|
|
456
|
-
let n =
|
|
469
|
+
let n = T(t.licenses ?? t.license_quota ?? t.quota), { data: r, error: i } = await e.from("freemius_pricing").select("id").eq("plan_id", k).eq("license_quota", n).maybeSingle();
|
|
457
470
|
i && console.warn(`[Freemius Sync] Could not check pricing for plan ${k}, quota ${n}:`, i.message || i);
|
|
458
471
|
let a = {
|
|
459
|
-
api_monthly_price:
|
|
460
|
-
api_annual_price:
|
|
461
|
-
api_lifetime_price:
|
|
472
|
+
api_monthly_price: C(t.monthly_price),
|
|
473
|
+
api_annual_price: C(t.annual_price),
|
|
474
|
+
api_lifetime_price: C(t.lifetime_price),
|
|
462
475
|
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
463
476
|
};
|
|
464
477
|
if (r) {
|
|
@@ -473,7 +486,7 @@ async function A(e, t, n, r, i, a) {
|
|
|
473
486
|
t && console.warn(`[Freemius Sync] Could not insert pricing for plan ${k}, quota ${n}:`, t.message || t);
|
|
474
487
|
}
|
|
475
488
|
}
|
|
476
|
-
console.log(`[Freemius Sync] Successfully fully synced product ${
|
|
489
|
+
console.log(`[Freemius Sync] Successfully fully synced product ${_.sku}.`), o++;
|
|
477
490
|
}
|
|
478
491
|
} catch (e) {
|
|
479
492
|
console.error(`[Freemius Sync] Failed sync for plugin ${n}:`, e.message);
|
|
@@ -481,4 +494,4 @@ async function A(e, t, n, r, i, a) {
|
|
|
481
494
|
return o;
|
|
482
495
|
}
|
|
483
496
|
//#endregion
|
|
484
|
-
export {
|
|
497
|
+
export { k as FreemiusProvider, E as parseFreemiusCheckoutCredentialsMap, _ as readFreemiusEnvValue, D as resolveFreemiusCheckoutCredentials, j as syncFreemiusProductsToSupabase, M as syncSingleFreemiusProduct };
|