feat(payment): add endpoint for payment configuration and update UI for test mode

This commit is contained in:
hamed
2026-06-15 11:35:23 +03:30
parent 5f5b0fa548
commit 8c0b3d8282
5 changed files with 322 additions and 61 deletions
+53 -28
View File
@@ -60,10 +60,17 @@ export default function SubscriptionPage() {
queryFn: () => api.get('/api/v1/subscription/my'),
});
const plans = plansData?.data ?? [];
const myRaw = myData?.data;
const my = myRaw?.subscription ?? null;
const usedTrial = myRaw?.used_trial ?? false;
const { data: paymentConfigData } = useQuery<ApiResponse<{ test_mode: boolean }>>({
queryKey: ['payment-config'],
queryFn: () => api.get('/api/v1/payment/config'),
staleTime: 5 * 60 * 1000,
});
const plans = plansData?.data ?? [];
const myRaw = myData?.data;
const my = myRaw?.subscription ?? null;
const usedTrial = myRaw?.used_trial ?? false;
const isTestMode = paymentConfigData?.data?.test_mode ?? false;
const trialMutation = useMutation({
mutationFn: () => api.post('/api/v1/subscription/trial', {}),
@@ -300,31 +307,47 @@ export default function SubscriptionPage() {
</div>
{/* انتخاب درگاه */}
<div>
<div style={{ fontSize: 12.5, fontWeight: 600, color: 'var(--text-2)', marginBottom: 10 }}>
انتخاب درگاه پرداخت
{isTestMode ? (
<div style={{
background: '#fef9c3',
border: '1px solid #fbbf24',
borderRadius: 10,
padding: '12px 16px',
display: 'flex', alignItems: 'center', gap: 10,
}}>
<span style={{ fontSize: 20 }}></span>
<div>
<div style={{ fontWeight: 700, fontSize: 13.5, color: '#92400e' }}>درگاه آزمایشی فعال است</div>
<div style={{ fontSize: 12, color: '#b45309', marginTop: 2 }}>پول واقعی کسر نخواهد شد این تراکنش آزمایشی است</div>
</div>
</div>
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }}>
{(['mellat', 'sep'] as const).map((gw) => (
<button
key={gw}
onClick={() => setSelectedGateway(gw)}
style={{
padding: '12px 16px', borderRadius: 'var(--r-sm)', cursor: 'pointer',
border: `2px solid ${selectedGateway === gw ? 'var(--primary)' : 'var(--border)'}`,
background: selectedGateway === gw ? 'var(--primary-soft)' : 'var(--surface)',
color: selectedGateway === gw ? 'var(--primary-700)' : 'var(--text-2)',
fontWeight: selectedGateway === gw ? 700 : 500,
fontSize: 13, transition: '.14s', fontFamily: 'inherit',
display: 'flex', alignItems: 'center', gap: 8,
}}
>
<CreditCardIcon style={{ width: 17, flexShrink: 0 }} />
{GATEWAY_LABELS[gw]}
</button>
))}
) : (
<div>
<div style={{ fontSize: 12.5, fontWeight: 600, color: 'var(--text-2)', marginBottom: 10 }}>
انتخاب درگاه پرداخت
</div>
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }}>
{(['mellat', 'sep'] as const).map((gw) => (
<button
key={gw}
onClick={() => setSelectedGateway(gw)}
style={{
padding: '12px 16px', borderRadius: 'var(--r-sm)', cursor: 'pointer',
border: `2px solid ${selectedGateway === gw ? 'var(--primary)' : 'var(--border)'}`,
background: selectedGateway === gw ? 'var(--primary-soft)' : 'var(--surface)',
color: selectedGateway === gw ? 'var(--primary-700)' : 'var(--text-2)',
fontWeight: selectedGateway === gw ? 700 : 500,
fontSize: 13, transition: '.14s', fontFamily: 'inherit',
display: 'flex', alignItems: 'center', gap: 8,
}}
>
<CreditCardIcon style={{ width: 17, flexShrink: 0 }} />
{GATEWAY_LABELS[gw]}
</button>
))}
</div>
</div>
</div>
)}
{/* دکمه‌ها */}
<div style={{ display: 'flex', gap: 10, marginTop: 4 }}>
@@ -338,7 +361,9 @@ export default function SubscriptionPage() {
>
{purchaseMutation.isPending
? 'در حال انتقال...'
: `پرداخت ${formatRial(purchaseTarget.period.price_rials)}`
: isTestMode
? `پرداخت آزمایشی ${formatRial(purchaseTarget.period.price_rials)}`
: `پرداخت ${formatRial(purchaseTarget.period.price_rials)}`
}
</button>
<button className="btn ghost" style={{ height: 44 }} onClick={() => setPurchaseTarget(null)}>