@superlogic/spree-pay 0.1.20 → 0.1.22
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 +141 -73
- package/build/index.d.cts +4 -4
- package/build/index.d.ts +4 -4
- package/build/index.js +141 -73
- package/package.json +1 -1
package/build/index.cjs
CHANGED
|
@@ -62,7 +62,7 @@ var PaymentError = class extends Error {
|
|
|
62
62
|
var PaymentType = /* @__PURE__ */ ((PaymentType2) => {
|
|
63
63
|
PaymentType2["CREDIT_CARD"] = "CREDIT_CARD";
|
|
64
64
|
PaymentType2["CRYPTO"] = "CRYPTO";
|
|
65
|
-
PaymentType2["
|
|
65
|
+
PaymentType2["CREDIT_CARD_SPLIT"] = "SPLIT";
|
|
66
66
|
PaymentType2["POINTS"] = "POINTS";
|
|
67
67
|
return PaymentType2;
|
|
68
68
|
})(PaymentType || {});
|
|
@@ -325,7 +325,8 @@ var CheckoutButton = ({ isLoggedIn }) => {
|
|
|
325
325
|
const { pointsTitle, pointsConversionRatio } = staticConfig;
|
|
326
326
|
const { selectedPaymentMethod, isInternalProcessing } = useSpreePaymentMethod();
|
|
327
327
|
const { splitAmount, type, method } = selectedPaymentMethod;
|
|
328
|
-
const
|
|
328
|
+
const usdAmount = getSplitAmount(amount ?? 0, splitAmount ?? 0, pointsConversionRatio);
|
|
329
|
+
const isDisabled = !amount || !method && usdAmount !== 0 || !!isProcessing || isInternalProcessing || !isLoggedIn;
|
|
329
330
|
const isCC = type === "CREDIT_CARD" /* CREDIT_CARD */;
|
|
330
331
|
const isCrypto = type === "CRYPTO" /* CRYPTO */;
|
|
331
332
|
const getCheckoutContent = () => {
|
|
@@ -333,7 +334,6 @@ var CheckoutButton = ({ isLoggedIn }) => {
|
|
|
333
334
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Spinner, { className: "inline", size: "sm" });
|
|
334
335
|
}
|
|
335
336
|
if (isCC && amount) {
|
|
336
|
-
const usdAmount = getSplitAmount(amount, splitAmount ?? 0, pointsConversionRatio);
|
|
337
337
|
if (splitAmount && usdAmount) {
|
|
338
338
|
return `Pay ${formatUSD(usdAmount + getTransactionFee(usdAmount, transactionFeePercentage))} + ${formatPoints(splitAmount, pointsTitle)}`;
|
|
339
339
|
}
|
|
@@ -394,7 +394,7 @@ var SpreeLegal = () => {
|
|
|
394
394
|
// src/components/CreditCardTab/CreditCardTab.tsx
|
|
395
395
|
var import_react13 = require("react");
|
|
396
396
|
|
|
397
|
-
// src/hooks/useCardPayment.ts
|
|
397
|
+
// src/hooks/payments/useCardPayment.ts
|
|
398
398
|
var import_nice_modal_react2 = __toESM(require("@ebay/nice-modal-react"), 1);
|
|
399
399
|
|
|
400
400
|
// src/modals/Iframe3ds.tsx
|
|
@@ -629,17 +629,8 @@ var registerApi = (config) => {
|
|
|
629
629
|
|
|
630
630
|
// src/services/slapi.ts
|
|
631
631
|
var SlapiPaymentService = {
|
|
632
|
-
createPayment: (
|
|
633
|
-
|
|
634
|
-
let reqParams;
|
|
635
|
-
if (type === "CRYPTO" /* CRYPTO */) {
|
|
636
|
-
reqParams = { type, hash, crypto: params.crypto };
|
|
637
|
-
} else if (type === "CREDIT_CARD" /* CREDIT_CARD */ && params.points && params.points.amount > 0) {
|
|
638
|
-
reqParams = { type: "SPLIT" /* SPLIT */, hash, card: params.card, points: params.points };
|
|
639
|
-
} else {
|
|
640
|
-
reqParams = { type, hash, card: params.card };
|
|
641
|
-
}
|
|
642
|
-
return slapiApi.post("/v1/payments", { ...reqParams, capture, metadata }).then((data) => ({ data }));
|
|
632
|
+
createPayment: ({ capture = false, ...rest }) => {
|
|
633
|
+
return slapiApi.post("/v1/payments", { ...rest, capture }).then((data) => ({ data }));
|
|
643
634
|
},
|
|
644
635
|
baseVerify: ({ id, txHash }) => {
|
|
645
636
|
return slapiApi.post(`/v1/base-transactions/transactions/${id}/verify`, { txHash });
|
|
@@ -658,7 +649,7 @@ var SlapiPaymentService = {
|
|
|
658
649
|
}
|
|
659
650
|
};
|
|
660
651
|
|
|
661
|
-
// src/hooks/useCardPayment.ts
|
|
652
|
+
// src/hooks/payments/useCardPayment.ts
|
|
662
653
|
var useCardPayment = () => {
|
|
663
654
|
const { selectedPaymentMethod } = useSpreePaymentMethod();
|
|
664
655
|
const { env } = useSpreePayEnv();
|
|
@@ -707,20 +698,6 @@ var useCardPayment = () => {
|
|
|
707
698
|
return { cardPayment };
|
|
708
699
|
};
|
|
709
700
|
|
|
710
|
-
// src/hooks/useCards.ts
|
|
711
|
-
var import_swr2 = __toESM(require("swr"), 1);
|
|
712
|
-
var useCards = () => {
|
|
713
|
-
const { data, isLoading, mutate } = (0, import_swr2.default)(`/v1/payments/cards`);
|
|
714
|
-
return {
|
|
715
|
-
cards: data?.data.filter((c) => c.active) || [],
|
|
716
|
-
cardsIsLoading: isLoading,
|
|
717
|
-
mutateCards: mutate
|
|
718
|
-
};
|
|
719
|
-
};
|
|
720
|
-
|
|
721
|
-
// src/hooks/useSplitCardPayments.ts
|
|
722
|
-
var import_nice_modal_react3 = __toESM(require("@ebay/nice-modal-react"), 1);
|
|
723
|
-
|
|
724
701
|
// src/services/AirWalletService.ts
|
|
725
702
|
var import_airkit = require("@mocanetwork/airkit");
|
|
726
703
|
var import_viem = require("viem");
|
|
@@ -747,7 +724,8 @@ async function createAndInit(opts) {
|
|
|
747
724
|
chain: opts.mocaChain,
|
|
748
725
|
account: address
|
|
749
726
|
}) : null;
|
|
750
|
-
|
|
727
|
+
const walletReady = Boolean(address && walletClient);
|
|
728
|
+
return { walletReady, address, walletClient, air, chain: opts.mocaChain };
|
|
751
729
|
} catch (e) {
|
|
752
730
|
const msg = e instanceof Error ? e.message : "Unknown error during AirWallet initialization";
|
|
753
731
|
return { walletReady: false, address: null, walletClient: null, air: null, chain: null, error: msg };
|
|
@@ -755,6 +733,10 @@ async function createAndInit(opts) {
|
|
|
755
733
|
}
|
|
756
734
|
async function getAirWallet(options) {
|
|
757
735
|
const key = optionsKey(options);
|
|
736
|
+
if (cachedKey === key && singletonState && !singletonState.walletReady) {
|
|
737
|
+
singletonState = null;
|
|
738
|
+
initPromise = null;
|
|
739
|
+
}
|
|
758
740
|
if (singletonState && cachedKey === key) return singletonState;
|
|
759
741
|
if (initPromise && cachedKey === key) return initPromise;
|
|
760
742
|
cachedKey = key;
|
|
@@ -807,7 +789,8 @@ async function handleSendErc20(params) {
|
|
|
807
789
|
}
|
|
808
790
|
}
|
|
809
791
|
|
|
810
|
-
// src/hooks/
|
|
792
|
+
// src/hooks/payments/utils.ts
|
|
793
|
+
var import_nice_modal_react3 = __toESM(require("@ebay/nice-modal-react"), 1);
|
|
811
794
|
var REFRESH_INTERVAL = 3 * 1e3;
|
|
812
795
|
var MAX_RETRIES = 10;
|
|
813
796
|
async function longPollPoints(paymentId) {
|
|
@@ -848,6 +831,51 @@ async function longPollCardStatus(paymentId) {
|
|
|
848
831
|
}
|
|
849
832
|
throw new Error("Payment polling timed out");
|
|
850
833
|
}
|
|
834
|
+
|
|
835
|
+
// src/hooks/payments/usePointsPayment.ts
|
|
836
|
+
var usePointsPayment = () => {
|
|
837
|
+
const { selectedPaymentMethod } = useSpreePaymentMethod();
|
|
838
|
+
const { spreePayConfig } = useSpreePayConfig();
|
|
839
|
+
const pointsPayment = async (params) => {
|
|
840
|
+
if (selectedPaymentMethod.type !== "CREDIT_CARD" /* CREDIT_CARD */) {
|
|
841
|
+
throw new Error("Unsupported payment method");
|
|
842
|
+
}
|
|
843
|
+
const { hash, capture, metadata } = params;
|
|
844
|
+
const { data: paymentResData } = await SlapiPaymentService.createPayment({
|
|
845
|
+
hash,
|
|
846
|
+
capture,
|
|
847
|
+
metadata,
|
|
848
|
+
type: "POINTS" /* POINTS */
|
|
849
|
+
});
|
|
850
|
+
const wallet = peekAirWallet();
|
|
851
|
+
if (!wallet || !spreePayConfig?.pointsChain) {
|
|
852
|
+
throw new Error("AirWallet not found");
|
|
853
|
+
}
|
|
854
|
+
const transaction = await handleSendErc20({
|
|
855
|
+
amount: params.points,
|
|
856
|
+
token: spreePayConfig.pointsChain.pointsCoin,
|
|
857
|
+
recipient: spreePayConfig.pointsChain.recipientAddress
|
|
858
|
+
});
|
|
859
|
+
if (!transaction) {
|
|
860
|
+
throw new Error("Points transaction failed");
|
|
861
|
+
}
|
|
862
|
+
await SlapiPaymentService.validatePoints({
|
|
863
|
+
paymentId: paymentResData.id,
|
|
864
|
+
txHash: transaction.txHash
|
|
865
|
+
});
|
|
866
|
+
const pointsStatus = await longPollPoints(paymentResData.id);
|
|
867
|
+
return {
|
|
868
|
+
status: pointsStatus,
|
|
869
|
+
txId: paymentResData.txId,
|
|
870
|
+
txHash: transaction.txHash,
|
|
871
|
+
paymentId: paymentResData.id,
|
|
872
|
+
paymentType: "POINTS" /* POINTS */
|
|
873
|
+
};
|
|
874
|
+
};
|
|
875
|
+
return { pointsPayment };
|
|
876
|
+
};
|
|
877
|
+
|
|
878
|
+
// src/hooks/payments/useSplitCardPayments.ts
|
|
851
879
|
var useSplitCardPayments = () => {
|
|
852
880
|
const { selectedPaymentMethod } = useSpreePaymentMethod();
|
|
853
881
|
const { env } = useSpreePayEnv();
|
|
@@ -872,7 +900,7 @@ var useSplitCardPayments = () => {
|
|
|
872
900
|
hash,
|
|
873
901
|
capture,
|
|
874
902
|
metadata,
|
|
875
|
-
type: "
|
|
903
|
+
type: "SPLIT" /* CREDIT_CARD_SPLIT */,
|
|
876
904
|
card: {
|
|
877
905
|
cardId,
|
|
878
906
|
transactionFee,
|
|
@@ -901,7 +929,7 @@ var useSplitCardPayments = () => {
|
|
|
901
929
|
});
|
|
902
930
|
const pointsStatus = await longPollPoints(paymentResData.id);
|
|
903
931
|
return {
|
|
904
|
-
paymentType: "SPLIT" /*
|
|
932
|
+
paymentType: "SPLIT" /* CREDIT_CARD_SPLIT */,
|
|
905
933
|
status: pointsStatus,
|
|
906
934
|
paymentId: paymentResData.id,
|
|
907
935
|
txId: paymentResData.txId,
|
|
@@ -911,6 +939,17 @@ var useSplitCardPayments = () => {
|
|
|
911
939
|
return { splitPayment };
|
|
912
940
|
};
|
|
913
941
|
|
|
942
|
+
// src/hooks/useCards.ts
|
|
943
|
+
var import_swr2 = __toESM(require("swr"), 1);
|
|
944
|
+
var useCards = () => {
|
|
945
|
+
const { data, isLoading, mutate } = (0, import_swr2.default)(`/v1/payments/cards`);
|
|
946
|
+
return {
|
|
947
|
+
cards: data?.data.filter((c) => c.active) || [],
|
|
948
|
+
cardsIsLoading: isLoading,
|
|
949
|
+
mutateCards: mutate
|
|
950
|
+
};
|
|
951
|
+
};
|
|
952
|
+
|
|
914
953
|
// src/components/CreditCardTab/CreditCard/CreditCard.tsx
|
|
915
954
|
var import_react6 = require("react");
|
|
916
955
|
var import_react_stripe_js2 = require("@stripe/react-stripe-js");
|
|
@@ -2282,7 +2321,7 @@ function Slider2({
|
|
|
2282
2321
|
// src/components/CreditCardTab/Points/PointsSelector.tsx
|
|
2283
2322
|
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
2284
2323
|
var PointsSelector = (props) => {
|
|
2285
|
-
const { isSelected, onSelect, children } = props;
|
|
2324
|
+
const { isDisabled, isSelected, onSelect, children } = props;
|
|
2286
2325
|
const { balance } = useSlapiBalance();
|
|
2287
2326
|
const { selectedPaymentMethod, setSelectedPaymentMethod } = useSpreePaymentMethod();
|
|
2288
2327
|
const { appProps, staticConfig } = useStaticConfig();
|
|
@@ -2290,16 +2329,18 @@ var PointsSelector = (props) => {
|
|
|
2290
2329
|
const max = Math.min((appProps.amount ?? 0) * staticConfig.pointsConversionRatio, balance?.availablePoints ?? 0);
|
|
2291
2330
|
const step = 10;
|
|
2292
2331
|
const [splitTokens, setSplitTokens] = (0, import_react10.useState)(0);
|
|
2293
|
-
const
|
|
2332
|
+
const usdAmount = getSplitAmount(appProps.amount ?? 0, splitTokens, staticConfig.pointsConversionRatio);
|
|
2294
2333
|
const handleCommit = (value) => {
|
|
2295
2334
|
setSelectedPaymentMethod({ ...selectedPaymentMethod, splitAmount: value });
|
|
2296
2335
|
};
|
|
2297
2336
|
return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
2298
2337
|
"button",
|
|
2299
2338
|
{
|
|
2339
|
+
disabled: isDisabled,
|
|
2300
2340
|
onClick: onSelect,
|
|
2301
2341
|
className: cn("bg-primary/8 cursor-pointer overflow-hidden rounded-md border-1 border-transparent", {
|
|
2302
|
-
"border-primary": isSelected
|
|
2342
|
+
"border-primary": isSelected,
|
|
2343
|
+
"cursor-not-allowed opacity-50": isDisabled
|
|
2303
2344
|
}),
|
|
2304
2345
|
children: [
|
|
2305
2346
|
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: cn("flex h-11 w-full", { "bg-black/4": isSelected }), children: [
|
|
@@ -2316,7 +2357,7 @@ var PointsSelector = (props) => {
|
|
|
2316
2357
|
] }),
|
|
2317
2358
|
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: [
|
|
2318
2359
|
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex max-w-[100px] flex-col gap-1", children: [
|
|
2319
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Input, { readOnly: true, value: splitTokens, className: "bg-white text-center font-medium" }),
|
|
2360
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Input, { readOnly: true, value: Math.round(splitTokens), className: "bg-white text-center font-medium" }),
|
|
2320
2361
|
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-left text-xs leading-[20px] text-black/45", children: "Points" })
|
|
2321
2362
|
] }),
|
|
2322
2363
|
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "flex w-full items-center pb-6", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
@@ -2335,7 +2376,7 @@ var PointsSelector = (props) => {
|
|
|
2335
2376
|
Input,
|
|
2336
2377
|
{
|
|
2337
2378
|
readOnly: true,
|
|
2338
|
-
value: formatUSD(
|
|
2379
|
+
value: formatUSD(usdAmount + getTransactionFee(usdAmount, appProps.transactionFeePercentage)),
|
|
2339
2380
|
className: "bg-white text-center font-medium"
|
|
2340
2381
|
}
|
|
2341
2382
|
),
|
|
@@ -2350,30 +2391,38 @@ var PointsSelector = (props) => {
|
|
|
2350
2391
|
// src/components/CreditCardTab/Points/SplitBlock.tsx
|
|
2351
2392
|
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
2352
2393
|
var SplitBlock = (props) => {
|
|
2353
|
-
const { isSelected, onSelect } = props;
|
|
2394
|
+
const { onToggle, isSelected, onSelect } = props;
|
|
2354
2395
|
const { balance, isBalanceLoading } = useSlapiBalance();
|
|
2355
2396
|
const { spreePayConfig } = useSpreePayConfig();
|
|
2356
2397
|
const [address, setAddress] = (0, import_react11.useState)(null);
|
|
2398
|
+
const [walletReady, setWalletReady] = (0, import_react11.useState)(false);
|
|
2357
2399
|
const { staticConfig } = useStaticConfig();
|
|
2358
2400
|
const { pointsConversionRatio, pointsTitle } = staticConfig;
|
|
2359
|
-
const initWallet = (0, import_react11.useCallback)(
|
|
2360
|
-
|
|
2361
|
-
return;
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2401
|
+
const initWallet = (0, import_react11.useCallback)(
|
|
2402
|
+
async (pointsChain) => {
|
|
2403
|
+
if (!pointsChain) return;
|
|
2404
|
+
try {
|
|
2405
|
+
const res = await getAirWallet({
|
|
2406
|
+
mocaChain: pointsChain.mocaChain,
|
|
2407
|
+
partnerId: pointsChain.partnerId
|
|
2408
|
+
});
|
|
2409
|
+
setAddress(res.address ?? null);
|
|
2410
|
+
setWalletReady(res.walletReady);
|
|
2411
|
+
if (!res.walletReady && res.error) {
|
|
2412
|
+
onToggle(false);
|
|
2413
|
+
}
|
|
2414
|
+
} catch (e) {
|
|
2415
|
+
console.error("Air Wallet init failed:", e);
|
|
2416
|
+
}
|
|
2417
|
+
},
|
|
2418
|
+
[onToggle]
|
|
2419
|
+
);
|
|
2373
2420
|
(0, import_react11.useEffect)(() => {
|
|
2421
|
+
setAddress(null);
|
|
2422
|
+
setWalletReady(false);
|
|
2374
2423
|
initWallet(spreePayConfig?.pointsChain);
|
|
2375
|
-
}, [spreePayConfig, initWallet]);
|
|
2376
|
-
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "flex flex-col gap-1", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(PointsSelector, { onSelect: () => onSelect("air"), isSelected, children: [
|
|
2424
|
+
}, [spreePayConfig?.pointsChain, initWallet]);
|
|
2425
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "flex flex-col gap-1", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(PointsSelector, { isDisabled: !walletReady, onSelect: () => onSelect("air"), isSelected, children: [
|
|
2377
2426
|
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "flex items-center gap-2", children: balance?.availablePoints ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("p", { className: "text-sm font-medium text-black", children: [
|
|
2378
2427
|
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "text-black/50", children: "Available" }),
|
|
2379
2428
|
" ",
|
|
@@ -2402,7 +2451,14 @@ var Points = () => {
|
|
|
2402
2451
|
};
|
|
2403
2452
|
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
|
|
2404
2453
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(PointsSwitch, { disabled: !spreePayConfig?.creditCard.enabled, value: usePoints, onChange: handleTogglePoints }),
|
|
2405
|
-
usePoints && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
2454
|
+
usePoints && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
2455
|
+
SplitBlock,
|
|
2456
|
+
{
|
|
2457
|
+
onToggle: handleTogglePoints,
|
|
2458
|
+
isSelected: selectedPointsType === "air",
|
|
2459
|
+
onSelect: setSelectedPointsType
|
|
2460
|
+
}
|
|
2461
|
+
)
|
|
2406
2462
|
] });
|
|
2407
2463
|
};
|
|
2408
2464
|
|
|
@@ -2410,26 +2466,29 @@ var Points = () => {
|
|
|
2410
2466
|
var import_jsx_runtime27 = require("react/jsx-runtime");
|
|
2411
2467
|
var CreditCardTab = () => {
|
|
2412
2468
|
const { selectedPaymentMethod, setSelectedPaymentMethod } = useSpreePaymentMethod();
|
|
2469
|
+
const { staticConfig, appProps } = useStaticConfig();
|
|
2413
2470
|
const { register } = useSpreePayRegister();
|
|
2414
2471
|
const { mutateCards } = useCards();
|
|
2415
2472
|
const { cardPayment } = useCardPayment();
|
|
2416
2473
|
const { splitPayment } = useSplitCardPayments();
|
|
2474
|
+
const { pointsPayment } = usePointsPayment();
|
|
2417
2475
|
const handlePay = (0, import_react13.useCallback)(
|
|
2418
2476
|
async (data) => {
|
|
2419
2477
|
try {
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
}
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2478
|
+
let res = null;
|
|
2479
|
+
const pointsAmount = selectedPaymentMethod.splitAmount ?? 0;
|
|
2480
|
+
const usdAmount = getSplitAmount(appProps.amount ?? 0, pointsAmount, staticConfig.pointsConversionRatio);
|
|
2481
|
+
if (usdAmount && pointsAmount) {
|
|
2482
|
+
res = await splitPayment({ ...data, points: pointsAmount });
|
|
2483
|
+
} else if (!usdAmount && pointsAmount) {
|
|
2484
|
+
res = await pointsPayment({ ...data, points: pointsAmount });
|
|
2485
|
+
} else {
|
|
2486
|
+
res = await cardPayment(data);
|
|
2487
|
+
}
|
|
2488
|
+
if (["AUTHORIZED" /* AUTHORIZED */, "CAPTURED" /* CAPTURED */].includes(res.status)) {
|
|
2489
|
+
return Promise.resolve(res);
|
|
2431
2490
|
}
|
|
2432
|
-
return Promise.reject(new PaymentError("
|
|
2491
|
+
return Promise.reject(new PaymentError("Card payment failed", res.status));
|
|
2433
2492
|
} catch (_) {
|
|
2434
2493
|
return Promise.reject(new PaymentError("Payment failed", "FAILED" /* FAILED */));
|
|
2435
2494
|
} finally {
|
|
@@ -2437,7 +2496,16 @@ var CreditCardTab = () => {
|
|
|
2437
2496
|
mutateCards();
|
|
2438
2497
|
}
|
|
2439
2498
|
},
|
|
2440
|
-
[
|
|
2499
|
+
[
|
|
2500
|
+
mutateCards,
|
|
2501
|
+
selectedPaymentMethod,
|
|
2502
|
+
pointsPayment,
|
|
2503
|
+
appProps.amount,
|
|
2504
|
+
setSelectedPaymentMethod,
|
|
2505
|
+
cardPayment,
|
|
2506
|
+
splitPayment,
|
|
2507
|
+
staticConfig.pointsConversionRatio
|
|
2508
|
+
]
|
|
2441
2509
|
);
|
|
2442
2510
|
(0, import_react13.useEffect)(() => {
|
|
2443
2511
|
register(handlePay);
|
|
@@ -2512,7 +2580,7 @@ async function waitForTransactionReceipt(config, parameters) {
|
|
|
2512
2580
|
// ../../node_modules/@wagmi/core/dist/esm/exports/index.js
|
|
2513
2581
|
var import_viem3 = require("viem");
|
|
2514
2582
|
|
|
2515
|
-
// src/hooks/useCryptoPayment.ts
|
|
2583
|
+
// src/hooks/payments/useCryptoPayment.ts
|
|
2516
2584
|
var import_viem4 = require("viem");
|
|
2517
2585
|
var import_wagmi = require("wagmi");
|
|
2518
2586
|
|
|
@@ -2553,7 +2621,7 @@ var BASE_TOKENS = [
|
|
|
2553
2621
|
}
|
|
2554
2622
|
];
|
|
2555
2623
|
|
|
2556
|
-
// src/hooks/useCryptoPayment.ts
|
|
2624
|
+
// src/hooks/payments/useCryptoPayment.ts
|
|
2557
2625
|
var MAX_UINT256 = BigInt(2) ** BigInt(256) - BigInt(1);
|
|
2558
2626
|
var ONE_INCH_AGGREGATION_ROUTER_V6 = "0x111111125421ca6dc452d289314280a0f8842a65";
|
|
2559
2627
|
var useCryptoPayment = () => {
|
|
@@ -2603,7 +2671,7 @@ var useCryptoPayment = () => {
|
|
|
2603
2671
|
token: TOKEN,
|
|
2604
2672
|
publicKey: walletClient.account.address,
|
|
2605
2673
|
slippageType: "fixed",
|
|
2606
|
-
slippageBps: 0.5 * 100
|
|
2674
|
+
slippageBps: Math.round(0.5 * 100)
|
|
2607
2675
|
}
|
|
2608
2676
|
});
|
|
2609
2677
|
const parsedTX = JSON.parse(paymentRes.data.encodedTx);
|
package/build/index.d.cts
CHANGED
|
@@ -50,7 +50,7 @@ type Card = {
|
|
|
50
50
|
active: boolean;
|
|
51
51
|
addressZipCheck: string;
|
|
52
52
|
cardId: string;
|
|
53
|
-
createdAt: Date;
|
|
53
|
+
createdAt: string | Date;
|
|
54
54
|
default: boolean;
|
|
55
55
|
expireMonth: string;
|
|
56
56
|
expireYear: string;
|
|
@@ -62,7 +62,7 @@ type Card = {
|
|
|
62
62
|
name: string;
|
|
63
63
|
paymentProvider: string;
|
|
64
64
|
schema: string | undefined;
|
|
65
|
-
updatedAt: Date;
|
|
65
|
+
updatedAt: string | Date;
|
|
66
66
|
userId: string;
|
|
67
67
|
zipCode: string;
|
|
68
68
|
};
|
|
@@ -84,10 +84,10 @@ type SelectedPaymentMethod = CardPaymentMethod | CryptoPaymentMethod;
|
|
|
84
84
|
declare enum PaymentType {
|
|
85
85
|
CREDIT_CARD = "CREDIT_CARD",
|
|
86
86
|
CRYPTO = "CRYPTO",
|
|
87
|
-
|
|
87
|
+
CREDIT_CARD_SPLIT = "SPLIT",
|
|
88
88
|
POINTS = "POINTS"
|
|
89
89
|
}
|
|
90
|
-
declare
|
|
90
|
+
declare enum SlapiPaymentStatus {
|
|
91
91
|
NOT_INITIALIZED = "NOT_INITIALIZED",// back-end only
|
|
92
92
|
PENDING = "PENDING",// back-end only
|
|
93
93
|
AUTHORIZED = "AUTHORIZED",// success
|
package/build/index.d.ts
CHANGED
|
@@ -50,7 +50,7 @@ type Card = {
|
|
|
50
50
|
active: boolean;
|
|
51
51
|
addressZipCheck: string;
|
|
52
52
|
cardId: string;
|
|
53
|
-
createdAt: Date;
|
|
53
|
+
createdAt: string | Date;
|
|
54
54
|
default: boolean;
|
|
55
55
|
expireMonth: string;
|
|
56
56
|
expireYear: string;
|
|
@@ -62,7 +62,7 @@ type Card = {
|
|
|
62
62
|
name: string;
|
|
63
63
|
paymentProvider: string;
|
|
64
64
|
schema: string | undefined;
|
|
65
|
-
updatedAt: Date;
|
|
65
|
+
updatedAt: string | Date;
|
|
66
66
|
userId: string;
|
|
67
67
|
zipCode: string;
|
|
68
68
|
};
|
|
@@ -84,10 +84,10 @@ type SelectedPaymentMethod = CardPaymentMethod | CryptoPaymentMethod;
|
|
|
84
84
|
declare enum PaymentType {
|
|
85
85
|
CREDIT_CARD = "CREDIT_CARD",
|
|
86
86
|
CRYPTO = "CRYPTO",
|
|
87
|
-
|
|
87
|
+
CREDIT_CARD_SPLIT = "SPLIT",
|
|
88
88
|
POINTS = "POINTS"
|
|
89
89
|
}
|
|
90
|
-
declare
|
|
90
|
+
declare enum SlapiPaymentStatus {
|
|
91
91
|
NOT_INITIALIZED = "NOT_INITIALIZED",// back-end only
|
|
92
92
|
PENDING = "PENDING",// back-end only
|
|
93
93
|
AUTHORIZED = "AUTHORIZED",// success
|
package/build/index.js
CHANGED
|
@@ -22,7 +22,7 @@ var PaymentError = class extends Error {
|
|
|
22
22
|
var PaymentType = /* @__PURE__ */ ((PaymentType2) => {
|
|
23
23
|
PaymentType2["CREDIT_CARD"] = "CREDIT_CARD";
|
|
24
24
|
PaymentType2["CRYPTO"] = "CRYPTO";
|
|
25
|
-
PaymentType2["
|
|
25
|
+
PaymentType2["CREDIT_CARD_SPLIT"] = "SPLIT";
|
|
26
26
|
PaymentType2["POINTS"] = "POINTS";
|
|
27
27
|
return PaymentType2;
|
|
28
28
|
})(PaymentType || {});
|
|
@@ -285,7 +285,8 @@ var CheckoutButton = ({ isLoggedIn }) => {
|
|
|
285
285
|
const { pointsTitle, pointsConversionRatio } = staticConfig;
|
|
286
286
|
const { selectedPaymentMethod, isInternalProcessing } = useSpreePaymentMethod();
|
|
287
287
|
const { splitAmount, type, method } = selectedPaymentMethod;
|
|
288
|
-
const
|
|
288
|
+
const usdAmount = getSplitAmount(amount ?? 0, splitAmount ?? 0, pointsConversionRatio);
|
|
289
|
+
const isDisabled = !amount || !method && usdAmount !== 0 || !!isProcessing || isInternalProcessing || !isLoggedIn;
|
|
289
290
|
const isCC = type === "CREDIT_CARD" /* CREDIT_CARD */;
|
|
290
291
|
const isCrypto = type === "CRYPTO" /* CRYPTO */;
|
|
291
292
|
const getCheckoutContent = () => {
|
|
@@ -293,7 +294,6 @@ var CheckoutButton = ({ isLoggedIn }) => {
|
|
|
293
294
|
return /* @__PURE__ */ jsx4(Spinner, { className: "inline", size: "sm" });
|
|
294
295
|
}
|
|
295
296
|
if (isCC && amount) {
|
|
296
|
-
const usdAmount = getSplitAmount(amount, splitAmount ?? 0, pointsConversionRatio);
|
|
297
297
|
if (splitAmount && usdAmount) {
|
|
298
298
|
return `Pay ${formatUSD(usdAmount + getTransactionFee(usdAmount, transactionFeePercentage))} + ${formatPoints(splitAmount, pointsTitle)}`;
|
|
299
299
|
}
|
|
@@ -354,7 +354,7 @@ var SpreeLegal = () => {
|
|
|
354
354
|
// src/components/CreditCardTab/CreditCardTab.tsx
|
|
355
355
|
import { useCallback as useCallback5, useEffect as useEffect7 } from "react";
|
|
356
356
|
|
|
357
|
-
// src/hooks/useCardPayment.ts
|
|
357
|
+
// src/hooks/payments/useCardPayment.ts
|
|
358
358
|
import NiceModal2 from "@ebay/nice-modal-react";
|
|
359
359
|
|
|
360
360
|
// src/modals/Iframe3ds.tsx
|
|
@@ -589,17 +589,8 @@ var registerApi = (config) => {
|
|
|
589
589
|
|
|
590
590
|
// src/services/slapi.ts
|
|
591
591
|
var SlapiPaymentService = {
|
|
592
|
-
createPayment: (
|
|
593
|
-
|
|
594
|
-
let reqParams;
|
|
595
|
-
if (type === "CRYPTO" /* CRYPTO */) {
|
|
596
|
-
reqParams = { type, hash, crypto: params.crypto };
|
|
597
|
-
} else if (type === "CREDIT_CARD" /* CREDIT_CARD */ && params.points && params.points.amount > 0) {
|
|
598
|
-
reqParams = { type: "SPLIT" /* SPLIT */, hash, card: params.card, points: params.points };
|
|
599
|
-
} else {
|
|
600
|
-
reqParams = { type, hash, card: params.card };
|
|
601
|
-
}
|
|
602
|
-
return slapiApi.post("/v1/payments", { ...reqParams, capture, metadata }).then((data) => ({ data }));
|
|
592
|
+
createPayment: ({ capture = false, ...rest }) => {
|
|
593
|
+
return slapiApi.post("/v1/payments", { ...rest, capture }).then((data) => ({ data }));
|
|
603
594
|
},
|
|
604
595
|
baseVerify: ({ id, txHash }) => {
|
|
605
596
|
return slapiApi.post(`/v1/base-transactions/transactions/${id}/verify`, { txHash });
|
|
@@ -618,7 +609,7 @@ var SlapiPaymentService = {
|
|
|
618
609
|
}
|
|
619
610
|
};
|
|
620
611
|
|
|
621
|
-
// src/hooks/useCardPayment.ts
|
|
612
|
+
// src/hooks/payments/useCardPayment.ts
|
|
622
613
|
var useCardPayment = () => {
|
|
623
614
|
const { selectedPaymentMethod } = useSpreePaymentMethod();
|
|
624
615
|
const { env } = useSpreePayEnv();
|
|
@@ -667,20 +658,6 @@ var useCardPayment = () => {
|
|
|
667
658
|
return { cardPayment };
|
|
668
659
|
};
|
|
669
660
|
|
|
670
|
-
// src/hooks/useCards.ts
|
|
671
|
-
import useSWR2 from "swr";
|
|
672
|
-
var useCards = () => {
|
|
673
|
-
const { data, isLoading, mutate } = useSWR2(`/v1/payments/cards`);
|
|
674
|
-
return {
|
|
675
|
-
cards: data?.data.filter((c) => c.active) || [],
|
|
676
|
-
cardsIsLoading: isLoading,
|
|
677
|
-
mutateCards: mutate
|
|
678
|
-
};
|
|
679
|
-
};
|
|
680
|
-
|
|
681
|
-
// src/hooks/useSplitCardPayments.ts
|
|
682
|
-
import NiceModal3 from "@ebay/nice-modal-react";
|
|
683
|
-
|
|
684
661
|
// src/services/AirWalletService.ts
|
|
685
662
|
import { AirService, BUILD_ENV } from "@mocanetwork/airkit";
|
|
686
663
|
import { createWalletClient, custom, encodeFunctionData, erc20Abi, parseUnits } from "viem";
|
|
@@ -707,7 +684,8 @@ async function createAndInit(opts) {
|
|
|
707
684
|
chain: opts.mocaChain,
|
|
708
685
|
account: address
|
|
709
686
|
}) : null;
|
|
710
|
-
|
|
687
|
+
const walletReady = Boolean(address && walletClient);
|
|
688
|
+
return { walletReady, address, walletClient, air, chain: opts.mocaChain };
|
|
711
689
|
} catch (e) {
|
|
712
690
|
const msg = e instanceof Error ? e.message : "Unknown error during AirWallet initialization";
|
|
713
691
|
return { walletReady: false, address: null, walletClient: null, air: null, chain: null, error: msg };
|
|
@@ -715,6 +693,10 @@ async function createAndInit(opts) {
|
|
|
715
693
|
}
|
|
716
694
|
async function getAirWallet(options) {
|
|
717
695
|
const key = optionsKey(options);
|
|
696
|
+
if (cachedKey === key && singletonState && !singletonState.walletReady) {
|
|
697
|
+
singletonState = null;
|
|
698
|
+
initPromise = null;
|
|
699
|
+
}
|
|
718
700
|
if (singletonState && cachedKey === key) return singletonState;
|
|
719
701
|
if (initPromise && cachedKey === key) return initPromise;
|
|
720
702
|
cachedKey = key;
|
|
@@ -767,7 +749,8 @@ async function handleSendErc20(params) {
|
|
|
767
749
|
}
|
|
768
750
|
}
|
|
769
751
|
|
|
770
|
-
// src/hooks/
|
|
752
|
+
// src/hooks/payments/utils.ts
|
|
753
|
+
import NiceModal3 from "@ebay/nice-modal-react";
|
|
771
754
|
var REFRESH_INTERVAL = 3 * 1e3;
|
|
772
755
|
var MAX_RETRIES = 10;
|
|
773
756
|
async function longPollPoints(paymentId) {
|
|
@@ -808,6 +791,51 @@ async function longPollCardStatus(paymentId) {
|
|
|
808
791
|
}
|
|
809
792
|
throw new Error("Payment polling timed out");
|
|
810
793
|
}
|
|
794
|
+
|
|
795
|
+
// src/hooks/payments/usePointsPayment.ts
|
|
796
|
+
var usePointsPayment = () => {
|
|
797
|
+
const { selectedPaymentMethod } = useSpreePaymentMethod();
|
|
798
|
+
const { spreePayConfig } = useSpreePayConfig();
|
|
799
|
+
const pointsPayment = async (params) => {
|
|
800
|
+
if (selectedPaymentMethod.type !== "CREDIT_CARD" /* CREDIT_CARD */) {
|
|
801
|
+
throw new Error("Unsupported payment method");
|
|
802
|
+
}
|
|
803
|
+
const { hash, capture, metadata } = params;
|
|
804
|
+
const { data: paymentResData } = await SlapiPaymentService.createPayment({
|
|
805
|
+
hash,
|
|
806
|
+
capture,
|
|
807
|
+
metadata,
|
|
808
|
+
type: "POINTS" /* POINTS */
|
|
809
|
+
});
|
|
810
|
+
const wallet = peekAirWallet();
|
|
811
|
+
if (!wallet || !spreePayConfig?.pointsChain) {
|
|
812
|
+
throw new Error("AirWallet not found");
|
|
813
|
+
}
|
|
814
|
+
const transaction = await handleSendErc20({
|
|
815
|
+
amount: params.points,
|
|
816
|
+
token: spreePayConfig.pointsChain.pointsCoin,
|
|
817
|
+
recipient: spreePayConfig.pointsChain.recipientAddress
|
|
818
|
+
});
|
|
819
|
+
if (!transaction) {
|
|
820
|
+
throw new Error("Points transaction failed");
|
|
821
|
+
}
|
|
822
|
+
await SlapiPaymentService.validatePoints({
|
|
823
|
+
paymentId: paymentResData.id,
|
|
824
|
+
txHash: transaction.txHash
|
|
825
|
+
});
|
|
826
|
+
const pointsStatus = await longPollPoints(paymentResData.id);
|
|
827
|
+
return {
|
|
828
|
+
status: pointsStatus,
|
|
829
|
+
txId: paymentResData.txId,
|
|
830
|
+
txHash: transaction.txHash,
|
|
831
|
+
paymentId: paymentResData.id,
|
|
832
|
+
paymentType: "POINTS" /* POINTS */
|
|
833
|
+
};
|
|
834
|
+
};
|
|
835
|
+
return { pointsPayment };
|
|
836
|
+
};
|
|
837
|
+
|
|
838
|
+
// src/hooks/payments/useSplitCardPayments.ts
|
|
811
839
|
var useSplitCardPayments = () => {
|
|
812
840
|
const { selectedPaymentMethod } = useSpreePaymentMethod();
|
|
813
841
|
const { env } = useSpreePayEnv();
|
|
@@ -832,7 +860,7 @@ var useSplitCardPayments = () => {
|
|
|
832
860
|
hash,
|
|
833
861
|
capture,
|
|
834
862
|
metadata,
|
|
835
|
-
type: "
|
|
863
|
+
type: "SPLIT" /* CREDIT_CARD_SPLIT */,
|
|
836
864
|
card: {
|
|
837
865
|
cardId,
|
|
838
866
|
transactionFee,
|
|
@@ -861,7 +889,7 @@ var useSplitCardPayments = () => {
|
|
|
861
889
|
});
|
|
862
890
|
const pointsStatus = await longPollPoints(paymentResData.id);
|
|
863
891
|
return {
|
|
864
|
-
paymentType: "SPLIT" /*
|
|
892
|
+
paymentType: "SPLIT" /* CREDIT_CARD_SPLIT */,
|
|
865
893
|
status: pointsStatus,
|
|
866
894
|
paymentId: paymentResData.id,
|
|
867
895
|
txId: paymentResData.txId,
|
|
@@ -871,6 +899,17 @@ var useSplitCardPayments = () => {
|
|
|
871
899
|
return { splitPayment };
|
|
872
900
|
};
|
|
873
901
|
|
|
902
|
+
// src/hooks/useCards.ts
|
|
903
|
+
import useSWR2 from "swr";
|
|
904
|
+
var useCards = () => {
|
|
905
|
+
const { data, isLoading, mutate } = useSWR2(`/v1/payments/cards`);
|
|
906
|
+
return {
|
|
907
|
+
cards: data?.data.filter((c) => c.active) || [],
|
|
908
|
+
cardsIsLoading: isLoading,
|
|
909
|
+
mutateCards: mutate
|
|
910
|
+
};
|
|
911
|
+
};
|
|
912
|
+
|
|
874
913
|
// src/components/CreditCardTab/CreditCard/CreditCard.tsx
|
|
875
914
|
import { useMemo as useMemo2, useState as useState4 } from "react";
|
|
876
915
|
import { Elements } from "@stripe/react-stripe-js";
|
|
@@ -2242,7 +2281,7 @@ function Slider2({
|
|
|
2242
2281
|
// src/components/CreditCardTab/Points/PointsSelector.tsx
|
|
2243
2282
|
import { jsx as jsx24, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
2244
2283
|
var PointsSelector = (props) => {
|
|
2245
|
-
const { isSelected, onSelect, children } = props;
|
|
2284
|
+
const { isDisabled, isSelected, onSelect, children } = props;
|
|
2246
2285
|
const { balance } = useSlapiBalance();
|
|
2247
2286
|
const { selectedPaymentMethod, setSelectedPaymentMethod } = useSpreePaymentMethod();
|
|
2248
2287
|
const { appProps, staticConfig } = useStaticConfig();
|
|
@@ -2250,16 +2289,18 @@ var PointsSelector = (props) => {
|
|
|
2250
2289
|
const max = Math.min((appProps.amount ?? 0) * staticConfig.pointsConversionRatio, balance?.availablePoints ?? 0);
|
|
2251
2290
|
const step = 10;
|
|
2252
2291
|
const [splitTokens, setSplitTokens] = useState8(0);
|
|
2253
|
-
const
|
|
2292
|
+
const usdAmount = getSplitAmount(appProps.amount ?? 0, splitTokens, staticConfig.pointsConversionRatio);
|
|
2254
2293
|
const handleCommit = (value) => {
|
|
2255
2294
|
setSelectedPaymentMethod({ ...selectedPaymentMethod, splitAmount: value });
|
|
2256
2295
|
};
|
|
2257
2296
|
return /* @__PURE__ */ jsxs12(
|
|
2258
2297
|
"button",
|
|
2259
2298
|
{
|
|
2299
|
+
disabled: isDisabled,
|
|
2260
2300
|
onClick: onSelect,
|
|
2261
2301
|
className: cn("bg-primary/8 cursor-pointer overflow-hidden rounded-md border-1 border-transparent", {
|
|
2262
|
-
"border-primary": isSelected
|
|
2302
|
+
"border-primary": isSelected,
|
|
2303
|
+
"cursor-not-allowed opacity-50": isDisabled
|
|
2263
2304
|
}),
|
|
2264
2305
|
children: [
|
|
2265
2306
|
/* @__PURE__ */ jsxs12("div", { className: cn("flex h-11 w-full", { "bg-black/4": isSelected }), children: [
|
|
@@ -2276,7 +2317,7 @@ var PointsSelector = (props) => {
|
|
|
2276
2317
|
] }),
|
|
2277
2318
|
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: [
|
|
2278
2319
|
/* @__PURE__ */ jsxs12("div", { className: "flex max-w-[100px] flex-col gap-1", children: [
|
|
2279
|
-
/* @__PURE__ */ jsx24(Input, { readOnly: true, value: splitTokens, className: "bg-white text-center font-medium" }),
|
|
2320
|
+
/* @__PURE__ */ jsx24(Input, { readOnly: true, value: Math.round(splitTokens), className: "bg-white text-center font-medium" }),
|
|
2280
2321
|
/* @__PURE__ */ jsx24("p", { className: "text-left text-xs leading-[20px] text-black/45", children: "Points" })
|
|
2281
2322
|
] }),
|
|
2282
2323
|
/* @__PURE__ */ jsx24("div", { className: "flex w-full items-center pb-6", children: /* @__PURE__ */ jsx24(
|
|
@@ -2295,7 +2336,7 @@ var PointsSelector = (props) => {
|
|
|
2295
2336
|
Input,
|
|
2296
2337
|
{
|
|
2297
2338
|
readOnly: true,
|
|
2298
|
-
value: formatUSD(
|
|
2339
|
+
value: formatUSD(usdAmount + getTransactionFee(usdAmount, appProps.transactionFeePercentage)),
|
|
2299
2340
|
className: "bg-white text-center font-medium"
|
|
2300
2341
|
}
|
|
2301
2342
|
),
|
|
@@ -2310,30 +2351,38 @@ var PointsSelector = (props) => {
|
|
|
2310
2351
|
// src/components/CreditCardTab/Points/SplitBlock.tsx
|
|
2311
2352
|
import { jsx as jsx25, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
2312
2353
|
var SplitBlock = (props) => {
|
|
2313
|
-
const { isSelected, onSelect } = props;
|
|
2354
|
+
const { onToggle, isSelected, onSelect } = props;
|
|
2314
2355
|
const { balance, isBalanceLoading } = useSlapiBalance();
|
|
2315
2356
|
const { spreePayConfig } = useSpreePayConfig();
|
|
2316
2357
|
const [address, setAddress] = useState9(null);
|
|
2358
|
+
const [walletReady, setWalletReady] = useState9(false);
|
|
2317
2359
|
const { staticConfig } = useStaticConfig();
|
|
2318
2360
|
const { pointsConversionRatio, pointsTitle } = staticConfig;
|
|
2319
|
-
const initWallet = useCallback4(
|
|
2320
|
-
|
|
2321
|
-
return;
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2361
|
+
const initWallet = useCallback4(
|
|
2362
|
+
async (pointsChain) => {
|
|
2363
|
+
if (!pointsChain) return;
|
|
2364
|
+
try {
|
|
2365
|
+
const res = await getAirWallet({
|
|
2366
|
+
mocaChain: pointsChain.mocaChain,
|
|
2367
|
+
partnerId: pointsChain.partnerId
|
|
2368
|
+
});
|
|
2369
|
+
setAddress(res.address ?? null);
|
|
2370
|
+
setWalletReady(res.walletReady);
|
|
2371
|
+
if (!res.walletReady && res.error) {
|
|
2372
|
+
onToggle(false);
|
|
2373
|
+
}
|
|
2374
|
+
} catch (e) {
|
|
2375
|
+
console.error("Air Wallet init failed:", e);
|
|
2376
|
+
}
|
|
2377
|
+
},
|
|
2378
|
+
[onToggle]
|
|
2379
|
+
);
|
|
2333
2380
|
useEffect6(() => {
|
|
2381
|
+
setAddress(null);
|
|
2382
|
+
setWalletReady(false);
|
|
2334
2383
|
initWallet(spreePayConfig?.pointsChain);
|
|
2335
|
-
}, [spreePayConfig, initWallet]);
|
|
2336
|
-
return /* @__PURE__ */ jsx25("div", { className: "flex flex-col gap-1", children: /* @__PURE__ */ jsxs13(PointsSelector, { onSelect: () => onSelect("air"), isSelected, children: [
|
|
2384
|
+
}, [spreePayConfig?.pointsChain, initWallet]);
|
|
2385
|
+
return /* @__PURE__ */ jsx25("div", { className: "flex flex-col gap-1", children: /* @__PURE__ */ jsxs13(PointsSelector, { isDisabled: !walletReady, onSelect: () => onSelect("air"), isSelected, children: [
|
|
2337
2386
|
/* @__PURE__ */ jsx25("div", { className: "flex items-center gap-2", children: balance?.availablePoints ? /* @__PURE__ */ jsxs13("p", { className: "text-sm font-medium text-black", children: [
|
|
2338
2387
|
/* @__PURE__ */ jsx25("span", { className: "text-black/50", children: "Available" }),
|
|
2339
2388
|
" ",
|
|
@@ -2362,7 +2411,14 @@ var Points = () => {
|
|
|
2362
2411
|
};
|
|
2363
2412
|
return /* @__PURE__ */ jsxs14(Fragment3, { children: [
|
|
2364
2413
|
/* @__PURE__ */ jsx26(PointsSwitch, { disabled: !spreePayConfig?.creditCard.enabled, value: usePoints, onChange: handleTogglePoints }),
|
|
2365
|
-
usePoints && /* @__PURE__ */ jsx26(
|
|
2414
|
+
usePoints && /* @__PURE__ */ jsx26(
|
|
2415
|
+
SplitBlock,
|
|
2416
|
+
{
|
|
2417
|
+
onToggle: handleTogglePoints,
|
|
2418
|
+
isSelected: selectedPointsType === "air",
|
|
2419
|
+
onSelect: setSelectedPointsType
|
|
2420
|
+
}
|
|
2421
|
+
)
|
|
2366
2422
|
] });
|
|
2367
2423
|
};
|
|
2368
2424
|
|
|
@@ -2370,26 +2426,29 @@ var Points = () => {
|
|
|
2370
2426
|
import { jsx as jsx27, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
2371
2427
|
var CreditCardTab = () => {
|
|
2372
2428
|
const { selectedPaymentMethod, setSelectedPaymentMethod } = useSpreePaymentMethod();
|
|
2429
|
+
const { staticConfig, appProps } = useStaticConfig();
|
|
2373
2430
|
const { register } = useSpreePayRegister();
|
|
2374
2431
|
const { mutateCards } = useCards();
|
|
2375
2432
|
const { cardPayment } = useCardPayment();
|
|
2376
2433
|
const { splitPayment } = useSplitCardPayments();
|
|
2434
|
+
const { pointsPayment } = usePointsPayment();
|
|
2377
2435
|
const handlePay = useCallback5(
|
|
2378
2436
|
async (data) => {
|
|
2379
2437
|
try {
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
}
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2438
|
+
let res = null;
|
|
2439
|
+
const pointsAmount = selectedPaymentMethod.splitAmount ?? 0;
|
|
2440
|
+
const usdAmount = getSplitAmount(appProps.amount ?? 0, pointsAmount, staticConfig.pointsConversionRatio);
|
|
2441
|
+
if (usdAmount && pointsAmount) {
|
|
2442
|
+
res = await splitPayment({ ...data, points: pointsAmount });
|
|
2443
|
+
} else if (!usdAmount && pointsAmount) {
|
|
2444
|
+
res = await pointsPayment({ ...data, points: pointsAmount });
|
|
2445
|
+
} else {
|
|
2446
|
+
res = await cardPayment(data);
|
|
2447
|
+
}
|
|
2448
|
+
if (["AUTHORIZED" /* AUTHORIZED */, "CAPTURED" /* CAPTURED */].includes(res.status)) {
|
|
2449
|
+
return Promise.resolve(res);
|
|
2391
2450
|
}
|
|
2392
|
-
return Promise.reject(new PaymentError("
|
|
2451
|
+
return Promise.reject(new PaymentError("Card payment failed", res.status));
|
|
2393
2452
|
} catch (_) {
|
|
2394
2453
|
return Promise.reject(new PaymentError("Payment failed", "FAILED" /* FAILED */));
|
|
2395
2454
|
} finally {
|
|
@@ -2397,7 +2456,16 @@ var CreditCardTab = () => {
|
|
|
2397
2456
|
mutateCards();
|
|
2398
2457
|
}
|
|
2399
2458
|
},
|
|
2400
|
-
[
|
|
2459
|
+
[
|
|
2460
|
+
mutateCards,
|
|
2461
|
+
selectedPaymentMethod,
|
|
2462
|
+
pointsPayment,
|
|
2463
|
+
appProps.amount,
|
|
2464
|
+
setSelectedPaymentMethod,
|
|
2465
|
+
cardPayment,
|
|
2466
|
+
splitPayment,
|
|
2467
|
+
staticConfig.pointsConversionRatio
|
|
2468
|
+
]
|
|
2401
2469
|
);
|
|
2402
2470
|
useEffect7(() => {
|
|
2403
2471
|
register(handlePay);
|
|
@@ -2472,7 +2540,7 @@ async function waitForTransactionReceipt(config, parameters) {
|
|
|
2472
2540
|
// ../../node_modules/@wagmi/core/dist/esm/exports/index.js
|
|
2473
2541
|
import { custom as custom2, http, webSocket } from "viem";
|
|
2474
2542
|
|
|
2475
|
-
// src/hooks/useCryptoPayment.ts
|
|
2543
|
+
// src/hooks/payments/useCryptoPayment.ts
|
|
2476
2544
|
import { erc20Abi as erc20Abi2 } from "viem";
|
|
2477
2545
|
import { useConfig, useWalletClient } from "wagmi";
|
|
2478
2546
|
|
|
@@ -2513,7 +2581,7 @@ var BASE_TOKENS = [
|
|
|
2513
2581
|
}
|
|
2514
2582
|
];
|
|
2515
2583
|
|
|
2516
|
-
// src/hooks/useCryptoPayment.ts
|
|
2584
|
+
// src/hooks/payments/useCryptoPayment.ts
|
|
2517
2585
|
var MAX_UINT256 = BigInt(2) ** BigInt(256) - BigInt(1);
|
|
2518
2586
|
var ONE_INCH_AGGREGATION_ROUTER_V6 = "0x111111125421ca6dc452d289314280a0f8842a65";
|
|
2519
2587
|
var useCryptoPayment = () => {
|
|
@@ -2563,7 +2631,7 @@ var useCryptoPayment = () => {
|
|
|
2563
2631
|
token: TOKEN,
|
|
2564
2632
|
publicKey: walletClient.account.address,
|
|
2565
2633
|
slippageType: "fixed",
|
|
2566
|
-
slippageBps: 0.5 * 100
|
|
2634
|
+
slippageBps: Math.round(0.5 * 100)
|
|
2567
2635
|
}
|
|
2568
2636
|
});
|
|
2569
2637
|
const parsedTX = JSON.parse(paymentRes.data.encodedTx);
|