From 9899741c00dbb597ac2132c598acb81e3e40485a Mon Sep 17 00:00:00 2001 From: smanylov Date: Wed, 4 Mar 2026 11:55:36 +0700 Subject: [PATCH] complite yooMoneyWidged and payments --- package.json | 2 +- src/app/actions/yooKassa.ts | 25 +------- .../payment => components}/YooMoneyWidget.tsx | 8 --- src/app/ui/payment/payment-tab-buy-tokens.tsx | 43 +++++++++++++- src/app/ui/payment/payment-tab-tariffs.tsx | 57 ++++--------------- 5 files changed, 55 insertions(+), 80 deletions(-) rename src/app/{ui/payment => components}/YooMoneyWidget.tsx (92%) diff --git a/package.json b/package.json index 7b1edf1..29232a7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "no-copy-frontend", - "version": "0.49.0", + "version": "0.50.0", "private": true, "scripts": { "dev": "next dev -p 2999", diff --git a/src/app/actions/yooKassa.ts b/src/app/actions/yooKassa.ts index 7ef69b5..4e17f87 100644 --- a/src/app/actions/yooKassa.ts +++ b/src/app/actions/yooKassa.ts @@ -37,8 +37,6 @@ export async function makePaymentOperation(email: string, tariffId: number, oper } export async function yooKasaCreatePayment(amount: number, tariff: number, operationType: 'TARIFF' | 'TOKEN') { - console.log('yooKasaCreatePayment'); - const userEmail = await getSessionData('email'); const timestamp = Date.now(); const random = Math.random().toString(36).substring(2, 10); @@ -53,27 +51,22 @@ export async function yooKasaCreatePayment(amount: number, tariff: number, opera value: amount.toLocaleString().replace(/\s/g, ''), currency: 'RUB' }, - /* payment_method_data: { - type: 'bank_card' - }, */ - /* payment_method_id: "3138d708-000f-5001-9000-19865cfcca68", */ confirmation: { type: 'embedded', - /* type: 'redirect', - return_url: 'test' */ }, metadata: { userMail: userEmail, tariff: tariff }, merchant_customer_id: userEmail, - capture: true + capture: true, + ...(operationType === 'TOKEN' && {save_payment_method: false}) }; try { const payment = await checkout.createPayment(createPayload, idempotenceKey); const response = await makePaymentOperation(userEmail, tariff, payment.id, operationType); - console.log(payment); + if (payment && response) { return payment?.confirmation.confirmation_token; } else { @@ -82,18 +75,6 @@ export async function yooKasaCreatePayment(amount: number, tariff: number, opera } catch (error) { return null } - - /* try { - const payment = await checkout.createPayment(createPayload, idempotenceKey); - const response = await makePaymentOperation(userEmail, tariff, payment.id, operationType); - if (response && payment) { - return payment?.confirmation.confirmation_url; - } else { - return null - } - } catch (error) { - return null - } */ } export async function fetchPaymentsHistory() { diff --git a/src/app/ui/payment/YooMoneyWidget.tsx b/src/app/components/YooMoneyWidget.tsx similarity index 92% rename from src/app/ui/payment/YooMoneyWidget.tsx rename to src/app/components/YooMoneyWidget.tsx index 025d6ac..f2c222f 100644 --- a/src/app/ui/payment/YooMoneyWidget.tsx +++ b/src/app/components/YooMoneyWidget.tsx @@ -41,7 +41,6 @@ export default function YooWidget({ config, onComplete, onSuccess, onFail, onMod }; } checkout = new window.YooMoneyCheckoutWidget(config); - console.log('checkout.create'); checkout.on('complete', (result) => { console.log('on complete', result); onComplete && onComplete(); @@ -60,7 +59,6 @@ export default function YooWidget({ config, onComplete, onSuccess, onFail, onMod if (config.customization?.modal) { checkout.on('modal_close', (result) => { - console.log('on modal_close', result); onModalClose && onModalClose(); destroy(); }); @@ -70,24 +68,18 @@ export default function YooWidget({ config, onComplete, onSuccess, onFail, onMod }, [config, onSuccess]); useEffect(() => { - console.log('isInited'); - console.log(isInited); - if (!isLoading && !isInited) { if (!window.YooMoneyCheckoutWidget) { isLoading = true; - console.log('load script'); const script = document.createElement('script'); script.src = 'https://yookassa.ru/checkout-widget/v1/checkout-widget.js'; script.async = true; script.onload = initializeWidget; document.head.appendChild(script); return () => { - console.log('unload script'); document.head.removeChild(script); }; } else { - console.log('init without loading'); initializeWidget(); } } diff --git a/src/app/ui/payment/payment-tab-buy-tokens.tsx b/src/app/ui/payment/payment-tab-buy-tokens.tsx index 4b2feaa..f5970ca 100644 --- a/src/app/ui/payment/payment-tab-buy-tokens.tsx +++ b/src/app/ui/payment/payment-tab-buy-tokens.tsx @@ -1,12 +1,14 @@ 'use client' import { fetchTariffs, fetchTokensBundle } from '@/app/actions/action'; -import { useQuery } from '@tanstack/react-query'; +import {useQuery, useQueryClient} from '@tanstack/react-query'; import { convertBytes } from '@/app/lib/convertBytes'; import { useTranslations } from 'next-intl'; import { yooKasaCreatePayment } from '@/app/actions/yooKassa'; import { useState } from 'react'; import ModalWindow from '@/app/components/ModalWindow'; +import YooMoneyWidget from '@/app/components/YooMoneyWidget'; +import { YooMoneyCheckoutWidgetConfig, YooMoneyErrorCallbackResult } from 'types-yoomoneycheckoutwidget'; interface Tariff { id: number; @@ -49,16 +51,32 @@ export default function PaymentTubBuyTokens() { tokensBundleID: number } | null>(null); const [isProcessing, setIsProcessing] = useState(false); + const [showWidget, setShowWidget] = useState(false); + const [yooMoneyConfig, setYooMoneyConfig] = useState(null); + const queryClient = useQueryClient(); async function createPayment(value: number, tokensBundle: number) { if (isProcessing) return; setIsProcessing(true); + setErrorMessage(null); try { const response = await yooKasaCreatePayment(value, tokensBundle, 'TOKEN'); if (response) { - window.open(response, '_blank', 'noopener,noreferrer'); + setShowWidget(true) + + const config: YooMoneyCheckoutWidgetConfig = { + confirmation_token: response, + error_callback: (result: YooMoneyErrorCallbackResult) => { + console.error('error_callback', result.error); + }, + customization: { + modal: true + } + } + + setYooMoneyConfig(config); closeModal(false); } else { setErrorMessage('payment-error'); @@ -143,6 +161,20 @@ export default function PaymentTubBuyTokens() { ); } + const onComplete = () => { + setYooMoneyConfig(null); + setShowWidget(false); + const timer = setTimeout(() => { + queryClient.invalidateQueries({ queryKey: ['userData'] }); + }, 2000); + + return () => clearTimeout(timer); + }; + const onModalClose = () => { + setYooMoneyConfig(null); + setShowWidget(false); + } + return ( <> @@ -171,7 +203,7 @@ export default function PaymentTubBuyTokens() {
{item.price ?? 0} ₽
- {item.tokens ?? 0} + {item.tokens ?? 0}
токенов
@@ -188,6 +220,11 @@ export default function PaymentTubBuyTokens() { ))}
+ + {/* Модальное окно с виджетом */} + {showWidget && yooMoneyConfig && ( + + )} ) diff --git a/src/app/ui/payment/payment-tab-tariffs.tsx b/src/app/ui/payment/payment-tab-tariffs.tsx index df3324e..8d55047 100644 --- a/src/app/ui/payment/payment-tab-tariffs.tsx +++ b/src/app/ui/payment/payment-tab-tariffs.tsx @@ -1,13 +1,13 @@ 'use client' import { fetchTariffs } from '@/app/actions/action'; -import { useQuery } from '@tanstack/react-query'; +import { useQuery, useQueryClient } from '@tanstack/react-query'; import { convertBytes } from '@/app/lib/convertBytes'; import { useTranslations } from 'next-intl'; import { yooKasaCreatePayment } from '@/app/actions/yooKassa'; import { useState, ReactNode, useEffect } from 'react'; import ModalWindow from '@/app/components/ModalWindow'; -import YooMoneyWidget from './YooMoneyWidget'; +import YooMoneyWidget from '../../components/YooMoneyWidget'; import { YooMoneyCheckoutWidgetConfig, YooMoneyErrorCallbackResult } from "types-yoomoneycheckoutwidget"; interface Tariff { @@ -51,33 +51,9 @@ export default function PaymentTabTariffs() { tariffId: number } | null>(null); const [isProcessing, setIsProcessing] = useState(false); - - /* async function createPayment(value: number, tariff: number) { - if (isProcessing) return; - - setIsProcessing(true); - - try { - const response = await yooKasaCreatePayment(value, tariff, 'TARIFF'); - if (response) { - console.log('response ok'); - //window.open(response, '_blank', 'noopener,noreferrer'); - closeModal(false); - } else { - setErrorMessage('payment-error'); - } - } catch (error) { - setErrorMessage('payment-error'); - } finally { - setIsProcessing(false); - } - } */ - - const [confirmationToken, setConfirmationToken] = useState(null); const [showWidget, setShowWidget] = useState(false); const [yooMoneyConfig, setYooMoneyConfig] = useState(null); - - + const queryClient = useQueryClient(); async function createPayment(value: number, tariff: number) { if (isProcessing) return; @@ -89,8 +65,6 @@ export default function PaymentTabTariffs() { const response = await yooKasaCreatePayment(value, tariff, 'TARIFF'); if (response) { - console.log('response ok', response); - setConfirmationToken(response); setShowWidget(true); const config: YooMoneyCheckoutWidgetConfig = { @@ -109,27 +83,12 @@ export default function PaymentTabTariffs() { setErrorMessage('payment-error'); } } catch (error) { - console.error('Payment creation error:', error); setErrorMessage('payment-error'); } finally { setIsProcessing(false); } } - const handleWidgetSuccess = () => { - console.log('Payment successful'); - // Здесь можно закрыть модалку или показать сообщение об успехе - setShowWidget(false); - setConfirmationToken(null); - }; - - const handleWidgetError = (error: any) => { - console.error('Widget error:', error); - setErrorMessage('widget-error'); - setShowWidget(false); - setConfirmationToken(null); - }; - function openPaymentWindow(value: number, tariff: string, tokens: number, tariffId: number) { setSelectedTariff({ value, tariff, tokens, tariffId }); setIsProcessing(false); @@ -210,12 +169,18 @@ export default function PaymentTabTariffs() { } const onComplete = () => { - console.log('Payment accepted'); + setYooMoneyConfig(null); + setShowWidget(false); + const timer = setTimeout(() => { + queryClient.invalidateQueries({ queryKey: ['userData'] }); + }, 2000); + + return () => clearTimeout(timer); }; + const onModalClose = () => { setYooMoneyConfig(null); setShowWidget(false); - console.log('Payment not finished'); } return (