fix(payment): rely on Huihui callback for status
This commit is contained in:
@@ -45,8 +45,8 @@
|
||||
<section class="checkout-section">
|
||||
<button
|
||||
class="checkout-btn"
|
||||
:class="{ disabled: !selectedPlan || charging || Boolean(pendingOrderId) }"
|
||||
:disabled="!selectedPlan || charging || Boolean(pendingOrderId)"
|
||||
:class="{ disabled: !selectedPlan || charging }"
|
||||
:disabled="!selectedPlan || charging"
|
||||
@click="doCharge"
|
||||
>
|
||||
{{ checkoutLabel }}
|
||||
@@ -85,7 +85,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import {
|
||||
chargeTokenOrg,
|
||||
@@ -93,10 +93,9 @@ import {
|
||||
getRechargePlans,
|
||||
getTokenBalance,
|
||||
getTokenOrders,
|
||||
getTokenPaymentStatus,
|
||||
type TokenPaymentOrder
|
||||
} from '@/api'
|
||||
import { isInUniWebView, onNativeMessage } from '@/utils/uniapp-bridge'
|
||||
import { isInUniWebView } from '@/utils/uniapp-bridge'
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
@@ -119,7 +118,6 @@ const selectedPlan = ref<any>(null)
|
||||
// 支付方式
|
||||
const paymentNotice = ref('')
|
||||
const paymentNoticeTone = ref<'pending' | 'success' | 'error'>('pending')
|
||||
const pendingOrderId = ref(sessionStorage.getItem('hh_pending_payment_order') || '')
|
||||
const recentOrders = ref<Array<TokenPaymentOrder & { invoice?: any }>>([])
|
||||
const invoiceOrder = ref<(TokenPaymentOrder & { invoice?: any }) | null>(null)
|
||||
const invoiceType = ref<'personal' | 'company'>('personal')
|
||||
@@ -128,9 +126,6 @@ const invoiceTaxNumber = ref('')
|
||||
const invoiceEmail = ref('')
|
||||
const invoiceError = ref('')
|
||||
const invoiceSubmitting = ref(false)
|
||||
let pollTimer: number | undefined
|
||||
let pollDeadline = 0
|
||||
let removeNativeListener: (() => void) | undefined
|
||||
|
||||
// 从后端加载余额与套餐
|
||||
const loadData = async () => {
|
||||
@@ -205,7 +200,6 @@ const formatPointsCopy = (value: string) => value.replace(/\bToken\b/gi, '积分
|
||||
const checkoutLabel = computed(() => {
|
||||
if (!selectedPlan.value) return '请选择充值套餐'
|
||||
if (charging.value) return '正在创建支付订单…'
|
||||
if (pendingOrderId.value) return '等待支付结果…'
|
||||
return '去支付'
|
||||
})
|
||||
|
||||
@@ -216,50 +210,6 @@ const payScene = () => {
|
||||
return 'H5' as const
|
||||
}
|
||||
|
||||
const clearPendingOrder = () => {
|
||||
pendingOrderId.value = ''
|
||||
sessionStorage.removeItem('hh_pending_payment_order')
|
||||
if (pollTimer) window.clearTimeout(pollTimer)
|
||||
pollTimer = undefined
|
||||
}
|
||||
|
||||
const pollPayment = async () => {
|
||||
if (!pendingOrderId.value) return
|
||||
try {
|
||||
const order = await getTokenPaymentStatus(pendingOrderId.value)
|
||||
if (order.status === 'paid') {
|
||||
currentBalance.value = order.balance
|
||||
paymentNoticeTone.value = 'success'
|
||||
paymentNotice.value = `支付成功,${order.pointsAmount.toLocaleString()} 积分已到账`
|
||||
clearPendingOrder()
|
||||
void loadData()
|
||||
return
|
||||
}
|
||||
if (order.status === 'failed' || order.status === 'closed') {
|
||||
paymentNoticeTone.value = 'error'
|
||||
paymentNotice.value = order.status === 'closed' ? '订单已关闭,请重新发起支付' : (order.failureReason || '支付未完成,请重新发起')
|
||||
clearPendingOrder()
|
||||
return
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('查询支付结果失败', error)
|
||||
}
|
||||
if (Date.now() < pollDeadline) pollTimer = window.setTimeout(pollPayment, 2000)
|
||||
else {
|
||||
paymentNoticeTone.value = 'pending'
|
||||
paymentNotice.value = '支付结果仍在确认中,可稍后刷新余额或重新发起'
|
||||
clearPendingOrder()
|
||||
}
|
||||
}
|
||||
|
||||
const startPolling = (orderId: string) => {
|
||||
pendingOrderId.value = orderId
|
||||
sessionStorage.setItem('hh_pending_payment_order', orderId)
|
||||
pollDeadline = Date.now() + 2 * 60 * 1000
|
||||
if (pollTimer) window.clearTimeout(pollTimer)
|
||||
void pollPayment()
|
||||
}
|
||||
|
||||
const doCharge = async () => {
|
||||
if (!selectedPlan.value || charging.value) return
|
||||
charging.value = true
|
||||
@@ -269,18 +219,19 @@ const doCharge = async () => {
|
||||
if (order.status === 'failed') throw new Error(order.failureReason || '支付订单创建失败')
|
||||
if (!order.providerOrderNo || !/^\d+$/.test(order.providerOrderNo)) throw new Error('会会充值订单号缺失')
|
||||
paymentNoticeTone.value = 'pending'
|
||||
paymentNotice.value = '支付订单已创建,正在等待付款结果'
|
||||
startPolling(order.id)
|
||||
paymentNotice.value = '支付订单已创建,支付结果将由会会回调确认'
|
||||
const checkoutBase = window.location.hostname === 'digital.99hui.com'
|
||||
? 'https://99hui.com/huihui-h5/'
|
||||
: 'https://fat-open.99hui.com/huihui-h5/'
|
||||
const evn = sessionStorage.getItem('hh_launch_evn') || 'wx'
|
||||
const evnPart = `&evn=${encodeURIComponent(evn)}`
|
||||
window.location.assign(`${checkoutBase}#/payOrder?orderNo=${encodeURIComponent(order.providerOrderNo)}&isOrg=true${evnPart}`)
|
||||
const tokenPart = order.checkoutToken
|
||||
? `&token=${encodeURIComponent(order.checkoutToken)}`
|
||||
: ''
|
||||
window.location.assign(`${checkoutBase}#/payOrder?orderNo=${encodeURIComponent(order.providerOrderNo)}&isOrg=true${evnPart}${tokenPart}`)
|
||||
} catch (error: any) {
|
||||
paymentNoticeTone.value = 'error'
|
||||
paymentNotice.value = error?.message || '充值失败,请重试'
|
||||
clearPendingOrder()
|
||||
} finally {
|
||||
charging.value = false
|
||||
}
|
||||
@@ -293,32 +244,6 @@ const goBack = () => {
|
||||
|
||||
onMounted(() => {
|
||||
void loadData()
|
||||
removeNativeListener = onNativeMessage((message) => {
|
||||
if (message?.type !== 'paymentResult') return
|
||||
if (message.orderId && message.orderId !== pendingOrderId.value) return
|
||||
if (['cancelled', 'canceled'].includes(String(message.status).toLowerCase())) {
|
||||
paymentNoticeTone.value = 'error'
|
||||
paymentNotice.value = '支付已取消'
|
||||
clearPendingOrder()
|
||||
return
|
||||
}
|
||||
if (String(message.status).toLowerCase() === 'failed') {
|
||||
paymentNoticeTone.value = 'error'
|
||||
paymentNotice.value = message.message || '支付未完成,请重新发起'
|
||||
clearPendingOrder()
|
||||
return
|
||||
}
|
||||
void pollPayment()
|
||||
})
|
||||
if (pendingOrderId.value) {
|
||||
paymentNotice.value = '正在确认上一笔支付结果'
|
||||
startPolling(pendingOrderId.value)
|
||||
}
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
if (pollTimer) window.clearTimeout(pollTimer)
|
||||
removeNativeListener?.()
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user