diff --git a/src/app/i18n/en.ts b/src/app/i18n/en.ts
index c8d811d..ae76e39 100644
--- a/src/app/i18n/en.ts
+++ b/src/app/i18n/en.ts
@@ -123,6 +123,9 @@ export const en: Translations = {
emailNeedsAt: 'Email must contain @',
emailNeedsDomain: 'Email must contain a domain (.com, .ru, etc.)',
emailInvalid: 'Invalid email format',
+ telegramIdMissing: 'We could not identify your Telegram account, so we could not save your contact details. Your payment was still successful.',
+ emailPlaceholder: 'you@example.com',
+ phonePlaceholder: '+7 (___) ___-__-__',
loginRequired: 'Log in to checkout',
loginRequiredDesc: 'Please log in via Telegram to place your order',
loginWithTelegram: 'Log in with Telegram',
diff --git a/src/app/i18n/hy.ts b/src/app/i18n/hy.ts
index 2d8c342..8c471d9 100644
--- a/src/app/i18n/hy.ts
+++ b/src/app/i18n/hy.ts
@@ -123,6 +123,9 @@ export const hy: Translations = {
emailNeedsAt: 'Email-ը պետք է պարունակի @',
emailNeedsDomain: 'Email-ը պետք է պարունակի դոմեյն (.com, .ru և այլն)',
emailInvalid: 'Սխալ email ձևաչափ',
+ telegramIdMissing: 'Չհաջողվեց հաստատել ձեր Telegram հաշիվը, ուստի կոնտակտային տվյալները չեն պահպանվել։ Վճարումը հաջողությամբ կատարվել է։',
+ emailPlaceholder: 'you@example.com',
+ phonePlaceholder: '+7 (___) ___-__-__',
loginRequired: 'Մուտք գործեք ձևակերպելու համար',
loginRequiredDesc: 'Պատվեր ձևակերպելու համար մուտք գործեք Telegram-ով',
loginWithTelegram: 'Մուտք Telegram-ով',
diff --git a/src/app/i18n/ru.ts b/src/app/i18n/ru.ts
index 5cdfdef..5f9d6dd 100644
--- a/src/app/i18n/ru.ts
+++ b/src/app/i18n/ru.ts
@@ -123,6 +123,9 @@ export const ru: Translations = {
emailNeedsAt: 'Email должен содержать @',
emailNeedsDomain: 'Email должен содержать домен (.com, .ru и т.д.)',
emailInvalid: 'Некорректный формат email',
+ telegramIdMissing: 'Не удалось определить ваш Telegram-аккаунт, поэтому контактные данные не сохранены. Оплата прошла успешно.',
+ emailPlaceholder: 'you@example.com',
+ phonePlaceholder: '+7 (___) ___-__-__',
loginRequired: 'Войдите для оформления',
loginRequiredDesc: 'Для оформления заказа войдите через Telegram',
loginWithTelegram: 'Войти через Telegram',
diff --git a/src/app/i18n/translations.ts b/src/app/i18n/translations.ts
index 8f8592d..2a9d780 100644
--- a/src/app/i18n/translations.ts
+++ b/src/app/i18n/translations.ts
@@ -121,6 +121,9 @@ export interface Translations {
emailNeedsAt: string;
emailNeedsDomain: string;
emailInvalid: string;
+ telegramIdMissing: string;
+ emailPlaceholder: string;
+ phonePlaceholder: string;
loginRequired: string;
loginRequiredDesc: string;
loginWithTelegram: string;
diff --git a/src/app/pages/cart/cart.component.html b/src/app/pages/cart/cart.component.html
index a6df206..2bfb1b9 100644
--- a/src/app/pages/cart/cart.component.html
+++ b/src/app/pages/cart/cart.component.html
@@ -271,6 +271,44 @@
✓
{{ 'cart.paymentSuccess' | translate }}
+ @if (!purchaseSubmitted()) {
+
{{ 'cart.paymentSuccessDesc' | translate }}
+
+ }
}
diff --git a/src/app/pages/cart/cart.component.scss b/src/app/pages/cart/cart.component.scss
index 3f1c608..759b0f8 100644
--- a/src/app/pages/cart/cart.component.scss
+++ b/src/app/pages/cart/cart.component.scss
@@ -722,6 +722,57 @@
color: white;
margin: 0 auto 20px;
}
+
+ .contact-capture-form {
+ display: flex;
+ flex-direction: column;
+ gap: 12px;
+ margin-top: 16px;
+ text-align: left;
+
+ label {
+ display: flex;
+ flex-direction: column;
+ gap: 4px;
+ }
+
+ input {
+ padding: 10px 12px;
+ border: 1px solid var(--border-color);
+ border-radius: var(--radius-md, 8px);
+ font-size: var(--font-size-sm, 0.875rem);
+ color: var(--text-primary);
+ background: var(--surface-color, #fff);
+
+ &[aria-invalid='true'] {
+ border-color: var(--error-color);
+ }
+
+ &:disabled {
+ opacity: 0.6;
+ }
+ }
+
+ .field-error {
+ font-size: var(--font-size-xs, 0.75rem);
+ color: var(--error-color);
+ }
+
+ button {
+ padding: 10px 16px;
+ border: none;
+ border-radius: var(--radius-md, 8px);
+ background: var(--primary-color, #2563eb);
+ color: white;
+ font-weight: var(--font-weight-bold, 700);
+ cursor: pointer;
+
+ &:disabled {
+ opacity: 0.6;
+ cursor: default;
+ }
+ }
+ }
}
&.error {
diff --git a/src/app/pages/cart/cart.component.ts b/src/app/pages/cart/cart.component.ts
index 77ec385..a5cb02d 100644
--- a/src/app/pages/cart/cart.component.ts
+++ b/src/app/pages/cart/cart.component.ts
@@ -71,6 +71,7 @@ export class CartComponent implements OnDestroy {
emailError = signal('');
phoneError = signal('');
emailSubmitting = signal(false);
+ purchaseSubmitted = signal(false);
paidItems: CartItem[] = [];
maxChecks = Math.ceil(PAYMENT_MIN_POLL_SECONDS / (PAYMENT_POLL_INTERVAL_MS / 1000));
@@ -219,6 +220,7 @@ export class CartComponent implements OnDestroy {
this.emailError.set('');
this.phoneError.set('');
this.emailSubmitting.set(false);
+ this.purchaseSubmitted.set(false);
this.paidItems = [...this.items()];
this.createPayment(paymentMethod);
}
@@ -439,29 +441,39 @@ export class CartComponent implements OnDestroy {
});
}
+ /**
+ * Fallback fired a few seconds after payment success if the user hasn't
+ * already submitted the email/phone form themselves (submitEmail()).
+ * Navigates home only once the submission result is known, never before -
+ * and sends whatever the user has typed so far instead of blank fields.
+ */
private autoSubmitPurchase(): void {
- setTimeout(() => {
- const lang = this.langService.currentLanguage();
- this.router.navigate([`/${lang}`]);}, 0);
- const telegramUserId = this.getTelegramUserId();
-
- // Telegram ID is mandatory
- if (!telegramUserId) {
- console.error('Cannot submit purchase: Telegram ID is required');
- this.emailSubmitting.set(false);
+ if (this.purchaseSubmitted()) {
return;
}
-
+
+ const telegramUserId = this.getTelegramUserId();
+
+ // Telegram ID is mandatory for submitPurchaseEmail.
+ if (!telegramUserId) {
+ this.notifications.show(this.i18n.t('cart.telegramIdMissing'), 'warning');
+ this.emailSubmitting.set(false);
+ this.closePaymentPopup();
+ const lang = this.langService.currentLanguage();
+ this.router.navigate([`/${lang}`]);
+ return;
+ }
+
this.emailSubmitting.set(true);
-
+
const emailData = {
- email: '',
- phone: '',
+ email: this.userEmail().trim(),
+ phone: this.userPhone().replace(/\D/g, ''),
telegramUserId: telegramUserId,
items: this.paidItems.map((item: CartItem) => ({
itemID: item.itemID,
name: item.name,
- price: item.discount > 0
+ price: item.discount > 0
? item.price * (1 - item.discount / 100)
: item.price,
currency: item.currency,
@@ -469,9 +481,10 @@ export class CartComponent implements OnDestroy {
...(item.selectedDelivery ? { delivery: [item.selectedDelivery] } : {})
}))
};
-
+
this.apiService.submitPurchaseEmail(emailData).subscribe({
next: () => {
+ this.purchaseSubmitted.set(true);
this.emailSubmitting.set(false);
this.closePaymentPopup();
const lang = this.langService.currentLanguage();
@@ -487,8 +500,6 @@ export class CartComponent implements OnDestroy {
}
});
this.paymentStatus.set(null);
-
-
}
copyPaymentLink(): void {
@@ -541,6 +552,11 @@ export class CartComponent implements OnDestroy {
this.apiService.submitPurchaseEmail(emailData).subscribe({
next: () => {
+ this.purchaseSubmitted.set(true);
+ if (this.closeTimeout) {
+ clearTimeout(this.closeTimeout);
+ this.closeTimeout = undefined;
+ }
this.emailSubmitting.set(false);
this.notifications.show(this.i18n.t('cart.emailSuccess'), 'success');
// Close popup and redirect to home page