почему не уходят поля         cardName: response.cardName,
        cardType: response.cardType,
        trxDate: response.trxDate,
        trxTime: response.trxTime,
        termNum: response.termNum,
        authCode: response.authCode,
        rrn: response.rrn,
        merchantTSN: response.merchantTSN,
        merchantBatchNum: response.merchantBatchNum,
        clientCard: response.clientCard,
        clientExpireDate: response.clientExpiryDate,
        hash: response.hash,
        ownCard: response.ownCard,



<script setup lang="ts">
import { onMounted, ref, computed, defineProps, watch, onUnmounted } from 'vue';
import { useRouter } from 'vue-router';
import QRCode from 'qrcode';
import ReceiptPrintPrompt from '@/pages/payment-page/ui/ReceiptPrintPrompt/ReceiptPrintPrompt.vue';
import IconArrowLeft from '@/shared/assets/icons/IconArrowLeft.svg';
import loaderSrc from '@/shared/assets/img/Loader.svg?url';
import picSrc from '@/shared/assets/img/PaymentPic.svg?url';
import { useGlobalStore } from '@/shared/store/globalStore.ts';
import { VButton } from '@/shared/ui';
import {
  paymentEvent,
  type PaymentItem,
  checkClient,
  changeKKTStatus,
  getPaymentQr,
  type GetPaymentQrParams,
  sendPaymentConfirmation,
  checkStatusSBP,
  type PaymentData,
  registerCard,
  type RegisterCardPayload,
  checkId,
} from '@/features/PaymentProcedure/model/api.ts';
import { useAuthStore } from '@/features/AccountAuthorization/model/store';
import { getUserStatistics, getUserStock } from '@/entities/user';

const props = defineProps<{
  clientId: string;
  amount: string;
  method: 'card' | 'sbp' | null;
  from?: 'cabinet' | 'pay-debt' | null;
  email: string;
}>();

const globalStore = useGlobalStore();
const authStore = useAuthStore();
const router = useRouter();

let requestId = '';
const isPaymentSuccessful = ref(false);
const paymentError = ref<string | null>(null);
const paymentQrCodeUrl = ref<string | null>(null);
const sbpLoading = ref<boolean>(false);

const qrImage = ref<string | null>(null);
let pollingInterval: NodeJS.Timeout | null = null;

const goBack = () => {
  if (props.from === 'cabinet') {
    router.push('/cabinet');
  } else if (props.method || props.clientId) {
    router.push('/pay-debt');
  } else {
    router.push('/');
  }
};

