Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
2026-05-05 01:45:46 +04:00
parent 28a1d1be8b
commit b238282569
2 changed files with 31 additions and 18 deletions

View File

@@ -18,15 +18,18 @@ interface SettingsResponse {
interface CreateQrResponse {
qrId?: string;
payload?: string; // raw QR data string to encode
qrUrl?: string; // pre-rendered image URL (if provided)
Status?: boolean;
nspkID?: string;
Payload?: string; // per API doc (capital P)
nspkurl?: string; // actual field name in real responses
qrUrl?: string;
qrStatus?: string;
[key: string]: unknown;
}
interface QrStatusResponse {
qrStatus?: string; // e.g. "PAID"
Status?: boolean;
status?: string; // "NEW" | "APPROVED" | "REJECTED" | "COMPLETED"
nspkurl?: string;
nspkID?: string;
[key: string]: unknown;
}
@@ -154,14 +157,16 @@ export class CreatePage {
.subscribe({
next: (res) => {
this.loading.set(false);
if (res?.qrId || res?.payload || res?.qrUrl) {
this.activeQrId = res.qrId ?? '';
// Use server-provided image URL or generate one from payload string.
const qrData = res.qrUrl ?? (res.payload
? `https://api.qrserver.com/v1/create-qr-code/?size=240x240&margin=8&data=${encodeURIComponent(res.payload)}`
: null);
const qrId = res?.qrId ?? res?.nspkID ?? '';
// Real API uses 'nspkurl'; doc says 'Payload' — try both
const nspkUrl = res?.nspkurl ?? res?.Payload;
if (qrId || nspkUrl) {
this.activeQrId = qrId;
const qrData = nspkUrl
? `https://api.qrserver.com/v1/create-qr-code/?size=256x256&margin=8&data=${encodeURIComponent(nspkUrl)}`
: (res.qrUrl ?? null);
this.qrImageUrl.set(qrData);
if (this.activeQrId) this.startPolling(this.activeQrId);
if (qrId) this.startPolling(qrId);
} else {
this.error.set(this.t('errors.payment_failed'));
}
@@ -181,10 +186,14 @@ export class CreatePage {
this.http.get<QrStatusResponse>(`${QR_VITANOVA_API}/qr/dynamic/${qrId}`)
.subscribe({
next: (res) => {
const paid = res?.qrStatus === 'PAID' || res?.Status === true;
if (paid) {
// API returns status: "NEW" | "APPROVED" | "REJECTED" | "COMPLETED"
if (res?.status === 'COMPLETED' || res?.status === 'APPROVED') {
this.stopPolling();
this.createFastcheck();
} else if (res?.status === 'REJECTED') {
this.stopPolling();
this.error.set(this.t('errors.payment_failed'));
this.qrImageUrl.set(null);
}
},
error: () => undefined

View File

@@ -17,7 +17,7 @@ interface WebSessionResponse {
interface CheckFastcheckResponse {
fastcheck: string;
amount?: number;
amount?: number; // not in doc but server may include it
expiration: string;
Status: boolean;
message?: string;
@@ -237,13 +237,17 @@ export class FastcheckPage {
this.fastcheckAmount.set(null);
this.codeEnabled.set(false);
// API doc: GET /fastcheck with fastcheck as query param
this.http
.get<CheckFastcheckResponse>(`${FASTCHECK_API}/fastcheck/${encodeURIComponent(number)}`)
.get<CheckFastcheckResponse>(`${FASTCHECK_API}/fastcheck`, {
params: { fastcheck: number }
})
.subscribe({
next: (res) => {
this.amountLoading.set(false);
if (res?.Status && typeof res.amount === 'number') {
this.fastcheckAmount.set(res.amount);
if (res?.Status) {
// amount may or may not be in response — show if present
this.fastcheckAmount.set(typeof res.amount === 'number' ? res.amount : null);
this.codeEnabled.set(true);
} else {
this.error.set(res?.message ?? this.t('errors.not_found'));