zjk
2026-09-29 54dcf0a82e7490fa58b1c056d5c0b9cb739c2931
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
/**
 * 判断当前是否为 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() : ''
}