fix sub distributor payment feedback
This commit is contained in:
1 parent
b850a5d709
commit
dae5c121b7
3 files changed
+83
-6
No files matched your search
@@ -135,6 +135,15 @@
|
||||
"subDist.fillRequired": "Please fill in the site name, slug, and payment method",
|
||||
"subDist.selectPayment": "Please select a payment method",
|
||||
"subDist.createFailed": "Failed to create order",
|
||||
"subDist.paymentPageOpened": "Order created. Please complete payment on the opened payment page.",
|
||||
"subDist.paymentPageFailed": "Failed to open the payment page. Please try again later or contact the site administrator.",
|
||||
"subDist.popupBlocked": "The browser blocked the payment window. Please allow pop-ups and try again.",
|
||||
"subDist.cryptoOrderCreated": "Crypto order created. Please complete the transfer using the details on this page.",
|
||||
"subDist.confirmingPayment": "Confirming payment result...",
|
||||
"subDist.paymentPending": "Returned to this page. If you have completed payment, activation will finish after the callback is confirmed. Please refresh shortly.",
|
||||
"subDist.openedSuccess": "Site activated successfully",
|
||||
"subDist.alreadyOpenTitle": "Your site is already activated",
|
||||
"subDist.alreadyOpenDesc": "Site {{name}} has been activated. Use the same account in the main console to continue setup.",
|
||||
|
||||
"tokens.title": "API Keys",
|
||||
"tokens.subtitle": "Manage your API access tokens",
|
||||
|
||||
@@ -135,6 +135,15 @@
|
||||
"subDist.fillRequired": "请填写站点名称、标识和支付方式",
|
||||
"subDist.selectPayment": "请选择支付方式",
|
||||
"subDist.createFailed": "创建订单失败",
|
||||
"subDist.paymentPageOpened": "订单已创建,请在打开的支付页面完成付款",
|
||||
"subDist.paymentPageFailed": "支付页面打开失败,请稍后重试或联系站点管理员",
|
||||
"subDist.popupBlocked": "浏览器拦截了支付窗口,请允许弹窗后重试",
|
||||
"subDist.cryptoOrderCreated": "加密货币订单已创建,请按页面信息完成转账",
|
||||
"subDist.confirmingPayment": "正在确认支付结果...",
|
||||
"subDist.paymentPending": "已返回当前页面。若您已完成付款,系统会在回调确认后自动开通,请稍后刷新查看。",
|
||||
"subDist.openedSuccess": "站点已开通成功",
|
||||
"subDist.alreadyOpenTitle": "您已开通站点",
|
||||
"subDist.alreadyOpenDesc": "站点 {{name}} 已完成开通,请使用同一账号进入主站控制台继续配置。",
|
||||
|
||||
"tokens.title": "API 密钥",
|
||||
"tokens.subtitle": "管理您的 API 访问令牌",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Link, useLocation, useNavigate } from 'react-router-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import toast from 'react-hot-toast';
|
||||
import { createSubDistributorOrder, getSubDistributorInfo } from '../api';
|
||||
@@ -9,7 +9,7 @@ import { useSite, useCurrency } from '../context/SiteContext';
|
||||
function submitEpayForm(resData) {
|
||||
const params = resData.data;
|
||||
const url = resData.url;
|
||||
if (!params || !url) return;
|
||||
if (!params || !url) return false;
|
||||
const form = document.createElement('form');
|
||||
form.action = url;
|
||||
form.method = 'POST';
|
||||
@@ -27,13 +27,16 @@ function submitEpayForm(resData) {
|
||||
document.body.appendChild(form);
|
||||
form.submit();
|
||||
document.body.removeChild(form);
|
||||
return true;
|
||||
}
|
||||
|
||||
export default function SubDistributor() {
|
||||
const { t } = useTranslation();
|
||||
const { user } = useAuth();
|
||||
const { user, refreshUser, loading: authLoading } = useAuth();
|
||||
const { site } = useSite();
|
||||
const { symbol, fmtCNY } = useCurrency();
|
||||
const location = useLocation();
|
||||
const navigate = useNavigate();
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [subInfo, setSubInfo] = useState(null);
|
||||
const [submitting, setSubmitting] = useState(false);
|
||||
@@ -66,6 +69,41 @@ export default function SubDistributor() {
|
||||
() => paymentMethods.find((item) => item.type === form.payment_method),
|
||||
[paymentMethods, form.payment_method]
|
||||
);
|
||||
const paymentReturned = useMemo(
|
||||
() => new URLSearchParams(location.search).get('payment') === 'return',
|
||||
[location.search]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (!paymentReturned || authLoading) return;
|
||||
|
||||
let cancelled = false;
|
||||
const toastId = 'sub-dist-payment-return';
|
||||
|
||||
const checkPaymentResult = async () => {
|
||||
if (!user) {
|
||||
toast(t('subDist.paymentPending'), { id: toastId });
|
||||
navigate('/sub-site', { replace: true });
|
||||
return;
|
||||
}
|
||||
|
||||
toast.loading(t('subDist.confirmingPayment'), { id: toastId });
|
||||
const refreshed = await refreshUser({ skipErrorHandler: true });
|
||||
if (cancelled) return;
|
||||
|
||||
if (refreshed?.has_distributor) {
|
||||
toast.success(t('subDist.openedSuccess'), { id: toastId });
|
||||
} else {
|
||||
toast(t('subDist.paymentPending'), { id: toastId });
|
||||
}
|
||||
navigate('/sub-site', { replace: true });
|
||||
};
|
||||
|
||||
checkPaymentResult();
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, [authLoading, navigate, paymentReturned, refreshUser, t, user]);
|
||||
|
||||
const handleSubmit = async (e) => {
|
||||
e.preventDefault();
|
||||
@@ -89,7 +127,7 @@ export default function SubDistributor() {
|
||||
name: form.name.trim(),
|
||||
slug: form.slug.trim().toLowerCase(),
|
||||
payment_method: form.payment_method,
|
||||
return_url: `${window.location.origin}/sub-distributor`,
|
||||
return_url: `${window.location.origin}/sub-site?payment=return`,
|
||||
};
|
||||
if (form.payment_method === 'crypto') {
|
||||
payload.chain = form.chain;
|
||||
@@ -98,14 +136,26 @@ export default function SubDistributor() {
|
||||
const res = await createSubDistributorOrder(payload);
|
||||
if (res.data.message === 'success') {
|
||||
if (res.data.payment_type === 'stripe' && res.data.data?.pay_link) {
|
||||
window.open(res.data.data.pay_link, '_blank');
|
||||
const opened = window.open(res.data.data.pay_link, '_blank');
|
||||
if (opened) {
|
||||
toast.success(t('subDist.paymentPageOpened'));
|
||||
} else {
|
||||
toast.error(t('subDist.popupBlocked'));
|
||||
}
|
||||
} else if (res.data.payment_type === 'crypto') {
|
||||
setCryptoOrder(res.data.data);
|
||||
toast.success(t('subDist.cryptoOrderCreated'));
|
||||
} else {
|
||||
submitEpayForm(res.data);
|
||||
if (submitEpayForm(res.data)) {
|
||||
toast.success(t('subDist.paymentPageOpened'));
|
||||
} else {
|
||||
toast.error(t('subDist.paymentPageFailed'));
|
||||
}
|
||||
}
|
||||
} else if (res.data.data) {
|
||||
toast.error(typeof res.data.data === 'string' ? res.data.data : t('subDist.createFailed'));
|
||||
} else {
|
||||
toast.error(t('subDist.createFailed'));
|
||||
}
|
||||
} catch (e) {
|
||||
// handled by interceptor
|
||||
@@ -146,6 +196,15 @@ export default function SubDistributor() {
|
||||
<Link to="/register" className="btn-secondary">{t('subDist.goRegister')}</Link>
|
||||
</div>
|
||||
</div>
|
||||
) : user?.has_distributor ? (
|
||||
<div className="rounded-2xl border border-emerald-500/20 bg-emerald-500/5 p-5 space-y-3">
|
||||
<p className="text-sm font-medium text-page">{t('subDist.alreadyOpenTitle')}</p>
|
||||
<p className="text-sm text-page-secondary">
|
||||
{t('subDist.alreadyOpenDesc', {
|
||||
name: user.distributor_name || user.distributor_slug || t('subDist.defaultSiteName'),
|
||||
})}
|
||||
</p>
|
||||
</div>
|
||||
) : (
|
||||
<form onSubmit={handleSubmit} className="space-y-5">
|
||||
<div>
|
||||
|
||||
Reference in new issue
Block a user