diff --git a/src/app/interceptors/mock-data.interceptor.ts b/src/app/interceptors/mock-data.interceptor.ts index 3f821ac..4384364 100644 --- a/src/app/interceptors/mock-data.interceptor.ts +++ b/src/app/interceptors/mock-data.interceptor.ts @@ -800,14 +800,6 @@ export const mockDataInterceptor: HttpInterceptorFn = (req, next) => { }, 300); } - // ── GET /qr/settings - if (url.endsWith('/qr/settings') && req.method === 'GET') { - return respond({ - minAmount: 30, - maxAmount: 200000, - }); - } - // ── POST /qr (create payment QR directly) if (url.endsWith('/qr') && req.method === 'POST') { return respond({ @@ -866,27 +858,7 @@ export const mockDataInterceptor: HttpInterceptorFn = (req, next) => { }, 500); } - // ── GET /qr/dynamic/:partnerID/:qrID (dynamic QR status) - if (url.match(/\/qr\/dynamic\/[^/]+\/[^/]+$/) && req.method === 'GET') { - return respond({ - status: 'APPROVED', - paymentStatus: 'COMPLETED', - code: 'SUCCESS', - amount: 0, - currency: 'RUB', - qrId: 'mock', - transactionId: 999, - transactionDate: new Date().toISOString(), - additionalInfo: '', - paymentPurpose: '', - createDate: new Date().toISOString(), - order: 'mock-order', - qrExpirationDate: new Date().toISOString(), - phoneNumber: '+70000000000' - }, 500); - } - - // ── GET /qr/payment/:qrId (legacy/direct payment status) + // ── GET /qr/payment/:qrId (payment status) if (url.match(/\/qr\/payment\/[^/]+$/) && req.method === 'GET') { return respond({ paymentStatus: 'COMPLETED', diff --git a/src/app/pages/cart/cart.component.ts b/src/app/pages/cart/cart.component.ts index 4e41a2f..f81fb4c 100644 --- a/src/app/pages/cart/cart.component.ts +++ b/src/app/pages/cart/cart.component.ts @@ -58,7 +58,6 @@ export class CartComponent implements OnDestroy { maxChecks = PAYMENT_MAX_CHECKS; private pollingSubscription?: Subscription; private closeTimeout?: ReturnType; - private qrPartnerId = ''; constructor( private cartService: CartService, @@ -160,7 +159,6 @@ export class CartComponent implements OnDestroy { openPaymentPopup(): void { this.showPaymentPopup.set(true); this.paymentStatus.set('creating'); - this.qrPartnerId = ''; this.paymentId.set(''); this.qrCodeUrl.set(''); this.paymentUrl.set(''); @@ -192,7 +190,6 @@ export class CartComponent implements OnDestroy { } this.paymentStatus.set('creating'); - this.qrPartnerId = ''; this.paymentId.set(''); this.qrCodeUrl.set(''); this.paymentUrl.set(''); @@ -202,12 +199,6 @@ export class CartComponent implements OnDestroy { createPayment(): void { const sessionId = this.authService.session()?.sessionId || ''; - const partnerQrId = this.getPartnerQrId(); - if (!partnerQrId) { - this.setPaymentError(); - return; - } - const cartItems = this.items().map((item: CartItem) => ({ itemID: item.itemID, quantity: item.quantity, @@ -227,22 +218,26 @@ export class CartComponent implements OnDestroy { ) : of(null); - const userIdValue = this.getUrlParam('userid-value') || undefined; - const authorizationKey = this.getUrlParam('authorization-key') || undefined; - const qrPayload = { - qrtype: 'QRDynamic' as const, + const paymentPayload = { amount: Number(this.totalPrice()), - currency: 'RUB' as const, - partnerqrID: partnerQrId, - qrDescription: `Order ${this.generateOrderId()}, total: ${this.totalPrice().toFixed(2)} ${this.currentCurrency}`, - Userid: userIdValue ?? this.getPaymentUserId(), - Reference: this.getUrlParam('ref') || (typeof window !== 'undefined' ? window.location.hostname : ''), - RedirectUrl: typeof window !== 'undefined' ? window.location.origin : undefined, + currency: this.currentCurrency, + siteuserID: this.getPaymentUserId(), + siteorderID: this.generateOrderId(), + redirectUrl: '', + telegramUsername: this.getTelegramUsername(), + items: this.items().map((item: CartItem) => ({ + itemID: item.itemID, + price: item.discount > 0 + ? item.price * (1 - item.discount / 100) + : item.price, + name: item.name, + quantity: item.quantity, + })), }; syncCart$ .pipe( - switchMap(() => this.apiService.createPayment(qrPayload, { authorizationKey, userIdValue })) + switchMap(() => this.apiService.createPayment(paymentPayload)) ) .subscribe({ next: (response) => { @@ -256,7 +251,6 @@ export class CartComponent implements OnDestroy { return; } - this.qrPartnerId = partnerQrId; this.paymentId.set(qrId); this.qrCodeUrl.set(qrUrl); this.paymentUrl.set(paymentLink); @@ -278,7 +272,7 @@ export class CartComponent implements OnDestroy { startPolling(): void { this.stopPolling(); - if (!this.qrPartnerId || !this.paymentId()) { + if (!this.paymentId()) { this.setPaymentError(); return; } @@ -287,7 +281,7 @@ export class CartComponent implements OnDestroy { .pipe( take(this.maxChecks), // maximum 36 checks (3 minutes) switchMap(() => { - return this.apiService.checkPaymentStatus(this.qrPartnerId, this.paymentId()).pipe( + return this.apiService.checkPaymentStatus(this.paymentId()).pipe( catchError((err) => { console.error('Error checking payment status:', err); return of(null); @@ -348,7 +342,6 @@ export class CartComponent implements OnDestroy { private setPaymentError(): void { this.paymentStatus.set('error'); this.stopPolling(); - this.qrPartnerId = ''; if (this.closeTimeout) { clearTimeout(this.closeTimeout); this.closeTimeout = undefined; @@ -452,24 +445,6 @@ export class CartComponent implements OnDestroy { return this.getTelegramUserId() ?? `web_${Date.now()}`; } - private getPartnerQrId(): string { - const fromQuery = this.getUrlParam('id'); - if (fromQuery) { - return fromQuery; - } - - const envValue = (environment as unknown as Record)['partnerqrID']; - return typeof envValue === 'string' ? envValue : ''; - } - - private getUrlParam(name: string): string | null { - if (typeof window === 'undefined') { - return null; - } - - return new URLSearchParams(window.location.search).get(name); - } - private generateOrderId(): string { const timestamp = Date.now(); const random = Math.random().toString(36).substring(2, 8); diff --git a/src/app/services/api.service.ts b/src/app/services/api.service.ts index fbefdd6..522c8c5 100644 --- a/src/app/services/api.service.ts +++ b/src/app/services/api.service.ts @@ -1,19 +1,18 @@ import { Injectable } from '@angular/core'; -import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http'; +import { HttpClient, HttpParams } from '@angular/common/http'; import { Observable, timer } from 'rxjs'; import { map, retry } from 'rxjs/operators'; import { Category, Item, Subcategory } from '../models'; import { environment } from '../../environments/environment'; -export interface QrCreateRequest { - qrtype: 'QRDynamic'; +export interface PaymentCreateRequest { amount: number; - currency: 'RUB'; - partnerqrID: string; - qrDescription?: string; - Userid?: string; - Reference?: string; - RedirectUrl?: string; + currency: string; + siteuserID: string; + siteorderID: string; + redirectUrl: string; + telegramUsername: string; + items: Array<{ itemID: number; price: number; name: string; quantity?: number }>; } export interface QrCreateResponse { @@ -34,8 +33,7 @@ export interface QrCreateResponse { PartnerID?: string | number; } -export interface QrStatusResponse { - status?: string; +export interface PaymentStatusResponse { additionalInfo: string; paymentPurpose: string; amount: number; @@ -393,23 +391,12 @@ export class ApiService { return this.http.post<{ message: string }>(`${this.baseUrl}/items/${itemID}/questiion`, body); } - createPayment(payload: QrCreateRequest, headers?: { authorizationKey?: string; userIdValue?: string }): Observable { - let httpHeaders = new HttpHeaders(); - - if (headers?.authorizationKey) { - httpHeaders = httpHeaders.set('authorization-key', headers.authorizationKey); - } - if (headers?.userIdValue) { - httpHeaders = httpHeaders.set('userid-value', headers.userIdValue); - } - - return this.http.post(`${this.baseUrl}/qr`, payload, { headers: httpHeaders }); + createPayment(payload: PaymentCreateRequest): Observable { + return this.http.post(`${this.baseUrl}/cart`, payload); } - checkPaymentStatus(partnerQrId: string, qrId: string): Observable { - return this.http.get( - `${this.baseUrl}/qr/dynamic/${encodeURIComponent(partnerQrId)}/${encodeURIComponent(qrId)}` - ); + checkPaymentStatus(qrId: string): Observable { + return this.http.get(`${this.baseUrl}/qr/payment/${encodeURIComponent(qrId)}`); } resolvePaymentQrId(response: QrCreateResponse): string {