更新记录
1.0.0(2026-04-07)
新增
- IAP 内购功能
queryProducts查询 App Store 商品信息purchase发起内购支付(消耗型/非消耗型/自动续期订阅/非续期订阅)restorePurchases恢复已购买项目finishTransaction完成交易确认getReceiptData获取 App Store 原始票据(base64)getPendingTransactions获取未完成交易列表
- Apple Pay 支付功能
canMakeApplePayPayments检查设备是否支持 Apple PayrequestApplePayPayment发起 Apple Pay 支付(支持收货地址、联系方式、配送方式)
- 原生 Swift 桥接层(PayDelegates.swift),解决 UTS 与 StoreKit/PassKit 的类型兼容问题
- 完整的错误码体系(IAP 9010001-9010008,Apple Pay 9020001-9020005)
- 示例项目:导航首页 + IAP 演示页 + Apple Pay 演示页
平台兼容性
uni-app(4.25)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| √ | √ | - | - | - | - | - | √ | - |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| - | - | - | - | - | - | - | - | - | - | - | - |
uni-app x(4.25)
| Chrome | Safari | Android | iOS | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|
| - | - | - | √ | - | - |
jwt-iospay
iOS 支付 UTS 插件,支持 IAP 内购 和 Apple Pay 两大支付能力。
功能特性
- IAP 内购:消耗型、非消耗型、自动续期订阅、非续期订阅
- Apple Pay:实物商品支付,支持收货地址、联系方式、配送方式
- 基于 StoreKit 1(兼容 iOS 12+)
- 返回原始票据数据,服务端自行验证
- 完整的错误码体系
平台兼容性
| 平台 | 支持 | 说明 |
|---|---|---|
| iOS | ✅ | 完整支持 IAP + Apple Pay |
| Android | ❌ | 返回平台不支持错误 |
| HarmonyOS | ❌ | 返回平台不支持错误 |
最低 iOS 版本:12.0
前置配置
IAP 内购
- 登录 App Store Connect
- 进入你的 App → 内购项目 → 创建商品(消耗型/非消耗型/订阅)
- 记录商品 ID(如
com.yourapp.coins100) - 在 用户和访问 → 沙盒 → 测试账户 中创建沙盒测试员
- 测试设备上:设置 → App Store → 沙盒账户 → 登录测试账号
Apple Pay
- 登录 Apple Developer
- Certificates, Identifiers & Profiles → Identifiers → Merchant IDs → 注册 Merchant ID
- 在你的 App ID 中启用 Apple Pay capability,关联 Merchant ID
- 测试设备上需添加银行卡到 Apple Wallet
安装
将 jwt-iospay 文件夹放入项目的 uni_modules 目录即可。
导入
import {
queryProducts,
purchase,
restorePurchases,
finishTransaction,
getReceiptData,
getPendingTransactions,
canMakeApplePayPayments,
requestApplePayPayment
} from "@/uni_modules/jwt-iospay"
API 参考
IAP 内购
queryProducts(options)
查询 App Store 商品信息。
queryProducts({
productIds: ['com.yourapp.coins100', 'com.yourapp.vip_monthly'],
success(res) {
// res.products: IAPProductInfo[]
// res.invalidProductIds: string[] — 无效的商品ID
res.products.forEach(p => {
console.log(p.productId) // 商品ID
console.log(p.title) // 商品名称
console.log(p.productDescription) // 商品描述
console.log(p.price) // 价格字符串 "6.00"
console.log(p.priceAmount) // 价格数值 6.0
console.log(p.currencyCode) // 货币代码 "CNY"
})
},
fail(err) {
console.error(err.errCode, err.errMsg)
}
})
Options
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| productIds | string[] | 是 | 商品ID数组 |
| success | Function | 否 | 成功回调 |
| fail | Function | 否 | 失败回调 |
| complete | Function | 否 | 完成回调 |
Result: QueryProductsResult
| 字段 | 类型 | 说明 |
|---|---|---|
| products | IAPProductInfo[] | 有效商品列表 |
| invalidProductIds | string[] | 无效的商品ID |
purchase(options)
发起内购支付。
purchase({
productId: 'com.yourapp.coins100',
quantity: 1, // 可选,默认1
applicationUsername: 'user_123', // 可选,用户标识(防欺诈)
success(res) {
// res.transaction: IAPTransactionInfo
// res.receiptData: string (base64)
console.log('交易号:', res.transaction.transactionId)
console.log('票据:', res.receiptData)
// ★ 重要:将 receiptData 发给你的服务端验证
// 服务端调用 Apple verifyReceipt API 验证
// 验证通过后再调用 finishTransaction
finishTransaction({
transactionId: res.transaction.transactionId
})
},
fail(err) {
if (err.errCode === 9010001) {
console.log('用户取消了支付')
} else {
console.error('支付失败:', err.errMsg)
}
}
})
Options
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| productId | string | 是 | 商品ID |
| quantity | number | 否 | 购买数量,默认1 |
| applicationUsername | string | 否 | 用户标识,用于防欺诈 |
| success | Function | 否 | 成功回调 |
| fail | Function | 否 | 失败回调 |
| complete | Function | 否 | 完成回调 |
Result: PurchaseResult
| 字段 | 类型 | 说明 |
|---|---|---|
| transaction | IAPTransactionInfo | 交易信息 |
| receiptData | string | App Store 收据(base64) |
restorePurchases(options)
恢复已购买项目(非消耗型商品和订阅)。
restorePurchases({
success(res) {
// res.transactions: IAPTransactionInfo[]
console.log(`恢复了 ${res.transactions.length} 笔交易`)
},
fail(err) {
console.error(err.errMsg)
}
})
finishTransaction(options)
完成(确认)交易。购买成功并经服务端验证后必须调用此方法,否则交易将在下次启动时重新推送。
finishTransaction({
transactionId: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
success(res) {
console.log('交易已确认')
},
fail(err) {
console.error(err.errMsg)
}
})
getReceiptData(options)
获取 App Store 收据数据。
getReceiptData({
forceRefresh: false, // true = 从 Apple 服务器刷新,false = 读本地缓存
success(res) {
// res.receiptData: string (base64)
console.log('票据长度:', res.receiptData.length)
},
fail(err) {
console.error(err.errMsg)
}
})
getPendingTransactions(options)
获取未完成的交易列表。
getPendingTransactions({
success(res) {
res.transactions.forEach(tx => {
console.log(tx.productId, tx.transactionState, tx.transactionId)
})
}
})
Apple Pay
canMakeApplePayPayments()
检查设备是否支持 Apple Pay。同步方法,直接返回结果。
const result = canMakeApplePayPayments()
if (result.canMakePayments) {
console.log('支持 Apple Pay')
} else {
console.log('不支持 Apple Pay')
}
requestApplePayPayment(options)
发起 Apple Pay 支付。
requestApplePayPayment({
merchantId: 'merchant.com.yourapp.pay',
countryCode: 'CN',
currencyCode: 'CNY',
// 支付项目(最后一项为合计行,label显示为商户名)
paymentItems: [
{ label: '商品A', amount: '29.90', type: 'final' },
{ label: '运费', amount: '10.00', type: 'final' },
{ label: '我的商店', amount: '39.90', type: 'final' }
],
// 支付网络(可选,默认 visa/masterCard/chinaUnionPay)
supportedNetworks: ['visa', 'masterCard', 'chinaUnionPay'],
// 需要用户提供的收货信息(可选)
requiredShippingContactFields: ['postalAddress', 'phoneNumber', 'name', 'emailAddress'],
requiredBillingContactFields: ['postalAddress'],
// 配送方式(可选)
shippingMethods: [
{ identifier: 'free', label: '免费配送', detail: '5-7个工作日', amount: '0.00' },
{ identifier: 'express', label: '加急快递', detail: '1-2个工作日', amount: '10.00' }
],
success(res) {
console.log('支付Token:', res.paymentToken) // base64,发给支付网关
console.log('交易标识:', res.transactionIdentifier)
console.log('支付方式:', res.paymentMethod) // 如 "Visa 1234"
if (res.shippingContact) {
console.log('收货人:', res.shippingContact.name)
console.log('电话:', res.shippingContact.phone)
console.log('城市:', res.shippingContact.city)
}
// ★ 将 paymentToken 发给你的支付网关(如 Stripe、银联等)处理扣款
},
fail(err) {
if (err.errCode === 9020002) {
console.log('用户取消了支付')
} else {
console.error('支付失败:', err.errMsg)
}
}
})
Options: ApplePayPaymentOptions
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| merchantId | string | 是 | Apple Developer 中注册的 Merchant ID |
| countryCode | string | 是 | 国家代码,如 CN、US |
| currencyCode | string | 是 | 货币代码,如 CNY、USD |
| paymentItems | ApplePayPaymentItem[] | 是 | 支付项列表(最后一项为合计) |
| supportedNetworks | string[] | 否 | 支付网络,默认 visa/masterCard/chinaUnionPay |
| requiredShippingContactFields | string[] | 否 | 需要的收货信息字段 |
| requiredBillingContactFields | string[] | 否 | 需要的账单信息字段 |
| shippingMethods | ApplePayShippingMethod[] | 否 | 配送方式选项 |
| success | Function | 否 | 支付成功回调 |
| fail | Function | 否 | 支付失败回调 |
| complete | Function | 否 | 完成回调 |
联系人字段可选值
postalAddress、emailAddress、phoneNumber、name
支持的支付网络
visa、masterCard、chinaUnionPay、amex、discover、jcb、interac
Result: ApplePayResult
| 字段 | 类型 | 说明 |
|---|---|---|
| paymentToken | string | 支付令牌(base64),发给支付网关处理 |
| transactionIdentifier | string | Apple 交易标识 |
| paymentMethod | string | 支付方式描述,如 "Visa 1234" |
| billingContact | ApplePayContact | 账单联系人(如果请求了) |
| shippingContact | ApplePayContact | 收货联系人(如果请求了) |
| shippingMethod | ApplePayShippingMethod | 用户选择的配送方式 |
数据类型
IAPProductInfo
| 字段 | 类型 | 说明 |
|---|---|---|
| productId | string | 商品ID |
| title | string | 商品名称 |
| productDescription | string | 商品描述 |
| price | string | 格式化价格字符串 |
| priceAmount | number | 价格数值 |
| currencyCode | string | 货币代码 |
| productType | string | 商品类型 |
IAPTransactionInfo
| 字段 | 类型 | 说明 |
|---|---|---|
| transactionId | string | 交易ID |
| productId | string | 商品ID |
| quantity | number | 购买数量 |
| transactionDate | number | 交易时间戳(毫秒) |
| transactionState | string | 交易状态:purchasing/purchased/failed/restored/deferred |
| originalTransactionId | string | 原始交易ID(续订/恢复时有值) |
ApplePayContact
| 字段 | 类型 | 说明 |
|---|---|---|
| name | string | 姓名 |
| string | 邮箱 | |
| phone | string | 电话 |
| addressLines | string[] | 详细地址 |
| city | string | 城市 |
| state | string | 省/州 |
| postalCode | string | 邮编 |
| country | string | 国家 |
| countryCode | string | 国家代码 |
错误码
IAP 内购
| 错误码 | 说明 |
|---|---|
| 9010001 | 用户取消支付 |
| 9010002 | 支付失败 |
| 9010003 | 商品不存在或无效 |
| 9010004 | 无权限购买(如家长控制) |
| 9010005 | 网络错误 |
| 9010006 | 交易未找到 |
| 9010007 | 恢复购买失败 |
| 9010008 | 当前平台不支持 IAP |
Apple Pay
| 错误码 | 说明 |
|---|---|
| 9020001 | 设备不支持 Apple Pay |
| 9020002 | 用户取消 Apple Pay |
| 9020003 | Apple Pay 支付失败 |
| 9020004 | 商户配置错误 |
| 9020005 | 当前平台不支持 Apple Pay |
典型业务流程
IAP 内购流程
客户端 你的服务端 Apple
| | |
|-- queryProducts(ids) --------->| |
|<-- products[] ----------------| |
| | |
|-- purchase(productId) -------->| |
|<-- receiptData + transaction --| |
| | |
|-- 发送 receiptData ----------->| |
| |-- verifyReceipt -------->|
| |<-- 验证结果 --------------|
| | |
|<-- 验证通过,发放商品 ---------| |
| | |
|-- finishTransaction(txId) ---->| |
Apple Pay 流程
客户端 你的服务端 支付网关(Stripe等)
| | |
|-- canMakeApplePayPayments() -->| |
| | |
|-- requestApplePayPayment() --->| |
| (弹出Apple Pay面板) | |
| (用户确认Face ID/Touch ID) | |
|<-- paymentToken ---------------| |
| | |
|-- 发送 paymentToken ---------->| |
| |-- 处理扣款 -------------->|
| |<-- 扣款结果 --------------|
| | |
|<-- 支付结果 ------------------| |
注意事项
-
finishTransaction 必须调用:购买成功后,必须在服务端验证通过后调用
finishTransaction。如果不调用,交易会在 App 每次启动时重新推送。 -
服务端验证:永远不要仅在客户端验证票据。必须将
receiptData发送给你的服务端,由服务端调用 Apple 的verifyReceiptAPI 验证。 -
Apple Pay Token 处理:
paymentToken需要发给支付网关(如 Stripe、Adyen、银联等)来完成实际扣款,客户端不直接处理。 -
沙盒测试:沙盒环境下 IAP 购买不会实际扣款。Apple Pay 需要真机测试,模拟器功能有限。
-
未完成交易:App 启动时建议调用
getPendingTransactions检查是否有未完成的交易,确保之前中断的购买能继续处理。

收藏人数:
购买源码授权版(
试用
使用 HBuilderX 导入示例项目
赞赏(0)
下载 42
赞赏 0
下载 11490175
赞赏 1902
赞赏
京公网安备:11010802035340号