使用微信Dount多端平台提供的wx.miniapp.IAP实现 Apple 支付的详细流程及注意事项
前言
微信Dount多端平台最近内测提供了可以将小程序转化为安卓和iOS的能力,想把之前做过的小程序转化为iOS,因为内容含有虚拟物品付费,所以就需要用到Apple 支付
,多端平台提供了wx.miniapp.IAP一整套接口,但是并没有详细地解释,让我一个没有做过iOS开发的前端人员很是苦恼。所以在我经历各种坑之后就有了这篇文章。
准备工作
- 首先你要有苹果后台账号创建自己的APP
- 创建完成之后在这个顶部的
商务
完成各种协议和收款账户的填写
- 创建虚拟商品(链接讲的很详细)
- 创建自己的沙盒测试号必须是没有注册过苹果ID的邮箱
- 退出测试设备的苹果商店账号
- 完成以上步骤就可以进行开发了
Apple 支付开发流程简述
以下是微信Dount提供的接口和我自己的封装
一、添加交易队列观察者
API:wx.miniapp.IAP.addTransactionObserver
作用: 添加交易观察者以处理交易状态的更新,包括购买成功或失败等。
输入参数:
ob
:一个包含回调函数的对象,用于处理不同的交易事件。updatedTransactions
:处理交易状态更新。restoreCompletedTransactionsFailedWithError
:处理恢复购买时出现的错误。paymentQueueRestoreCompletedTransactionsFinished
:在恢复购买交易完成时调用。shouldAddStorePayment
:询问是否应该添加商店付款。paymentQueueDidChangeStorefront
:处理 App Store 店面变化。didRevokeEntitlementsForProductIdentifiers
:处理撤销某些产品的权限。
输出参数: 无直接输出参数,通过回调函数处理交易事件。
function initialize() {
const ob = {
updatedTransactions: (args) => {
console.log('处理交易状态更新,例如购买成功或失败。:', args);
args.transactions.forEach(item => handleTransaction(item));
},
restoreCompletedTransactionsFailedWithError: (args) => {
console.log('处理恢复购买时出现的错误。:', args);
},
paymentQueueRestoreCompletedTransactionsFinished: (args) => {
console.log('在恢复购买交易完成时调用。', args);
},
shouldAddStorePayment: (args) => {
console.log('询问是否应该添加商店付款。', args);
},
paymentQueueDidChangeStorefront: (args) => {
console.log('处理 App Store 店面变化。', args);
},
didRevokeEntitlementsForProductIdentifiers: (args) => {
console.log('处理撤销某些产品的权限。', args);
},
};
wx.miniapp.IAP.addTransactionObserver(ob);
}
二、请求商品信息
API:wx.miniapp.IAP.requestSKProducts
作用: 请求指定商品的详细信息。
输入参数:
productIdentifiers
:商品标识符数组,指定需要请求信息的商品。success
:请求成功的回调函数,返回商品信息。fail
:请求失败的回调函数,返回错误信息。
输出参数:
invalidProductIdentifiers
:无效的商品标识符数组。products
:有效的商品信息数组。
function requestProduct(index, paySuccess, payFail) {
const canMake = canMakePayments();
if (!canMake) {
uni.showToast({
title: '没有支付环境',
icon: 'none'
});
payFail();
return;
}
gPaySuccess = paySuccess;
gPayFail = payFail;
wx.miniapp.IAP.requestSKProducts({
productIdentifiers: [],// 这里是用户要购买的商品ID
success: (ret) => {
console.log(ret.invalidProductIdentifiers, '无效商品标识');
console.log(ret.products, '商品标识');
if (ret.products.length > 0) {
startPayment(null, ret.products);
} else {
startPayment('未查到商品', ret.products);
uni.hideLoading();
}
},
fail: (error) => {
console.error(`获取商品信息失败: ${error}`);
gPayFail();
uni.hideLoading();
}
});
}
三、发起支付
API:wx.miniapp.IAP.addPaymentByProductIdentifiers
作用: 发起支付请求。
输入参数:
productIdentifier
:商品标识符,指定需要支付的商品。success
:支付请求成功的回调函数,返回支付请求的结果。fail
:支付请求失败的回调函数,返回错误信息。
输出参数: 无直接输出参数,通过回调函数处理支付请求的结果。
function startPayment(err, productIdentifier) {
if (err) {
uni.showToast({
title: err,
icon: "none",
});
gPayFail();
uni.hideLoading();
return;
}
wx.miniapp.IAP.addPaymentByProductIdentifiers({
productIdentifier: productIdentifier[0].productIdentifier,
success: (args) => {
console.log('拉起支付成功', args);
uni.hideLoading();
},
fail: (args) => {
console.error('拉起支付失败', args);
gPayFail();
uni.hideLoading();
}
});
}
四、处理交易
作用: 处理交易状态更新,包括成功、失败、恢复等。
输入参数:
transaction
:交易对象,包含交易状态、交易收据等信息。
输出参数: 无直接输出参数,通过交易状态处理不同的逻辑。
function handleTransaction(transaction) {
if (transaction.transactionState === "SKPaymentTransactionStatePurchased" ||
transaction.transactionState === "SKPaymentTransactionStateRestored") {
console.log(transaction.transactionReceipt, '订单收据');
finishTransaction(null, transaction);
} else if (transaction.transactionState === "SKPaymentTransactionStateFailed") {
finishTransaction('交易失败', transaction);
gPayFail();
} else if (transaction.transactionState === "SKPaymentTransactionStateDeferred") {
finishTransaction('等待外部操作', transaction);
}
}
五、结束交易
API:wx.miniapp.IAP.finishTransaction
作用: 完成交易,通知系统交易已经处理完毕。
输入参数:
transactionIdentifier
:交易标识符,指定需要结束的交易。success
:结束交易成功的回调函数,返回结果。fail
:结束交易失败的回调函数,返回错误信息。
输出参数: 无直接输出参数,通过回调函数处理结束交易的结果。
function finishTransaction(err, transaction) {
if (err) {
uni.showToast({
title: err,
icon: "none",
});
return;
}
wx.miniapp.IAP.finishTransaction({
transactionIdentifier: transaction.transactionIdentifier,
success: (args) => {
console.log('完成交易 success', args);
gPaySuccess();
},
fail: (args) => {
console.error('完成交易 fail', args);
gPayFail();
}
});
}
六、检查支付环境
API:wx.miniapp.IAP.canMakePayments
作用: 检查当前设备是否支持支付功能。
输入参数: 无
输出参数:
- 返回值:布尔值,表示设备是否支持支付功能。
function canMakePayments() {
const canMake = wx.miniapp.IAP.canMakePayments();
console.log(canMake, "检查是否可以发起支付");
return canMake;
}
七、获取交易列表
API:wx.miniapp.IAP.getTransactions
作用: 获取当前未完成的交易列表。
输入参数:
success
:获取交易列表成功的回调函数,返回交易列表。fail
:获取交易列表失败的回调函数,返回错误信息。
输出参数:
transactions
:未完成的交易列表。
function getTransactions(callback) {
wx.miniapp.IAP.getTransactions({
success: (transactions) => {
console.log('当前交易列表', transactions);
callback(null, transactions);
},
fail: (error) => {
console.error('获取交易列表失败', error);
callback('获取交易列表失败');
}
});
}
八、恢复已完成的交易
API:wx.miniapp.IAP.restoreCompletedTransactions
作用: 恢复已完成的交易。
输入参数:
success
:恢复交易成功的回调函数,返回交易列表。fail
:恢复交易失败的回调函数,返回错误信息。
输出参数:
transactions
:恢复的交易列表。
function restoreTransactions(callback) {
wx.miniapp.IAP.restoreCompletedTransactions({
success: (transactions) => {
console.log('恢复的交易', transactions);
callback(null, transactions);
},
fail: (error) => {
console.error('恢复交易失败', error);
callback(error);
}
});
}
九、获取交易收据 URL
API:wx.miniapp.IAP.getAppStoreReceiptURL
作用: 获取交易收据的 URL。
输入参数:
success
:获取收据 URL 成功的回调函数,返回收据 URL。fail
:获取收据 URL 失败的回调函数,返回错误信息。
输出参数:
url
:交易收据的 URL。
function getReceiptURL() {
wx.miniapp.IAP.getAppStore
ReceiptURL({
success: (url) => {
console.log('交易收据 URL', url);
getReceiptData(null, url);
},
fail: (error) => {
console.error('获取收据 URL 失败', error);
getReceiptData('获取收据 URL 失败');
}
});
}
十、获取交易收据数据
API:wx.miniapp.IAP.getAppStoreReceiptData
作用: 获取交易收据数据。
输入参数:
success
:获取收据数据成功的回调函数,返回收据数据。fail
:获取收据数据失败的回调函数,返回错误信息。
输出参数:
data
:交易收据数据。
function getReceiptData(err) {
if (err) {
uni.showToast({
title: err,
icon: "none",
});
return;
}
wx.miniapp.IAP.getAppStoreReceiptData({
success: (data) => {
console.log('交易收据数据', data);
// 调用后端接口传送交易数据
},
fail: (error) => {
console.error('获取收据数据失败', error);
}
});
}
十一、刷新收据
API:wx.miniapp.IAP.requestSKReceiptRefreshRequest
作用: 发起请求刷新收据。
输入参数:
success
:刷新收据成功的回调函数,返回结果。fail
:刷新收据失败的回调函数,返回错误信息。
输出参数:
args
:刷新收据的结果。
function refreshReceipt(err, callback) {
if (err) {
uni.showToast({
title: err,
icon: "none",
});
return;
}
wx.miniapp.IAP.requestSKReceiptRefreshRequest({
success: (args) => {
console.log('刷新收据成功', args);
callback(null, args);
},
fail: (error) => {
console.error('刷新收据失败', error);
callback(error);
}
});
}
十二、获取 App Store 信息
API:wx.miniapp.IAP.getStorefront
作用: 获取当前 App Store 店面的信息。
输入参数:
success
:获取店面信息成功的回调函数,返回店面信息。fail
:获取店面信息失败的回调函数,返回错误信息。
输出参数:
info
:App Store 店面信息。
function getStorefront(callback) {
wx.miniapp.IAP.getStorefront({
success: (info) => {
console.log('App Store 信息', info);
callback(null, info);
},
fail: (error) => {
console.error('获取 App Store 信息失败', error);
callback(error);
}
});
}
十三、移除交易观察者
API:wx.miniapp.IAP.removeTransactionObserver
作用: 移除交易观察者。
输入参数:
success
:移除交易观察者成功的回调函数,返回结果。fail
:移除交易观察者失败的回调函数,返回错误信息。
输出参数:
args
:移除交易观察者的结果。
function removeObserver() {
wx.miniapp.IAP.removeTransactionObserver(ob);
}
完整流程及注意事项
- 初始化:在应用启动时调用
initialize
函数添加交易队列观察者,以便处理交易状态的更新。 - 请求商品信息:用户选择商品后,调用
requestProduct
函数请求商品信息。首先检查设备是否支持支付(canMakePayments
),然后通过wx.miniapp.IAP.requestSKProducts
请求商品信息。 - 发起支付:在成功获取商品信息后,调用
startPayment
函数发起支付请求,通过wx.miniapp.IAP.addPaymentByProductIdentifiers
实现。 - 处理交易:交易状态更新会触发观察者的
updatedTransactions
回调函数,调用handleTransaction
函数处理不同的交易状态。 - 结束交易:在处理完交易后,调用
finishTransaction
函数结束交易,通知系统交易已经处理完毕。 - 恢复交易:提供恢复已完成交易的功能,方便用户在重新安装应用或更换设备后恢复已购买的内容。
- 获取交易收据:在交易完成后,可以通过
getReceiptURL
和getReceiptData
获取交易收据,并发送到后端进行验证。
注意事项
- 检查支付环境:确保设备可以进行支付(
canMakePayments
),如果设备不支持支付,应提示用户并终止支付流程。 - 错误处理:每一步操作都需要进行错误处理,并且在错误发生时应向用户展示友好的提示信息。
- 安全性:获取订单收据后应及时发送到后端进行验证,确保支付的真实性。
- 交易状态处理:对于不同的交易状态,需要分别处理,确保在用户支付成功后能够正确提供商品或服务。
- 恢复交易:提供恢复已完成交易的功能,方便用户在重新安装应用或更换设备后恢复已购买的内容。
- 用户体验:在每一步操作(如请求商品信息、发起支付等)时应显示加载提示,确保用户了解当前正在进行的操作。
通过上述步骤和注意事项,可以完成苹果支付的流程,并确保在支付过程中为用户提供良好的体验。