@superlogic/spree-pay 0.1.22 → 0.1.24
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/build/index.cjs +100 -64
- package/build/index.css +16 -5
- package/build/index.js +100 -64
- package/package.json +1 -1
package/build/index.cjs
CHANGED
|
@@ -141,48 +141,36 @@ var CONFIG = {
|
|
|
141
141
|
bookit: {
|
|
142
142
|
slapiUrl: "https://slapi.dev.superlogic.com",
|
|
143
143
|
keycloakUrl: "https://auth.dev.join.bookit.com",
|
|
144
|
-
keycloakClientId: "oneof-next"
|
|
145
|
-
pointsConversionRatio: 100,
|
|
146
|
-
pointsTitle: "AIR SP"
|
|
144
|
+
keycloakClientId: "oneof-next"
|
|
147
145
|
},
|
|
148
146
|
moca: {
|
|
149
147
|
slapiUrl: "https://slapi.dev.air.shop",
|
|
150
148
|
keycloakUrl: "https://login.dev.air.shop",
|
|
151
|
-
keycloakClientId: "oneof-next"
|
|
152
|
-
pointsConversionRatio: 100,
|
|
153
|
-
pointsTitle: "AIR SP"
|
|
149
|
+
keycloakClientId: "oneof-next"
|
|
154
150
|
}
|
|
155
151
|
},
|
|
156
152
|
stg: {
|
|
157
153
|
bookit: {
|
|
158
154
|
slapiUrl: "https://slapi.stg.superlogic.com",
|
|
159
155
|
keycloakUrl: "https://auth.stg.join.bookit.com",
|
|
160
|
-
keycloakClientId: "oneof-next"
|
|
161
|
-
pointsConversionRatio: 100,
|
|
162
|
-
pointsTitle: "AIR SP"
|
|
156
|
+
keycloakClientId: "oneof-next"
|
|
163
157
|
},
|
|
164
158
|
moca: {
|
|
165
159
|
slapiUrl: "https://slapi.stg.air.shop",
|
|
166
160
|
keycloakUrl: "https://login.stg.air.shop",
|
|
167
|
-
keycloakClientId: "oneof-next"
|
|
168
|
-
pointsConversionRatio: 100,
|
|
169
|
-
pointsTitle: "AIR SP"
|
|
161
|
+
keycloakClientId: "oneof-next"
|
|
170
162
|
}
|
|
171
163
|
},
|
|
172
164
|
prod: {
|
|
173
165
|
bookit: {
|
|
174
166
|
slapiUrl: "https://slapi.superlogic.com",
|
|
175
167
|
keycloakUrl: "https://auth.join.bookit.com",
|
|
176
|
-
keycloakClientId: "oneof-next"
|
|
177
|
-
pointsConversionRatio: 100,
|
|
178
|
-
pointsTitle: "AIR SP"
|
|
168
|
+
keycloakClientId: "oneof-next"
|
|
179
169
|
},
|
|
180
170
|
moca: {
|
|
181
171
|
slapiUrl: "https://slapi.air.shop",
|
|
182
172
|
keycloakUrl: "https://login.air.shop",
|
|
183
|
-
keycloakClientId: "oneof-next"
|
|
184
|
-
pointsConversionRatio: 100,
|
|
185
|
-
pointsTitle: "AIR SP"
|
|
173
|
+
keycloakClientId: "oneof-next"
|
|
186
174
|
}
|
|
187
175
|
}
|
|
188
176
|
};
|
|
@@ -210,7 +198,20 @@ var useStaticConfig = () => {
|
|
|
210
198
|
var import_swr = __toESM(require("swr"), 1);
|
|
211
199
|
var useSpreePayConfig = () => {
|
|
212
200
|
const { data, isLoading } = (0, import_swr.default)("/v1/tenants/configs/spree-pay");
|
|
213
|
-
return {
|
|
201
|
+
return {
|
|
202
|
+
spreePayConfig: data ? {
|
|
203
|
+
...data,
|
|
204
|
+
rainbowProjectId: data.rainbowProjectId ?? "3fdcd5ff50cb84917cd05e40146975d8",
|
|
205
|
+
rainbowAppName: data.rainbowAppName ?? "AIR Shop",
|
|
206
|
+
pointsTitle: data.pointsTitle ?? "AIR SP",
|
|
207
|
+
pointsConversionRatio: data.pointsConversionRatio ?? 0.01,
|
|
208
|
+
crypto: {
|
|
209
|
+
...data.crypto,
|
|
210
|
+
oneInchAggregationRouter: data.crypto?.oneInchAggregationRouter || "0x111111125421ca6dc452d289314280a0f8842a65"
|
|
211
|
+
}
|
|
212
|
+
} : null,
|
|
213
|
+
configIsLoading: isLoading
|
|
214
|
+
};
|
|
214
215
|
};
|
|
215
216
|
|
|
216
217
|
// src/lib/utils.ts
|
|
@@ -277,7 +278,7 @@ var formatUSD = (amount, currency = "USD") => {
|
|
|
277
278
|
}).format(amount);
|
|
278
279
|
return formattedAmount;
|
|
279
280
|
};
|
|
280
|
-
var formatPoints = (amount, pointsTitle = "
|
|
281
|
+
var formatPoints = (amount, pointsTitle = "") => {
|
|
281
282
|
const formattedAmount = new Intl.NumberFormat("en-US", {
|
|
282
283
|
notation: "compact",
|
|
283
284
|
style: "decimal",
|
|
@@ -297,11 +298,11 @@ var formatCoin = (amount, currency = "USDC") => {
|
|
|
297
298
|
|
|
298
299
|
// src/utils/split.ts
|
|
299
300
|
var getSplitAmount = (amount, splitTokens, pointsConversionRatio) => {
|
|
300
|
-
if (!Number.isFinite(amount) || !Number.isFinite(splitTokens) || !Number.isFinite(pointsConversionRatio)) {
|
|
301
|
+
if (!Number.isFinite(amount) || !Number.isFinite(splitTokens) || !pointsConversionRatio || !Number.isFinite(pointsConversionRatio)) {
|
|
301
302
|
return amount;
|
|
302
303
|
}
|
|
303
304
|
if (pointsConversionRatio <= 0) return amount;
|
|
304
|
-
const usdCoveredByPoints = splitTokens
|
|
305
|
+
const usdCoveredByPoints = splitTokens * pointsConversionRatio;
|
|
305
306
|
const remaining = amount - usdCoveredByPoints;
|
|
306
307
|
return Math.max(0, parseFloat(remaining.toFixed(2)));
|
|
307
308
|
};
|
|
@@ -319,13 +320,12 @@ var getTransactionFee = (amount = 0, transactionFeePercentage) => {
|
|
|
319
320
|
// src/components/CheckoutButton.tsx
|
|
320
321
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
321
322
|
var CheckoutButton = ({ isLoggedIn }) => {
|
|
322
|
-
const {
|
|
323
|
+
const { appProps } = useStaticConfig();
|
|
323
324
|
const { amount, onProcess, isProcessing, transactionFeePercentage } = appProps;
|
|
324
325
|
const { spreePayConfig } = useSpreePayConfig();
|
|
325
|
-
const { pointsTitle, pointsConversionRatio } = staticConfig;
|
|
326
326
|
const { selectedPaymentMethod, isInternalProcessing } = useSpreePaymentMethod();
|
|
327
327
|
const { splitAmount, type, method } = selectedPaymentMethod;
|
|
328
|
-
const usdAmount = getSplitAmount(amount ?? 0, splitAmount ?? 0, pointsConversionRatio);
|
|
328
|
+
const usdAmount = getSplitAmount(amount ?? 0, splitAmount ?? 0, spreePayConfig?.pointsConversionRatio);
|
|
329
329
|
const isDisabled = !amount || !method && usdAmount !== 0 || !!isProcessing || isInternalProcessing || !isLoggedIn;
|
|
330
330
|
const isCC = type === "CREDIT_CARD" /* CREDIT_CARD */;
|
|
331
331
|
const isCrypto = type === "CRYPTO" /* CRYPTO */;
|
|
@@ -335,13 +335,13 @@ var CheckoutButton = ({ isLoggedIn }) => {
|
|
|
335
335
|
}
|
|
336
336
|
if (isCC && amount) {
|
|
337
337
|
if (splitAmount && usdAmount) {
|
|
338
|
-
return `Pay ${formatUSD(usdAmount + getTransactionFee(usdAmount, transactionFeePercentage))} + ${formatPoints(splitAmount, pointsTitle)}`;
|
|
338
|
+
return `Pay ${formatUSD(usdAmount + getTransactionFee(usdAmount, transactionFeePercentage))} + ${formatPoints(splitAmount, spreePayConfig?.pointsTitle)}`;
|
|
339
339
|
}
|
|
340
340
|
if (usdAmount) {
|
|
341
341
|
return `Pay ${formatUSD(usdAmount + getTransactionFee(usdAmount, transactionFeePercentage))}`;
|
|
342
342
|
}
|
|
343
343
|
if (splitAmount) {
|
|
344
|
-
return `Pay ${formatPoints(splitAmount, pointsTitle)}`;
|
|
344
|
+
return `Pay ${formatPoints(splitAmount, spreePayConfig?.pointsTitle)}`;
|
|
345
345
|
}
|
|
346
346
|
return "Checkout";
|
|
347
347
|
}
|
|
@@ -879,7 +879,7 @@ var usePointsPayment = () => {
|
|
|
879
879
|
var useSplitCardPayments = () => {
|
|
880
880
|
const { selectedPaymentMethod } = useSpreePaymentMethod();
|
|
881
881
|
const { env } = useSpreePayEnv();
|
|
882
|
-
const { appProps
|
|
882
|
+
const { appProps } = useStaticConfig();
|
|
883
883
|
const { spreePayConfig } = useSpreePayConfig();
|
|
884
884
|
const splitPayment = async (params) => {
|
|
885
885
|
if (selectedPaymentMethod.type !== "CREDIT_CARD" /* CREDIT_CARD */ || !selectedPaymentMethod.method || !params.points) {
|
|
@@ -894,7 +894,7 @@ var useSplitCardPayments = () => {
|
|
|
894
894
|
} else {
|
|
895
895
|
cardId = card.id;
|
|
896
896
|
}
|
|
897
|
-
const usdAmount = getSplitAmount(appProps.amount ?? 0, points,
|
|
897
|
+
const usdAmount = getSplitAmount(appProps.amount ?? 0, points, spreePayConfig?.pointsConversionRatio);
|
|
898
898
|
const transactionFee = getTransactionFee(usdAmount, appProps.transactionFeePercentage);
|
|
899
899
|
const { data: paymentResData } = await SlapiPaymentService.createPayment({
|
|
900
900
|
hash,
|
|
@@ -1303,24 +1303,35 @@ function Switch({ className, ...props }) {
|
|
|
1303
1303
|
// src/components/common/PointsSwitch.tsx
|
|
1304
1304
|
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
1305
1305
|
var PointsSwitch = (props) => {
|
|
1306
|
-
const { disabled = false, value, onChange } = props;
|
|
1307
|
-
const {
|
|
1308
|
-
const { pointsConversionRatio, pointsTitle } = staticConfig;
|
|
1306
|
+
const { disabled = false, value, onChange, message } = props;
|
|
1307
|
+
const { spreePayConfig } = useSpreePayConfig();
|
|
1309
1308
|
const { balance } = useSlapiBalance();
|
|
1310
1309
|
const id = (0, import_react7.useId)();
|
|
1311
|
-
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex
|
|
1312
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex items-center gap-3", children: [
|
|
1313
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.
|
|
1314
|
-
|
|
1315
|
-
"
|
|
1316
|
-
|
|
1317
|
-
|
|
1310
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex flex-col gap-6", children: [
|
|
1311
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex items-center justify-between gap-3", children: [
|
|
1312
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex items-center gap-3", children: [
|
|
1313
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(Switch, { checked: value, onCheckedChange: onChange, disabled, id }),
|
|
1314
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(Label, { className: "text-md items-baseline leading-[1.3] font-semibold text-black md:text-xl", htmlFor: id, children: [
|
|
1315
|
+
"Use Points ",
|
|
1316
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "text-xs font-medium", children: "Optional" })
|
|
1317
|
+
] })
|
|
1318
|
+
] }),
|
|
1319
|
+
balance?.availablePoints ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("p", { className: "flex-1 text-right text-sm font-medium text-black", children: [
|
|
1320
|
+
formatPoints(balance.availablePoints, spreePayConfig?.pointsTitle),
|
|
1321
|
+
" ",
|
|
1322
|
+
!!spreePayConfig?.pointsConversionRatio && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "text-black/50", children: formatUSD(balance.availablePoints * spreePayConfig.pointsConversionRatio) })
|
|
1323
|
+
] }) : null
|
|
1318
1324
|
] }),
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1325
|
+
message && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex items-start gap-1 rounded-sm border-1 border-[#006FD533] bg-[#006FD50D] p-1.5", children: [
|
|
1326
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("svg", { className: "size-5 shrink-0", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 20 20", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
1327
|
+
"path",
|
|
1328
|
+
{
|
|
1329
|
+
fill: "#000",
|
|
1330
|
+
d: "M9.6 13.8h.8V9.2h-.8zM10 8q.2 0 .4-.2l.1-.3-.1-.4L10 7l-.4.1-.1.4.1.3zm0 9.5a7 7 0 0 1-5.3-2.2 8 8 0 0 1-1.6-8.2 8 8 0 0 1 4-4q1.4-.6 2.9-.6a7 7 0 0 1 5.3 2.2 8 8 0 0 1 1.6 8.2 8 8 0 0 1-4 4q-1.4.6-2.9.6m0-.8q2.8 0 4.7-2 2-1.9 2-4.7t-2-4.7a6 6 0 0 0-4.7-2q-2.8 0-4.7 2a6 6 0 0 0-2 4.7q0 2.8 2 4.7 1.9 2 4.7 2"
|
|
1331
|
+
}
|
|
1332
|
+
) }),
|
|
1333
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "text-xs font-medium text-black", children: message })
|
|
1334
|
+
] })
|
|
1324
1335
|
] });
|
|
1325
1336
|
};
|
|
1326
1337
|
|
|
@@ -2324,12 +2335,15 @@ var PointsSelector = (props) => {
|
|
|
2324
2335
|
const { isDisabled, isSelected, onSelect, children } = props;
|
|
2325
2336
|
const { balance } = useSlapiBalance();
|
|
2326
2337
|
const { selectedPaymentMethod, setSelectedPaymentMethod } = useSpreePaymentMethod();
|
|
2327
|
-
const { appProps
|
|
2338
|
+
const { appProps } = useStaticConfig();
|
|
2339
|
+
const { spreePayConfig } = useSpreePayConfig();
|
|
2340
|
+
const { pointsConversionRatio } = spreePayConfig || {};
|
|
2328
2341
|
const min = 0;
|
|
2329
|
-
const
|
|
2342
|
+
const maxByAmount = pointsConversionRatio && pointsConversionRatio > 0 ? (appProps.amount ?? 0) / pointsConversionRatio : 0;
|
|
2343
|
+
const max = Math.min(maxByAmount, balance?.availablePoints ?? 0);
|
|
2330
2344
|
const step = 10;
|
|
2331
2345
|
const [splitTokens, setSplitTokens] = (0, import_react10.useState)(0);
|
|
2332
|
-
const usdAmount = getSplitAmount(appProps.amount ?? 0, splitTokens,
|
|
2346
|
+
const usdAmount = getSplitAmount(appProps.amount ?? 0, splitTokens, pointsConversionRatio);
|
|
2333
2347
|
const handleCommit = (value) => {
|
|
2334
2348
|
setSelectedPaymentMethod({ ...selectedPaymentMethod, splitAmount: value });
|
|
2335
2349
|
};
|
|
@@ -2357,7 +2371,15 @@ var PointsSelector = (props) => {
|
|
|
2357
2371
|
] }),
|
|
2358
2372
|
isSelected && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "px-3 pt-6 pb-2 md:px-4", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex justify-between gap-3", children: [
|
|
2359
2373
|
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex max-w-[100px] flex-col gap-1", children: [
|
|
2360
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
2374
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
2375
|
+
Input,
|
|
2376
|
+
{
|
|
2377
|
+
readOnly: true,
|
|
2378
|
+
value: Math.round(splitTokens),
|
|
2379
|
+
className: "bg-white text-center font-medium",
|
|
2380
|
+
onClick: (e) => e.stopPropagation()
|
|
2381
|
+
}
|
|
2382
|
+
),
|
|
2361
2383
|
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-left text-xs leading-[20px] text-black/45", children: "Points" })
|
|
2362
2384
|
] }),
|
|
2363
2385
|
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "flex w-full items-center pb-6", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
@@ -2366,6 +2388,7 @@ var PointsSelector = (props) => {
|
|
|
2366
2388
|
value: [splitTokens],
|
|
2367
2389
|
onValueCommit: ([v]) => handleCommit(v),
|
|
2368
2390
|
onValueChange: ([v]) => setSplitTokens(v),
|
|
2391
|
+
onPointerDown: (e) => e.stopPropagation(),
|
|
2369
2392
|
min,
|
|
2370
2393
|
max,
|
|
2371
2394
|
step
|
|
@@ -2377,7 +2400,8 @@ var PointsSelector = (props) => {
|
|
|
2377
2400
|
{
|
|
2378
2401
|
readOnly: true,
|
|
2379
2402
|
value: formatUSD(usdAmount + getTransactionFee(usdAmount, appProps.transactionFeePercentage)),
|
|
2380
|
-
className: "bg-white text-center font-medium"
|
|
2403
|
+
className: "bg-white text-center font-medium",
|
|
2404
|
+
onClick: (e) => e.stopPropagation()
|
|
2381
2405
|
}
|
|
2382
2406
|
),
|
|
2383
2407
|
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-left text-xs leading-[20px] text-black/45", children: "Card" })
|
|
@@ -2396,8 +2420,7 @@ var SplitBlock = (props) => {
|
|
|
2396
2420
|
const { spreePayConfig } = useSpreePayConfig();
|
|
2397
2421
|
const [address, setAddress] = (0, import_react11.useState)(null);
|
|
2398
2422
|
const [walletReady, setWalletReady] = (0, import_react11.useState)(false);
|
|
2399
|
-
const {
|
|
2400
|
-
const { pointsConversionRatio, pointsTitle } = staticConfig;
|
|
2423
|
+
const { pointsConversionRatio, pointsTitle } = spreePayConfig || {};
|
|
2401
2424
|
const initWallet = (0, import_react11.useCallback)(
|
|
2402
2425
|
async (pointsChain) => {
|
|
2403
2426
|
if (!pointsChain) return;
|
|
@@ -2428,7 +2451,7 @@ var SplitBlock = (props) => {
|
|
|
2428
2451
|
" ",
|
|
2429
2452
|
formatPoints(balance.availablePoints, pointsTitle),
|
|
2430
2453
|
" ",
|
|
2431
|
-
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "text-black/50", children: formatUSD(balance.availablePoints
|
|
2454
|
+
pointsConversionRatio && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "text-black/50", children: formatUSD(balance.availablePoints * pointsConversionRatio) })
|
|
2432
2455
|
] }) : null }),
|
|
2433
2456
|
isBalanceLoading ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "h-4 w-6 animate-pulse bg-gray-200" }) : !balance?.availablePoints && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { className: "text-sm font-medium text-black", children: "No points available" }),
|
|
2434
2457
|
address && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "text-sm font-medium text-black", children: address.length > 8 ? `${address.slice(0, 4)}...${address.slice(-4)}` : address })
|
|
@@ -2450,7 +2473,15 @@ var Points = () => {
|
|
|
2450
2473
|
}
|
|
2451
2474
|
};
|
|
2452
2475
|
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
|
|
2453
|
-
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
2476
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
2477
|
+
PointsSwitch,
|
|
2478
|
+
{
|
|
2479
|
+
value: usePoints,
|
|
2480
|
+
onChange: handleTogglePoints,
|
|
2481
|
+
message: spreePayConfig?.creditCard.pointsInfoMessage,
|
|
2482
|
+
disabled: !spreePayConfig?.creditCard.enabled || !spreePayConfig?.creditCard.points
|
|
2483
|
+
}
|
|
2484
|
+
),
|
|
2454
2485
|
usePoints && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
2455
2486
|
SplitBlock,
|
|
2456
2487
|
{
|
|
@@ -2466,7 +2497,8 @@ var Points = () => {
|
|
|
2466
2497
|
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
2467
2498
|
var CreditCardTab = () => {
|
|
2468
2499
|
const { selectedPaymentMethod, setSelectedPaymentMethod } = useSpreePaymentMethod();
|
|
2469
|
-
const {
|
|
2500
|
+
const { appProps } = useStaticConfig();
|
|
2501
|
+
const { spreePayConfig } = useSpreePayConfig();
|
|
2470
2502
|
const { register } = useSpreePayRegister();
|
|
2471
2503
|
const { mutateCards } = useCards();
|
|
2472
2504
|
const { cardPayment } = useCardPayment();
|
|
@@ -2477,7 +2509,7 @@ var CreditCardTab = () => {
|
|
|
2477
2509
|
try {
|
|
2478
2510
|
let res = null;
|
|
2479
2511
|
const pointsAmount = selectedPaymentMethod.splitAmount ?? 0;
|
|
2480
|
-
const usdAmount = getSplitAmount(appProps.amount ?? 0, pointsAmount,
|
|
2512
|
+
const usdAmount = getSplitAmount(appProps.amount ?? 0, pointsAmount, spreePayConfig?.pointsConversionRatio);
|
|
2481
2513
|
if (usdAmount && pointsAmount) {
|
|
2482
2514
|
res = await splitPayment({ ...data, points: pointsAmount });
|
|
2483
2515
|
} else if (!usdAmount && pointsAmount) {
|
|
@@ -2504,7 +2536,7 @@ var CreditCardTab = () => {
|
|
|
2504
2536
|
setSelectedPaymentMethod,
|
|
2505
2537
|
cardPayment,
|
|
2506
2538
|
splitPayment,
|
|
2507
|
-
|
|
2539
|
+
spreePayConfig
|
|
2508
2540
|
]
|
|
2509
2541
|
);
|
|
2510
2542
|
(0, import_react13.useEffect)(() => {
|
|
@@ -2623,15 +2655,18 @@ var BASE_TOKENS = [
|
|
|
2623
2655
|
|
|
2624
2656
|
// src/hooks/payments/useCryptoPayment.ts
|
|
2625
2657
|
var MAX_UINT256 = BigInt(2) ** BigInt(256) - BigInt(1);
|
|
2626
|
-
var ONE_INCH_AGGREGATION_ROUTER_V6 = "0x111111125421ca6dc452d289314280a0f8842a65";
|
|
2627
2658
|
var useCryptoPayment = () => {
|
|
2628
2659
|
const { data: walletClient } = (0, import_wagmi.useWalletClient)();
|
|
2660
|
+
const { spreePayConfig } = useSpreePayConfig();
|
|
2629
2661
|
const config = (0, import_wagmi.useConfig)();
|
|
2630
2662
|
const { selectedPaymentMethod } = useSpreePaymentMethod();
|
|
2631
2663
|
const cryptoPayment = async (params) => {
|
|
2632
2664
|
if (!walletClient) {
|
|
2633
2665
|
throw new Error("Wallet not connected");
|
|
2634
2666
|
}
|
|
2667
|
+
if (!spreePayConfig) {
|
|
2668
|
+
throw new Error("Spree Pay config not loaded");
|
|
2669
|
+
}
|
|
2635
2670
|
if (selectedPaymentMethod.type !== "CRYPTO" /* CRYPTO */ || !selectedPaymentMethod.method?.symbol) {
|
|
2636
2671
|
throw new Error("Unsupported payment method");
|
|
2637
2672
|
}
|
|
@@ -2646,14 +2681,14 @@ var useCryptoPayment = () => {
|
|
|
2646
2681
|
address: tokenAddress,
|
|
2647
2682
|
abi: import_viem4.erc20Abi,
|
|
2648
2683
|
functionName: "allowance",
|
|
2649
|
-
args: [walletClient.account.address,
|
|
2684
|
+
args: [walletClient.account.address, spreePayConfig.crypto.oneInchAggregationRouter]
|
|
2650
2685
|
});
|
|
2651
2686
|
if (allowance <= 0n) {
|
|
2652
2687
|
const result = await walletClient.writeContract({
|
|
2653
2688
|
address: tokenAddress,
|
|
2654
2689
|
abi: import_viem4.erc20Abi,
|
|
2655
2690
|
functionName: "approve",
|
|
2656
|
-
args: [
|
|
2691
|
+
args: [spreePayConfig.crypto.oneInchAggregationRouter, MAX_UINT256]
|
|
2657
2692
|
});
|
|
2658
2693
|
await waitForTransactionReceipt(config, {
|
|
2659
2694
|
hash: result,
|
|
@@ -3218,8 +3253,8 @@ var CryptoWrapper = () => {
|
|
|
3218
3253
|
const config = (0, import_react16.useMemo)(() => {
|
|
3219
3254
|
if (!spreePayConfig) return null;
|
|
3220
3255
|
return (0, import_rainbowkit2.getDefaultConfig)({
|
|
3221
|
-
appName: spreePayConfig.rainbowAppName
|
|
3222
|
-
projectId: spreePayConfig.rainbowProjectId
|
|
3256
|
+
appName: spreePayConfig.rainbowAppName,
|
|
3257
|
+
projectId: spreePayConfig.rainbowProjectId,
|
|
3223
3258
|
chains: [import_chains.base],
|
|
3224
3259
|
ssr: true
|
|
3225
3260
|
});
|
|
@@ -3231,9 +3266,10 @@ var CryptoWrapper = () => {
|
|
|
3231
3266
|
// src/components/CryptoTab/CryptoTab.tsx
|
|
3232
3267
|
var import_jsx_runtime39 = require("react/jsx-runtime");
|
|
3233
3268
|
var CryptoTab = () => {
|
|
3269
|
+
const { spreePayConfig } = useSpreePayConfig();
|
|
3234
3270
|
return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { children: [
|
|
3235
|
-
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "border-b-1 border-black/7 px-5 py-5 md:px-7 md:py-
|
|
3236
|
-
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "px-5 py-5 md:px-7 md:py-6", children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(PointsSwitch, { disabled: true }) })
|
|
3271
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "border-b-1 border-black/7 px-5 py-5 md:px-7 md:py-6", children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(CryptoWrapper, {}) }),
|
|
3272
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "px-5 py-5 md:px-7 md:py-6", children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(PointsSwitch, { disabled: true, message: spreePayConfig?.crypto.pointsInfoMessage }) })
|
|
3237
3273
|
] });
|
|
3238
3274
|
};
|
|
3239
3275
|
|
|
@@ -3285,7 +3321,7 @@ var TabButtons = (props) => {
|
|
|
3285
3321
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
|
|
3286
3322
|
TabButton,
|
|
3287
3323
|
{
|
|
3288
|
-
isDisabled: !spreePayConfig?.
|
|
3324
|
+
isDisabled: !spreePayConfig?.crypto.enabled,
|
|
3289
3325
|
onClick: handleChange("CRYPTO" /* CRYPTO */),
|
|
3290
3326
|
isActive: value === "CRYPTO" /* CRYPTO */,
|
|
3291
3327
|
children: [
|
package/build/index.css
CHANGED
|
@@ -344,6 +344,10 @@
|
|
|
344
344
|
width: calc(var(--spacing) * 4);
|
|
345
345
|
height: calc(var(--spacing) * 4);
|
|
346
346
|
}
|
|
347
|
+
.sl-spreepay .size-5 {
|
|
348
|
+
width: calc(var(--spacing) * 5);
|
|
349
|
+
height: calc(var(--spacing) * 5);
|
|
350
|
+
}
|
|
347
351
|
.sl-spreepay .size-6 {
|
|
348
352
|
width: calc(var(--spacing) * 6);
|
|
349
353
|
height: calc(var(--spacing) * 6);
|
|
@@ -507,6 +511,9 @@
|
|
|
507
511
|
.sl-spreepay .items-center {
|
|
508
512
|
align-items: center;
|
|
509
513
|
}
|
|
514
|
+
.sl-spreepay .items-start {
|
|
515
|
+
align-items: flex-start;
|
|
516
|
+
}
|
|
510
517
|
.sl-spreepay .justify-between {
|
|
511
518
|
justify-content: space-between;
|
|
512
519
|
}
|
|
@@ -591,6 +598,9 @@
|
|
|
591
598
|
border-left-style: var(--tw-border-style) !important;
|
|
592
599
|
border-left-width: 0px !important;
|
|
593
600
|
}
|
|
601
|
+
.sl-spreepay .border-\[\#006FD533\] {
|
|
602
|
+
border-color: #006FD533;
|
|
603
|
+
}
|
|
594
604
|
.sl-spreepay .border-\[\#F5F7FA\] {
|
|
595
605
|
border-color: #F5F7FA;
|
|
596
606
|
}
|
|
@@ -630,6 +640,9 @@
|
|
|
630
640
|
.sl-spreepay .border-transparent {
|
|
631
641
|
border-color: transparent;
|
|
632
642
|
}
|
|
643
|
+
.sl-spreepay .bg-\[\#006FD50D\] {
|
|
644
|
+
background-color: #006FD50D;
|
|
645
|
+
}
|
|
633
646
|
.sl-spreepay .bg-\[\#F5F7FA\] {
|
|
634
647
|
background-color: #F5F7FA;
|
|
635
648
|
}
|
|
@@ -699,6 +712,9 @@
|
|
|
699
712
|
.sl-spreepay .p-1 {
|
|
700
713
|
padding: calc(var(--spacing) * 1);
|
|
701
714
|
}
|
|
715
|
+
.sl-spreepay .p-1\.5 {
|
|
716
|
+
padding: calc(var(--spacing) * 1.5);
|
|
717
|
+
}
|
|
702
718
|
.sl-spreepay .p-6 {
|
|
703
719
|
padding: calc(var(--spacing) * 6);
|
|
704
720
|
}
|
|
@@ -1467,11 +1483,6 @@
|
|
|
1467
1483
|
padding-inline: calc(var(--spacing) * 7);
|
|
1468
1484
|
}
|
|
1469
1485
|
}
|
|
1470
|
-
.sl-spreepay .md\:py-5 {
|
|
1471
|
-
@media (width >= 48rem) {
|
|
1472
|
-
padding-block: calc(var(--spacing) * 5);
|
|
1473
|
-
}
|
|
1474
|
-
}
|
|
1475
1486
|
.sl-spreepay .md\:py-6 {
|
|
1476
1487
|
@media (width >= 48rem) {
|
|
1477
1488
|
padding-block: calc(var(--spacing) * 6);
|
package/build/index.js
CHANGED
|
@@ -101,48 +101,36 @@ var CONFIG = {
|
|
|
101
101
|
bookit: {
|
|
102
102
|
slapiUrl: "https://slapi.dev.superlogic.com",
|
|
103
103
|
keycloakUrl: "https://auth.dev.join.bookit.com",
|
|
104
|
-
keycloakClientId: "oneof-next"
|
|
105
|
-
pointsConversionRatio: 100,
|
|
106
|
-
pointsTitle: "AIR SP"
|
|
104
|
+
keycloakClientId: "oneof-next"
|
|
107
105
|
},
|
|
108
106
|
moca: {
|
|
109
107
|
slapiUrl: "https://slapi.dev.air.shop",
|
|
110
108
|
keycloakUrl: "https://login.dev.air.shop",
|
|
111
|
-
keycloakClientId: "oneof-next"
|
|
112
|
-
pointsConversionRatio: 100,
|
|
113
|
-
pointsTitle: "AIR SP"
|
|
109
|
+
keycloakClientId: "oneof-next"
|
|
114
110
|
}
|
|
115
111
|
},
|
|
116
112
|
stg: {
|
|
117
113
|
bookit: {
|
|
118
114
|
slapiUrl: "https://slapi.stg.superlogic.com",
|
|
119
115
|
keycloakUrl: "https://auth.stg.join.bookit.com",
|
|
120
|
-
keycloakClientId: "oneof-next"
|
|
121
|
-
pointsConversionRatio: 100,
|
|
122
|
-
pointsTitle: "AIR SP"
|
|
116
|
+
keycloakClientId: "oneof-next"
|
|
123
117
|
},
|
|
124
118
|
moca: {
|
|
125
119
|
slapiUrl: "https://slapi.stg.air.shop",
|
|
126
120
|
keycloakUrl: "https://login.stg.air.shop",
|
|
127
|
-
keycloakClientId: "oneof-next"
|
|
128
|
-
pointsConversionRatio: 100,
|
|
129
|
-
pointsTitle: "AIR SP"
|
|
121
|
+
keycloakClientId: "oneof-next"
|
|
130
122
|
}
|
|
131
123
|
},
|
|
132
124
|
prod: {
|
|
133
125
|
bookit: {
|
|
134
126
|
slapiUrl: "https://slapi.superlogic.com",
|
|
135
127
|
keycloakUrl: "https://auth.join.bookit.com",
|
|
136
|
-
keycloakClientId: "oneof-next"
|
|
137
|
-
pointsConversionRatio: 100,
|
|
138
|
-
pointsTitle: "AIR SP"
|
|
128
|
+
keycloakClientId: "oneof-next"
|
|
139
129
|
},
|
|
140
130
|
moca: {
|
|
141
131
|
slapiUrl: "https://slapi.air.shop",
|
|
142
132
|
keycloakUrl: "https://login.air.shop",
|
|
143
|
-
keycloakClientId: "oneof-next"
|
|
144
|
-
pointsConversionRatio: 100,
|
|
145
|
-
pointsTitle: "AIR SP"
|
|
133
|
+
keycloakClientId: "oneof-next"
|
|
146
134
|
}
|
|
147
135
|
}
|
|
148
136
|
};
|
|
@@ -170,7 +158,20 @@ var useStaticConfig = () => {
|
|
|
170
158
|
import useSWR from "swr";
|
|
171
159
|
var useSpreePayConfig = () => {
|
|
172
160
|
const { data, isLoading } = useSWR("/v1/tenants/configs/spree-pay");
|
|
173
|
-
return {
|
|
161
|
+
return {
|
|
162
|
+
spreePayConfig: data ? {
|
|
163
|
+
...data,
|
|
164
|
+
rainbowProjectId: data.rainbowProjectId ?? "3fdcd5ff50cb84917cd05e40146975d8",
|
|
165
|
+
rainbowAppName: data.rainbowAppName ?? "AIR Shop",
|
|
166
|
+
pointsTitle: data.pointsTitle ?? "AIR SP",
|
|
167
|
+
pointsConversionRatio: data.pointsConversionRatio ?? 0.01,
|
|
168
|
+
crypto: {
|
|
169
|
+
...data.crypto,
|
|
170
|
+
oneInchAggregationRouter: data.crypto?.oneInchAggregationRouter || "0x111111125421ca6dc452d289314280a0f8842a65"
|
|
171
|
+
}
|
|
172
|
+
} : null,
|
|
173
|
+
configIsLoading: isLoading
|
|
174
|
+
};
|
|
174
175
|
};
|
|
175
176
|
|
|
176
177
|
// src/lib/utils.ts
|
|
@@ -237,7 +238,7 @@ var formatUSD = (amount, currency = "USD") => {
|
|
|
237
238
|
}).format(amount);
|
|
238
239
|
return formattedAmount;
|
|
239
240
|
};
|
|
240
|
-
var formatPoints = (amount, pointsTitle = "
|
|
241
|
+
var formatPoints = (amount, pointsTitle = "") => {
|
|
241
242
|
const formattedAmount = new Intl.NumberFormat("en-US", {
|
|
242
243
|
notation: "compact",
|
|
243
244
|
style: "decimal",
|
|
@@ -257,11 +258,11 @@ var formatCoin = (amount, currency = "USDC") => {
|
|
|
257
258
|
|
|
258
259
|
// src/utils/split.ts
|
|
259
260
|
var getSplitAmount = (amount, splitTokens, pointsConversionRatio) => {
|
|
260
|
-
if (!Number.isFinite(amount) || !Number.isFinite(splitTokens) || !Number.isFinite(pointsConversionRatio)) {
|
|
261
|
+
if (!Number.isFinite(amount) || !Number.isFinite(splitTokens) || !pointsConversionRatio || !Number.isFinite(pointsConversionRatio)) {
|
|
261
262
|
return amount;
|
|
262
263
|
}
|
|
263
264
|
if (pointsConversionRatio <= 0) return amount;
|
|
264
|
-
const usdCoveredByPoints = splitTokens
|
|
265
|
+
const usdCoveredByPoints = splitTokens * pointsConversionRatio;
|
|
265
266
|
const remaining = amount - usdCoveredByPoints;
|
|
266
267
|
return Math.max(0, parseFloat(remaining.toFixed(2)));
|
|
267
268
|
};
|
|
@@ -279,13 +280,12 @@ var getTransactionFee = (amount = 0, transactionFeePercentage) => {
|
|
|
279
280
|
// src/components/CheckoutButton.tsx
|
|
280
281
|
import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
281
282
|
var CheckoutButton = ({ isLoggedIn }) => {
|
|
282
|
-
const {
|
|
283
|
+
const { appProps } = useStaticConfig();
|
|
283
284
|
const { amount, onProcess, isProcessing, transactionFeePercentage } = appProps;
|
|
284
285
|
const { spreePayConfig } = useSpreePayConfig();
|
|
285
|
-
const { pointsTitle, pointsConversionRatio } = staticConfig;
|
|
286
286
|
const { selectedPaymentMethod, isInternalProcessing } = useSpreePaymentMethod();
|
|
287
287
|
const { splitAmount, type, method } = selectedPaymentMethod;
|
|
288
|
-
const usdAmount = getSplitAmount(amount ?? 0, splitAmount ?? 0, pointsConversionRatio);
|
|
288
|
+
const usdAmount = getSplitAmount(amount ?? 0, splitAmount ?? 0, spreePayConfig?.pointsConversionRatio);
|
|
289
289
|
const isDisabled = !amount || !method && usdAmount !== 0 || !!isProcessing || isInternalProcessing || !isLoggedIn;
|
|
290
290
|
const isCC = type === "CREDIT_CARD" /* CREDIT_CARD */;
|
|
291
291
|
const isCrypto = type === "CRYPTO" /* CRYPTO */;
|
|
@@ -295,13 +295,13 @@ var CheckoutButton = ({ isLoggedIn }) => {
|
|
|
295
295
|
}
|
|
296
296
|
if (isCC && amount) {
|
|
297
297
|
if (splitAmount && usdAmount) {
|
|
298
|
-
return `Pay ${formatUSD(usdAmount + getTransactionFee(usdAmount, transactionFeePercentage))} + ${formatPoints(splitAmount, pointsTitle)}`;
|
|
298
|
+
return `Pay ${formatUSD(usdAmount + getTransactionFee(usdAmount, transactionFeePercentage))} + ${formatPoints(splitAmount, spreePayConfig?.pointsTitle)}`;
|
|
299
299
|
}
|
|
300
300
|
if (usdAmount) {
|
|
301
301
|
return `Pay ${formatUSD(usdAmount + getTransactionFee(usdAmount, transactionFeePercentage))}`;
|
|
302
302
|
}
|
|
303
303
|
if (splitAmount) {
|
|
304
|
-
return `Pay ${formatPoints(splitAmount, pointsTitle)}`;
|
|
304
|
+
return `Pay ${formatPoints(splitAmount, spreePayConfig?.pointsTitle)}`;
|
|
305
305
|
}
|
|
306
306
|
return "Checkout";
|
|
307
307
|
}
|
|
@@ -839,7 +839,7 @@ var usePointsPayment = () => {
|
|
|
839
839
|
var useSplitCardPayments = () => {
|
|
840
840
|
const { selectedPaymentMethod } = useSpreePaymentMethod();
|
|
841
841
|
const { env } = useSpreePayEnv();
|
|
842
|
-
const { appProps
|
|
842
|
+
const { appProps } = useStaticConfig();
|
|
843
843
|
const { spreePayConfig } = useSpreePayConfig();
|
|
844
844
|
const splitPayment = async (params) => {
|
|
845
845
|
if (selectedPaymentMethod.type !== "CREDIT_CARD" /* CREDIT_CARD */ || !selectedPaymentMethod.method || !params.points) {
|
|
@@ -854,7 +854,7 @@ var useSplitCardPayments = () => {
|
|
|
854
854
|
} else {
|
|
855
855
|
cardId = card.id;
|
|
856
856
|
}
|
|
857
|
-
const usdAmount = getSplitAmount(appProps.amount ?? 0, points,
|
|
857
|
+
const usdAmount = getSplitAmount(appProps.amount ?? 0, points, spreePayConfig?.pointsConversionRatio);
|
|
858
858
|
const transactionFee = getTransactionFee(usdAmount, appProps.transactionFeePercentage);
|
|
859
859
|
const { data: paymentResData } = await SlapiPaymentService.createPayment({
|
|
860
860
|
hash,
|
|
@@ -1263,24 +1263,35 @@ function Switch({ className, ...props }) {
|
|
|
1263
1263
|
// src/components/common/PointsSwitch.tsx
|
|
1264
1264
|
import { jsx as jsx15, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1265
1265
|
var PointsSwitch = (props) => {
|
|
1266
|
-
const { disabled = false, value, onChange } = props;
|
|
1267
|
-
const {
|
|
1268
|
-
const { pointsConversionRatio, pointsTitle } = staticConfig;
|
|
1266
|
+
const { disabled = false, value, onChange, message } = props;
|
|
1267
|
+
const { spreePayConfig } = useSpreePayConfig();
|
|
1269
1268
|
const { balance } = useSlapiBalance();
|
|
1270
1269
|
const id = useId2();
|
|
1271
|
-
return /* @__PURE__ */ jsxs9("div", { className: "flex
|
|
1272
|
-
/* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-3", children: [
|
|
1273
|
-
/* @__PURE__ */
|
|
1274
|
-
|
|
1275
|
-
"
|
|
1276
|
-
|
|
1277
|
-
|
|
1270
|
+
return /* @__PURE__ */ jsxs9("div", { className: "flex flex-col gap-6", children: [
|
|
1271
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex items-center justify-between gap-3", children: [
|
|
1272
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-3", children: [
|
|
1273
|
+
/* @__PURE__ */ jsx15(Switch, { checked: value, onCheckedChange: onChange, disabled, id }),
|
|
1274
|
+
/* @__PURE__ */ jsxs9(Label, { className: "text-md items-baseline leading-[1.3] font-semibold text-black md:text-xl", htmlFor: id, children: [
|
|
1275
|
+
"Use Points ",
|
|
1276
|
+
/* @__PURE__ */ jsx15("span", { className: "text-xs font-medium", children: "Optional" })
|
|
1277
|
+
] })
|
|
1278
|
+
] }),
|
|
1279
|
+
balance?.availablePoints ? /* @__PURE__ */ jsxs9("p", { className: "flex-1 text-right text-sm font-medium text-black", children: [
|
|
1280
|
+
formatPoints(balance.availablePoints, spreePayConfig?.pointsTitle),
|
|
1281
|
+
" ",
|
|
1282
|
+
!!spreePayConfig?.pointsConversionRatio && /* @__PURE__ */ jsx15("span", { className: "text-black/50", children: formatUSD(balance.availablePoints * spreePayConfig.pointsConversionRatio) })
|
|
1283
|
+
] }) : null
|
|
1278
1284
|
] }),
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1285
|
+
message && /* @__PURE__ */ jsxs9("div", { className: "flex items-start gap-1 rounded-sm border-1 border-[#006FD533] bg-[#006FD50D] p-1.5", children: [
|
|
1286
|
+
/* @__PURE__ */ jsx15("svg", { className: "size-5 shrink-0", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx15(
|
|
1287
|
+
"path",
|
|
1288
|
+
{
|
|
1289
|
+
fill: "#000",
|
|
1290
|
+
d: "M9.6 13.8h.8V9.2h-.8zM10 8q.2 0 .4-.2l.1-.3-.1-.4L10 7l-.4.1-.1.4.1.3zm0 9.5a7 7 0 0 1-5.3-2.2 8 8 0 0 1-1.6-8.2 8 8 0 0 1 4-4q1.4-.6 2.9-.6a7 7 0 0 1 5.3 2.2 8 8 0 0 1 1.6 8.2 8 8 0 0 1-4 4q-1.4.6-2.9.6m0-.8q2.8 0 4.7-2 2-1.9 2-4.7t-2-4.7a6 6 0 0 0-4.7-2q-2.8 0-4.7 2a6 6 0 0 0-2 4.7q0 2.8 2 4.7 1.9 2 4.7 2"
|
|
1291
|
+
}
|
|
1292
|
+
) }),
|
|
1293
|
+
/* @__PURE__ */ jsx15("p", { className: "text-xs font-medium text-black", children: message })
|
|
1294
|
+
] })
|
|
1284
1295
|
] });
|
|
1285
1296
|
};
|
|
1286
1297
|
|
|
@@ -2284,12 +2295,15 @@ var PointsSelector = (props) => {
|
|
|
2284
2295
|
const { isDisabled, isSelected, onSelect, children } = props;
|
|
2285
2296
|
const { balance } = useSlapiBalance();
|
|
2286
2297
|
const { selectedPaymentMethod, setSelectedPaymentMethod } = useSpreePaymentMethod();
|
|
2287
|
-
const { appProps
|
|
2298
|
+
const { appProps } = useStaticConfig();
|
|
2299
|
+
const { spreePayConfig } = useSpreePayConfig();
|
|
2300
|
+
const { pointsConversionRatio } = spreePayConfig || {};
|
|
2288
2301
|
const min = 0;
|
|
2289
|
-
const
|
|
2302
|
+
const maxByAmount = pointsConversionRatio && pointsConversionRatio > 0 ? (appProps.amount ?? 0) / pointsConversionRatio : 0;
|
|
2303
|
+
const max = Math.min(maxByAmount, balance?.availablePoints ?? 0);
|
|
2290
2304
|
const step = 10;
|
|
2291
2305
|
const [splitTokens, setSplitTokens] = useState8(0);
|
|
2292
|
-
const usdAmount = getSplitAmount(appProps.amount ?? 0, splitTokens,
|
|
2306
|
+
const usdAmount = getSplitAmount(appProps.amount ?? 0, splitTokens, pointsConversionRatio);
|
|
2293
2307
|
const handleCommit = (value) => {
|
|
2294
2308
|
setSelectedPaymentMethod({ ...selectedPaymentMethod, splitAmount: value });
|
|
2295
2309
|
};
|
|
@@ -2317,7 +2331,15 @@ var PointsSelector = (props) => {
|
|
|
2317
2331
|
] }),
|
|
2318
2332
|
isSelected && /* @__PURE__ */ jsx24("div", { className: "px-3 pt-6 pb-2 md:px-4", children: /* @__PURE__ */ jsxs12("div", { className: "flex justify-between gap-3", children: [
|
|
2319
2333
|
/* @__PURE__ */ jsxs12("div", { className: "flex max-w-[100px] flex-col gap-1", children: [
|
|
2320
|
-
/* @__PURE__ */ jsx24(
|
|
2334
|
+
/* @__PURE__ */ jsx24(
|
|
2335
|
+
Input,
|
|
2336
|
+
{
|
|
2337
|
+
readOnly: true,
|
|
2338
|
+
value: Math.round(splitTokens),
|
|
2339
|
+
className: "bg-white text-center font-medium",
|
|
2340
|
+
onClick: (e) => e.stopPropagation()
|
|
2341
|
+
}
|
|
2342
|
+
),
|
|
2321
2343
|
/* @__PURE__ */ jsx24("p", { className: "text-left text-xs leading-[20px] text-black/45", children: "Points" })
|
|
2322
2344
|
] }),
|
|
2323
2345
|
/* @__PURE__ */ jsx24("div", { className: "flex w-full items-center pb-6", children: /* @__PURE__ */ jsx24(
|
|
@@ -2326,6 +2348,7 @@ var PointsSelector = (props) => {
|
|
|
2326
2348
|
value: [splitTokens],
|
|
2327
2349
|
onValueCommit: ([v]) => handleCommit(v),
|
|
2328
2350
|
onValueChange: ([v]) => setSplitTokens(v),
|
|
2351
|
+
onPointerDown: (e) => e.stopPropagation(),
|
|
2329
2352
|
min,
|
|
2330
2353
|
max,
|
|
2331
2354
|
step
|
|
@@ -2337,7 +2360,8 @@ var PointsSelector = (props) => {
|
|
|
2337
2360
|
{
|
|
2338
2361
|
readOnly: true,
|
|
2339
2362
|
value: formatUSD(usdAmount + getTransactionFee(usdAmount, appProps.transactionFeePercentage)),
|
|
2340
|
-
className: "bg-white text-center font-medium"
|
|
2363
|
+
className: "bg-white text-center font-medium",
|
|
2364
|
+
onClick: (e) => e.stopPropagation()
|
|
2341
2365
|
}
|
|
2342
2366
|
),
|
|
2343
2367
|
/* @__PURE__ */ jsx24("p", { className: "text-left text-xs leading-[20px] text-black/45", children: "Card" })
|
|
@@ -2356,8 +2380,7 @@ var SplitBlock = (props) => {
|
|
|
2356
2380
|
const { spreePayConfig } = useSpreePayConfig();
|
|
2357
2381
|
const [address, setAddress] = useState9(null);
|
|
2358
2382
|
const [walletReady, setWalletReady] = useState9(false);
|
|
2359
|
-
const {
|
|
2360
|
-
const { pointsConversionRatio, pointsTitle } = staticConfig;
|
|
2383
|
+
const { pointsConversionRatio, pointsTitle } = spreePayConfig || {};
|
|
2361
2384
|
const initWallet = useCallback4(
|
|
2362
2385
|
async (pointsChain) => {
|
|
2363
2386
|
if (!pointsChain) return;
|
|
@@ -2388,7 +2411,7 @@ var SplitBlock = (props) => {
|
|
|
2388
2411
|
" ",
|
|
2389
2412
|
formatPoints(balance.availablePoints, pointsTitle),
|
|
2390
2413
|
" ",
|
|
2391
|
-
/* @__PURE__ */ jsx25("span", { className: "text-black/50", children: formatUSD(balance.availablePoints
|
|
2414
|
+
pointsConversionRatio && /* @__PURE__ */ jsx25("span", { className: "text-black/50", children: formatUSD(balance.availablePoints * pointsConversionRatio) })
|
|
2392
2415
|
] }) : null }),
|
|
2393
2416
|
isBalanceLoading ? /* @__PURE__ */ jsx25("div", { className: "h-4 w-6 animate-pulse bg-gray-200" }) : !balance?.availablePoints && /* @__PURE__ */ jsx25("p", { className: "text-sm font-medium text-black", children: "No points available" }),
|
|
2394
2417
|
address && /* @__PURE__ */ jsx25("div", { className: "text-sm font-medium text-black", children: address.length > 8 ? `${address.slice(0, 4)}...${address.slice(-4)}` : address })
|
|
@@ -2410,7 +2433,15 @@ var Points = () => {
|
|
|
2410
2433
|
}
|
|
2411
2434
|
};
|
|
2412
2435
|
return /* @__PURE__ */ jsxs14(Fragment3, { children: [
|
|
2413
|
-
/* @__PURE__ */ jsx26(
|
|
2436
|
+
/* @__PURE__ */ jsx26(
|
|
2437
|
+
PointsSwitch,
|
|
2438
|
+
{
|
|
2439
|
+
value: usePoints,
|
|
2440
|
+
onChange: handleTogglePoints,
|
|
2441
|
+
message: spreePayConfig?.creditCard.pointsInfoMessage,
|
|
2442
|
+
disabled: !spreePayConfig?.creditCard.enabled || !spreePayConfig?.creditCard.points
|
|
2443
|
+
}
|
|
2444
|
+
),
|
|
2414
2445
|
usePoints && /* @__PURE__ */ jsx26(
|
|
2415
2446
|
SplitBlock,
|
|
2416
2447
|
{
|
|
@@ -2426,7 +2457,8 @@ var Points = () => {
|
|
|
2426
2457
|
import { jsx as jsx27, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
2427
2458
|
var CreditCardTab = () => {
|
|
2428
2459
|
const { selectedPaymentMethod, setSelectedPaymentMethod } = useSpreePaymentMethod();
|
|
2429
|
-
const {
|
|
2460
|
+
const { appProps } = useStaticConfig();
|
|
2461
|
+
const { spreePayConfig } = useSpreePayConfig();
|
|
2430
2462
|
const { register } = useSpreePayRegister();
|
|
2431
2463
|
const { mutateCards } = useCards();
|
|
2432
2464
|
const { cardPayment } = useCardPayment();
|
|
@@ -2437,7 +2469,7 @@ var CreditCardTab = () => {
|
|
|
2437
2469
|
try {
|
|
2438
2470
|
let res = null;
|
|
2439
2471
|
const pointsAmount = selectedPaymentMethod.splitAmount ?? 0;
|
|
2440
|
-
const usdAmount = getSplitAmount(appProps.amount ?? 0, pointsAmount,
|
|
2472
|
+
const usdAmount = getSplitAmount(appProps.amount ?? 0, pointsAmount, spreePayConfig?.pointsConversionRatio);
|
|
2441
2473
|
if (usdAmount && pointsAmount) {
|
|
2442
2474
|
res = await splitPayment({ ...data, points: pointsAmount });
|
|
2443
2475
|
} else if (!usdAmount && pointsAmount) {
|
|
@@ -2464,7 +2496,7 @@ var CreditCardTab = () => {
|
|
|
2464
2496
|
setSelectedPaymentMethod,
|
|
2465
2497
|
cardPayment,
|
|
2466
2498
|
splitPayment,
|
|
2467
|
-
|
|
2499
|
+
spreePayConfig
|
|
2468
2500
|
]
|
|
2469
2501
|
);
|
|
2470
2502
|
useEffect7(() => {
|
|
@@ -2583,15 +2615,18 @@ var BASE_TOKENS = [
|
|
|
2583
2615
|
|
|
2584
2616
|
// src/hooks/payments/useCryptoPayment.ts
|
|
2585
2617
|
var MAX_UINT256 = BigInt(2) ** BigInt(256) - BigInt(1);
|
|
2586
|
-
var ONE_INCH_AGGREGATION_ROUTER_V6 = "0x111111125421ca6dc452d289314280a0f8842a65";
|
|
2587
2618
|
var useCryptoPayment = () => {
|
|
2588
2619
|
const { data: walletClient } = useWalletClient();
|
|
2620
|
+
const { spreePayConfig } = useSpreePayConfig();
|
|
2589
2621
|
const config = useConfig();
|
|
2590
2622
|
const { selectedPaymentMethod } = useSpreePaymentMethod();
|
|
2591
2623
|
const cryptoPayment = async (params) => {
|
|
2592
2624
|
if (!walletClient) {
|
|
2593
2625
|
throw new Error("Wallet not connected");
|
|
2594
2626
|
}
|
|
2627
|
+
if (!spreePayConfig) {
|
|
2628
|
+
throw new Error("Spree Pay config not loaded");
|
|
2629
|
+
}
|
|
2595
2630
|
if (selectedPaymentMethod.type !== "CRYPTO" /* CRYPTO */ || !selectedPaymentMethod.method?.symbol) {
|
|
2596
2631
|
throw new Error("Unsupported payment method");
|
|
2597
2632
|
}
|
|
@@ -2606,14 +2641,14 @@ var useCryptoPayment = () => {
|
|
|
2606
2641
|
address: tokenAddress,
|
|
2607
2642
|
abi: erc20Abi2,
|
|
2608
2643
|
functionName: "allowance",
|
|
2609
|
-
args: [walletClient.account.address,
|
|
2644
|
+
args: [walletClient.account.address, spreePayConfig.crypto.oneInchAggregationRouter]
|
|
2610
2645
|
});
|
|
2611
2646
|
if (allowance <= 0n) {
|
|
2612
2647
|
const result = await walletClient.writeContract({
|
|
2613
2648
|
address: tokenAddress,
|
|
2614
2649
|
abi: erc20Abi2,
|
|
2615
2650
|
functionName: "approve",
|
|
2616
|
-
args: [
|
|
2651
|
+
args: [spreePayConfig.crypto.oneInchAggregationRouter, MAX_UINT256]
|
|
2617
2652
|
});
|
|
2618
2653
|
await waitForTransactionReceipt(config, {
|
|
2619
2654
|
hash: result,
|
|
@@ -3178,8 +3213,8 @@ var CryptoWrapper = () => {
|
|
|
3178
3213
|
const config = useMemo9(() => {
|
|
3179
3214
|
if (!spreePayConfig) return null;
|
|
3180
3215
|
return getDefaultConfig({
|
|
3181
|
-
appName: spreePayConfig.rainbowAppName
|
|
3182
|
-
projectId: spreePayConfig.rainbowProjectId
|
|
3216
|
+
appName: spreePayConfig.rainbowAppName,
|
|
3217
|
+
projectId: spreePayConfig.rainbowProjectId,
|
|
3183
3218
|
chains: [base],
|
|
3184
3219
|
ssr: true
|
|
3185
3220
|
});
|
|
@@ -3191,9 +3226,10 @@ var CryptoWrapper = () => {
|
|
|
3191
3226
|
// src/components/CryptoTab/CryptoTab.tsx
|
|
3192
3227
|
import { jsx as jsx39, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
3193
3228
|
var CryptoTab = () => {
|
|
3229
|
+
const { spreePayConfig } = useSpreePayConfig();
|
|
3194
3230
|
return /* @__PURE__ */ jsxs23("div", { children: [
|
|
3195
|
-
/* @__PURE__ */ jsx39("div", { className: "border-b-1 border-black/7 px-5 py-5 md:px-7 md:py-
|
|
3196
|
-
/* @__PURE__ */ jsx39("div", { className: "px-5 py-5 md:px-7 md:py-6", children: /* @__PURE__ */ jsx39(PointsSwitch, { disabled: true }) })
|
|
3231
|
+
/* @__PURE__ */ jsx39("div", { className: "border-b-1 border-black/7 px-5 py-5 md:px-7 md:py-6", children: /* @__PURE__ */ jsx39(CryptoWrapper, {}) }),
|
|
3232
|
+
/* @__PURE__ */ jsx39("div", { className: "px-5 py-5 md:px-7 md:py-6", children: /* @__PURE__ */ jsx39(PointsSwitch, { disabled: true, message: spreePayConfig?.crypto.pointsInfoMessage }) })
|
|
3197
3233
|
] });
|
|
3198
3234
|
};
|
|
3199
3235
|
|
|
@@ -3245,7 +3281,7 @@ var TabButtons = (props) => {
|
|
|
3245
3281
|
/* @__PURE__ */ jsxs24(
|
|
3246
3282
|
TabButton,
|
|
3247
3283
|
{
|
|
3248
|
-
isDisabled: !spreePayConfig?.
|
|
3284
|
+
isDisabled: !spreePayConfig?.crypto.enabled,
|
|
3249
3285
|
onClick: handleChange("CRYPTO" /* CRYPTO */),
|
|
3250
3286
|
isActive: value === "CRYPTO" /* CRYPTO */,
|
|
3251
3287
|
children: [
|