/**
|
* 判断当前是否为 iOS App 运行环境。
|
*/
|
export function isIosAppRuntime() {
|
// #ifndef APP-PLUS
|
return false
|
// #endif
|
// #ifdef APP-PLUS
|
try {
|
return plus.os?.name === 'iOS'
|
} catch {
|
return false
|
}
|
// #endif
|
}
|
|
/**
|
* 读取苹果内购支付通道。
|
*/
|
export function getAppleIapChannel() {
|
return new Promise((resolve, reject) => {
|
// #ifndef APP-PLUS
|
reject({
|
code: -3,
|
message: '当前环境不支持苹果内购',
|
})
|
return
|
// #endif
|
// #ifdef APP-PLUS
|
plus.payment.getChannels((channels) => {
|
const appleChannel = Array.isArray(channels) ? channels.find((item) => item.id === 'appleiap') : null
|
if (!appleChannel) {
|
reject({
|
code: -3,
|
message: '当前应用未启用苹果内购',
|
})
|
return
|
}
|
resolve(appleChannel)
|
}, (error) => {
|
reject(error || {
|
code: -99,
|
message: '获取苹果内购通道失败',
|
})
|
})
|
// #endif
|
})
|
}
|
|
/**
|
* 拉起苹果内购支付并返回原始交易结果。
|
*/
|
export async function requestAppleIapPayment({ productId, username } = {}) {
|
const normalizedProductId = typeof productId === 'string' ? productId.trim() : ''
|
if (!normalizedProductId) {
|
throw {
|
code: -1,
|
message: '缺少苹果内购商品ID',
|
}
|
}
|
const channel = await getAppleIapChannel()
|
return new Promise((resolve, reject) => {
|
const orderInfo = {
|
productid: normalizedProductId,
|
}
|
const normalizedUsername = typeof username === 'string' ? username.trim() : ''
|
if (normalizedUsername) {
|
orderInfo.username = normalizedUsername
|
}
|
plus.payment.request(channel, orderInfo, (result) => {
|
resolve(normalizeAppleIapResult(result, normalizedProductId))
|
}, (error) => {
|
reject(error || {
|
code: -99,
|
message: '苹果内购支付失败',
|
})
|
})
|
})
|
}
|
|
/**
|
* 归一化苹果内购结果,方便业务页直接拿 receipt 回传后端。
|
*/
|
function normalizeAppleIapResult(result, productId) {
|
const receipt = normalizeOptionalText(result?.transactionReceipt || result?.receipt)
|
return {
|
productId,
|
transactionDate: normalizeOptionalText(result?.transactionDate),
|
transactionIdentifier: normalizeOptionalText(result?.transactionIdentifier || result?.transactionId),
|
transactionReceipt: receipt,
|
receiptData: receipt,
|
raw: result || null,
|
}
|
}
|
|
function normalizeOptionalText(value) {
|
return typeof value === 'string' ? value.trim() : ''
|
}
|