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(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,请查询订单后重试"}') } }