UNPKG

@blocklet/payment-react

Version:

Reusable react components for payment kit v2

165 lines (164 loc) 5.37 kB
import { Fragment, jsx, jsxs } from "react/jsx-runtime"; import { useLocaleContext } from "@arcblock/ux/lib/Locale/context"; import Toast from "@arcblock/ux/lib/Toast"; import { Dialog } from "@arcblock/ux"; import { Button, Typography } from "@mui/material"; import { useSetState } from "ahooks"; import { useEffect, useRef } from "react"; import StripeForm from "../payment/form/stripe/index.js"; import api from "../libs/api.js"; import { formatError } from "../libs/util.js"; export default function StripePaymentAction(props) { const { invoice, invoiceIds, subscriptionId, customerId, currencyId, paymentMethod, autoTrigger = false, onExternalPayment, onSuccess, onError, onClose, children } = props; const { t } = useLocaleContext(); const [state, setState] = useSetState({ paying: false, confirmDialog: false, stripeDialog: false, clientSecret: null, publishableKey: null, customer: null }); const autoTriggerRef = useRef(false); useEffect(() => { if (autoTrigger && !autoTriggerRef.current) { autoTriggerRef.current = true; handlePay(); } }, [autoTrigger]); const handlePay = async () => { if (state.paying) { return; } const hasSubscription = !!(subscriptionId || invoice?.subscription_id); const method = paymentMethod || invoice?.paymentMethod; const shouldShowConfirm = hasSubscription && method?.type === "stripe"; if (shouldShowConfirm) { setState({ confirmDialog: true }); return; } await proceedWithPayment(); }; const proceedWithPayment = async () => { setState({ paying: true, confirmDialog: false }); const derivedCurrencyId = currencyId || invoice?.currency_id || invoice?.paymentCurrency?.id; const derivedPaymentMethod = paymentMethod || invoice?.paymentMethod; const isStripePayment = derivedPaymentMethod?.type === "stripe"; if (isStripePayment && derivedCurrencyId) { const stripePayload = {}; if (invoiceIds && invoiceIds.length > 0) { stripePayload.invoice_ids = invoiceIds; } else if (invoice) { stripePayload.invoice_ids = [invoice.id]; } else if (subscriptionId) { stripePayload.subscription_id = subscriptionId; } else if (customerId) { stripePayload.customer_id = customerId; } if (derivedCurrencyId) { stripePayload.currency_id = derivedCurrencyId; } try { const { data: paymentData } = await api.post("/api/invoices/pay-stripe", stripePayload); setState({ paying: false, stripeDialog: true, clientSecret: paymentData.client_secret, publishableKey: paymentData.publishable_key, customer: paymentData.customer || null }); return; } catch (err) { const error = formatError(err); Toast.error(error); setState({ paying: false }); onError?.(error); return; } } setState({ paying: false }); if (onExternalPayment) { onExternalPayment(invoice?.id); return; } Toast.error(t("payment.customer.invoice.payError")); onError?.(new Error("EXTERNAL_PAYMENT_HANDLER_NOT_PROVIDED")); }; const handleConfirmCancel = () => { setState({ confirmDialog: false, paying: false }); onClose?.(); }; const handleStripeConfirm = () => { Toast.success(t("payment.customer.invoice.payProcessing")); setState({ paying: false, stripeDialog: false, clientSecret: null, publishableKey: null, customer: null }); setTimeout(() => { onSuccess?.(); }, 2e3); }; const handleStripeCancel = () => { setState({ paying: false, stripeDialog: false, clientSecret: null, publishableKey: null, customer: null }); onClose?.(); }; return /* @__PURE__ */ jsxs(Fragment, { children: [ children?.(handlePay, state.paying), state.confirmDialog && /* @__PURE__ */ jsx( Dialog, { open: state.confirmDialog, title: t("payment.customer.invoice.paymentConfirmTitle"), onClose: handleConfirmCancel, maxWidth: "sm", PaperProps: { style: { minHeight: 0 } }, actions: [ /* @__PURE__ */ jsx(Button, { variant: "outlined", onClick: handleConfirmCancel, children: t("common.cancel") }, "cancel"), /* @__PURE__ */ jsx(Button, { variant: "contained", onClick: proceedWithPayment, children: t("payment.customer.invoice.continue") }, "continue") ], children: /* @__PURE__ */ jsx(Typography, { variant: "body1", sx: { color: "text.secondary", mt: -2 }, children: t("payment.customer.invoice.paymentConfirmDescription") }) } ), state.stripeDialog && state.clientSecret && state.publishableKey && state.customer && /* @__PURE__ */ jsx( StripeForm, { clientSecret: state.clientSecret, intentType: "setup_intent", publicKey: state.publishableKey, customer: state.customer, mode: "setup", title: t("payment.customer.invoice.pay"), submitButtonText: t("common.submit"), onConfirm: handleStripeConfirm, onCancel: handleStripeCancel, returnUrl: window.location.href } ) ] }); }