From 80d0c675a0e223aebd93f01afe0afe7da31b0e1d Mon Sep 17 00:00:00 2001 From: ghazall-ag Date: Tue, 6 Jan 2026 12:28:42 +0330 Subject: [PATCH] fix(topup-agent-management): fix wallet deposit fields --- src/pages/Currency.jsx | 172 +++++++++++++++++------ src/pages/Issuer.jsx | 263 +++++++++--------------------------- src/pages/Settings.jsx | 164 ++++++++++++++++++++-- src/services/currencyAPI.js | 3 +- src/services/generalAPI.js | 51 +++++++ src/services/issuerAPI.js | 2 + 6 files changed, 398 insertions(+), 257 deletions(-) diff --git a/src/pages/Currency.jsx b/src/pages/Currency.jsx index 48e086b..69f4ee4 100644 --- a/src/pages/Currency.jsx +++ b/src/pages/Currency.jsx @@ -49,10 +49,13 @@ const Currency = () => { voucherLimits: { min: null, max: null }, }); const [feesForm, setFeesForm] = useState({ - depositLimits: { min: null, max: null }, - cashOutLimits: { min: null, max: null }, - transferLimits: { min: null, max: null }, - voucherLimits: { min: null, max: null }, + depositFee: { percent: 0, fixed: 0, minAmount: null, maxAmount: null }, + cashOutFee: { percent: 0, fixed: 0, minAmount: null, maxAmount: null }, + transferFee: { percent: 0, fixed: 0, minAmount: null, maxAmount: null }, + exchangeFee: { percent: 0, fixed: 0, minAmount: null, maxAmount: null }, + generateVoucherByAgentFee: { percent: 0, fixed: 0, minAmount: null, maxAmount: null }, + generateVoucherByUserFee: { percent: 0, fixed: 0, minAmount: null, maxAmount: null }, + expireVoucherSystemFee: { percent: 0, fixed: 0, minAmount: null, maxAmount: null }, }); // دریافت ارزها @@ -180,16 +183,51 @@ const Currency = () => { const onUpdateFees = async (currencyCode, fees) => { try { // API PUT expects: depositFee, cashOutFee, transferFee, exchangeFee, generateVoucherByAgentFee, generateVoucherByUserFee, expireVoucherSystemFee - // But GET returns: depositLimits, cashOutLimits, transferLimits, voucherLimits - // Map our structure to API expected structure + // Each with: { percent, fixed, minAmount, maxAmount } + // Ensure all fields are properly formatted const payload = { - depositFee: fees.depositLimits || { min: null, max: null }, - cashOutFee: fees.cashOutLimits || { min: null, max: null }, - transferFee: fees.transferLimits || { min: null, max: null }, - exchangeFee: { min: null, max: null }, // Required by API - generateVoucherByAgentFee: fees.voucherLimits || { min: null, max: null }, // Map voucherLimits to generateVoucherByAgentFee - generateVoucherByUserFee: { min: null, max: null }, // Required by API - expireVoucherSystemFee: { min: null, max: null }, // Required by API + depositFee: { + percent: Number(fees.depositFee?.percent) || 0, + fixed: Number(fees.depositFee?.fixed) || 0, + minAmount: fees.depositFee?.minAmount != null ? Number(fees.depositFee.minAmount) : null, + maxAmount: fees.depositFee?.maxAmount != null ? Number(fees.depositFee.maxAmount) : null, + }, + cashOutFee: { + percent: Number(fees.cashOutFee?.percent) || 0, + fixed: Number(fees.cashOutFee?.fixed) || 0, + minAmount: fees.cashOutFee?.minAmount != null ? Number(fees.cashOutFee.minAmount) : null, + maxAmount: fees.cashOutFee?.maxAmount != null ? Number(fees.cashOutFee.maxAmount) : null, + }, + transferFee: { + percent: Number(fees.transferFee?.percent) || 0, + fixed: Number(fees.transferFee?.fixed) || 0, + minAmount: fees.transferFee?.minAmount != null ? Number(fees.transferFee.minAmount) : null, + maxAmount: fees.transferFee?.maxAmount != null ? Number(fees.transferFee.maxAmount) : null, + }, + exchangeFee: { + percent: Number(fees.exchangeFee?.percent) || 0, + fixed: Number(fees.exchangeFee?.fixed) || 0, + minAmount: fees.exchangeFee?.minAmount != null ? Number(fees.exchangeFee.minAmount) : null, + maxAmount: fees.exchangeFee?.maxAmount != null ? Number(fees.exchangeFee.maxAmount) : null, + }, + generateVoucherByAgentFee: { + percent: Number(fees.generateVoucherByAgentFee?.percent) || 0, + fixed: Number(fees.generateVoucherByAgentFee?.fixed) || 0, + minAmount: fees.generateVoucherByAgentFee?.minAmount != null ? Number(fees.generateVoucherByAgentFee.minAmount) : null, + maxAmount: fees.generateVoucherByAgentFee?.maxAmount != null ? Number(fees.generateVoucherByAgentFee.maxAmount) : null, + }, + generateVoucherByUserFee: { + percent: Number(fees.generateVoucherByUserFee?.percent) || 0, + fixed: Number(fees.generateVoucherByUserFee?.fixed) || 0, + minAmount: fees.generateVoucherByUserFee?.minAmount != null ? Number(fees.generateVoucherByUserFee.minAmount) : null, + maxAmount: fees.generateVoucherByUserFee?.maxAmount != null ? Number(fees.generateVoucherByUserFee.maxAmount) : null, + }, + expireVoucherSystemFee: { + percent: Number(fees.expireVoucherSystemFee?.percent) || 0, + fixed: Number(fees.expireVoucherSystemFee?.fixed) || 0, + minAmount: fees.expireVoucherSystemFee?.minAmount != null ? Number(fees.expireVoucherSystemFee.minAmount) : null, + maxAmount: fees.expireVoucherSystemFee?.maxAmount != null ? Number(fees.expireVoucherSystemFee.maxAmount) : null, + }, }; console.log('🔵 Currency - onUpdateFees payload:', payload); const result = await currencyAPI.updateFees(currencyCode, payload); @@ -313,17 +351,32 @@ const Currency = () => { try { // Fetch fees data from API const feesData = await currencyAPI.getFees(row.currencyCode); - // API returns: depositLimits, cashOutLimits, transferLimits, voucherLimits - const allowedFields = ['depositLimits', 'cashOutLimits', 'transferLimits', 'voucherLimits']; - const filteredFees = allowedFields.reduce((acc, key) => { + // API returns: depositFee, cashOutFee, transferFee, exchangeFee, generateVoucherByAgentFee, generateVoucherByUserFee, expireVoucherSystemFee + // Each with: { percent, fixed, minAmount, maxAmount } + const defaultFee = { percent: 0, fixed: 0, minAmount: null, maxAmount: null }; + const feeFields = [ + 'depositFee', + 'cashOutFee', + 'transferFee', + 'exchangeFee', + 'generateVoucherByAgentFee', + 'generateVoucherByUserFee', + 'expireVoucherSystemFee' + ]; + const formattedFees = feeFields.reduce((acc, key) => { if (feesData && feesData[key]) { - acc[key] = feesData[key]; + acc[key] = { + percent: feesData[key].percent ?? 0, + fixed: feesData[key].fixed ?? 0, + minAmount: feesData[key].minAmount ?? null, + maxAmount: feesData[key].maxAmount ?? null, + }; } else { - acc[key] = { min: null, max: null }; + acc[key] = { ...defaultFee }; } return acc; }, {}); - setFeesForm(filteredFees); + setFeesForm(formattedFees); } catch (err) { console.error('Error fetching fees:', err); // Fallback to default structure @@ -558,45 +611,76 @@ const Currency = () => { ...feesForm, [category]: { ...feesForm[category], - [type]: value === '' ? null : parseFloat(value) || null, + [type]: value === '' ? (type === 'percent' || type === 'fixed' ? 0 : null) : parseFloat(value) || (type === 'percent' || type === 'fixed' ? 0 : null), }, }); }; + const formatCategoryName = (category) => { + return category + .replace(/([A-Z])/g, ' $1') + .replace(/^./, str => str.toUpperCase()) + .trim(); + }; + return ( <>
setFeesModal(null)} />
-
+

