引言
在移动应用开发中,虚拟商品支付是核心功能之一,而针对iOS平台,苹果App Store强制要求虚拟商品必须通过其官方内购渠道完成交易,这使得Uniapp项目集成苹果内购成为iOS端开发的必备技能。本文将全面复盘Uniapp苹果内购支付的完整流程,涵盖Uniapp项目代码集成、苹果开发者后台App ID创建、App Store Connect内购项目配置及最终打包提交全环节,并提供可直接参考的实战代码示例,助力开发者快速攻克内购集成难题。

一、前期准备:明确核心前提与工具
在正式开始内购集成前,需确保完成以下基础准备工作,避免后续流程出现阻塞:
- 苹果开发者账号:必须拥有有效的苹果开发者账号(个人账号、公司账号均可,但个人账号无法使用某些企业级功能,推荐使用公司账号),且账号状态正常,已完成付费订阅。内购功能仅对已付费的开发者账号开放。
- Uniapp项目基础:确保Uniapp项目已完成基础开发,明确需要接入内购的虚拟商品(如会员、积分、道具等),并规划好商品的唯一标识(将用于内购项目配置与代码关联)。
- 开发工具:准备好HBuilderX(用于Uniapp项目开发与打包)、Xcode(可选,用于iOS端调试),以及苹果开发者后台、App Store Connect后台的访问权限。

