更新记录
1.0.1(2026-08-15)
- 重写使用文档:用法介绍、快速上手、API 示例、错误码表、后端验签说明、常见问题
1.0.0(2026-08-15)
- 首次发布为 UTS 插件(iOS StoreKit2)
- Swift 核心 + UTS 桥 + JS 便捷封装
- 支持消耗型、非消耗型、自动续期订阅、非续期订阅
- 便捷用法:init / applyPrices / purchase
- 遗留交易由 SDK 内部自动处理
- 最低 iOS 15.0
平台兼容性
uni-app(4.0)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | iOS插件版本 | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|---|
| - | - | - | - | - | - | - | 15 | 1.0.0 | × |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| - | - | - | - | - | - | - | - | - | - | - | - |
FZ-SK2-IAP · iOS StoreKit2 内购 UTS 插件
基于 Apple StoreKit 2 的 iOS 内购插件(UTS 实现),支持:
- 消耗型 / 非消耗型 / 自动续期订阅 / 非续期订阅
- 商品拉取与价格本地化展示
- 购买、恢复购买、订阅状态查询
- 交易 JWS 票据透传(配合后端 App Store Server API 验签)
- 遗留交易自动监听与补发验签
- Android / H5 / 小程序调用自动降级(返回"iOS only"错误,不崩溃)
环境要求
| 项 | 要求 |
|---|---|
| 系统 | iOS 15.0+ |
| HBuilderX | 4.0+ |
| 打包方式 | 云打包 / 自定义基座(标准基座可用于真机调试) |
| 商品配置 | 需先在 App Store Connect 创建内购商品,且已签署付费应用协议 |
快速上手
import { appleIap, isAppleIapCancelled, isAppleIapPending } from '@/uni_modules/fz-sk2-iap/js_sdk/index'
// 1. 初始化:注册验签回调(购买成功与遗留交易都会走 verify)
const ok = await appleIap.init({
// 把票据交给自己的后端验签(推荐 App Store Server API 验 transactionJwsToken)
verify: (tx) => yourBackendVerify({
transactionId: tx.transactionId,
transactionJwsToken: tx.transactionJwsToken,
}),
// 验签成功后刷新会员状态
onVerified: () => refreshVip(),
})
if (!ok) {
// 非 iOS 或系统低于 15.0,走其他支付渠道或隐藏订阅入口
}
// 2. 回填套餐价格(plans 里每项需有 externalProductId = App Store 商品ID)
await appleIap.applyPrices(plans)
plans.forEach(p => console.log(p.displayPrice)) // 本地化价格字符串,直接展示
// 3. 发起购买
try {
const tx = await appleIap.purchase(productId)
console.log('购买并验签成功', tx.transactionId)
} catch (err) {
if (isAppleIapCancelled(err)) {
// 用户取消,无需提示错误
} else if (isAppleIapPending(err)) {
// 家长同意等场景,交易 pending,等待 onVerified 补发
} else {
console.error(err.code, err.message)
}
}
API
appleIap 对象
从 @/uni_modules/fz-sk2-iap/js_sdk/index 导入。
appleIap.init(options) → Promise\<boolean>
初始化并绑定原生事件监听。false 表示当前环境不可用(非 iOS 或系统 < 15.0)。
| 参数 | 说明 |
|---|---|
| options.verify | (tx: AppleVerifyPayload) => Promise 购买成功和遗留交易的验签回调;抛错会重置该笔的验签状态,下次会重试 |
| options.onVerified | 验签成功回调,用于刷新会员状态 |
appleIap.isSupported() → Promise\<boolean>
当前设备是否支持 StoreKit 2。
appleIap.fetchProducts(productIds) → Promise\<{ products, invalidIds }>
按商品 ID 拉取商品信息。invalidIds 是 App Store 未识别的 ID,可用来排查配置问题。
appleIap.applyPrices(plans) → Promise\<plans>
批量把 App Store 本地化价格回填到套餐对象(需套餐字段 externalProductId):
回填字段:displayPrice(带货币符号的展示价)、priceStr、currency、iapProduct(完整商品对象)。
appleIap.purchase(productId, appAccountToken?) → Promise\<AppleVerifyPayload>
发起购买并自动验签,成功返回 { transactionId, transactionJwsToken, productId, ... }。
- 取消 / pending / 失败会 throw,用
isAppleIapCancelled/isAppleIapPending判断 appAccountToken可选,传合法 UUID 用于和自己的账号系统对账;不传自动生成随机 UUID 并在结果中返回
appleIap.purchaseProduct(productId, appAccountToken?) → Promise\<AppleIapPurchaseResult>
购买的原始结果(不走 verify 自动验签):result 为 success(含 transaction)/ userCancelled / pending。
appleIap.restorePurchases() → Promise\<{ transactions }>
恢复购买(会先 AppStore.sync()),返回当前所有有效交易。
appleIap.getCurrentSubscriptions() → Promise\<AppleIapTransaction[]>
当前有效的订阅列表(含每条的 subscriptionStatus)。
appleIap.getSubscriptionStatus(productId) → Promise\<AppleIapSubscriptionStatus>
查询单个订阅状态:state(active / expired / inGracePeriod / inBillingRetryPeriod / revoked)、willAutoRenew、expirationDate 等。
appleIap.getAppStoreReceiptBase64() → Promise\<AppleIapReceiptInfo>
获取收据(优先返回最新交易的 JWS),用于老式收据校验。新项目建议直接用购买结果里的 transactionJwsToken。
属性
appleIap.available:是否 iOS 平台appleIap.ready:init 后是否可用appleIap.products/appleIap.invalidIds:最近一次 fetchProducts 的结果
工具函数
import { isAppleIapCancelled, isAppleIapPending, toVerifyPayload } from '@/uni_modules/fz-sk2-iap/js_sdk/index'
isAppleIapCancelled(err) // 用户是否取消了购买
isAppleIapPending(err) // 购买是否处于 pending(如家长批准)
toVerifyPayload(tx) // 交易对象 → 后端验签入参(transactionId + transactionJwsToken)
底层 UTS 接口
也可直接从 @/uni_modules/fz-sk2-iap 导入与原生一一对应的 Promise 接口:isSupportStoreKit2 / fetchProducts / purchaseProduct / restorePurchases / getCurrentSubscriptions / getSubscriptionStatus / getAppStoreReceiptBase64。一般情况直接用 appleIap 即可。
错误码
| code | 含义 |
|---|---|
| -1 | 系统不支持(需 iOS 15+) |
| -2 | 未知错误 |
| -3 | 网络错误 |
| -4 | 商品不存在(未在 App Store Connect 配置或 ID 写错) |
| -5 | 用户取消购买 |
| -6 | 已有购买进行中 / 交易待确认 |
| -7 | 购买失败(含交易验签未通过) |
| -8 | 参数错误(productId 为空、token 非 UUID 等) |
| -9 | 获取收据失败 |
后端验签(重要)
不要在客户端判断发货。 购买/恢复返回的交易都带 jwsRepresentation(JWS 格式的 StoreKit 2 交易票据),把它交给后端,用 App Store Server API 验签后再发放权益:
客户端 purchase() → transactionJwsToken → 你的后端 → App Store Server API 验证 → 发放权益
插件会在 App 启动后自动监听遗留交易(退款重购、跨设备等),走同一个 verify 回调,避免丢单。
常见问题
- 拉不到商品:检查 App Store Connect 商品状态、付费应用协议是否签署、商品 ID 是否一致、真机登录的沙盒账号地区。
- 价格展示:一律用
displayPrice(系统本地化字符串),不要自己拼price浮点数。 - 模拟器:StoreKit 2 购买需真机 + 沙盒账号;模拟器仅能验证插件编译与接口调用。
- 测试:Xcode 工程 配置
StoreKit Configuration文件可在本地模拟购买流程(不产生真实扣费)。 - Android/H5:调用返回
iOS only错误,请在业务侧按appleIap.available分流。

收藏人数:
购买普通授权版(
试用
赞赏(0)
下载 0
赞赏 0
下载 12509489
赞赏 1943
赞赏
京公网安备:11010802035340号