Fees: {code}

{Object.keys(feesForm).map((category) => { return ( -
-

{category}

-
-
- - updateFee(category, 'min', e.target.value)} - className="w-full p-2 border rounded" - placeholder="Min" - /> -
-
- - updateFee(category, 'max', e.target.value)} - className="w-full p-2 border rounded" - placeholder="Max" - /> +
+

{formatCategoryName(category)}

+
+
+ + updateFee(category, 'percent', e.target.value)} + className="w-full p-2 border rounded" + placeholder="0" + /> +
+
+ + updateFee(category, 'fixed', e.target.value)} + className="w-full p-2 border rounded" + placeholder="0" + /> +
+
+ + updateFee(category, 'minAmount', e.target.value)} + className="w-full p-2 border rounded" + placeholder="Min" + /> +
+
+ + updateFee(category, 'maxAmount', e.target.value)} + className="w-full p-2 border rounded" + placeholder="Max" + /> +
-
); })}
diff --git a/src/pages/Issuer.jsx b/src/pages/Issuer.jsx index a203be8..3de0b22 100644 --- a/src/pages/Issuer.jsx +++ b/src/pages/Issuer.jsx @@ -57,10 +57,7 @@ const Issuer = () => { const [topUpAgentCurrencyModal, setTopUpAgentCurrencyModal] = useState(null); const [topUpAgentCurrencyForm, setTopUpAgentCurrencyForm] = useState({ currencyCode: '', - voucherGeneratingFee: { percent: 0, fixed: 0, minAmount: 0, maxAmount: 0 }, - agentMarketingFee: { percent: 0, fixed: 0, minAmount: 0, maxAmount: 0 }, - agentWalletMaxBalanceLimit: { min: 0, max: 0 }, - agentWalletDepositMonthlyLimit: { amount: 0 } + voucherGenerationCommission: 0 }); // Wallet states @@ -479,19 +476,13 @@ const Issuer = () => { // Edit mode setTopUpAgentCurrencyForm({ currencyCode: currency.currencyCode || currency.code || '', - voucherGeneratingFee: currency.voucherGeneratingFee || { percent: 0, fixed: 0, minAmount: 0, maxAmount: 0 }, - agentMarketingFee: currency.agentMarketingFee || { percent: 0, fixed: 0, minAmount: 0, maxAmount: 0 }, - agentWalletMaxBalanceLimit: currency.agentWalletMaxBalanceLimit || { min: 0, max: 0 }, - agentWalletDepositMonthlyLimit: currency.agentWalletDepositMonthlyLimit || { amount: 0 } + voucherGenerationCommission: currency.voucherGenerationCommission ?? 0 }); } else { // Add mode setTopUpAgentCurrencyForm({ currencyCode: '', - voucherGeneratingFee: { percent: 0, fixed: 0, minAmount: 0, maxAmount: 0 }, - agentMarketingFee: { percent: 0, fixed: 0, minAmount: 0, maxAmount: 0 }, - agentWalletMaxBalanceLimit: { min: 0, max: 0 }, - agentWalletDepositMonthlyLimit: { amount: 0 } + voucherGenerationCommission: 0 }); } setTopUpAgentCurrencyModal(currency); @@ -504,12 +495,21 @@ const Issuer = () => { return; } try { + // Prepare payload with default values for required fields (not shown in UI) + const currencyData = { + voucherGenerationCommission: Number(topUpAgentCurrencyForm.voucherGenerationCommission) || 0, + voucherGeneratingFee: { percent: 0, fixed: 0, minAmount: null, maxAmount: null }, + agentMarketingFee: { percent: 0, fixed: 0, minAmount: null, maxAmount: null }, + agentWalletMaxBalanceLimit: { min: null, max: null }, + agentWalletDepositMonthlyLimit: { amount: null } + }; + if (topUpAgentCurrencyModal) { // Update existing currency await issuerAPI.updateTopUpAgentManagementCurrency( topUpAgentModal.id, topUpAgentCurrencyForm.currencyCode, - topUpAgentCurrencyForm + currencyData ); toast.success('Currency updated successfully'); } else { @@ -517,7 +517,7 @@ const Issuer = () => { await issuerAPI.createTopUpAgentManagementCurrency( topUpAgentModal.id, topUpAgentCurrencyForm.currencyCode, - topUpAgentCurrencyForm + currencyData ); toast.success('Currency added successfully'); } @@ -528,10 +528,7 @@ const Issuer = () => { setTopUpAgentCurrencyModal(null); setTopUpAgentCurrencyForm({ currencyCode: '', - voucherGeneratingFee: { percent: 0, fixed: 0, minAmount: 0, maxAmount: 0 }, - agentMarketingFee: { percent: 0, fixed: 0, minAmount: 0, maxAmount: 0 }, - agentWalletMaxBalanceLimit: { min: 0, max: 0 }, - agentWalletDepositMonthlyLimit: { amount: 0 } + voucherGenerationCommission: 0 }); } catch (err) { toast.error(getErrorMessage(err)); @@ -559,13 +556,38 @@ const Issuer = () => { setSelectedCurrencyForWallet(currencyCode); setWalletLoading(true); try { - // دریافت balance و transactions به صورت همزمان - const [balance, transactions] = await Promise.all([ - issuerAPI.getTopUpAgentManagementWalletBalance(topUpAgentModal.id, currencyCode), - issuerAPI.getTopUpAgentManagementWalletTransactions(topUpAgentModal.id, currencyCode) - ]); + // دریافت balance و transactions به صورت جداگانه برای handle کردن خطاها + let balance = null; + let transactions = []; + + try { + balance = await issuerAPI.getTopUpAgentManagementWalletBalance(topUpAgentModal.id, currencyCode); + } catch (err) { + console.error('Error loading wallet balance:', err); + toast.error('Failed to load wallet balance'); + } + + try { + transactions = await issuerAPI.getTopUpAgentManagementWalletTransactions(topUpAgentModal.id, currencyCode); + transactions = Array.isArray(transactions) ? transactions : []; + } catch (err) { + console.error('Error loading wallet transactions:', err); + // اگر transactions خطا داد، فقط warning نشان بده و balance را نمایش بده + const errorMessage = err?.response?.status === 500 + ? 'Unable to load transaction history. Balance information is available.' + : 'Failed to load transaction history'; + + // Use toast.warning if available, otherwise use toast.error + if (toast.warning) { + toast.warning(errorMessage); + } else { + toast.error(errorMessage); + } + transactions = []; + } + setWalletBalance(balance); - setWalletTransactions(Array.isArray(transactions) ? transactions : []); + setWalletTransactions(transactions); } catch (err) { console.error('Error loading wallet data:', err); toast.error('Failed to load wallet data'); @@ -1152,16 +1174,6 @@ const Issuer = () => { required />
-
- setTopUpAgentData({ ...topUpAgentData, isActive: e.target.checked })} - disabled - className="w-4 h-4" - /> - -
- {/* Voucher Generating Fee */} -
-

