feat: похуйу
This commit is contained in:
@@ -25,7 +25,7 @@ export interface PaymentQuote {
|
|||||||
|
|
||||||
export async function getPaymentConfig(): Promise<PaymentConfig> {
|
export async function getPaymentConfig(): Promise<PaymentConfig> {
|
||||||
const csrf = await getCsrfToken()
|
const csrf = await getCsrfToken()
|
||||||
const res = await fetch(`${PAYMENT_API_URL}/config`, {
|
const res = await fetch(`${PAYMENT_API_URL}/payment/config`, {
|
||||||
credentials: 'include',
|
credentials: 'include',
|
||||||
headers: { 'X-CSRF-Token': csrf },
|
headers: { 'X-CSRF-Token': csrf },
|
||||||
})
|
})
|
||||||
@@ -44,3 +44,53 @@ export async function getPaymentQuote(usdtAmount: number): Promise<PaymentQuote>
|
|||||||
if (!res.ok) throw data
|
if (!res.ok) throw data
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface CreateOrderPayload {
|
||||||
|
usdt_amount: number
|
||||||
|
usdt_exchange_rate: number
|
||||||
|
gas_fee: number
|
||||||
|
total_price: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface OrderResult {
|
||||||
|
status_code: number
|
||||||
|
order: {
|
||||||
|
id: string
|
||||||
|
created_at: string
|
||||||
|
updated_at: string
|
||||||
|
user_id: string
|
||||||
|
usdt_amount: string
|
||||||
|
usdt_exchange_rate: string
|
||||||
|
gas_fee: string
|
||||||
|
total_price: string
|
||||||
|
service_fee: string
|
||||||
|
status: string
|
||||||
|
client_payment_id: string
|
||||||
|
itpay_payment_qr_url_desktop: string
|
||||||
|
itpay_payment_qr_url_android: string
|
||||||
|
itpay_payment_qr_url_ios: string
|
||||||
|
itpay_payment_qr_image_desktop: string
|
||||||
|
itpay_payment_qr_image_android: string
|
||||||
|
itpay_payment_qr_image_ios: string
|
||||||
|
itpay_id: string
|
||||||
|
itpay_qr_id: string
|
||||||
|
itpay_amount: string
|
||||||
|
itpay_created_at: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function createOrder(payload: CreateOrderPayload): Promise<OrderResult> {
|
||||||
|
const csrf = await getCsrfToken()
|
||||||
|
const res = await fetch(`${PAYMENT_API_URL}/order/create`, {
|
||||||
|
method: 'POST',
|
||||||
|
credentials: 'include',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'X-CSRF-Token': csrf,
|
||||||
|
},
|
||||||
|
body: JSON.stringify(payload),
|
||||||
|
})
|
||||||
|
const data = await res.json()
|
||||||
|
if (!res.ok) throw data
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|||||||
12
src/features/payment/hooks/useCreateOrder.ts
Normal file
12
src/features/payment/hooks/useCreateOrder.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import { useMutation } from '@tanstack/react-query'
|
||||||
|
import { createOrder } from '../api/paymentApi'
|
||||||
|
|
||||||
|
export function useCreateOrder() {
|
||||||
|
return useMutation({
|
||||||
|
mutationFn: createOrder,
|
||||||
|
onSuccess: (data) => {
|
||||||
|
const url = data.order.itpay_payment_qr_url_desktop
|
||||||
|
if (url) window.location.href = url
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
export { usePaymentConfig } from './hooks/usePaymentConfig'
|
export { usePaymentConfig } from './hooks/usePaymentConfig'
|
||||||
export { usePaymentQuote } from './hooks/usePaymentQuote'
|
export { usePaymentQuote } from './hooks/usePaymentQuote'
|
||||||
export type { PaymentConfig, PaymentQuote } from './api/paymentApi'
|
export { useCreateOrder } from './hooks/useCreateOrder'
|
||||||
|
export type { PaymentConfig, PaymentQuote, CreateOrderPayload, OrderResult } from './api/paymentApi'
|
||||||
|
|||||||
@@ -174,6 +174,24 @@
|
|||||||
border-top: 1px solid var(--glass-border);
|
border-top: 1px solid var(--glass-border);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.payBtn {
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 24px;
|
||||||
|
padding: 18px;
|
||||||
|
border-radius: 12px;
|
||||||
|
background: var(--grad-center);
|
||||||
|
color: var(--text-primary);
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
transition: opacity 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.payBtn:disabled {
|
||||||
|
opacity: 0.4;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 1024px) {
|
@media (max-width: 1024px) {
|
||||||
.body {
|
.body {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { useConverter } from '@widgets/currency-converter'
|
import { useConverter } from '@widgets/currency-converter'
|
||||||
import { USDT_RATE, GAS_PRICE } from '@shared/config/constants'
|
import { USDT_RATE, GAS_PRICE } from '@shared/config/constants'
|
||||||
import { useDebounce } from '@shared/lib/hooks/useDebounce'
|
import { useDebounce } from '@shared/lib/hooks/useDebounce'
|
||||||
import { usePaymentConfig, usePaymentQuote } from '@features/payment'
|
import { usePaymentConfig, usePaymentQuote, useCreateOrder } from '@features/payment'
|
||||||
import { CommissionPanel } from './CommissionPanel'
|
import { CommissionPanel } from './CommissionPanel'
|
||||||
import { AgreementCheck } from './AgreementCheck'
|
import { AgreementCheck } from './AgreementCheck'
|
||||||
import styles from './ConverterSection.module.css'
|
import styles from './ConverterSection.module.css'
|
||||||
@@ -19,6 +19,17 @@ export function ConverterSection() {
|
|||||||
|
|
||||||
const rubTotal = quote?.total_price ?? ''
|
const rubTotal = quote?.total_price ?? ''
|
||||||
|
|
||||||
|
const { mutate: submitOrder, isPending } = useCreateOrder()
|
||||||
|
|
||||||
|
function handlePay() {
|
||||||
|
submitOrder({
|
||||||
|
usdt_amount: c.numRub,
|
||||||
|
usdt_exchange_rate: 1,
|
||||||
|
gas_fee: 1,
|
||||||
|
total_price: Number(rubTotal) || 0,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.wrap}>
|
<div className={styles.wrap}>
|
||||||
<div className={styles.header}>
|
<div className={styles.header}>
|
||||||
@@ -49,6 +60,7 @@ export function ConverterSection() {
|
|||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
disabled
|
||||||
className={styles.tab}
|
className={styles.tab}
|
||||||
data-active={c.mode === 'sell' || undefined}
|
data-active={c.mode === 'sell' || undefined}
|
||||||
onClick={() => c.setMode('sell')}
|
onClick={() => c.setMode('sell')}
|
||||||
@@ -116,6 +128,15 @@ export function ConverterSection() {
|
|||||||
<div className={styles.bottom}>
|
<div className={styles.bottom}>
|
||||||
<AgreementCheck checked={c.agreed} onToggle={() => c.setAgreed(!c.agreed)} />
|
<AgreementCheck checked={c.agreed} onToggle={() => c.setAgreed(!c.agreed)} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className={styles.payBtn}
|
||||||
|
onClick={handlePay}
|
||||||
|
disabled={!rubTotal || isPending}
|
||||||
|
>
|
||||||
|
{isPending ? 'Обработка...' : 'Оплатить'}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ export function Converter() {
|
|||||||
className={styles.tab}
|
className={styles.tab}
|
||||||
data-active={c.mode === 'sell' || undefined}
|
data-active={c.mode === 'sell' || undefined}
|
||||||
onClick={() => c.setMode('sell')}
|
onClick={() => c.setMode('sell')}
|
||||||
|
disabled
|
||||||
>
|
>
|
||||||
ПРОДАТЬ
|
ПРОДАТЬ
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
{"root":["./src/main.tsx","./src/vite-env.d.ts","./src/app/app.tsx","./src/app/providers/guestroute.tsx","./src/app/providers/protectedroute.tsx","./src/app/providers/queryprovider.tsx","./src/app/providers/routerprovider.tsx","./src/app/providers/scrolltotop.tsx","./src/app/providers/index.ts","./src/features/auth/index.ts","./src/features/auth/api/profileapi.ts","./src/features/auth/api/registrationapi.ts","./src/features/auth/hooks/useauth.ts","./src/features/auth/hooks/useisauthenticated.ts","./src/features/auth/hooks/useme.ts","./src/features/kyc/api/kycapi.ts","./src/features/payment/index.ts","./src/features/payment/api/paymentapi.ts","./src/features/payment/hooks/usepaymentconfig.ts","./src/features/payment/hooks/usepaymentquote.ts","./src/pages/converter/index.ts","./src/pages/converter/ui/converterpage.tsx","./src/pages/home/index.ts","./src/pages/home/ui/homepage.tsx","./src/pages/kyc/index.ts","./src/pages/kyc/ui/kycpage.tsx","./src/pages/login/index.ts","./src/pages/login/ui/loginpage.tsx","./src/pages/profile/index.ts","./src/pages/profile/ui/profilepage.tsx","./src/pages/register/index.ts","./src/pages/register/ui/registerpage.tsx","./src/pages/seed-phrase/index.ts","./src/pages/seed-phrase/ui/seedphrasepage.tsx","./src/pages/swap/index.ts","./src/pages/swap/ui/swappage.tsx","./src/pages/wallet/index.ts","./src/pages/wallet/ui/walletpage.tsx","./src/shared/api/base.ts","./src/shared/api/csrf.ts","./src/shared/api/tokenstore.ts","./src/shared/api/types.ts","./src/shared/config/constants.ts","./src/shared/config/env.ts","./src/shared/config/routes.ts","./src/shared/lib/hooks/usedebounce.ts","./src/shared/lib/hooks/uselocalstorage.ts","./src/shared/lib/utils/cn.ts","./src/shared/types/index.ts","./src/shared/ui/index.ts","./src/shared/ui/button/button.tsx","./src/shared/ui/button/index.ts","./src/shared/ui/formfield/formfield.tsx","./src/shared/ui/formfield/index.ts","./src/shared/ui/notification/notification.tsx","./src/shared/ui/notification/index.ts","./src/shared/ui/pill/pill.tsx","./src/shared/ui/pill/index.ts","./src/shared/ui/primarybutton/primarybutton.tsx","./src/shared/ui/primarybutton/index.ts","./src/shared/ui/title/title.tsx","./src/shared/ui/tokenicon/tokenicon.tsx","./src/shared/ui/tokenicon/index.ts","./src/widgets/about/index.ts","./src/widgets/about/ui/about.tsx","./src/widgets/balance-card/index.ts","./src/widgets/balance-card/ui/balancecard.tsx","./src/widgets/converter-page/index.ts","./src/widgets/converter-page/ui/agreementcheck.tsx","./src/widgets/converter-page/ui/commissionpanel.tsx","./src/widgets/converter-page/ui/convertersection.tsx","./src/widgets/currency-converter/index.ts","./src/widgets/currency-converter/model/tiers.ts","./src/widgets/currency-converter/model/useconverter.ts","./src/widgets/currency-converter/ui/agreementcheckbox.tsx","./src/widgets/currency-converter/ui/commissiontable.tsx","./src/widgets/currency-converter/ui/converter.tsx","./src/widgets/currency-converter/ui/tiers.tsx","./src/widgets/footer/index.ts","./src/widgets/footer/ui/footer.tsx","./src/widgets/header/index.ts","./src/widgets/header/ui/header.tsx","./src/widgets/hero/index.ts","./src/widgets/hero/lib/usecountdown.ts","./src/widgets/hero/ui/conversionflow.tsx","./src/widgets/hero/ui/countdown.tsx","./src/widgets/hero/ui/exchangecard.tsx","./src/widgets/hero/ui/hero.tsx","./src/widgets/kyc-verification/index.ts","./src/widgets/kyc-verification/model/usekyc.ts","./src/widgets/kyc-verification/ui/kycmodal.tsx","./src/widgets/kyc-verification/ui/kycwidget.tsx","./src/widgets/login-form/index.ts","./src/widgets/login-form/model/useloginform.ts","./src/widgets/login-form/ui/loginform.tsx","./src/widgets/networks-table/index.ts","./src/widgets/networks-table/model/networks.ts","./src/widgets/networks-table/ui/networkstable.tsx","./src/widgets/profile/index.ts","./src/widgets/profile/ui/profileavatar.tsx","./src/widgets/profile/ui/profilesection.tsx","./src/widgets/register-form/index.ts","./src/widgets/register-form/model/useregisterform.ts","./src/widgets/register-form/ui/registerform.tsx","./src/widgets/seed-phrase/index.ts","./src/widgets/seed-phrase/model/useseedphrase.ts","./src/widgets/seed-phrase/ui/seedphrasewidget.tsx","./src/widgets/swap-form/index.ts","./src/widgets/swap-form/model/useswapform.ts","./src/widgets/swap-form/ui/raterow.tsx","./src/widgets/swap-form/ui/swapcard.tsx","./src/widgets/swap-form/ui/swapdirectionbutton.tsx","./src/widgets/swap-form/ui/swapform.tsx","./src/widgets/swap-form/ui/swapinfopanel.tsx","./src/widgets/swap-form/ui/tokenselect.tsx","./src/widgets/token-table/index.ts","./src/widgets/token-table/model/tokens.ts","./src/widgets/token-table/ui/tokentable.tsx","./src/widgets/wallet-header/index.ts","./src/widgets/wallet-header/ui/walletheader.tsx"],"version":"5.6.3"}
|
{"root":["./src/main.tsx","./src/vite-env.d.ts","./src/app/app.tsx","./src/app/providers/guestroute.tsx","./src/app/providers/protectedroute.tsx","./src/app/providers/queryprovider.tsx","./src/app/providers/routerprovider.tsx","./src/app/providers/scrolltotop.tsx","./src/app/providers/index.ts","./src/features/auth/index.ts","./src/features/auth/api/profileapi.ts","./src/features/auth/api/registrationapi.ts","./src/features/auth/hooks/useauth.ts","./src/features/auth/hooks/useisauthenticated.ts","./src/features/auth/hooks/useme.ts","./src/features/kyc/api/kycapi.ts","./src/features/payment/index.ts","./src/features/payment/api/paymentapi.ts","./src/features/payment/hooks/usecreateorder.ts","./src/features/payment/hooks/usepaymentconfig.ts","./src/features/payment/hooks/usepaymentquote.ts","./src/pages/converter/index.ts","./src/pages/converter/ui/converterpage.tsx","./src/pages/home/index.ts","./src/pages/home/ui/homepage.tsx","./src/pages/kyc/index.ts","./src/pages/kyc/ui/kycpage.tsx","./src/pages/login/index.ts","./src/pages/login/ui/loginpage.tsx","./src/pages/profile/index.ts","./src/pages/profile/ui/profilepage.tsx","./src/pages/register/index.ts","./src/pages/register/ui/registerpage.tsx","./src/pages/seed-phrase/index.ts","./src/pages/seed-phrase/ui/seedphrasepage.tsx","./src/pages/swap/index.ts","./src/pages/swap/ui/swappage.tsx","./src/pages/wallet/index.ts","./src/pages/wallet/ui/walletpage.tsx","./src/shared/api/base.ts","./src/shared/api/csrf.ts","./src/shared/api/tokenstore.ts","./src/shared/api/types.ts","./src/shared/config/constants.ts","./src/shared/config/env.ts","./src/shared/config/routes.ts","./src/shared/lib/hooks/usedebounce.ts","./src/shared/lib/hooks/uselocalstorage.ts","./src/shared/lib/utils/cn.ts","./src/shared/types/index.ts","./src/shared/ui/index.ts","./src/shared/ui/button/button.tsx","./src/shared/ui/button/index.ts","./src/shared/ui/formfield/formfield.tsx","./src/shared/ui/formfield/index.ts","./src/shared/ui/notification/notification.tsx","./src/shared/ui/notification/index.ts","./src/shared/ui/pill/pill.tsx","./src/shared/ui/pill/index.ts","./src/shared/ui/primarybutton/primarybutton.tsx","./src/shared/ui/primarybutton/index.ts","./src/shared/ui/title/title.tsx","./src/shared/ui/tokenicon/tokenicon.tsx","./src/shared/ui/tokenicon/index.ts","./src/widgets/about/index.ts","./src/widgets/about/ui/about.tsx","./src/widgets/balance-card/index.ts","./src/widgets/balance-card/ui/balancecard.tsx","./src/widgets/converter-page/index.ts","./src/widgets/converter-page/ui/agreementcheck.tsx","./src/widgets/converter-page/ui/commissionpanel.tsx","./src/widgets/converter-page/ui/convertersection.tsx","./src/widgets/currency-converter/index.ts","./src/widgets/currency-converter/model/tiers.ts","./src/widgets/currency-converter/model/useconverter.ts","./src/widgets/currency-converter/ui/agreementcheckbox.tsx","./src/widgets/currency-converter/ui/commissiontable.tsx","./src/widgets/currency-converter/ui/converter.tsx","./src/widgets/currency-converter/ui/tiers.tsx","./src/widgets/footer/index.ts","./src/widgets/footer/ui/footer.tsx","./src/widgets/header/index.ts","./src/widgets/header/ui/header.tsx","./src/widgets/hero/index.ts","./src/widgets/hero/lib/usecountdown.ts","./src/widgets/hero/ui/conversionflow.tsx","./src/widgets/hero/ui/countdown.tsx","./src/widgets/hero/ui/exchangecard.tsx","./src/widgets/hero/ui/hero.tsx","./src/widgets/kyc-verification/index.ts","./src/widgets/kyc-verification/model/usekyc.ts","./src/widgets/kyc-verification/ui/kycmodal.tsx","./src/widgets/kyc-verification/ui/kycwidget.tsx","./src/widgets/login-form/index.ts","./src/widgets/login-form/model/useloginform.ts","./src/widgets/login-form/ui/loginform.tsx","./src/widgets/networks-table/index.ts","./src/widgets/networks-table/model/networks.ts","./src/widgets/networks-table/ui/networkstable.tsx","./src/widgets/profile/index.ts","./src/widgets/profile/ui/profileavatar.tsx","./src/widgets/profile/ui/profilesection.tsx","./src/widgets/register-form/index.ts","./src/widgets/register-form/model/useregisterform.ts","./src/widgets/register-form/ui/registerform.tsx","./src/widgets/seed-phrase/index.ts","./src/widgets/seed-phrase/model/useseedphrase.ts","./src/widgets/seed-phrase/ui/seedphrasewidget.tsx","./src/widgets/swap-form/index.ts","./src/widgets/swap-form/model/useswapform.ts","./src/widgets/swap-form/ui/raterow.tsx","./src/widgets/swap-form/ui/swapcard.tsx","./src/widgets/swap-form/ui/swapdirectionbutton.tsx","./src/widgets/swap-form/ui/swapform.tsx","./src/widgets/swap-form/ui/swapinfopanel.tsx","./src/widgets/swap-form/ui/tokenselect.tsx","./src/widgets/token-table/index.ts","./src/widgets/token-table/model/tokens.ts","./src/widgets/token-table/ui/tokentable.tsx","./src/widgets/wallet-header/index.ts","./src/widgets/wallet-header/ui/walletheader.tsx"],"version":"5.6.3"}
|
||||||
Reference in New Issue
Block a user