/* Copyright (C) 2023-2026 QuantumNous This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . For commercial licensing, please contact support@quantumnous.com */ import { type ChangeEvent, useRef, type SetStateAction, useState } from 'react' import { Plus, Pencil, Trash2 } from 'lucide-react' import { useTranslation } from 'react-i18next' import { toast } from 'sonner' import { Alert, AlertDescription } from '@/components/ui/alert' import { Button } from '@/components/ui/button' import { Input } from '@/components/ui/input' import { Label } from '@/components/ui/label' import { Separator } from '@/components/ui/separator' import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from '@/components/ui/table' import { Textarea } from '@/components/ui/textarea' import { Dialog } from '@/components/dialog' import { SettingsSwitchField } from '../components/settings-form-layout' export interface WaffoSettingsValues { WaffoEnabled: boolean WaffoApiKey: string WaffoPrivateKey: string WaffoPublicCert: string WaffoSandboxPublicCert: string WaffoSandboxApiKey: string WaffoSandboxPrivateKey: string WaffoSandbox: boolean WaffoMerchantId: string WaffoCurrency: string WaffoUnitPrice: number WaffoMinTopUp: number WaffoNotifyUrl: string WaffoReturnUrl: string WaffoPayMethods: string } export interface PayMethod { name: string icon: string payMethodType: string payMethodName: string } type WaffoFieldValues = Omit interface Props { values: WaffoSettingsValues onValueChange: ( key: K, value: WaffoFieldValues[K] ) => void payMethods: PayMethod[] onPayMethodsChange: (value: SetStateAction) => void } export function WaffoSettingsSection({ values, onValueChange, payMethods, onPayMethodsChange, }: Props) { const { t } = useTranslation() const iconFileInputRef = useRef(null) const [methodDialogOpen, setMethodDialogOpen] = useState(false) const [editingIdx, setEditingIdx] = useState(-1) const [methodForm, setMethodForm] = useState({ name: '', icon: '', payMethodType: '', payMethodName: '', }) const openAdd = () => { setEditingIdx(-1) setMethodForm({ name: '', icon: '', payMethodType: '', payMethodName: '' }) setMethodDialogOpen(true) } const openEdit = (idx: number) => { setEditingIdx(idx) setMethodForm({ ...payMethods[idx] }) setMethodDialogOpen(true) } const saveMethod = () => { if (!methodForm.name.trim()) return toast.error(t('Payment method name is required')) if (editingIdx === -1) { onPayMethodsChange((prev) => [...prev, methodForm]) } else { onPayMethodsChange((prev) => prev.map((m, i) => (i === editingIdx ? methodForm : m)) ) } setMethodDialogOpen(false) } const handleIconFileChange = (event: ChangeEvent) => { const file = event.target.files?.[0] if (!file) { return } const maxIconSize = 100 * 1024 if (file.size > maxIconSize) { toast.error(t('Icon file must be 100 KB or smaller')) event.target.value = '' return } const reader = new FileReader() reader.onload = (loadEvent) => { setMethodForm((previous) => ({ ...previous, icon: typeof loadEvent.target?.result === 'string' ? loadEvent.target.result : '', })) } reader.readAsDataURL(file) event.target.value = '' } return ( <>

{t('Waffo Aggregator Gateway')}

{t( 'Payment aggregator mode — onboard with your own registered company (offshore entity). Built for Enterprise.' )}

{t( 'Obtain the API key, merchant ID, and RSA key pair from the Waffo dashboard, and configure the callback URL.' )}
onValueChange('WaffoEnabled', v)} label={t('Enable Waffo')} className='border-b-0 py-0' /> onValueChange('WaffoSandbox', v)} label={t('Sandbox mode')} className='border-b-0 py-0' />
onValueChange('WaffoApiKey', event.target.value) } />
onValueChange('WaffoSandboxApiKey', event.target.value) } />
onValueChange('WaffoMerchantId', event.target.value) } />