const handleCardPayment = async (
  clientId: string,
  amountNumber: number,
  email: string
) => {
  try {
    const paymentData: PaymentData = {
      items: [
        {
          title: `Оплата задолженности клиента ${clientId}`,
          count: 1,
          price: amountNumber,
        },
      ],
      phoneOrEmail: email,
      payStatus: false,
    };

    const response = await paymentEvent(paymentData);

    if (response.result === 'success') {
      const now = new Date();
      const dateTime = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}T${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}:${String(now.getSeconds()).padStart(2, '0')}`;

      const registerCardPayload: RegisterCardPayload = {
        ceid: clientId,
        sum: amountNumber,
        dateTime: dateTime,
        statusCheck: true,
        requestId: requestId,
        amountClear: +response.amountClear,
        amount: +response.amount,
        cardName: response.cardName,
        cardType: response.cardType,
        trxDate: response.trxDate,
        trxTime: response.trxTime,
        termNum: response.termNum,
        authCode: response.authCode,
        rrn: response.rrn,
        merchantTSN: response.merchantTSN,
        merchantBatchNum: response.merchantBatchNum,
        clientCard: response.clientCard,
        clientExpireDate: response.clientExpiryDate,
        hash: response.hash,
        ownCard: response.ownCard,
      };

      try {
        const registerResponse = await registerCard(registerCardPayload);

        if (registerResponse?.status === true) {
          console.log('Карта успешно зарегистрирована');
          isPaymentSuccessful.value = true;
          globalStore.setIsSuccess(true);
        } else {
          console.error('Регистрация карты неуспешна:', registerResponse);
          paymentError.value = 'Ошибка регистрации карты. Попробуйте повторно.';
          globalStore.setIsError(true);
        }
      } catch (registerError) {
        console.error('Ошибка при регистрации карты:', registerError);
        paymentError.value =
          'Ошибка при регистрации карты. Платеж прошел, но данные карты не сохранены.';
        globalStore.setIsError(true);
      }

      if (props.from === 'cabinet') {
        window.ym?.(100955373, 'reachGoal', 'pay_debt_lk_card');
        console.log("Цель 'pay_debt_lk_card' отправлена в Яндекс.Метрику.");
      } else {
        window.ym?.(100955373, 'reachGoal', 'pay_debt_card_succes');
        console.log("Цель 'pay_debt_card_succes' отправлена в Яндекс.Метрику.");
      }

      if (response.description === 'paper_status=false') {
        try {
          const terminalId = window.TERMINAL_ID;
          await changeKKTStatus(terminalId);
        } catch (statusError) {
          console.error('Ошибка при вызове changePaperStatus:', statusError);
        }
      }

      try {
        const terminalID = window.TERMINAL_ID;
        await sendPaymentConfirmation({
          terminalId: terminalID,
          ceid: clientId,
          price: amountNumber,
        });
        console.log('Платеж успешно подтвержден на бэкенде');
      } catch (confirmationError) {
        console.error('Ошибка при подтверждении платежа:', confirmationError);
      }
      goBack();
    } else {
      paymentError.value = `Платеж не удался (API: ${response.result}). Детали: ${response.description}`;
      globalStore.setIsError(true);
    }
  } catch (error) {
    console.error('Ошибка при вызове paymentEvent:', error);
    paymentError.value =
      error instanceof Error
        ? error.message
        : 'Произошла неизвестная ошибка при оплате.';
    globalStore.setIsError(true);
  }
};

const handleSbpPayment = async (clientId: string, amountStr: string) => {
  sbpLoading.value = true;
  paymentError.value = null;
  paymentQrCodeUrl.value = null;

  if (!amountStr) {
    paymentError.value = 'Сумма для оплаты СБП не указана.';
    globalStore.setIsError(true);
    sbpLoading.value = false;
    return;
  }

  const amountInRub = parseFloat(amountStr);
  if (isNaN(amountInRub)) {
    paymentError.value = 'Некорректная сумма для оплаты СБП.';
    globalStore.setIsError(true);
    sbpLoading.value = false;
    return;
  }

  if (amountInRub < 10) {
    paymentError.value =
      'Минимальная сумма операции через СБП составляет 10 рублей.';
    globalStore.setIsError(true);
    sbpLoading.value = false;
    return;
  }

  const amountInKopecks = Math.round(amountInRub * 100);

  try {
    const qrParams: GetPaymentQrParams = {
      ceid: clientId,
      amount: amountInKopecks,
    };

    const qrData = await getPaymentQr(qrParams);
    paymentQrCodeUrl.value = qrData.sbp;

    if (qrData.uid) {
      pollingInterval = setInterval(() => {
        pollSbpStatus(qrData.uid);
      }, 5000);
    } else {
      paymentError.value = 'UID для проверки статуса не получен.';
      globalStore.setIsError(true);
    }
  } catch (error) {
    console.error('Ошибка при получении QR-кода СБП:', error);
    paymentError.value =
      error instanceof Error
        ? error.message
        : 'Произошла ошибка при получении QR-кода для оплаты СБП.';
    globalStore.setIsError(true);
  } finally {
    sbpLoading.value = false;
  }
};

const pollSbpStatus = async (uid: string) => {
  try {
    const response = await checkStatusSBP(uid);
    const status = response.data.status;

    if (status === 'CONFIRMED') {
      if (pollingInterval) {
        clearInterval(pollingInterval);
        pollingInterval = null;
      }

      const amountNumber = parseFloat(props.amount);
      const paymentData: PaymentData = {
        items: [
          {
            title: `Оплата задолженности клиента ${props.clientId}`,
            count: 1,
            price: amountNumber,
          },
        ],
        phoneOrEmail: props.email,
        payStatus: true,
      };

      try {
        const paymentResponse = await paymentEvent(paymentData);
        if (paymentResponse.result === 'success') {
          isPaymentSuccessful.value = true;
          globalStore.setIsSuccess(true);
          goBack();
        } else {
          console.error('Ошибка в paymentEvent:', paymentResponse.description);
          paymentError.value = `Ошибка при регистрации платежа: ${paymentResponse.description}`;
          globalStore.setIsError(true);
        }
      } catch (error) {
        console.error('Ошибка при вызове paymentEvent:', error);
        paymentError.value =
          error instanceof Error
            ? error.message
            : 'Произошла ошибка при регистрации платежа.';
        globalStore.setIsError(true);
      }

      if (props.from === 'cabinet') {
        // await updateUserData();
        window.ym?.(100955373, 'reachGoal', 'pay_debt_lk_sbp');
        console.log("Цель 'pay_debt_lk_sbp' отправлена в Яндекс.Метрику.");
      } else {
        window.ym?.(100955373, 'reachGoal', 'pay_debt_sbp_succes');
        console.log("Цель 'pay_debt_sbp_succes' отправлена в Яндекс.Метрику.");
      }
    } else if (status === 'AUTHORIZED') {
      console.log('Платеж в статусе AUTHORIZED, продолжаем опрос...');
    } else if (status !== 'FORM_SHOWED') {
      paymentError.value = `Ошибка оплаты: некорректный статус "${status}"`;
      globalStore.setIsError(true);
      if (pollingInterval) {
        clearInterval(pollingInterval);
        pollingInterval = null;
      }
    }
  } catch (error) {
    console.error('Ошибка при проверке статуса СБП:', error);
    paymentError.value =
      error instanceof Error
        ? error.message
        : 'Произошла ошибка при проверке статуса платежа.';
    globalStore.setIsError(true);
    if (pollingInterval) {
      clearInterval(pollingInterval);
      pollingInterval = null;
    }
  }
};

onMounted(async () => {
  globalStore.reset();

  if (!props.clientId) {
    paymentError.value = 'ID клиента не указан.';
    globalStore.setIsError(true);
    return;
  }

  try {
    if (props.method === 'card') {
      const canClientPay = await checkClient(props.clientId, +props.amount);
      if (!canClientPay.requestId) {
        paymentError.value = `Оплата для клиента ${props.clientId} невозможна (клиент заблокирован или отсутствует).`;
        globalStore.setIsError(true);
        return;
      }
      requestId = canClientPay.requestId;
    } else if (props.method === 'sbp') {
      const canClientPay = await checkId(props.clientId);
      if (!canClientPay) {
        paymentError.value = `Оплата для клиента ${props.clientId} невозможна (клиент заблокирован или отсутствует).`;
        globalStore.setIsError(true);
        return;
      }
    } else {
      paymentError.value = 'Метод оплаты не выбран.';
      globalStore.setIsError(true);
      return;
    }
  } catch (error) {
    console.error('Ошибка при проверке клиента:', error);
    paymentError.value =
      error instanceof Error
        ? error.message
        : 'Произошла ошибка при проверке статуса клиента.';
    globalStore.setIsError(true);
    return;
  }

  if (props.method === 'card') {
    if (!props.amount) {
      paymentError.value = 'Сумма для оплаты не указана.';
      globalStore.setIsError(true);
      return;
    }
    const priceAmount = parseFloat(props.amount);
    if (isNaN(priceAmount) || priceAmount <= 0) {
      paymentError.value = 'Некорректная сумма для оплаты.';
      globalStore.setIsError(true);
      return;
    }
    await handleCardPayment(props.clientId, priceAmount, props.email);
  } else if (props.method === 'sbp') {
    await handleSbpPayment(props.clientId, props.amount);
  }
});

const pageTitle = computed(() => {
  if (props.method === 'sbp') {
    return 'Оплата через СБП';
  }
  if (props.method === 'card') {
    return 'Оплата банковской картой';
  }
  return 'Процесс оплаты';
});

const pageSubtitle = computed(() => {
  if (props.method === 'sbp') {
    return 'Сканируйте QR-код для продолжения оплаты';
  }
  if (props.method === 'card') {
    return 'Используйте терминал оплаты';
  }
  return '';
});

watch(paymentQrCodeUrl, (newValue) => {
  if (newValue) {
    QRCode.toDataURL(newValue, { width: 400 }, (err, url) => {
      if (!err) {
        qrImage.value = url;
      } else {
        console.error('Ошибка при генерации QR:', err);
        qrImage.value = null;
      }
    });
  } else {
    qrImage.value = null;
  }
});

const displayImage = computed(() => {
  if (props.method === 'sbp') {
    if (qrImage.value && !paymentError.value && !sbpLoading.value) {
      return qrImage.value;
    }
    return null;
  }
  return picSrc;
});

onUnmounted(() => {
  if (pollingInterval) {
    clearInterval(pollingInterval);
    pollingInterval = null;
  }
});
</script>

<template>
  <section class="payment-procedure">
    <div v-if="!isPaymentSuccessful" class="payment-procedure__inner">
      <div class="payment-procedure__header">
        <VButton
          variant="primary"
          class="payment-procedure__btn"
          @click="goBack"
        >
          <IconArrowLeft />
          Назад
        </VButton>
      </div>
      <div class="payment-procedure__body">
        <h1
          class="payment-procedure__title"
          :style="{
            order:
              props.method === 'sbp' && !paymentError && !sbpLoading ? 0 : 1,
          }"
        >
          {{ pageTitle }}
        </h1>
        <div
          class="payment-procedure__subtitle"
          :style="{
            order:
              props.method === 'sbp' && !paymentError && !sbpLoading ? 1 : 2,
          }"
        >
          {{ pageSubtitle }}
        </div>
        <div
          class="payment-procedure__picture"
          :style="{
            order:
              props.method === 'sbp' && !paymentError && !sbpLoading ? 2 : 0,
          }"
        >
          <div
            v-if="props.method === 'sbp' && sbpLoading"
            class="payment-procedure__qr-loader"
          >
            <img
              :src="loaderSrc"
              width="128"
              height="128"
              alt="Загрузка..."
              class="payment-procedure__loader-img"
            />
          </div>
          <div
            v-else-if="displayImage"
            style="background-color: #faf5f7; border-radius: 30px; width: 400px"
          >
            <img
              :src="displayImage"
              alt="payment visualization"
              style="mix-blend-mode: multiply"
              width="400"
              height="400"
            />
          </div>
        </div>
      </div>
    </div>
    <!--    <ReceiptPrintPrompt-->
    <!--      v-else-->
    <!--      :amount="props.amount ? parseFloat(props.amount) : undefined"-->
    <!--      :client-id="props.clientId"-->
    <!--      @printReceipt="-->
    <!--        () => {-->
    <!--          goBack();-->
    <!--        }-->
    <!--      "-->
    <!--      @skipReceipt="-->
    <!--        () => {-->
    <!--          goBack();-->
    <!--        }-->
    <!--      "-->
    <!--    />-->
  </section>
</template>

<style scoped lang="scss">
.payment-procedure {
  height: 1475px;

  &__inner {
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: center;
  }

  &__header {
    align-self: flex-start;
  }

  &__body {
    text-align: center;
    flex-grow: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 40px;
  }

  &__picture {
    margin-bottom: 40px;
  }

  &__loader-img {
    animation: spin 1s linear infinite;
  }

  &__title {
    font-size: 64px;
  }

  &__subtitle {
    font-size: 32px;
    letter-spacing: 0.01em;
  }

  &__btn {
    font-size: 32px;
    min-width: 320px;
    min-height: 104px;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 18px;

    svg {
      width: 40px;
      height: 40px;
    }
  }

  &__error {
    color: var(--red-primary, #d32f2f);
    font-size: 24px;
    margin-top: 20px;
  }
}

@keyframes spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}
</style>

import { axiosInstance, paymentApi } from '@/shared/api/axiosInstance.ts';
import { reportError } from '@/entities/error';
import { formatErrorText } from '@/shared/utils';
import { bool } from 'yup';

export interface PaymentItem {
  title: string;
  count: number;
  price: number;
}

export interface PaymentData {
  items: PaymentItem[];
  phoneOrEmail: string;
  payStatus: boolean;
}

export interface PaymentQrResponse {
  ceid: string;
  amount: string;
  typePlatform?: string;
  ya_client_id?: string;
  payment_id: string;
  uid: string;
  url: string;
  sbp: string;
}

export interface GetPaymentQrParams {
  ceid: string;
  amount: number;
  typePlatform?: string;
  ya_client_id?: string;
}

export interface PaymentQrApiPayload {
  ceid: string;
  amount: string;
  typePlatform?: string;
  ya_client_id?: string;
}

export interface SuccessfulPayment {
  ceid: string;
  terminalId: number;
  price: number;
}

export interface StatusSBP {
  data: {
    uid: string;
    status: string;
    amount: string;
  };
}

export interface PaymentResponse {
  success: boolean;
}

export interface RegisterCardPayload {
  ceid: string;
  sum: number;
  dateTime: string;
  statusCheck: boolean;
  requestId: string;
  amountClear: number;
  amount: number;
  cardName: string;
  cardType: string;
  trxDate: string;
  trxTime: string;
  termNum: string;
  authCode: string;
  rrn: string;
  merchantTSN: string;
  merchantBatchNum: string;
  clientCard: string;
  clientExpireDate: string;
  hash: string;
  ownCard: number;
}

interface PaymentCardResponse {
  result: string;
  description: string;
  amountClear: string;
  amount: string;
  cardName: string;
  cardType: string;
  trxDate: string;
  trxTime: string;
  termNum: string;
  merchNum: string;
  authCode: string;
  rrn: string;
  merchantTSN: string;
  merchantBatchNum: string;
  clientCard: string;
  clientExpiryDate: string;
  hash: string;
  ownCard: number;
  loyaltyIdentifier: string;
  errorData: string;
}

interface CheckClient {
  ceid: string;
  sum: number;
  dateTime: string;
  statusCheck: boolean;
  requestId: string;
}

export async function paymentEvent(
  paymentData: PaymentData
): Promise<PaymentCardResponse> {
  try {
    const response = await paymentApi.post<PaymentCardResponse>(
      '/',
      paymentData,
      {
        headers: {
          'Content-Type': 'application/json; charset=utf-8',
        },
      }
    );
    return response.data;
  } catch (error) {
    await reportError(formatErrorText(error));
    throw new Error(
      `Payment event failed: ${error instanceof Error ? error.message : String(error)}`
    );
  }
}

export async function checkId(ceid: string): Promise<boolean> {
  try {
    const response = await axiosInstance.post<{ status: boolean }>(
      '/api/eos/checksId',
      { ceid }
    );
    return response.data.status;
  } catch (error) {
    await reportError(formatErrorText(error));
    throw new Error(
      `Client check failed for CEID ${ceid}: ${error instanceof Error ? error.message : String(error)}`
    );
  }
}

export async function checkClient(
  ceid: string,
  sum: number
): Promise<CheckClient> {
  try {
    const now = new Date();
    const dateTime = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}T${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}:${String(now.getSeconds()).padStart(2, '0')}`;

    const response = await axiosInstance.post<CheckClient>(
      '/api/eos/checkCard',
      {
        ceid,
        sum,
        dateTime,
      }
    );
    return response.data;
  } catch (error) {
    await reportError(formatErrorText(error));
    throw new Error(
      `Client check failed for CEID ${ceid}: ${error instanceof Error ? error.message : String(error)}`
    );
  }
}

