diff options
| author | Adam Soltys <[email protected]> | 2026-10-02 07:10:15 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-10-02 07:10:15 -0700 |
| commit | c890225add1f5e88595f6ae9ce2a0a9d07d5f050 (patch) | |
| tree | e264ae87cbdf6cc92851f6c63cdb2aa6ea2c38a4 | |
| parent | 1213ac7a1f5f4f50f742aadebf970e37c186a234 (diff) | |
| download | coinos-ui-c890225add1f5e88595f6ae9ce2a0a9d07d5f050.tar.gz coinos-ui-c890225add1f5e88595f6ae9ce2a0a9d07d5f050.zip | |
send: explain duplicate submits instead of reporting a routing failure
Resubmitting an invoice that was already paid, is still in flight, or is
awaiting reconciliation came back as the generic "failed to route" error,
which reads as if the payment never went out. Map those server responses
to specific messages with a link to the payment history.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
| -rw-r--r-- | src/locales/ar.json | 3 | ||||
| -rw-r--r-- | src/locales/bn.json | 3 | ||||
| -rw-r--r-- | src/locales/de.json | 3 | ||||
| -rw-r--r-- | src/locales/el.json | 3 | ||||
| -rw-r--r-- | src/locales/en.json | 3 | ||||
| -rw-r--r-- | src/locales/es.json | 3 | ||||
| -rw-r--r-- | src/locales/fa.json | 3 | ||||
| -rw-r--r-- | src/locales/fr.json | 3 | ||||
| -rw-r--r-- | src/locales/hi.json | 3 | ||||
| -rw-r--r-- | src/locales/it.json | 3 | ||||
| -rw-r--r-- | src/locales/ja.json | 3 | ||||
| -rw-r--r-- | src/locales/ko.json | 3 | ||||
| -rw-r--r-- | src/locales/nl.json | 3 | ||||
| -rw-r--r-- | src/locales/pl.json | 3 | ||||
| -rw-r--r-- | src/locales/pt.json | 3 | ||||
| -rw-r--r-- | src/locales/ru.json | 3 | ||||
| -rw-r--r-- | src/locales/th.json | 3 | ||||
| -rw-r--r-- | src/locales/tr.json | 3 | ||||
| -rw-r--r-- | src/locales/zh.json | 3 | ||||
| -rw-r--r-- | src/routes/(app)/send/lightning/[payreq]/[...memo]/+page.svelte | 17 |
20 files changed, 74 insertions, 0 deletions
diff --git a/src/locales/ar.json b/src/locales/ar.json index 3f335609..e858e59e 100644 --- a/src/locales/ar.json +++ b/src/locales/ar.json @@ -405,6 +405,9 @@ "ok": "حسناً", "cancel": "إلغاء", "failedToRoute": "ولا يمكن الوصول إلى المتلقي إذا لم يتم الدفع على الطريق. حاول إرسال كمية أصغر أو زيادة احتياطي رسوم الحد الأقصى.", + "alreadyPaid": "تم دفع هذه الفاتورة بالفعل. تحقق من سجل مدفوعاتك.", + "alreadyUnderway": "هذه الدفعة قيد التنفيذ بالفعل. تحقق من سجل مدفوعاتك قبل المحاولة مرة أخرى.", + "stillSettling": "لا تزال محاولة سابقة لدفع هذه الفاتورة قيد التسوية. يرجى المحاولة مرة أخرى بعد دقيقة.", "message": "الرسالة", "enterWalletPass": "كلمة السر", "legacyVersion": "النسخة الأصلية", diff --git a/src/locales/bn.json b/src/locales/bn.json index fedccebf..ca5e81f8 100644 --- a/src/locales/bn.json +++ b/src/locales/bn.json @@ -405,6 +405,9 @@ "ok": "ঠিক আছে", "cancel": "বাতিল", "failedToRoute": "টাকা প্রদান করতে ব্যর্থ, সম্ভবত নিম্নলিখিত ঠিকানায় প্রেরিত হবে। সামান্য বড় অঙ্কের টাকা দিয়ে অথবা তার মূল্য বাড়ানোর চেষ্টা করুন।.", + "alreadyPaid": "এই ইনভয়েসটি ইতিমধ্যে পরিশোধ করা হয়েছে। আপনার পেমেন্টের ইতিহাস দেখুন।", + "alreadyUnderway": "এই পেমেন্টটি ইতিমধ্যে প্রক্রিয়াধীন। আবার চেষ্টা করার আগে আপনার পেমেন্টের ইতিহাস দেখুন।", + "stillSettling": "এই ইনভয়েস পরিশোধের আগের একটি চেষ্টা এখনও সম্পন্ন হচ্ছে। অনুগ্রহ করে এক মিনিট পরে আবার চেষ্টা করুন।", "message": "বার্তা", "enterWalletPass": "ওয়ালেট পাসওয়ার্ড", "legacyVersion": "লিগ্যাসি সংস্করণ", diff --git a/src/locales/de.json b/src/locales/de.json index 3b4e7061..b4769cfd 100644 --- a/src/locales/de.json +++ b/src/locales/de.json @@ -466,6 +466,9 @@ "amountPrompt": "Immer nach dem Betrag fragen", "enterWalletPass": "Wallet-Passwort", "failedToRoute": "Die Weiterleitung der Zahlung ist fehlgeschlagen. Der Empfänger ist möglicherweise nicht erreichbar. Versuchen Sie, einen kleineren Betrag zu senden oder die maximale Gebührenreserve zu erhöhen.", + "alreadyPaid": "Diese Rechnung wurde bereits bezahlt. Prüfe deinen Zahlungsverlauf.", + "alreadyUnderway": "Diese Zahlung wird bereits ausgeführt. Prüfe deinen Zahlungsverlauf, bevor du es erneut versuchst.", + "stillSettling": "Ein vorheriger Zahlungsversuch für diese Rechnung wird noch abgeschlossen. Bitte versuche es in einer Minute erneut.", "ok": "Ok", "cancel": "Abbrechen", "message": "Nachricht", diff --git a/src/locales/el.json b/src/locales/el.json index 166b8159..b2dba1cc 100644 --- a/src/locales/el.json +++ b/src/locales/el.json @@ -457,6 +457,9 @@ "amountPrompt": "Πάντα προτροπή για ποσό", "enterWalletPass": "Κωδικός πρόσβασης πορτοφολιού", "failedToRoute": "Η δρομολόγηση της πληρωμής απέτυχε, ο παραλήπτης ενδέχεται να μην είναι προσβάσιμος. Δοκιμάστε να στείλετε ένα μικρότερο ποσό ή να αυξήσετε το μέγιστο απόθεμα χρέωσης.", + "alreadyPaid": "Αυτό το τιμολόγιο έχει ήδη πληρωθεί. Ελέγξτε το ιστορικό πληρωμών σας.", + "alreadyUnderway": "Αυτή η πληρωμή βρίσκεται ήδη σε εξέλιξη. Ελέγξτε το ιστορικό πληρωμών σας πριν δοκιμάσετε ξανά.", + "stillSettling": "Μια προηγούμενη προσπάθεια πληρωμής αυτού του τιμολογίου ολοκληρώνεται ακόμα. Δοκιμάστε ξανά σε ένα λεπτό.", "ok": "Εντάξει", "cancel": "Ακύρωση", "message": "Μήνυμα", diff --git a/src/locales/en.json b/src/locales/en.json index b602bd01..17decb28 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -433,6 +433,9 @@ "ok": "Ok", "cancel": "Cancel", "failedToRoute": "Failed to route payment, recipient may not be reachable. Try sending a smaller amount or increasing the max fee reserve.", + "alreadyPaid": "This invoice has already been paid. Check your payment history.", + "alreadyUnderway": "This payment is already in progress. Check your payment history before trying again.", + "stillSettling": "A previous attempt to pay this invoice is still settling. Please try again in a minute.", "message": "Message", "enterWalletPass": "Wallet password", "legacyVersion": "Legacy version", diff --git a/src/locales/es.json b/src/locales/es.json index fc762f69..fcc52260 100644 --- a/src/locales/es.json +++ b/src/locales/es.json @@ -440,6 +440,9 @@ "amountPrompt": "Siempre solicite la cantidad", "enterWalletPass": "Contraseña de la billetera", "failedToRoute": "No se pudo enviar el pago; es posible que no se pueda contactar al destinatario. Intente enviar un monto menor o aumentar la reserva de tarifa máxima.", + "alreadyPaid": "Esta factura ya fue pagada. Revisa tu historial de pagos.", + "alreadyUnderway": "Este pago ya está en curso. Revisa tu historial de pagos antes de intentarlo de nuevo.", + "stillSettling": "Un intento anterior de pagar esta factura aún se está procesando. Inténtalo de nuevo en un minuto.", "ok": "Ok", "cancel": "Cancelar", "message": "Mensaje", diff --git a/src/locales/fa.json b/src/locales/fa.json index 6855f22e..f6d6e279 100644 --- a/src/locales/fa.json +++ b/src/locales/fa.json @@ -439,6 +439,9 @@ "amountPrompt": "همیشه مقدار را درخواست کنید", "enterWalletPass": "رمز کیف پول", "failedToRoute": "مسیر پرداخت انجام نشد، ممکن است گیرنده قابل دسترسی نباشد. سعی کنید مبلغ کمتری ارسال کنید یا حداکثر ذخیره هزینه را افزایش دهید.", + "alreadyPaid": "این صورتحساب قبلاً پرداخت شده است. تاریخچه پرداختهای خود را بررسی کنید.", + "alreadyUnderway": "این پرداخت در حال انجام است. پیش از تلاش دوباره، تاریخچه پرداختهای خود را بررسی کنید.", + "stillSettling": "تلاش قبلی برای پرداخت این صورتحساب هنوز در حال تسویه است. لطفاً یک دقیقه دیگر دوباره تلاش کنید.", "ok": "Ok", "cancel": "لغو", "message": "پیام", diff --git a/src/locales/fr.json b/src/locales/fr.json index dafc9749..fdb04b31 100644 --- a/src/locales/fr.json +++ b/src/locales/fr.json @@ -439,6 +439,9 @@ "amountPrompt": "Toujours demander le montant", "enterWalletPass": "Mot de passe du portefeuille", "failedToRoute": "Impossible d'acheminer le paiement, le destinataire n'est peut-être pas joignable. Essayez d'envoyer un montant inférieur ou d'augmenter les frais de transaction.", + "alreadyPaid": "Cette facture a déjà été payée. Consultez votre historique de paiements.", + "alreadyUnderway": "Ce paiement est déjà en cours. Consultez votre historique de paiements avant de réessayer.", + "stillSettling": "Une tentative précédente de payer cette facture est encore en cours de règlement. Réessayez dans une minute.", "ok": "ok", "cancel": "Annuler", "message": "Message", diff --git a/src/locales/hi.json b/src/locales/hi.json index 974155e3..8ea0b43d 100644 --- a/src/locales/hi.json +++ b/src/locales/hi.json @@ -405,6 +405,9 @@ "ok": "ठीक है", "cancel": "रद्द करना", "failedToRoute": "भुगतान करने में विफल, प्राप्तकर्ता पहुंच योग्य नहीं हो सकता है। एक छोटी राशि भेजने या अधिकतम शुल्क आरक्षित बढ़ाने की कोशिश करें।.", + "alreadyPaid": "इस इनवॉइस का भुगतान पहले ही हो चुका है। अपना भुगतान इतिहास देखें।", + "alreadyUnderway": "यह भुगतान पहले से प्रगति में है। दोबारा कोशिश करने से पहले अपना भुगतान इतिहास देखें।", + "stillSettling": "इस इनवॉइस के भुगतान का पिछला प्रयास अभी पूरा हो रहा है। कृपया एक मिनट बाद फिर कोशिश करें।", "message": "संदेश", "enterWalletPass": "वॉलेट पासवर्ड", "legacyVersion": "विरासत संस्करण", diff --git a/src/locales/it.json b/src/locales/it.json index b4a1bb49..a5986b4f 100644 --- a/src/locales/it.json +++ b/src/locales/it.json @@ -405,6 +405,9 @@ "ok": "Ok", "cancel": "Annulla", "failedToRoute": "Impossibile inoltrare il pagamento, il destinatario potrebbe non essere raggiungibile. Prova ad inviare un importo inferiore o aumentando la quota di commissione.", + "alreadyPaid": "Questa fattura è già stata pagata. Controlla la cronologia dei pagamenti.", + "alreadyUnderway": "Questo pagamento è già in corso. Controlla la cronologia dei pagamenti prima di riprovare.", + "stillSettling": "Un tentativo precedente di pagare questa fattura è ancora in elaborazione. Riprova tra un minuto.", "message": "Messaggio", "enterWalletPass": "Portafoglio password", "legacyVersion": "Versione legacy", diff --git a/src/locales/ja.json b/src/locales/ja.json index 365f8128..9fef5307 100644 --- a/src/locales/ja.json +++ b/src/locales/ja.json @@ -439,6 +439,9 @@ "amountPrompt": "常に金額の入力を求める", "enterWalletPass": "ウォレットパスワード", "failedToRoute": "支払いのルーティングに失敗しました。受取人に連絡が取れない可能性があります。送金金額を減らすか、最大手数料準備金を増やしてみてください。", + "alreadyPaid": "この請求書はすでに支払われています。支払い履歴をご確認ください。", + "alreadyUnderway": "この支払いはすでに処理中です。もう一度試す前に支払い履歴をご確認ください。", + "stillSettling": "この請求書への以前の支払いがまだ確定処理中です。1分後にもう一度お試しください。", "ok": "お問い合わせ", "cancel": "キャンセル", "message": "メッセージ", diff --git a/src/locales/ko.json b/src/locales/ko.json index e1db706a..7333cc69 100644 --- a/src/locales/ko.json +++ b/src/locales/ko.json @@ -405,6 +405,9 @@ "ok": "·", "cancel": "이름 *", "failedToRoute": "결제에 실패, 수신자는 도달 할 수 없습니다. 더 작은 금액을 보내거나 최대 수수료 예약을 증가하십시오.", + "alreadyPaid": "이 인보이스는 이미 결제되었습니다. 결제 내역을 확인하세요.", + "alreadyUnderway": "이 결제는 이미 진행 중입니다. 다시 시도하기 전에 결제 내역을 확인하세요.", + "stillSettling": "이 인보이스에 대한 이전 결제 시도가 아직 정산 중입니다. 1분 후에 다시 시도하세요.", "message": "이름 *", "enterWalletPass": "지갑 암호", "legacyVersion": "Legacy 버전", diff --git a/src/locales/nl.json b/src/locales/nl.json index 5cbf3438..f385e743 100644 --- a/src/locales/nl.json +++ b/src/locales/nl.json @@ -405,6 +405,9 @@ "ok": "Ok", "cancel": "Annuleren", "failedToRoute": "Het is mogelijk dat de ontvanger niet bereikbaar is. Probeer het verzenden van een kleiner bedrag of controleer met de ontvanger.", + "alreadyPaid": "Deze factuur is al betaald. Bekijk je betalingsgeschiedenis.", + "alreadyUnderway": "Deze betaling is al bezig. Bekijk je betalingsgeschiedenis voordat je het opnieuw probeert.", + "stillSettling": "Een eerdere poging om deze factuur te betalen wordt nog afgehandeld. Probeer het over een minuut opnieuw.", "message": "Notitie", "enterWalletPass": "Wachtwoord portemonnee", "legacyVersion": "Legacy versie", diff --git a/src/locales/pl.json b/src/locales/pl.json index 05e5b6d7..657a9ecd 100644 --- a/src/locales/pl.json +++ b/src/locales/pl.json @@ -405,6 +405,9 @@ "ok": "Ok", "cancel": "Anuluj", "failedToRoute": "Nie udało się dokonać płatności za trasę, odbiorca może nie być dostępny. Spróbuj wysłać mniejszą kwotę lub zwiększenie maksymalnej rezerwy opłat.", + "alreadyPaid": "Ta faktura została już opłacona. Sprawdź historię płatności.", + "alreadyUnderway": "Ta płatność jest już w toku. Sprawdź historię płatności przed ponowną próbą.", + "stillSettling": "Poprzednia próba opłacenia tej faktury jest wciąż rozliczana. Spróbuj ponownie za minutę.", "message": "Wiadomość", "enterWalletPass": "Hasło portfela", "legacyVersion": "Wersja w języku litewskim", diff --git a/src/locales/pt.json b/src/locales/pt.json index 480bc51d..eaa92c9b 100644 --- a/src/locales/pt.json +++ b/src/locales/pt.json @@ -461,6 +461,9 @@ "amountPrompt": "Sempre solicite o valor", "enterWalletPass": "Senha da carteira", "failedToRoute": "Falha ao encaminhar o pagamento, o destinatário pode não estar acessível. Tente enviar uma quantia menor ou aumentar a reserva de taxa máxima.", + "alreadyPaid": "Esta fatura já foi paga. Confira seu histórico de pagamentos.", + "alreadyUnderway": "Este pagamento já está em andamento. Confira seu histórico de pagamentos antes de tentar novamente.", + "stillSettling": "Uma tentativa anterior de pagar esta fatura ainda está sendo concluída. Tente novamente em um minuto.", "ok": "Ok", "cancel": "Cancelar", "message": "Mensagem", diff --git a/src/locales/ru.json b/src/locales/ru.json index a71c74e4..e4e5773d 100644 --- a/src/locales/ru.json +++ b/src/locales/ru.json @@ -439,6 +439,9 @@ "amountPrompt": "Всегда запрашивать сумму", "enterWalletPass": "Пароль кошелька", "failedToRoute": "Не удалось направить платеж, получатель может быть недоступен. Попробуйте отправить меньшую сумму или увеличить максимальный резерв комиссии.", + "alreadyPaid": "Этот счёт уже оплачен. Проверьте историю платежей.", + "alreadyUnderway": "Этот платёж уже выполняется. Проверьте историю платежей, прежде чем пробовать снова.", + "stillSettling": "Предыдущая попытка оплатить этот счёт ещё обрабатывается. Попробуйте снова через минуту.", "ok": "Хорошо", "cancel": "Отменить", "message": "Сообщение", diff --git a/src/locales/th.json b/src/locales/th.json index 85c524db..21b108f0 100644 --- a/src/locales/th.json +++ b/src/locales/th.json @@ -405,6 +405,9 @@ "ok": "โอเค", "cancel": "ยกเลิก", "failedToRoute": "การจ่ายเงินตามเส้นทางล้มเหลว อาจไม่สามารถเข้าถึงผู้รับได้ ลอง ส่ง เงิน ที่ มี ค่า น้อย กว่า หรือ ทํา การ เพิ่ม อัตรา ค่า ธรรมเนียม ให้ มาก ที่ สุด.", + "alreadyPaid": "ใบแจ้งหนี้นี้ชำระแล้ว โปรดตรวจสอบประวัติการชำระเงินของคุณ", + "alreadyUnderway": "การชำระเงินนี้กำลังดำเนินการอยู่แล้ว โปรดตรวจสอบประวัติการชำระเงินก่อนลองอีกครั้ง", + "stillSettling": "ความพยายามชำระใบแจ้งหนี้นี้ครั้งก่อนยังอยู่ระหว่างดำเนินการ โปรดลองอีกครั้งในอีกหนึ่งนาที", "message": "จดหมาย", "enterWalletPass": "รหัสผ่านของกระเป๋าคุมข้อมูล", "legacyVersion": "รุ่นของมรดก", diff --git a/src/locales/tr.json b/src/locales/tr.json index d2248713..218f9db1 100644 --- a/src/locales/tr.json +++ b/src/locales/tr.json @@ -405,6 +405,9 @@ "ok": "Tamam", "cancel": "Cancel", "failedToRoute": "Yol ödemesine başarısız oldu, alıcı ulaşılamaz olabilir. Daha küçük bir miktar göndermeye veya maksimum ücret rezervini arttırmaya çalışın.", + "alreadyPaid": "Bu fatura zaten ödendi. Ödeme geçmişinizi kontrol edin.", + "alreadyUnderway": "Bu ödeme zaten devam ediyor. Tekrar denemeden önce ödeme geçmişinizi kontrol edin.", + "stillSettling": "Bu faturayı ödemek için önceki bir deneme hâlâ tamamlanıyor. Lütfen bir dakika sonra tekrar deneyin.", "message": "Mesaj", "enterWalletPass": "Cüzdan şifresi", "legacyVersion": "Legacy Version", diff --git a/src/locales/zh.json b/src/locales/zh.json index 0d887ba4..8a785f06 100644 --- a/src/locales/zh.json +++ b/src/locales/zh.json @@ -439,6 +439,9 @@ "amountPrompt": "始终提示金额", "enterWalletPass": "钱包密码", "failedToRoute": "付款路线失败,收款人可能无法联系到。请尝试发送较少的金额或增加最大费用储备。", + "alreadyPaid": "此发票已支付。请查看您的付款记录。", + "alreadyUnderway": "此付款正在进行中。请在重试前查看您的付款记录。", + "stillSettling": "此前对该发票的付款尝试仍在结算中。请一分钟后再试。", "ok": "确认", "cancel": "取消", "message": "消息", diff --git a/src/routes/(app)/send/lightning/[payreq]/[...memo]/+page.svelte b/src/routes/(app)/send/lightning/[payreq]/[...memo]/+page.svelte index d3d9f757..7b42a42d 100644 --- a/src/routes/(app)/send/lightning/[payreq]/[...memo]/+page.svelte +++ b/src/routes/(app)/send/lightning/[payreq]/[...memo]/+page.svelte @@ -48,6 +48,20 @@ (form.message.includes($t("payments.insufficientFunds")) || form.message.includes("Routing fee")), ); + + // A resubmitted invoice (back button, double tap) isn't a routing failure — + // the first attempt went through or is still in flight. Say so instead of + // telling the user the recipient is unreachable. + let duplicate = $derived( + form?.message && + (/already (been )?paid/i.test(form.message) + ? "payments.alreadyPaid" + : form.message.includes("already underway") + ? "payments.alreadyUnderway" + : form.message.includes("still settling") + ? "payments.stillSettling" + : null), + ); </script> <div class="container px-4 max-w-xl mx-auto text-center space-y-2"> @@ -58,6 +72,9 @@ {#if form.message.includes($t("payments.insufficientFunds"))} <div>{$t("payments.lockedBalance")}: {locked}</div> {/if} + {:else if duplicate} + <div>{$t(duplicate)}</div> + <a href="/payments" class="underline">{$t("payments.header")}</a> {:else} {$t("payments.failedToRoute")} {/if} |