Voucher Generating Fee

-
-
- - setTopUpAgentCurrencyForm({ - ...topUpAgentCurrencyForm, - voucherGeneratingFee: { ...topUpAgentCurrencyForm.voucherGeneratingFee, percent: Number(e.target.value) || 0 } - })} - className="w-full p-2 border rounded-lg" - /> -
-
- - setTopUpAgentCurrencyForm({ - ...topUpAgentCurrencyForm, - voucherGeneratingFee: { ...topUpAgentCurrencyForm.voucherGeneratingFee, fixed: Number(e.target.value) || 0 } - })} - className="w-full p-2 border rounded-lg" - /> -
-
- - setTopUpAgentCurrencyForm({ - ...topUpAgentCurrencyForm, - voucherGeneratingFee: { ...topUpAgentCurrencyForm.voucherGeneratingFee, minAmount: Number(e.target.value) || 0 } - })} - className="w-full p-2 border rounded-lg" - /> -
-
- - setTopUpAgentCurrencyForm({ - ...topUpAgentCurrencyForm, - voucherGeneratingFee: { ...topUpAgentCurrencyForm.voucherGeneratingFee, maxAmount: Number(e.target.value) || 0 } - })} - className="w-full p-2 border rounded-lg" - /> -
-
-
- - {/* Agent Marketing Fee */} -
-