export async function changeKKTStatus(id: number): Promise<boolean> {
  try {
    const response = await axiosInstance.post<{
      status: string;
      details: string;
    }>('/api/terminals/edit', { id, kkt: false });
    return response.data.status === 'success';
  } catch (error) {
    await reportError(formatErrorText(error));
    throw new Error(
      `KKT status update failed for terminal ${id}: ${error instanceof Error ? error.message : String(error)}`
    );
  }
}

export async function getPaymentQr(
  params: GetPaymentQrParams
): Promise<PaymentQrResponse> {
  try {
    const payload: PaymentQrApiPayload = {
      ceid: params.ceid,
      amount: String(params.amount),
      typePlatform: params.typePlatform || 'terminal',
      ...(params.ya_client_id && { ya_client_id: params.ya_client_id }),
    };

    const response = await axiosInstance.post<PaymentQrResponse>(
      '/api/eos/paymentSBP',
      payload
    );
    return response.data;
  } catch (error) {
    await reportError(formatErrorText(error));
    throw new Error(
      `QR-code generation failed: ${error instanceof Error ? error.message : String(error)}`
    );
  }
}

export async function sendPaymentConfirmation(
  params: SuccessfulPayment
): Promise<PaymentResponse> {
  try {
    const response = await axiosInstance.post<PaymentResponse>(
      '/api/payments',
      params
    );
    return response.data;
  } catch (error) {
    await reportError(formatErrorText(error));
    throw new Error(
      `Payment confirmation failed: ${error instanceof Error ? error.message : String(error)}`
    );
  }
}

export async function checkStatusSBP(uid: string): Promise<StatusSBP> {
  try {
    const response = await axiosInstance.post<StatusSBP>(
      '/api/eos/checkSBP',

      {
        uid,
      },
      { skipGlobalLoader: true }
    );
    return response.data;
  } catch (error) {
    await reportError(formatErrorText(error));
    throw new Error(
      `Payment confirmation failed: ${error instanceof Error ? error.message : String(error)}`
    );
  }
}

export async function registerCard(payload: RegisterCardPayload) {
  try {
    const response = await axiosInstance.post('/api/eos/registerCard', payload);
    return response.data;
  } catch (error) {
    await reportError(formatErrorText(error));
    throw new Error(
      `Register card failed: ${error instanceof Error ? error.message : String(error)}`
    );
  }
}