Tighten WeChat payment resume flow
This commit is contained in:
77
frontend/src/views/user/paymentWechatResume.ts
Normal file
77
frontend/src/views/user/paymentWechatResume.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
import type { LocationQuery, LocationQueryRaw } from 'vue-router'
|
||||
import type { SubscriptionPlan } from '@/types/payment'
|
||||
import { normalizeVisibleMethod } from '@/components/payment/paymentFlow'
|
||||
|
||||
export interface ParsedWechatResumeRoute {
|
||||
orderAmount: number
|
||||
orderType: 'balance' | 'subscription'
|
||||
paymentType: string
|
||||
planId?: number
|
||||
openid?: string
|
||||
wechatResumeToken?: string
|
||||
}
|
||||
|
||||
function readQueryString(query: LocationQuery, key: string): string {
|
||||
const value = query[key]
|
||||
if (Array.isArray(value)) {
|
||||
return typeof value[0] === 'string' ? value[0] : ''
|
||||
}
|
||||
return typeof value === 'string' ? value : ''
|
||||
}
|
||||
|
||||
export function parseWechatResumeRoute(
|
||||
query: LocationQuery,
|
||||
plans: SubscriptionPlan[],
|
||||
fallbackBalanceAmount: number,
|
||||
): ParsedWechatResumeRoute | null {
|
||||
if (readQueryString(query, 'wechat_resume') !== '1') {
|
||||
return null
|
||||
}
|
||||
|
||||
const wechatResumeToken = readQueryString(query, 'wechat_resume_token')
|
||||
if (wechatResumeToken) {
|
||||
return {
|
||||
wechatResumeToken,
|
||||
paymentType: 'wxpay',
|
||||
orderType: 'balance',
|
||||
orderAmount: 0,
|
||||
}
|
||||
}
|
||||
|
||||
const openid = readQueryString(query, 'openid')
|
||||
if (!openid) {
|
||||
return null
|
||||
}
|
||||
|
||||
const paymentType = normalizeVisibleMethod(readQueryString(query, 'payment_type')) || 'wxpay'
|
||||
const orderType = readQueryString(query, 'order_type') === 'subscription' ? 'subscription' : 'balance'
|
||||
const planId = Number.parseInt(readQueryString(query, 'plan_id'), 10)
|
||||
const rawAmount = Number.parseFloat(readQueryString(query, 'amount'))
|
||||
const orderAmount = Number.isFinite(rawAmount) && rawAmount > 0
|
||||
? rawAmount
|
||||
: (orderType === 'subscription'
|
||||
? (plans.find(plan => plan.id === planId)?.price ?? 0)
|
||||
: fallbackBalanceAmount)
|
||||
|
||||
return {
|
||||
openid,
|
||||
paymentType,
|
||||
orderType,
|
||||
orderAmount,
|
||||
planId: Number.isFinite(planId) && planId > 0 ? planId : undefined,
|
||||
}
|
||||
}
|
||||
|
||||
export function stripWechatResumeQuery(query: LocationQuery): LocationQueryRaw {
|
||||
const nextQuery: LocationQueryRaw = { ...query }
|
||||
delete nextQuery.wechat_resume
|
||||
delete nextQuery.wechat_resume_token
|
||||
delete nextQuery.openid
|
||||
delete nextQuery.state
|
||||
delete nextQuery.scope
|
||||
delete nextQuery.payment_type
|
||||
delete nextQuery.amount
|
||||
delete nextQuery.order_type
|
||||
delete nextQuery.plan_id
|
||||
return nextQuery
|
||||
}
|
||||
Reference in New Issue
Block a user