complite yooMoneyWidged and payments

This commit is contained in:
smanylov
2026-03-04 11:55:36 +07:00
parent a53c1b4b49
commit 9899741c00
5 changed files with 55 additions and 80 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "no-copy-frontend",
"version": "0.49.0",
"version": "0.50.0",
"private": true,
"scripts": {
"dev": "next dev -p 2999",
+3 -22
View File
@@ -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() {
@@ -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();
}
}
+40 -3
View File
@@ -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<boolean>(false);
const [showWidget, setShowWidget] = useState<boolean>(false);
const [yooMoneyConfig, setYooMoneyConfig] = useState<YooMoneyCheckoutWidgetConfig | null>(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 (
<>
<ModalWindow state={openWindow} callBack={closeModal}>
@@ -171,7 +203,7 @@ export default function PaymentTubBuyTokens() {
<div className="plan-header">
<div className="plan-price">{item.price ?? 0} </div>
<div className="plan-tokens header">
{item.tokens ?? 0}
{item.tokens ?? 0}
<br />
токенов
</div>
@@ -188,6 +220,11 @@ export default function PaymentTubBuyTokens() {
))}
</div>
</div>
{/* Модальное окно с виджетом */}
{showWidget && yooMoneyConfig && (
<YooMoneyWidget config={yooMoneyConfig} onComplete={onComplete} onModalClose={onModalClose} />
)}
</>
)
+11 -46
View File
@@ -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<boolean>(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<string | null>(null);
const [showWidget, setShowWidget] = useState<boolean>(false);
const [yooMoneyConfig, setYooMoneyConfig] = useState<YooMoneyCheckoutWidgetConfig | null>(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 (