82 lines
3.1 KiB
Plaintext
82 lines
3.1 KiB
Plaintext
import { PayInfo, PayOptions, PayCallback, PayResult } from './interface.uts'
|
|
|
|
let appId = ''
|
|
let busy = false
|
|
let sequence = 0
|
|
|
|
// Host calls only after authenticated server reconciliation of the saved transaction.
|
|
export function resetPending(): void {
|
|
busy = false
|
|
sequence += 1
|
|
}
|
|
|
|
export function configure(id: string): boolean {
|
|
if (busy || id.trim().length == 0) return false
|
|
appId = id
|
|
return true
|
|
}
|
|
|
|
export function invoke(options: PayOptions, callback: PayCallback,
|
|
nativePay: (payload: string, loading: boolean, done: (raw: string) => void) => void): void {
|
|
if (busy) {
|
|
const result: PayResult = { resultCode: '103', errorMsg: '已有支付正在进行,请勿重复点击', needsQuery: true }
|
|
callback(result)
|
|
return
|
|
}
|
|
let valid = false
|
|
let payload: string = ''
|
|
try {
|
|
// Swift infers an optional from the generated PayInfo! property unless
|
|
// the local type is explicit. Check before narrowing on both platforms.
|
|
const candidate: PayInfo | null = options.payInfo
|
|
if (candidate != null) {
|
|
const info: PayInfo = candidate as PayInfo
|
|
const values = new Array<string>(info.appid ?? '', info.partnerid ?? '', info.prepayid ?? '',
|
|
info.package ?? '', info.noncestr ?? '', info.timestamp ?? '', info.sign ?? '')
|
|
valid = appId.length > 0 && values[0] == appId && values[3] == 'Sign=DYPay'
|
|
values.forEach((value: string) => { if (value.trim().length == 0) valid = false })
|
|
if (!/^[0-9]{1,10}$/.test(values[5]) || values[4].length > 32) valid = false
|
|
// UTS JSON.stringify returns string | null. Serialize before taking the
|
|
// payment lock, and never pass a nullable value to a native String API.
|
|
if (valid) {
|
|
payload = JSON.stringify(info) ?? ''
|
|
if (payload.length == 0) valid = false
|
|
}
|
|
}
|
|
} catch (e) { valid = false }
|
|
if (!valid) {
|
|
const result: PayResult = { resultCode: '-1', errorMsg: '支付参数不完整或 AppID 不匹配,请重新下单', needsQuery: false }
|
|
callback(result)
|
|
return
|
|
}
|
|
busy = true
|
|
sequence += 1
|
|
const current = sequence
|
|
const timer = setTimeout(() => {
|
|
if (!busy || sequence != current) return
|
|
busy = false
|
|
sequence += 1
|
|
const result: PayResult = { resultCode: '3', errorMsg: '支付结果等待超时,请查询订单,勿重复付款', needsQuery: true }
|
|
callback(result)
|
|
}, 300000)
|
|
const complete = (raw: string): void => {
|
|
if (!busy || sequence != current) return
|
|
busy = false
|
|
clearTimeout(timer)
|
|
let result: PayResult = { resultCode: '3', errorMsg: '支付结果未知,请查询订单', needsQuery: true }
|
|
try {
|
|
const parsed = JSON.parseObject(raw)
|
|
if (parsed != null) {
|
|
result.resultCode = parsed.getString('resultCode') ?? '3'
|
|
result.errorMsg = parsed.getString('errorMsg') ?? ''
|
|
}
|
|
} catch (e) { /* An invalid native result must never become a payment success. */ }
|
|
callback(result)
|
|
}
|
|
try {
|
|
nativePay(payload, options.showLoading ?? true, complete)
|
|
} catch (e) {
|
|
complete('{"resultCode":"2","errorMsg":"无法调用支付 SDK,请查询订单后重试"}')
|
|
}
|
|
}
|