From fde4a45c4a05c950aebb538865219a89d3c22a9b Mon Sep 17 00:00:00 2001
From: yyg-max <175597134+yyg-max@users.noreply.github.com>
Date: Wed, 15 Jul 2026 14:27:35 +0800
Subject: [PATCH 1/2] fix(payment): allow users to resume pending payments
---
.../common/receive/ReceiveContent.tsx | 92 ++++++++++++++-
frontend/lib/services/payment/index.ts | 2 +
.../lib/services/payment/payment.service.ts | 23 ++++
frontend/lib/services/payment/types.ts | 9 ++
internal/apps/payment/err.go | 2 +-
internal/apps/payment/router.go | 38 ++++++
internal/apps/payment/service.go | 109 ++++++++++++++----
internal/router/router.go | 1 +
8 files changed, 249 insertions(+), 27 deletions(-)
diff --git a/frontend/components/common/receive/ReceiveContent.tsx b/frontend/components/common/receive/ReceiveContent.tsx
index 4d7edc94..389194eb 100644
--- a/frontend/components/common/receive/ReceiveContent.tsx
+++ b/frontend/components/common/receive/ReceiveContent.tsx
@@ -17,6 +17,7 @@ import {ReceiveVerify, ReceiveVerifyRef} from '@/components/common/receive/Recei
import services from '@/lib/services';
import {BasicUserInfo} from '@/lib/services/core';
import {GetProjectResponseData} from '@/lib/services/project';
+import {PendingPaymentData} from '@/lib/services/payment';
import {formatDate, formatDateTimeWithSeconds, copyToClipboard} from '@/lib/utils';
import {motion} from 'motion/react';
import {Separator} from '@/components/ui/separator';
@@ -46,7 +47,11 @@ interface ReceiveButtonProps {
user: BasicUserInfo | null;
currentTime: Date;
isVerifying: boolean;
+ isCheckingPendingPayment: boolean;
+ isContinuingPayment: boolean;
+ pendingPayment: PendingPaymentData | null;
onReceive: () => void;
+ onContinuePayment: () => void;
}
/**
@@ -57,11 +62,17 @@ const ReceiveButton = ({
user,
currentTime,
isVerifying,
+ isCheckingPendingPayment,
+ isContinuingPayment,
+ pendingPayment,
onReceive,
+ onContinuePayment,
}: ReceiveButtonProps) => {
const now = currentTime;
const startTime = new Date(project.start_time);
const endTime = new Date(project.end_time);
+ const priceNum = Number(project.price || '0');
+ const isPaid = priceNum > 0;
if (now < startTime) {
const timeRemaining = getTimeRemainingText(startTime, now);
@@ -82,6 +93,28 @@ const ReceiveButton = ({
);
}
+ if (isPaid && project.available_items_count <= 0 && isCheckingPendingPayment) {
+ return (
+
+ );
+ }
+
+ if (pendingPayment?.has_pending && pendingPayment.pay_url) {
+ return (
+
+ );
+ }
+
if (project.available_items_count <= 0) {
return (