feat(payment): unify payment flow with new pure redirect entry and update related endpoints
This commit is contained in:
@@ -32,6 +32,7 @@ const schema = z.object({
|
||||
tax_enabled: z.string(),
|
||||
tax_percent: z.string(),
|
||||
sms_panel_fee_rials: z.string(),
|
||||
sms_price_rials: z.string(),
|
||||
appointment_fee_rials: z.string(),
|
||||
// payment gateways
|
||||
payment_test_mode: z.string(),
|
||||
@@ -60,6 +61,7 @@ const toForm = (s: Partial<Settings>): FormValues => ({
|
||||
tax_enabled: s.tax_enabled ?? '0',
|
||||
tax_percent: s.tax_percent ?? '10',
|
||||
sms_panel_fee_rials: s.sms_panel_fee_rials ?? '1500000',
|
||||
sms_price_rials: s.sms_price_rials ?? '500',
|
||||
appointment_fee_rials: s.appointment_fee_rials ?? '150000',
|
||||
payment_test_mode: s.payment_test_mode ?? '0',
|
||||
mellat_enabled: s.mellat_enabled ?? '1',
|
||||
@@ -452,6 +454,9 @@ export default function SettingsPage() {
|
||||
: <><ExclamationTriangleIcon style={{ width: 18, height: 18, color: 'var(--danger)' }} /><span style={{ color: 'var(--danger)' }}>تنظیمنشده — مقدار KAVENEGAR_API_KEY را در فایل env قرار دهید</span></>}
|
||||
</div>
|
||||
</Field>
|
||||
<Field label="هزینه هر پیامک" hint="مبلغ کسرشده از کیف پول به ازای هر پیامک ارسالی (ریال). مبنای محاسبهٔ تعداد پیامک از موجودی.">
|
||||
<input {...register('sms_price_rials')} type="number" min={0} dir="ltr" className="input" style={{ maxWidth: 200 }} placeholder="500" />
|
||||
</Field>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useState } from 'react';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
@@ -68,7 +68,10 @@ function SmsWalletPageInner() {
|
||||
|
||||
const chargeMutation = useMutation({
|
||||
mutationFn: ({ amount_rials }: ChargeForm) =>
|
||||
api.post<{ data: { payment_url: string } }>('/api/v1/sms/wallet/charge', { gateway, amount_rials }),
|
||||
api.post<{ data: { payment_url: string } }>('/api/v1/sms/wallet/charge', {
|
||||
gateway, amount_rials,
|
||||
frontend_address: `${window.location.origin}${window.location.pathname}`,
|
||||
}),
|
||||
onSuccess: (res: any) => {
|
||||
const url = res?.data?.pay_url ?? res?.data?.redirect_url ?? res?.data?.payment_url;
|
||||
if (url) window.location.href = url;
|
||||
@@ -80,9 +83,16 @@ function SmsWalletPageInner() {
|
||||
const [localSettings, setLocalSettings] = useState<SmsSettings | null>(null);
|
||||
const currentSettings = localSettings ?? settings;
|
||||
|
||||
// با هر بار تازهشدن دادهی سرور، ویرایش محلی صفر شود تا وضعیت واقعی (مثل وضعیت تأیید متن) نمایش داده شود.
|
||||
useEffect(() => { setLocalSettings(null); }, [settingsData]);
|
||||
|
||||
const saveMutation = useMutation({
|
||||
mutationFn: (body: SmsSettings) => api.patch('/api/v1/sms/settings', body),
|
||||
onSuccess: () => { qc.invalidateQueries({ queryKey: ['sms-settings'] }); toast.success('تنظیمات ذخیره شد'); },
|
||||
onSuccess: () => {
|
||||
setLocalSettings(null);
|
||||
qc.invalidateQueries({ queryKey: ['sms-settings'] });
|
||||
toast.success('تنظیمات ذخیره شد');
|
||||
},
|
||||
onError: (e: any) => toast.error(e.message),
|
||||
});
|
||||
|
||||
@@ -233,11 +243,14 @@ function SmsWalletPageInner() {
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={`switch${currentSettings.reminder_enabled ? ' on' : ''}`}
|
||||
style={{ marginTop: 4, flexShrink: 0 }}
|
||||
onClick={() => setLocalSettings({ ...currentSettings, reminder_enabled: !currentSettings.reminder_enabled })}
|
||||
/>
|
||||
<label className="switch" style={{ marginTop: 4, flexShrink: 0 }}>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={currentSettings.reminder_enabled}
|
||||
onChange={() => setLocalSettings({ ...currentSettings, reminder_enabled: !currentSettings.reminder_enabled })}
|
||||
/>
|
||||
<span className="switch-track"><span className="switch-thumb" /></span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
{/* ردیف: پیامک بعد از ویزیت */}
|
||||
@@ -253,11 +266,14 @@ function SmsWalletPageInner() {
|
||||
<div style={{ color: 'var(--text-3)', fontSize: 12.5, marginTop: 3 }}>متن تشکر پس از پایان مراجعه برای بیمار ارسال میشود</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={`switch${currentSettings.post_visit_enabled ? ' on' : ''}`}
|
||||
style={{ flexShrink: 0 }}
|
||||
onClick={() => setLocalSettings({ ...currentSettings, post_visit_enabled: !currentSettings.post_visit_enabled })}
|
||||
/>
|
||||
<label className="switch" style={{ flexShrink: 0 }}>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={currentSettings.post_visit_enabled}
|
||||
onChange={() => setLocalSettings({ ...currentSettings, post_visit_enabled: !currentSettings.post_visit_enabled })}
|
||||
/>
|
||||
<span className="switch-track"><span className="switch-thumb" /></span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
{/* محتوای بازشونده */}
|
||||
|
||||
@@ -83,7 +83,10 @@ export default function SubscriptionPage() {
|
||||
|
||||
const purchaseMutation = useMutation({
|
||||
mutationFn: ({ period_uuid, gateway, amount_rials }: { period_uuid: string; gateway: string; amount_rials: number }) =>
|
||||
api.post<{ data: { payment_url: string } }>('/api/v1/subscription-payment', { period_uuid, gateway, amount_rials }),
|
||||
api.post<{ data: { payment_url: string } }>('/api/v1/subscription-payment', {
|
||||
period_uuid, gateway, amount_rials,
|
||||
frontend_address: `${window.location.origin}/admin/subscription`,
|
||||
}),
|
||||
onSuccess: (res: any) => {
|
||||
const url = res?.data?.pay_url ?? res?.data?.redirect_url ?? res?.data?.payment_url;
|
||||
if (url) window.location.href = url;
|
||||
|
||||
Reference in New Issue
Block a user