mirror of
https://github.com/QuantumNous/new-api.git
synced 2026-09-12 15:21:09 +00:00
[Feature Request] Waffo Pancake gateway — full integration with subscription support + admin catalog binding flow (#4935)
This commit is contained in:
+14
-3
@@ -47,6 +47,7 @@ import {
|
||||
} from 'lucide-react';
|
||||
import { IconGift } from '@douyinfe/semi-icons';
|
||||
import { useMinimumLoadingTime } from '../../hooks/common/useMinimumLoadingTime';
|
||||
import { useActualTheme } from '../../context/Theme';
|
||||
import { getCurrencyConfig } from '../../helpers/render';
|
||||
import SubscriptionPlansCard from './SubscriptionPlansCard';
|
||||
|
||||
@@ -102,6 +103,7 @@ const RechargeCard = ({
|
||||
const redeemFormApiRef = useRef(null);
|
||||
const initialTabSetRef = useRef(false);
|
||||
const showAmountSkeleton = useMinimumLoadingTime(amountLoading);
|
||||
const actualTheme = useActualTheme();
|
||||
const [activeTab, setActiveTab] = useState('topup');
|
||||
const shouldShowSubscription =
|
||||
!subscriptionLoading && subscriptionPlans.length > 0;
|
||||
@@ -355,9 +357,18 @@ const RechargeCard = ({
|
||||
}}
|
||||
/>
|
||||
) : payMethod.type === 'waffo_pancake' ? (
|
||||
<CreditCard
|
||||
size={18}
|
||||
color='var(--semi-color-primary)'
|
||||
<img
|
||||
src={
|
||||
actualTheme === 'dark'
|
||||
? '/waffo-logo-dark.svg'
|
||||
: '/waffo-logo-light.svg'
|
||||
}
|
||||
alt='Waffo'
|
||||
style={{
|
||||
width: 18,
|
||||
height: 18,
|
||||
objectFit: 'contain',
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<CreditCard
|
||||
|
||||
+23
-2
@@ -40,6 +40,23 @@ import TransferModal from './modals/TransferModal';
|
||||
import PaymentConfirmModal from './modals/PaymentConfirmModal';
|
||||
import TopupHistoryModal from './modals/TopupHistoryModal';
|
||||
|
||||
// Reject non-navigable schemes (e.g. javascript:, data:) and relative URLs.
|
||||
// Only http / https are allowed for backend-provided redirect targets.
|
||||
// Mirrors isSafeHttpCheckoutUrl in the default frontend's
|
||||
// features/wallet/hooks/use-waffo-pancake-payment.ts.
|
||||
function isSafeHttpCheckoutUrl(value) {
|
||||
const trimmed = (value || '').trim();
|
||||
if (!trimmed) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
const u = new URL(trimmed);
|
||||
return u.protocol === 'http:' || u.protocol === 'https:';
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const TopUp = () => {
|
||||
const { t } = useTranslation();
|
||||
const [searchParams, setSearchParams] = useSearchParams();
|
||||
@@ -454,8 +471,12 @@ const TopUp = () => {
|
||||
const { message, data } = res.data;
|
||||
if (message === 'success') {
|
||||
const checkoutUrl = data?.checkout_url || '';
|
||||
if (checkoutUrl) {
|
||||
window.open(checkoutUrl, '_blank');
|
||||
if (checkoutUrl && isSafeHttpCheckoutUrl(checkoutUrl)) {
|
||||
// In-tab redirect (not window.open) — popup blocker fires after
|
||||
// the await loses user-gesture context.
|
||||
window.location.href = checkoutUrl;
|
||||
} else if (checkoutUrl) {
|
||||
showError(t('支付跳转地址不安全'));
|
||||
} else {
|
||||
showError(t('支付请求失败'));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user