Agent Marketing Fee

-
-
- - setTopUpAgentCurrencyForm({ - ...topUpAgentCurrencyForm, - agentMarketingFee: { ...topUpAgentCurrencyForm.agentMarketingFee, percent: Number(e.target.value) || 0 } - })} - className="w-full p-2 border rounded-lg" - /> -
-
- - setTopUpAgentCurrencyForm({ - ...topUpAgentCurrencyForm, - agentMarketingFee: { ...topUpAgentCurrencyForm.agentMarketingFee, fixed: Number(e.target.value) || 0 } - })} - className="w-full p-2 border rounded-lg" - /> -
-
- - setTopUpAgentCurrencyForm({ - ...topUpAgentCurrencyForm, - agentMarketingFee: { ...topUpAgentCurrencyForm.agentMarketingFee, minAmount: Number(e.target.value) || 0 } - })} - className="w-full p-2 border rounded-lg" - /> -
-
- - setTopUpAgentCurrencyForm({ - ...topUpAgentCurrencyForm, - agentMarketingFee: { ...topUpAgentCurrencyForm.agentMarketingFee, maxAmount: Number(e.target.value) || 0 } - })} - className="w-full p-2 border rounded-lg" - /> -
-
-
- - {/* Agent Wallet Max Balance Limit */} -
-

