From 175022a3fd127f8dc408cd67380f2532be461533 Mon Sep 17 00:00:00 2001 From: admin Date: Thu, 28 May 2026 01:40:54 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=94=B6=E9=93=B6=E5=8F=B0=E9=87=91?= =?UTF-8?q?=E9=A2=9D=E5=92=8C=E4=BA=8C=E7=BB=B4=E7=A0=81=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?-=E6=8F=90=E5=8F=96payment=5Furl=E7=94=A8=E4=BA=8E=E4=BA=8C?= =?UTF-8?q?=E7=BB=B4=E7=A0=81=E5=92=8C=E6=94=AF=E4=BB=98=E9=93=BE=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/internal/api/handlers/payment.go | 16 ++++++- frontend/src/views/user/Checkout.vue | 57 +++++++++++++++++------- 2 files changed, 55 insertions(+), 18 deletions(-) diff --git a/backend/internal/api/handlers/payment.go b/backend/internal/api/handlers/payment.go index 57532be..b6174fb 100644 --- a/backend/internal/api/handlers/payment.go +++ b/backend/internal/api/handlers/payment.go @@ -141,10 +141,23 @@ func (h *PaymentHandler) CreatePayment(c *gin.Context) { tradeID, _ := data["trade_id"].(string) token, _ := data["token"].(string) + paymentURL, _ := data["payment_url"].(string) + + var amount float64 + if v, ok := data["amount"].(float64); ok { + amount = v + } else if v, ok := data["amount"].(string); ok { + amount, _ = strconv.ParseFloat(v, 64) + } var actualAmount float64 if v, ok := data["actual_amount"].(float64); ok { actualAmount = v + } else if v, ok := data["actual_amount"].(string); ok { + actualAmount, _ = strconv.ParseFloat(v, 64) + } + if actualAmount == 0 { + actualAmount = amount } var expiration int64 @@ -170,9 +183,10 @@ func (h *PaymentHandler) CreatePayment(c *gin.Context) { paymentInfo := map[string]interface{}{ "trade_id": tradeID, "order_id": order.ID, - "amount": data["amount"], + "amount": amount, "actual_amount": actualAmount, "token": token, + "payment_url": paymentURL, "expiration_time": remainingSeconds, "trade_type": tradeType, "channel_id": channel.ID, diff --git a/frontend/src/views/user/Checkout.vue b/frontend/src/views/user/Checkout.vue index 9910c81..414e1b2 100644 --- a/frontend/src/views/user/Checkout.vue +++ b/frontend/src/views/user/Checkout.vue @@ -21,28 +21,30 @@
支付金额
-
{{ paymentInfo.actual_amount }} USDT
-
≈ ¥{{ paymentInfo.amount }}
+
{{ paymentInfo.actual_amount || paymentInfo.amount }} USDT
+
订单金额:¥{{ orderAmount }}
-
-
收款地址
+
+
支付链接
- {{ paymentInfo.token }} - 复制 + {{ paymentInfo.payment_url }} + 复制
+ 打开支付页面
-
+
扫码支付
+
请使用手机浏览器扫码打开支付页面

1. 请使用 {{ paymentInfo.trade_type?.toUpperCase() }} 网络转账

-

2. 请准确转账 {{ paymentInfo.actual_amount }} USDT

+

2. 请准确转账 {{ paymentInfo.actual_amount || paymentInfo.amount }} USDT

3. 转账后系统会自动确认,无需手动操作

@@ -84,6 +86,7 @@ const paymentInfo = ref(null) const paymentError = ref('') const remaining = ref(0) const totalTime = ref(0) +const orderAmount = ref(0) let pollTimer: any = null let countdownTimer: any = null @@ -95,11 +98,16 @@ async function createPayment() { totalTime.value = res.data.expiration_time || 600 remaining.value = totalTime.value - await QRCode.toCanvas(qrCanvas.value, res.data.token, { - width: 180, - margin: 2, - color: { dark: '#000', light: '#fff' } - }) + const orderRes: any = await orderApi.getById(orderId) + orderAmount.value = orderRes.data?.total_amount || 0 + + if (qrCanvas.value && res.data.payment_url) { + await QRCode.toCanvas(qrCanvas.value, res.data.payment_url, { + width: 180, + margin: 2, + color: { dark: '#000', light: '#fff' } + }) + } startCountdown() startPolling() @@ -133,10 +141,14 @@ function startPolling() { }, 5000) } -function copyAddress() { - if (paymentInfo.value?.token) { - navigator.clipboard.writeText(paymentInfo.value.token) - ElMessage.success('地址已复制') +function copyText(text: string) { + navigator.clipboard.writeText(text) + ElMessage.success('已复制') +} + +function openPaymentUrl() { + if (paymentInfo.value?.payment_url) { + window.open(paymentInfo.value.payment_url, '_blank') } } @@ -287,6 +299,17 @@ onUnmounted(() => { padding: 12px; display: inline-block; } + + .qr-tip { + font-size: 12px; + color: rgba(255, 255, 255, 0.4); + margin-top: 8px; + } +} + +.open-link-btn { + margin-top: 8px; + width: 100%; } .tips {