From 31daaf6172570bd738f28e73aab92e4125e732ce Mon Sep 17 00:00:00 2001 From: hamid zarghami Date: Wed, 5 Feb 2025 11:10:17 +0330 Subject: [PATCH] online payment --- .env | 4 +- src/assets/images/zarinpal-logo-min.png | Bin 0 -> 7314 bytes src/langs/fa.json | 6 +- src/pages/wallet/components/Online.tsx | 136 ++++++++++++---------- src/pages/wallet/hooks/useWalletData.ts | 16 +++ src/pages/wallet/service/WalletService.ts | 12 ++ src/pages/wallet/types/WalletTypes.ts | 4 + src/router/Main.tsx | 9 +- 8 files changed, 120 insertions(+), 67 deletions(-) create mode 100644 src/assets/images/zarinpal-logo-min.png create mode 100644 src/pages/wallet/hooks/useWalletData.ts create mode 100644 src/pages/wallet/service/WalletService.ts create mode 100644 src/pages/wallet/types/WalletTypes.ts diff --git a/.env b/.env index cb6837e..d62a7ef 100644 --- a/.env +++ b/.env @@ -1,4 +1,4 @@ VITE_TOKEN_NAME = 'dsc_token' VITE_REFRESH_TOKEN_NAME = 'dsc_refresh_token' -VITE_BASE_URL = 'https://danak-dsc-api.run.danakcorp.com' -# VITE_BASE_URL = 'http://192.168.0.207:3500' \ No newline at end of file +# VITE_BASE_URL = 'https://danak-dsc-api.run.danakcorp.com' +VITE_BASE_URL = 'http://192.168.0.221:4000' \ No newline at end of file diff --git a/src/assets/images/zarinpal-logo-min.png b/src/assets/images/zarinpal-logo-min.png new file mode 100644 index 0000000000000000000000000000000000000000..7970712aa07982ef8110db7647732ac07643d0d3 GIT binary patch literal 7314 zcmV;D9Bt!?P)|Ni{{{{H{|`Tzg_|Ns8~{rDgxPXGV=|Ns5}{qrIwPyhb^|NZj+{q+CW z3;+H4|NZv={O|wR5dZq*|NZ{{{{H{@+yDFK|NHF!`|17t{r}bh|NQa)`raBINdNfM z|N7zo_}CR1Mf>~w|JMf-7efF1?f?J$I6Gh+Axr=F&S7MMBPUQUGFboG9S#ycla;C2 z+TrT!?)dro|K2x=i=e*0%k%X1MM!E^S$O~Qum9|g|L>vy@TLFeX05Kh|MkVo%++db zi2wAwCMr^%pR#>_m;dgU3IL)O2Hq*6R7pfZRCwC# zTg`6jNE1cle@!D}Y#;(G90eqVr7T!w6>_g4Wf3V+?)yK?SEs7lHVFiKgl92d`jXs0 zXve2dRh{bUVi5dC#^49Y50D=qKR|wf`~dj@^8X1W48nSNp~r)MIDVymfd;}bOq48V{$2~hjgNHGVJF|D~8u|6-8T1Q!jehYD4XiaI zfZ=+$3xYrx979ObCK!HV=ym=*z0orz-&Acgh6b&>>+w1`Zt0fvz>hS;BM=_o_h?#5 zhu#8iTE6*s;2-@@Ptz1&Qe9(0;u=|BVZ$&ThPnJoC%+<0Dl2_3VggfowK>p@yFLN% zqX=IS{|8Vh;Lt6Vd|!sp6AkQPw9YV|umZvF)kV>tnMn_Zhe4&%xf(}yL%gpAgNE}05OdY>`fDQRt5{P$D(o`MTE2sGy68%I-p z1cA$@W=+f}4gfHgPmCyYIS$kCGSKN;qolW%ogKa{BW~%5O*rfo#p}bl@iFux+-xcS zTas1sIvBn{$!0`k5RCl!@aN&-&*6CyxEV~791ZVbyj}HV(9%QT=8oF4p9F{1`SB5E zzFk}6l_7u_WBr+75RN$ccpI;_G*;WU-@71*;B%HnQ<{#p)tV6stWL>3?)yXU_i8#g zJ*L|?m)yj6;Z2U`z_tP+LR=XZ1lLI7=ZDpHFr}-|*LL-AA14u@0Ezf~M3V~S-egz3nBQnV-$tL>& z;;DwY2r^l576{?^lSc_|$hxit0UUlx%bsOJ_i4JFj+@iA`xoXUvO$?Nh-~uujF1P? zLcy*m#!k)w0gg#Dq$unI38_iwRH2*gO4i|hH6Dzc^MGWYf)gJ|9LL<0-Nae=xp2uKoX|B_2V&(A0S7pW>poG1|;D&UFSpvs)Z~_O-{_TKFw#t$fzKd-Q+9q0{o9!woish;B3%i;Z z`9y#KhmW}BYK~a(aTt$J;Q%Fzgvj)n6EXlY${rY@>x!omA(Pzw3IujF-z}EJ$Y^M9 z$0oJpz{2Jv{k7em#xdAV?=w(BjHIa*_v-=)JmW&r#6t*3`UMDZZ1P#YT<#`CqLi?0 zImm<|Kj4E>f-`*J5-)9;NcN(^MQSnH1Vp61s!8bSt+x>m96WfAj zx!z6OhmTl7iplab5W?|xzn-txGhw7i#I#b``Ek@HKD^WVQH|BxY=_CBisb7zS7#*l zL<}Lz#cr7&17SXHH@9nMM4cU}tos+|SCM7|hwXQKAlpoG(3#2Jgmg6S!?b`T63fbG zNdpM@c)s1t=eJ-4IQU*PYfLrn7VgvdTRvb}OPa1BkHtOig%OtxWJs2kuZJ}d#xcJG z4hFKEj8xf)LWV&&hR~1i_+UbYGpxf<&9V@x@{o!mbv0}tN@^1kVMkHPdj$11tBF#upkX<1Y@SeWc58`9+G}~yIm zFp6PCRnC7&KLp1ef(0%i$}Z_|U*Xq37DU=d-LC+YF7fKHx@cFAxAzu^&9x+H>?uV_ zQF%y&l6?O0=l4D1SThWd%YB|R{O_Ig+tZUx2Dw-BNBxGgpd@&(QGYa zrrQu(b/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 { const { t } = useTranslation('global') - const [priceSelect, setPriceSelect] = useState(1) - const [bankSelected, setBankSelected] = useState(1) + const getGetWays = useGetGetWays() + const payment = usePayment() + const [bankSelected, setBankSelected] = useState(getWays[0].name) + const [desiredAmount, setDesiredAmount] = useState(0) + const [amountSelected, setAmountSelected] = useState(0) + + const handlePay = () => { + if (desiredAmount === 0 && amountSelected === 0) { + toast.error(t('wallet.error_select_price')) + } else { + const amout = desiredAmount === 0 ? amountSelected : desiredAmount + if (amout < 100000) { + toast.error(t('wallet.error_min_price')) + return + } else { + payment.mutate({ amount: amout, gateway: bankSelected }, { + onSuccess: (data) => { + toast.success(t('wallet.transfer_to_getway')) + window.location.href = data?.data?.redirectUrl + }, + onError: (error: ErrorType) => { + toast.error(error?.response?.data?.error?.message[0]) + } + }) + } + } + } return (
@@ -22,42 +59,24 @@ const Online: FC = () => {
-
setPriceSelect(1)} className={clx( - 'bg-[#EBEDF5] border border-[#EBEDF5] cursor-pointer flex items-center text-xs h-10 px-6 rounded-lg', - priceSelect === 1 && 'border-black' - )}> - ۱۰,۰۰۰,۰۰۰ تومان -
-
setPriceSelect(2)} className={clx( - 'bg-[#EBEDF5] border border-[#EBEDF5] cursor-pointer flex items-center text-xs h-10 px-6 rounded-lg', - priceSelect === 2 && 'border-black' - )}> - ۱۰,۰۰۰,۰۰۰ تومان -
-
setPriceSelect(3)} className={clx( - 'bg-[#EBEDF5] border border-[#EBEDF5] cursor-pointer flex items-center text-xs h-10 px-6 rounded-lg', - priceSelect === 3 && 'border-black' - )}> - ۱۰,۰۰۰,۰۰۰ تومان -
-
setPriceSelect(4)} className={clx( - 'bg-[#EBEDF5] border border-[#EBEDF5] cursor-pointer flex items-center text-xs h-10 px-6 rounded-lg', - priceSelect === 4 && 'border-black' - )}> - ۱۰,۰۰۰,۰۰۰ تومان -
-
setPriceSelect(5)} className={clx( - 'bg-[#EBEDF5] border border-[#EBEDF5] cursor-pointer flex items-center text-xs h-10 px-6 rounded-lg', - priceSelect === 5 && 'border-black' - )}> - ۱۰,۰۰۰,۰۰۰ تومان -
+ { + defaultAmounts.map((amount) => ( +
setAmountSelected(amount)} key={amount} className={clx( + 'bg-[#EBEDF5] border border-[#EBEDF5] cursor-pointer flex items-center text-xs h-10 px-6 rounded-lg', + amountSelected === amount && 'border-black' + )}> + {amount.toLocaleString()} تومان +
+ )) + } +
setDesiredAmount(Number(e.target.value))} />
@@ -67,40 +86,35 @@ const Online: FC = () => {
-
setBankSelected(1)} className={clx( - 'xl:h-16 rounded-xl cursor-pointer flex xl:flex-row flex-col gap-4 items-center text-center py-3 xl:py-0 xl:text-right px-4 border border-border xl:w-[240px]', - bankSelected === 1 && 'border-black' - )}> - -
-
- بانک پارسیان -
-
- تمام کارت های عضو شتاب -
-
-
-
setBankSelected(2)} className={clx( - 'xl:h-16 rounded-xl cursor-pointer flex xl:flex-row flex-col gap-4 items-center text-center py-3 xl:py-0 xl:text-right px-4 border border-border xl:w-[240px]', - bankSelected === 2 && 'border-black' - )}> - -
-
- بانک پارسیان -
-
- تمام کارت های عضو شتاب -
-
-
+ { + getGetWays.data?.data?.gateways?.map((item: { name: string }) => { + const way = getWays.find((way) => way.name === item.name) + return ( +
setBankSelected(way?.name ? way?.name : '')} className={clx( + 'xl:h-16 rounded-xl cursor-pointer flex xl:flex-row flex-col gap-4 items-center text-center py-3 xl:py-0 xl:text-right px-4 border border-border xl:w-[240px]', + bankSelected === way?.name && 'border-black' + )}> + +
+
+ {way?.title} +
+
+ {t('wallet.all_cards')} +
+
+
+ ) + }) + }
diff --git a/src/pages/wallet/hooks/useWalletData.ts b/src/pages/wallet/hooks/useWalletData.ts new file mode 100644 index 0000000..e39c69d --- /dev/null +++ b/src/pages/wallet/hooks/useWalletData.ts @@ -0,0 +1,16 @@ +import { useMutation, useQuery } from "@tanstack/react-query"; +import * as api from "../service/WalletService"; +import { PaymentType } from "../types/WalletTypes"; + +export const useGetGetWays = () => { + return useQuery({ + queryKey: ["getGetWays"], + queryFn: api.getGetWays, + }); +}; + +export const usePayment = () => { + return useMutation({ + mutationFn: (variables: PaymentType) => api.payment(variables), + }); +}; diff --git a/src/pages/wallet/service/WalletService.ts b/src/pages/wallet/service/WalletService.ts new file mode 100644 index 0000000..aaf4f53 --- /dev/null +++ b/src/pages/wallet/service/WalletService.ts @@ -0,0 +1,12 @@ +import axios from "../../../config/axios"; +import { PaymentType } from "../types/WalletTypes"; + +export const getGetWays = async () => { + const { data } = await axios.get(`/payments/gateways`); + return data; +}; + +export const payment = async (params: PaymentType) => { + const { data } = await axios.post(`/payments/deposit/gateway`, params); + return data; +}; diff --git a/src/pages/wallet/types/WalletTypes.ts b/src/pages/wallet/types/WalletTypes.ts new file mode 100644 index 0000000..76599bd --- /dev/null +++ b/src/pages/wallet/types/WalletTypes.ts @@ -0,0 +1,4 @@ +export type PaymentType = { + amount: number; + gateway: string; +}; diff --git a/src/router/Main.tsx b/src/router/Main.tsx index 2685135..38096ec 100644 --- a/src/router/Main.tsx +++ b/src/router/Main.tsx @@ -5,9 +5,9 @@ import { Route, Routes } from 'react-router-dom' import { Pages } from '../config/Pages' import Home from '../pages/home/Home' import MyServices from '../pages/service/MyServices' -import TicketList from '../pages/ticket/TicketList' -import CreateTicket from '../pages/ticket/CreateTicket' -import TicketDetail from '../pages/ticket/Detail' +// import TicketList from '../pages/ticket/TicketList' +// import CreateTicket from '../pages/ticket/CreateTicket' +// import TicketDetail from '../pages/ticket/Detail' import TransactionList from '../pages/transaction/List' import ReceiptsList from '../pages/receipts/List' import AnnouncementtList from '../pages/annoncement/List' @@ -21,6 +21,9 @@ import OtherServices from '../pages/service/OtherServices' import Footer from '../shared/Footer' import AnnouncementDetail from '../pages/annoncement/Detail' import DetailService from '../pages/service/DetailService' +import TicketList from '../pages/ticket/TicketList' +import CreateTicket from '../pages/ticket/CreateTicket' +import TicketDetail from '../pages/ticket/Detail' const MainRouter: FC = () => { return (