Agent Wallet Max Balance Limit

-
-
- - setTopUpAgentCurrencyForm({ - ...topUpAgentCurrencyForm, - agentWalletMaxBalanceLimit: { ...topUpAgentCurrencyForm.agentWalletMaxBalanceLimit, min: Number(e.target.value) || 0 } - })} - className="w-full p-2 border rounded-lg" - /> -
-
- - setTopUpAgentCurrencyForm({ - ...topUpAgentCurrencyForm, - agentWalletMaxBalanceLimit: { ...topUpAgentCurrencyForm.agentWalletMaxBalanceLimit, max: Number(e.target.value) || 0 } - })} - className="w-full p-2 border rounded-lg" - /> -
-
-
- - {/* Agent Wallet Deposit Monthly Limit */} -
-

Agent Wallet Deposit Monthly Limit

-
- - setTopUpAgentCurrencyForm({ - ...topUpAgentCurrencyForm, - agentWalletDepositMonthlyLimit: { amount: Number(e.target.value) || 0 } - })} - className="w-full p-2 border rounded-lg" - /> -
+
+ + setTopUpAgentCurrencyForm({ ...topUpAgentCurrencyForm, voucherGenerationCommission: Number(e.target.value) || 0 })} + className="w-full p-2 border rounded-lg" + placeholder="0" + /> +

Commission for voucher generation

