@doujins/payments-ui 0.0.13 → 0.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +202 -136
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +202 -136
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2520,6 +2520,143 @@ var SolanaPaymentView = ({
|
|
|
2520
2520
|
renderBody()
|
|
2521
2521
|
] });
|
|
2522
2522
|
};
|
|
2523
|
+
var useSubscriptionActions = () => {
|
|
2524
|
+
const { services } = usePaymentContext();
|
|
2525
|
+
const ensurePrice = (priceId) => {
|
|
2526
|
+
if (!priceId) {
|
|
2527
|
+
throw new Error("payments-ui: priceId is required for subscription actions");
|
|
2528
|
+
}
|
|
2529
|
+
return priceId;
|
|
2530
|
+
};
|
|
2531
|
+
const subscribeWithCard = React3.useCallback(
|
|
2532
|
+
async ({
|
|
2533
|
+
priceId,
|
|
2534
|
+
processor = "nmi",
|
|
2535
|
+
provider,
|
|
2536
|
+
paymentToken,
|
|
2537
|
+
billing
|
|
2538
|
+
}) => {
|
|
2539
|
+
const payload = {
|
|
2540
|
+
priceId: ensurePrice(priceId),
|
|
2541
|
+
paymentToken,
|
|
2542
|
+
processor,
|
|
2543
|
+
provider,
|
|
2544
|
+
email: billing.email,
|
|
2545
|
+
firstName: billing.firstName,
|
|
2546
|
+
lastName: billing.lastName,
|
|
2547
|
+
address1: billing.address1,
|
|
2548
|
+
city: billing.city,
|
|
2549
|
+
state: billing.stateRegion,
|
|
2550
|
+
zipCode: billing.postalCode,
|
|
2551
|
+
country: billing.country
|
|
2552
|
+
};
|
|
2553
|
+
return services.subscriptions.subscribe("nmi", payload);
|
|
2554
|
+
},
|
|
2555
|
+
[services]
|
|
2556
|
+
);
|
|
2557
|
+
const subscribeWithSavedMethod = React3.useCallback(
|
|
2558
|
+
async ({
|
|
2559
|
+
priceId,
|
|
2560
|
+
processor = "nmi",
|
|
2561
|
+
provider,
|
|
2562
|
+
paymentMethodId,
|
|
2563
|
+
email
|
|
2564
|
+
}) => {
|
|
2565
|
+
const payload = {
|
|
2566
|
+
priceId: ensurePrice(priceId),
|
|
2567
|
+
paymentMethodId,
|
|
2568
|
+
processor,
|
|
2569
|
+
provider,
|
|
2570
|
+
email
|
|
2571
|
+
};
|
|
2572
|
+
return services.subscriptions.subscribe("nmi", payload);
|
|
2573
|
+
},
|
|
2574
|
+
[services]
|
|
2575
|
+
);
|
|
2576
|
+
const subscribeWithCCBill = React3.useCallback(
|
|
2577
|
+
async ({
|
|
2578
|
+
priceId,
|
|
2579
|
+
email,
|
|
2580
|
+
firstName,
|
|
2581
|
+
lastName,
|
|
2582
|
+
zipCode,
|
|
2583
|
+
country,
|
|
2584
|
+
processor = "ccbill"
|
|
2585
|
+
}) => {
|
|
2586
|
+
const payload = {
|
|
2587
|
+
priceId: ensurePrice(priceId),
|
|
2588
|
+
email,
|
|
2589
|
+
firstName,
|
|
2590
|
+
lastName,
|
|
2591
|
+
zipCode,
|
|
2592
|
+
country,
|
|
2593
|
+
processor
|
|
2594
|
+
};
|
|
2595
|
+
return services.subscriptions.subscribe("ccbill", payload);
|
|
2596
|
+
},
|
|
2597
|
+
[services]
|
|
2598
|
+
);
|
|
2599
|
+
const generateFlexFormUrl = React3.useCallback(
|
|
2600
|
+
async ({
|
|
2601
|
+
priceId,
|
|
2602
|
+
firstName,
|
|
2603
|
+
lastName,
|
|
2604
|
+
address1,
|
|
2605
|
+
city,
|
|
2606
|
+
state,
|
|
2607
|
+
zipCode,
|
|
2608
|
+
country
|
|
2609
|
+
}) => {
|
|
2610
|
+
const payload = {
|
|
2611
|
+
price_id: ensurePrice(priceId),
|
|
2612
|
+
first_name: firstName,
|
|
2613
|
+
last_name: lastName,
|
|
2614
|
+
address1,
|
|
2615
|
+
city,
|
|
2616
|
+
state,
|
|
2617
|
+
zip_code: zipCode,
|
|
2618
|
+
country
|
|
2619
|
+
};
|
|
2620
|
+
return services.subscriptions.generateFlexFormUrl(payload);
|
|
2621
|
+
},
|
|
2622
|
+
[services]
|
|
2623
|
+
);
|
|
2624
|
+
return {
|
|
2625
|
+
subscribeWithCard,
|
|
2626
|
+
subscribeWithSavedMethod,
|
|
2627
|
+
subscribeWithCCBill,
|
|
2628
|
+
generateFlexFormUrl
|
|
2629
|
+
};
|
|
2630
|
+
};
|
|
2631
|
+
|
|
2632
|
+
// src/hooks/useAlternativePaymentProvider.ts
|
|
2633
|
+
var useAlternativePaymentProvider = () => {
|
|
2634
|
+
const [isLoading, setIsLoading] = React3.useState(false);
|
|
2635
|
+
const [error, setError] = React3.useState(null);
|
|
2636
|
+
const { generateFlexFormUrl } = useSubscriptionActions();
|
|
2637
|
+
const openFlexForm = React3.useCallback(
|
|
2638
|
+
async (payload) => {
|
|
2639
|
+
setIsLoading(true);
|
|
2640
|
+
setError(null);
|
|
2641
|
+
try {
|
|
2642
|
+
const response = await generateFlexFormUrl(payload);
|
|
2643
|
+
if (response?.iframe_url) {
|
|
2644
|
+
window.location.href = response.iframe_url;
|
|
2645
|
+
} else {
|
|
2646
|
+
throw new Error("Unable to launch payment provider.");
|
|
2647
|
+
}
|
|
2648
|
+
} catch (err) {
|
|
2649
|
+
const message = err instanceof Error ? err.message : "Failed to open payment provider.";
|
|
2650
|
+
setError(message);
|
|
2651
|
+
console.error("[payments-ui] failed to open alternative payment provider", err);
|
|
2652
|
+
} finally {
|
|
2653
|
+
setIsLoading(false);
|
|
2654
|
+
}
|
|
2655
|
+
},
|
|
2656
|
+
[generateFlexFormUrl]
|
|
2657
|
+
);
|
|
2658
|
+
return { openFlexForm, isLoading, error };
|
|
2659
|
+
};
|
|
2523
2660
|
var PaymentExperience = ({
|
|
2524
2661
|
priceId,
|
|
2525
2662
|
usdAmount,
|
|
@@ -2528,6 +2665,7 @@ var PaymentExperience = ({
|
|
|
2528
2665
|
enableNewCard = true,
|
|
2529
2666
|
enableStoredMethods = true,
|
|
2530
2667
|
enableSolanaPay = true,
|
|
2668
|
+
enableAlternativePayments = true,
|
|
2531
2669
|
onSolanaSuccess,
|
|
2532
2670
|
onSolanaError,
|
|
2533
2671
|
initialMode = "cards"
|
|
@@ -2544,7 +2682,14 @@ var PaymentExperience = ({
|
|
|
2544
2682
|
const [savedError, setSavedError] = React3.useState(null);
|
|
2545
2683
|
const [newCardStatus, setNewCardStatus] = React3.useState("idle");
|
|
2546
2684
|
const [newCardError, setNewCardError] = React3.useState(null);
|
|
2685
|
+
const [billingDetails, setBillingDetails] = React3.useState(null);
|
|
2686
|
+
const [alternativePaymentError, setAlternativePaymentError] = React3.useState(null);
|
|
2547
2687
|
const { notifyStatus, notifySuccess, notifyError } = usePaymentNotifications();
|
|
2688
|
+
const {
|
|
2689
|
+
openFlexForm,
|
|
2690
|
+
isLoading: flexFormLoading,
|
|
2691
|
+
error: flexFormError
|
|
2692
|
+
} = useAlternativePaymentProvider();
|
|
2548
2693
|
React3.useEffect(() => {
|
|
2549
2694
|
setActiveTab(showStored ? "saved" : "new");
|
|
2550
2695
|
}, [showStored]);
|
|
@@ -2624,6 +2769,48 @@ var PaymentExperience = ({
|
|
|
2624
2769
|
},
|
|
2625
2770
|
[onSolanaError]
|
|
2626
2771
|
);
|
|
2772
|
+
const handleAlternativePayment = React3.useCallback(() => {
|
|
2773
|
+
if (!enableAlternativePayments || !priceId) {
|
|
2774
|
+
return;
|
|
2775
|
+
}
|
|
2776
|
+
if (!billingDetails) {
|
|
2777
|
+
setAlternativePaymentError("Enter your billing details first.");
|
|
2778
|
+
return;
|
|
2779
|
+
}
|
|
2780
|
+
const requiredFields = [
|
|
2781
|
+
"firstName",
|
|
2782
|
+
"lastName",
|
|
2783
|
+
"address1",
|
|
2784
|
+
"city",
|
|
2785
|
+
"stateRegion",
|
|
2786
|
+
"postalCode",
|
|
2787
|
+
"country"
|
|
2788
|
+
];
|
|
2789
|
+
const missingField = requiredFields.find((field) => {
|
|
2790
|
+
const value = billingDetails[field];
|
|
2791
|
+
return typeof value !== "string" || value.trim().length === 0;
|
|
2792
|
+
});
|
|
2793
|
+
if (missingField) {
|
|
2794
|
+
setAlternativePaymentError("Please complete your billing address before continuing.");
|
|
2795
|
+
return;
|
|
2796
|
+
}
|
|
2797
|
+
setAlternativePaymentError(null);
|
|
2798
|
+
openFlexForm({
|
|
2799
|
+
priceId,
|
|
2800
|
+
firstName: billingDetails.firstName,
|
|
2801
|
+
lastName: billingDetails.lastName,
|
|
2802
|
+
address1: billingDetails.address1,
|
|
2803
|
+
city: billingDetails.city,
|
|
2804
|
+
state: billingDetails.stateRegion ?? "",
|
|
2805
|
+
zipCode: billingDetails.postalCode,
|
|
2806
|
+
country: billingDetails.country
|
|
2807
|
+
});
|
|
2808
|
+
}, [
|
|
2809
|
+
billingDetails,
|
|
2810
|
+
enableAlternativePayments,
|
|
2811
|
+
openFlexForm,
|
|
2812
|
+
priceId
|
|
2813
|
+
]);
|
|
2627
2814
|
const renderSavedTab = () => {
|
|
2628
2815
|
if (!showStored) {
|
|
2629
2816
|
return /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground", children: "Saved payment methods are unavailable right now. Add a new card to get started." });
|
|
@@ -2662,7 +2849,8 @@ var PaymentExperience = ({
|
|
|
2662
2849
|
submitLabel: "Pay now",
|
|
2663
2850
|
externalError: newCardError,
|
|
2664
2851
|
onTokenize: handleNewCardTokenize,
|
|
2665
|
-
submitting: newCardStatus === "processing"
|
|
2852
|
+
submitting: newCardStatus === "processing",
|
|
2853
|
+
onBillingChange: setBillingDetails
|
|
2666
2854
|
}
|
|
2667
2855
|
);
|
|
2668
2856
|
};
|
|
@@ -2690,6 +2878,19 @@ var PaymentExperience = ({
|
|
|
2690
2878
|
] });
|
|
2691
2879
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-6 pt-4", children: [
|
|
2692
2880
|
mode === "cards" && renderCardExperience(),
|
|
2881
|
+
mode === "cards" && enableAlternativePayments && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2 text-center text-sm text-muted-foreground", children: [
|
|
2882
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2883
|
+
"button",
|
|
2884
|
+
{
|
|
2885
|
+
type: "button",
|
|
2886
|
+
className: "text-primary underline-offset-4 hover:underline disabled:opacity-60",
|
|
2887
|
+
onClick: handleAlternativePayment,
|
|
2888
|
+
disabled: flexFormLoading || !priceId,
|
|
2889
|
+
children: flexFormLoading ? "Preparing alternative checkout\u2026" : "Prefer a different processor? Pay with CCBill"
|
|
2890
|
+
}
|
|
2891
|
+
),
|
|
2892
|
+
(alternativePaymentError || flexFormError) && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-destructive", children: alternativePaymentError || flexFormError })
|
|
2893
|
+
] }),
|
|
2693
2894
|
mode === "solana" && enableSolanaPay && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2694
2895
|
SolanaPaymentView,
|
|
2695
2896
|
{
|
|
@@ -2730,114 +2931,6 @@ var SubscriptionSuccessDialog = ({
|
|
|
2730
2931
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-6 py-6", children: /* @__PURE__ */ jsxRuntime.jsx(Button, { className: "w-full", onClick: onClose, children: "Continue exploring" }) })
|
|
2731
2932
|
] }) });
|
|
2732
2933
|
};
|
|
2733
|
-
var useSubscriptionActions = () => {
|
|
2734
|
-
const { services } = usePaymentContext();
|
|
2735
|
-
const ensurePrice = (priceId) => {
|
|
2736
|
-
if (!priceId) {
|
|
2737
|
-
throw new Error("payments-ui: priceId is required for subscription actions");
|
|
2738
|
-
}
|
|
2739
|
-
return priceId;
|
|
2740
|
-
};
|
|
2741
|
-
const subscribeWithCard = React3.useCallback(
|
|
2742
|
-
async ({
|
|
2743
|
-
priceId,
|
|
2744
|
-
processor = "nmi",
|
|
2745
|
-
provider,
|
|
2746
|
-
paymentToken,
|
|
2747
|
-
billing
|
|
2748
|
-
}) => {
|
|
2749
|
-
const payload = {
|
|
2750
|
-
priceId: ensurePrice(priceId),
|
|
2751
|
-
paymentToken,
|
|
2752
|
-
processor,
|
|
2753
|
-
provider,
|
|
2754
|
-
email: billing.email,
|
|
2755
|
-
firstName: billing.firstName,
|
|
2756
|
-
lastName: billing.lastName,
|
|
2757
|
-
address1: billing.address1,
|
|
2758
|
-
city: billing.city,
|
|
2759
|
-
state: billing.stateRegion,
|
|
2760
|
-
zipCode: billing.postalCode,
|
|
2761
|
-
country: billing.country
|
|
2762
|
-
};
|
|
2763
|
-
return services.subscriptions.subscribe("nmi", payload);
|
|
2764
|
-
},
|
|
2765
|
-
[services]
|
|
2766
|
-
);
|
|
2767
|
-
const subscribeWithSavedMethod = React3.useCallback(
|
|
2768
|
-
async ({
|
|
2769
|
-
priceId,
|
|
2770
|
-
processor = "nmi",
|
|
2771
|
-
provider,
|
|
2772
|
-
paymentMethodId,
|
|
2773
|
-
email
|
|
2774
|
-
}) => {
|
|
2775
|
-
const payload = {
|
|
2776
|
-
priceId: ensurePrice(priceId),
|
|
2777
|
-
paymentMethodId,
|
|
2778
|
-
processor,
|
|
2779
|
-
provider,
|
|
2780
|
-
email
|
|
2781
|
-
};
|
|
2782
|
-
return services.subscriptions.subscribe("nmi", payload);
|
|
2783
|
-
},
|
|
2784
|
-
[services]
|
|
2785
|
-
);
|
|
2786
|
-
const subscribeWithCCBill = React3.useCallback(
|
|
2787
|
-
async ({
|
|
2788
|
-
priceId,
|
|
2789
|
-
email,
|
|
2790
|
-
firstName,
|
|
2791
|
-
lastName,
|
|
2792
|
-
zipCode,
|
|
2793
|
-
country,
|
|
2794
|
-
processor = "ccbill"
|
|
2795
|
-
}) => {
|
|
2796
|
-
const payload = {
|
|
2797
|
-
priceId: ensurePrice(priceId),
|
|
2798
|
-
email,
|
|
2799
|
-
firstName,
|
|
2800
|
-
lastName,
|
|
2801
|
-
zipCode,
|
|
2802
|
-
country,
|
|
2803
|
-
processor
|
|
2804
|
-
};
|
|
2805
|
-
return services.subscriptions.subscribe("ccbill", payload);
|
|
2806
|
-
},
|
|
2807
|
-
[services]
|
|
2808
|
-
);
|
|
2809
|
-
const generateFlexFormUrl = React3.useCallback(
|
|
2810
|
-
async ({
|
|
2811
|
-
priceId,
|
|
2812
|
-
firstName,
|
|
2813
|
-
lastName,
|
|
2814
|
-
address1,
|
|
2815
|
-
city,
|
|
2816
|
-
state,
|
|
2817
|
-
zipCode,
|
|
2818
|
-
country
|
|
2819
|
-
}) => {
|
|
2820
|
-
const payload = {
|
|
2821
|
-
price_id: ensurePrice(priceId),
|
|
2822
|
-
first_name: firstName,
|
|
2823
|
-
last_name: lastName,
|
|
2824
|
-
address1,
|
|
2825
|
-
city,
|
|
2826
|
-
state,
|
|
2827
|
-
zip_code: zipCode,
|
|
2828
|
-
country
|
|
2829
|
-
};
|
|
2830
|
-
return services.subscriptions.generateFlexFormUrl(payload);
|
|
2831
|
-
},
|
|
2832
|
-
[services]
|
|
2833
|
-
);
|
|
2834
|
-
return {
|
|
2835
|
-
subscribeWithCard,
|
|
2836
|
-
subscribeWithSavedMethod,
|
|
2837
|
-
subscribeWithCCBill,
|
|
2838
|
-
generateFlexFormUrl
|
|
2839
|
-
};
|
|
2840
|
-
};
|
|
2841
2934
|
var SubscriptionCheckoutModal = ({
|
|
2842
2935
|
open,
|
|
2843
2936
|
onOpenChange,
|
|
@@ -4885,33 +4978,6 @@ var usePaymentStatus = (options = {}) => {
|
|
|
4885
4978
|
isPending: getConfirmationStatus() === "pending"
|
|
4886
4979
|
};
|
|
4887
4980
|
};
|
|
4888
|
-
var useAlternativePaymentProvider = () => {
|
|
4889
|
-
const [isLoading, setIsLoading] = React3.useState(false);
|
|
4890
|
-
const [error, setError] = React3.useState(null);
|
|
4891
|
-
const { generateFlexFormUrl } = useSubscriptionActions();
|
|
4892
|
-
const openFlexForm = React3.useCallback(
|
|
4893
|
-
async (payload) => {
|
|
4894
|
-
setIsLoading(true);
|
|
4895
|
-
setError(null);
|
|
4896
|
-
try {
|
|
4897
|
-
const response = await generateFlexFormUrl(payload);
|
|
4898
|
-
if (response?.iframe_url) {
|
|
4899
|
-
window.location.href = response.iframe_url;
|
|
4900
|
-
} else {
|
|
4901
|
-
throw new Error("Unable to launch payment provider.");
|
|
4902
|
-
}
|
|
4903
|
-
} catch (err) {
|
|
4904
|
-
const message = err instanceof Error ? err.message : "Failed to open payment provider.";
|
|
4905
|
-
setError(message);
|
|
4906
|
-
console.error("[payments-ui] failed to open alternative payment provider", err);
|
|
4907
|
-
} finally {
|
|
4908
|
-
setIsLoading(false);
|
|
4909
|
-
}
|
|
4910
|
-
},
|
|
4911
|
-
[generateFlexFormUrl]
|
|
4912
|
-
);
|
|
4913
|
-
return { openFlexForm, isLoading, error };
|
|
4914
|
-
};
|
|
4915
4981
|
|
|
4916
4982
|
exports.BillingHistory = BillingHistory;
|
|
4917
4983
|
exports.CancelMembershipDialog = CancelMembershipDialog;
|