二、核心步骤一:Uniapp项目集成苹果内购代码
Uniapp封装了苹果内购的相关API,开发者无需深入原生开发即可快速集成。核心流程包括:获取支付渠道、请求商品信息、发起支付请求、处理支付结果。以下是完整的代码示例及详细解析。
2.1 完整集成代码示例
在Uniapp项目的页面组件中,可通过以下代码实现内购支付的核心逻辑,需根据实际业务场景修改商品标识、支付结果处理逻辑等内容:
// 触发苹果内购支付的入口函数
payFun() {
let that = this;
// 1. 获取当前设备支持的支付渠道
uni.getProvider({
service: 'payment', // 指定服务类型为支付
success: (paymentRes) => {
// 筛选出苹果内购渠道(渠道ID为appleiap)
const iapChannel = paymentRes.providers.find((channel) => {
return channel.id === 'appleiap';
});
// 若未找到苹果内购渠道,提示不支持
if (!iapChannel) {
uni.showToast({
title: '暂不支持苹果支付',
icon: 'none',
duration: 2000
});
return;
}
// 2. 请求商品信息(key为内购项目的产品ID,需与App Store Connect配置一致)
let productId = 'newOceanOneYear'; // 示例:年度会员商品ID,多商品时可动态替换
iapChannel.requestProduct([productId],
// 商品请求成功回调
function(orderList) {
console.log('获取商品信息成功:', orderList);
// 校验商品列表有效性,发起支付
if (orderList && orderList.length > 0) {
that.applePay(orderList[0]); // 传入商品信息,执行支付
} else {
uni.showToast({
title: '未获取到商品信息',
icon: 'none'
});
}
},
// 商品请求失败回调
function(error) {
console.error('获取商品信息失败:', error);
uni.showToast({
title: '商品信息加载失败,请重试',
icon: 'none'
});
}
);
},
// 获取支付渠道失败回调
fail(err) {
console.error('获取支付渠道失败:', err);
uni.showToast({
title: '支付功能初始化失败',
icon: 'none'
});
}
});
},
// 发起苹果内购支付的具体实现
applePay(product) {
const that = this;
// 显示加载提示,防止用户重复操作
uni.showLoading({
title: '充值中请勿离开',
mask: true// 遮罩,防止背景点击
});
// 3. 调用Uniapp支付API发起内购请求
uni.requestPayment({
provider: 'appleiap', // 固定为苹果内购渠道
orderInfo: {
productId: product.productId, // 商品ID(与请求的商品信息一致)
// 注意:苹果内购的orderInfo无需传入订单号等信息,由苹果后台生成交易凭证
},
// 支付成功回调
success: (payRes) => {
uni.hideLoading();
console.log('支付请求成功:', payRes);
// 苹果内购交易状态说明:transactionState为1表示交易成功
if (payRes.transactionState === 1) {
uni.showToast({
title: '支付成功',
icon: 'success'
});
// 关键:此处需调用后端接口,传入支付凭证(payRes.transactionReceipt)进行验证
that.verifyPayment(payRes.transactionReceipt);
} else {
// 处理其他交易状态(如交易待确认、已取消等)
uni.showToast({
title: '支付状态异常,请核实',
icon: 'none'
});
}
},
// 支付失败回调
fail: (payErr) => {
uni.hideLoading();
console.error('支付失败:', payErr);
// 区分用户主动取消与其他错误
if (payErr.errMsg.includes('cancel')) {
uni.showToast({
title: '您已取消支付',
icon: 'none'
});
} else {
uni.showToast({
title: '支付失败,请重试',
icon: 'none'
});
}
},
// 支付完成回调(无论成功失败都会执行)
complete: () => {
uni.hideLoading();
}
});
},
// 支付凭证验证(核心:苹果内购必须通过后端与苹果服务器验证,防止本地伪造)
verifyPayment(receipt) {
// 调用后端接口,将凭证传给服务器进行验证
uni.request({
url: that.$api.verifyApplePay, // 后端验证接口地址
method: 'POST',
data: {
receipt: receipt, // 苹果返回的交易凭证
productId: 'newOceanOneYear', // 对应的商品ID
userId: that.userId // 当前用户ID,用于关联订单
},
success: (res) => {
if (res.data.code === 200 && res.data.data.isValid) {
console.log('凭证验证成功,订单已确认');
// 执行后续业务逻辑(如更新会员状态、发放道具等)
that.updateMemberStatus();
} else {
console.error('凭证验证失败:', res.data.msg);
uni.showToast({
title: '订单验证失败,请联系客服',
icon: 'none'
});
}
},
fail: (err) => {
console.error('验证接口请求失败:', err);
uni.showToast({
title: '网络异常,订单验证中',
icon: 'none'
});
}
});
}
2.2 代码关键说明
- 支付渠道获取:通过
uni.getProvider获取设备支持的支付方式,筛选出苹果内购(appleiap),确保仅在支持的设备上触发内购。 - 商品信息请求:
requestProduct方法传入商品ID,从苹果服务器获取商品的名称、价格等信息,避免本地硬编码价格导致与App Store不一致。 - 支付结果处理:
transactionState为1是苹果内购成功的核心标识,但必须通过后端验证凭证,不能仅依赖前端状态——前端状态可被篡改,苹果服务器的凭证验证才是唯一可靠的依据。 - 凭证验证:后端需将前端传入的
transactionReceipt提交至苹果的验证服务器(沙盒环境:https://sandbox.itunes.apple.com/verifyReceipt;正式环境:https://buy.itunes.apple.com/verifyReceipt),根据返回结果确认支付有效性。

三、核心步骤二:苹果开发者后台创建App ID并配置内购权限
App ID是应用的唯一标识,也是启用内购功能的基础。需在苹果开发者后台创建并配置对应的权限,具体步骤如下:
3.1 登录苹果开发者后台
访问苹果开发者官网(https://developer.apple.com/account/),使用已付费的开发者账号登录,进入“Certificates, Identifiers & Profiles”(证书、标识和配置文件)页面。
3.2 创建App ID
- 点击左侧“Identifiers”,然后点击右上角“+”号,选择“App IDs”,点击“Continue”。
- 选择“App”类型(适用于iOS、macOS等平台的应用),点击“Continue”。
- 填写App ID信息:Description:应用描述(如“XX会员服务App”),将显示在开发者后台。
- Bundle ID:应用的唯一标识符,格式为反向域名(如“com.company.appname”),必须与Uniapp项目的“manifest.json”中配置的iOS Bundle ID完全一致,后续打包、上架均依赖此ID。
- 启用内购权限:在“Capabilities”列表中,找到“App内购买项目”(In-App Purchase)并勾选,确保该权限处于启用状态。其他权限根据应用需求选择,完成后点击“Continue”。
- 确认信息无误后,点击“Register”完成App ID创建。
3.3 关键注意事项
App ID创建后不可修改Bundle ID,因此需提前规划好格式;内购权限一旦勾选,无需额外申请,但需确保开发者账号状态正常,否则权限可能无法生效。

四、核心步骤三:App Store Connect配置内购项目
App Store Connect是管理应用上架、内购项目的平台,需在此处创建内购商品,并与Uniapp项目中的商品ID关联。核心目标是将虚拟商品信息录入苹果系统,使其能被App请求并完成交易。
4.1 登录App Store Connect并关联App
- 访问App Store Connect(https://appstoreconnect.apple.com/),使用与开发者账号关联的Apple ID登录。
- 若未创建应用,点击“我的App”→“+”号→“新建App”,填写应用名称、Primary Language、Bundle ID(选择步骤二中创建的App ID对应的Bundle ID)等信息,完成应用创建。若已创建应用,直接进入应用管理页面。
4.2 创建内购项目
- 进入应用管理页面,点击左侧“功能”→“App内购买项目”,然后点击右上角“+”号,选择内购项目类型。苹果内购项目分为以下几类,需根据商品类型选择:消耗型项目:如游戏道具、一次性积分,购买后可重复购买,消耗后需再次购买。
- 非消耗型项目:如永久解锁的功能,购买一次即可永久使用,支持恢复购买。
- 自动续期订阅:如月度/年度会员,到期自动扣费续期,支持免费试用。
- 非续期订阅:如季度会员,到期后需手动续期,不自动扣费。
- 以“自动续期订阅”(如年度会员)为例,选择对应类型后,点击“创建”。
- 填写内购项目基本信息:参考名称:仅用于开发者后台识别,如“年度会员-12个月”。
- 产品ID:核心标识,需与Uniapp代码中
productId完全一致(如示例中的“newOceanOneYear”),建议格式为“com.company.appname.productname”,便于管理。 - 清理级别:根据商品内容选择,一般选择“4+”即可。
- 设置价格与地区:选择商品的价格等级(苹果提供固定的价格档位,不同地区货币自动转换),设置是否允许在特定地区销售,完成后点击“存储”。
- 填写商品描述与元数据:上传商品图标(尺寸为1024×1024,无圆角,PNG格式)、填写商品名称(将显示在App内购界面)、描述(介绍商品权益),完成后点击“存储”。
4.3 设置内购项目状态为“准备提交”
内购项目创建完成后,状态默认为“等待审核”,需手动将其设置为“准备提交”:在“App内购买项目”列表中,找到创建的项目,点击进入详情页,确认所有信息填写完整后,点击“状态”下拉框,选择“准备提交”。关键提醒:此时仅需将内购项目设置为“准备提交”,无需单独提交审核,后续与App一起提交审核即可,避免提前提交导致审核驳回。

五、核心步骤四:HBuilderX打包IPA并提交审核
Uniapp项目代码集成与苹果后台配置完成后,需通过HBuilderX打包生成iOS安装包(IPA),并提交至App Store Connect进行审核,审核通过后内购功能方可正式生效。
5.1 HBuilderX配置与打包
- 打开Uniapp项目,进入“manifest.json”配置页面,选择“App原生配置”→“iOS配置”:Bundle ID:填写与苹果开发者后台创建的App ID一致的Bundle ID(如“com.company.appname”)。
- 启用内购:在“模块配置”中,找到“Payment(支付)”模块,勾选“Apple In-App Purchase(苹果内购)”,确保该模块被启用。
- 点击“发行”→“原生App-云打包”,选择“iOS打包”:打包类型:若用于提交审核,选择“正式打包”;若用于测试,选择“测试打包”(需配置测试证书)。
- 证书配置:上传苹果开发者后台生成的发布证书(p12文件)与描述文件(mobileprovision),确保证书与Bundle ID匹配,且包含内购权限。
- 其他配置:根据需求设置应用名称、版本号等,点击“开始打包”,等待打包完成后下载IPA文件。
5.2 提交IPA至App Store Connect并关联内购项目
- 通过Xcode或Transporter工具将IPA文件上传至App Store Connect: Transporter工具:登录后点击“添加App”,选择下载的IPA文件,验证通过后点击“交付”,完成上传。
- Xcode:连接iOS设备,选择“Window”→“Organizer”,找到打包的应用归档文件,点击“Distribute App”,选择“App Store Connect”,按提示完成上传。
- 关联内购项目:在App Store Connect的应用管理页面,进入“App信息”→“App内购买项目”,确保创建的内购项目已被关联至当前应用。
- 提交审核:进入“提交审核”页面,填写审核信息(如联系人、测试账号等),确认应用与内购项目均处于“准备提交”状态后,点击“提交审核”。苹果审核周期一般为1-3个工作日,审核通过后应用与内购功能将同步上线。

六、常见问题与避坑指南
- 商品请求失败:检查商品ID与App Store Connect配置的一致;确认App ID已勾选内购权限;测试时需使用沙盒测试账号,且设备未登录正式Apple ID。
- 支付成功后凭证验证失败:区分沙盒与正式环境——测试时后端需调用苹果沙盒验证接口,正式上线后切换至正式接口;确保凭证未被篡改,且与当前用户、商品ID关联正确。
- 审核驳回:内购项目未配置完整:检查内购项目的图标、描述、价格等信息是否填写完整;确保内购项目状态为“准备提交”,且与应用关联正确。
- 恢复购买功能缺失:对于非消耗型项目与订阅项目,需实现恢复购买功能(调用
iapChannel.restoreCompletedTransactions方法),否则可能被审核驳回。
七、总结
Uniapp苹果内购支付的核心在于“代码集成-后台配置-凭证验证-审核上线”的全流程闭环,其中商品ID的一致性、凭证的后端验证、内购项目的状态配置是关键节点。开发者需严格遵循苹果的规则,确保每一步操作符合规范,同时做好测试工作(使用沙盒测试账号模拟支付场景),避免上线后出现功能异常。通过本文的流程梳理与代码示例,希望能帮助开发者高效完成内购集成,为iOS用户提供流畅的支付体验。
Dcloud插件地址:
https://ext.dcloud.net.cn/plugin?id=25216