@@ -1509,7 +1366,9 @@ const Issuer = () => {

Current Balance

{walletBalance !== null ? (
- {typeof walletBalance === 'object' && walletBalance.balance !== undefined + {typeof walletBalance === 'object' && walletBalance.amount !== undefined + ? walletBalance.amount + : typeof walletBalance === 'object' && walletBalance.balance !== undefined ? walletBalance.balance : typeof walletBalance === 'number' ? walletBalance diff --git a/src/pages/Settings.jsx b/src/pages/Settings.jsx index 2bf593b..ba6533b 100644 --- a/src/pages/Settings.jsx +++ b/src/pages/Settings.jsx @@ -1,5 +1,9 @@ import React, { useState, useEffect } from 'react'; -import { Save, Key, Globe, DollarSign, Bell, Shield, Database } from 'lucide-react'; +import { Save, Key, Globe, DollarSign, Bell, Shield, Database, Ticket } from 'lucide-react'; +import { generalAPI } from '../services/api'; +import { ToastContainer, toast } from 'react-toastify'; +import 'react-toastify/dist/ReactToastify.css'; +import { getErrorMessage, getSuccessMessage } from '../utils/errorHandler'; const Settings = () => { const [settings, setSettings] = useState({ @@ -21,12 +25,21 @@ const Settings = () => { } }); + const [voucherConfig, setVoucherConfig] = useState({ + expireInDays: 0, + refundUponVoucherExpiration: true, + canPurchaseByAgentVouchers: true, + canTopUpWithUserVouchers: true + }); + const [loading, setLoading] = useState(false); + const [voucherLoading, setVoucherLoading] = useState(false); const [message, setMessage] = useState(''); const [activeTab, setActiveTab] = useState('payment'); useEffect(() => { loadSettings(); + loadVoucherConfiguration(); }, []); const loadSettings = () => { @@ -36,6 +49,26 @@ const Settings = () => { } }; + const loadVoucherConfiguration = async () => { + try { + setVoucherLoading(true); + const config = await generalAPI.getVoucherConfiguration(); + if (config) { + setVoucherConfig({ + expireInDays: config.expireInDays ?? 0, + refundUponVoucherExpiration: config.refundUponVoucherExpiration ?? true, + canPurchaseByAgentVouchers: config.canPurchaseByAgentVouchers ?? true, + canTopUpWithUserVouchers: config.canTopUpWithUserVouchers ?? true + }); + } + } catch (err) { + console.error('Error loading voucher configuration:', err); + toast.error(getErrorMessage(err)); + } finally { + setVoucherLoading(false); + } + }; + const handleInputChange = (section, field, value) => { setSettings(prev => ({ ...prev, @@ -72,11 +105,32 @@ const Settings = () => { } }; + const handleVoucherSave = async () => { + setVoucherLoading(true); + try { + const result = await generalAPI.updateVoucherConfiguration(voucherConfig); + toast.success(getSuccessMessage(result) || 'Voucher configuration saved successfully'); + await loadVoucherConfiguration(); + } catch (err) { + toast.error(getErrorMessage(err)); + } finally { + setVoucherLoading(false); + } + }; + + const handleVoucherChange = (field, value) => { + setVoucherConfig(prev => ({ + ...prev, + [field]: value + })); + }; + const tabs = [ { id: 'payment', label: 'Payment', icon: DollarSign }, { id: 'notifications', label: 'Notifications', icon: Bell }, { id: 'security', label: 'Security', icon: Shield }, - { id: 'data', label: 'Data', icon: Database } + { id: 'data', label: 'Data', icon: Database }, + { id: 'voucher', label: 'Voucher', icon: Ticket } ]; const currencies = [ @@ -90,6 +144,7 @@ const Settings = () => { return (
+

Settings

Configure your payment system preferences

@@ -331,16 +386,105 @@ const Settings = () => {
)} + {/* Voucher Settings */} + {activeTab === 'voucher' && ( +
+

Voucher Configuration

+ {voucherLoading ? ( +
+
+
+ ) : ( +
+
+ + handleVoucherChange('expireInDays', Number(e.target.value) || 0)} + className="input-field w-32" + /> +

+ Number of days before vouchers expire +

+
+ +
+
+ +

Automatically refund when voucher expires

+
+ +
+ +
+
+ +

Allow purchases using agent-generated vouchers

+
+ +
+ +
+
+ +

Allow top-up using user-generated vouchers

+
+ +
+
+ )} +
+ )} + {/* Save Button */}
- + {activeTab === 'voucher' ? ( + + ) : ( + + )}
diff --git a/src/services/currencyAPI.js b/src/services/currencyAPI.js index d2f1c27..8441f96 100644 --- a/src/services/currencyAPI.js +++ b/src/services/currencyAPI.js @@ -157,7 +157,8 @@ export const currencyAPI = { skipAuthRedirect: true }); console.log('🟢 Currency API - getFees response:', res?.data); - // Response structure: { statusCode, isSuccess, code, message, errors, data: { depositLimits, cashOutLimits, transferLimits, voucherLimits } } + // Response structure: { statusCode, isSuccess, code, message, errors, data: { depositFee, cashOutFee, transferFee, exchangeFee, generateVoucherByAgentFee, generateVoucherByUserFee, expireVoucherSystemFee } } + // Each fee has: { percent, fixed, minAmount, maxAmount } // Return the data field from the response return res?.data?.data || null; } catch (error) { diff --git a/src/services/generalAPI.js b/src/services/generalAPI.js index 5bdf893..b743661 100644 --- a/src/services/generalAPI.js +++ b/src/services/generalAPI.js @@ -54,5 +54,56 @@ export const generalAPI = { throw error; } }, + + // ========== System Configuration Voucher API ========== + + // GET /api/v1/SystemConfiguration/Voucher + async getVoucherConfiguration() { + try { + console.log('🔵 General API - getVoucherConfiguration request'); + const res = await api.get('/api/v1/SystemConfiguration/Voucher', { + skipAuthRedirect: true + }); + console.log('🟢 General API - getVoucherConfiguration response:', res?.data); + // Response structure: { statusCode, isSuccess, code, message, errors, data: { expireInDays, refundUponVoucherExpiration, canPurchaseByAgentVouchers, canTopUpWithUserVouchers } } + return res?.data?.data || null; + } catch (error) { + console.error('🔴 General API - getVoucherConfiguration error:', { + status: error?.response?.status, + data: error?.response?.data, + error: error?.response?.data || error?.message + }); + throw error; + } + }, + + // PUT /api/v1/SystemConfiguration/Voucher + async updateVoucherConfiguration(config) { + if (!config) { + throw new Error('Voucher configuration is required'); + } + try { + const payload = { + expireInDays: Number(config.expireInDays) || 0, + refundUponVoucherExpiration: Boolean(config.refundUponVoucherExpiration), + canPurchaseByAgentVouchers: Boolean(config.canPurchaseByAgentVouchers), + canTopUpWithUserVouchers: Boolean(config.canTopUpWithUserVouchers) + }; + console.log('🔵 General API - updateVoucherConfiguration request:', { payload }); + const res = await api.put('/api/v1/SystemConfiguration/Voucher', payload, { + skipAuthRedirect: true + }); + console.log('🟢 General API - updateVoucherConfiguration response:', res?.data); + return res?.data; + } catch (error) { + console.error('🔴 General API - updateVoucherConfiguration error:', { + payload: config, + status: error?.response?.status, + data: error?.response?.data, + error: error?.response?.data || error?.message + }); + throw error; + } + }, }; diff --git a/src/services/issuerAPI.js b/src/services/issuerAPI.js index 7b1fbba..db5326e 100644 --- a/src/services/issuerAPI.js +++ b/src/services/issuerAPI.js @@ -455,6 +455,7 @@ export const issuerAPI = { } try { const payload = { + voucherGenerationCommission: Number(currencyData.voucherGenerationCommission) || 0, voucherGeneratingFee: { percent: Number(currencyData.voucherGeneratingFee?.percent) || 0, fixed: Number(currencyData.voucherGeneratingFee?.fixed) || 0, @@ -498,6 +499,7 @@ export const issuerAPI = { } try { const payload = { + voucherGenerationCommission: Number(currencyData.voucherGenerationCommission) || 0, voucherGeneratingFee: { percent: Number(currencyData.voucherGeneratingFee?.percent) || 0, fixed: Number(currencyData.voucherGeneratingFee?.fixed) || 0,