简介:本文详细解析苹果内购(IAP)非订阅型商品充值全流程,涵盖配置、代码实现、安全验证及异常处理,助力开发者高效集成IAP功能。
苹果内购(IAP)的非订阅型商品(Non-Consumable/Consumable)充值流程是开发者为应用添加虚拟商品(如金币、道具、解锁功能等)的核心机制。与订阅型商品不同,非订阅型商品具有一次性交易或可重复购买的特点,其流程设计需兼顾用户体验与支付安全性。本文将从配置准备、代码实现、安全验证到异常处理,系统梳理完整流程。
非订阅型商品充值流程分为四个阶段:
创建商品ID:
商品ID: com.example.app.100coins参考名称: 100 Coins价格等级: Tier 2 ($0.99)审核信息: 截图展示商品购买界面
协议与税务设置:
沙盒账号创建:
example@icloud.com(无需真实邮箱)。测试场景覆盖:
在App启动时请求商品列表:
import StoreKitclass IAPManager: NSObject, SKProductsRequestDelegate {var productsRequest: SKProductsRequest?var productIdentifiers: Set<String> = ["com.example.app.100coins"]func fetchProducts() {productsRequest = SKProductsRequest(productIdentifiers: productIdentifiers)productsRequest?.delegate = selfproductsRequest?.start()}func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {let validProducts = response.products// 更新UI显示商品列表}}
用户点击购买按钮时触发:
func purchaseProduct(_ product: SKProduct) {let payment = SKPayment(product: product)SKPaymentQueue.default().add(payment)}
实现SKPaymentTransactionObserver协议监听交易状态:
class IAPManager: NSObject, SKPaymentTransactionObserver {func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {for transaction in transactions {switch transaction.transactionState {case .purchased:// 验证收据并交付商品deliverProduct(for: transaction)SKPaymentQueue.default().finishTransaction(transaction)case .failed:// 显示错误信息showError(transaction.error?.localizedDescription ?? "Unknown error")SKPaymentQueue.default().finishTransaction(transaction)case .restored:// 处理恢复购买逻辑breakdefault:break}}}private func deliverProduct(for transaction: SKPaymentTransaction) {guard let receiptURL = Bundle.main.appStoreReceiptURL,let receiptData = try? Data(contentsOf: receiptURL) else {return}// 将receiptData发送至服务器验证ServerAPI.validateReceipt(receiptData) { success inif success {// 解锁商品或增加金币UserDefaults.standard.set(true, forKey: "com.example.app.premiumUnlocked")}}}}
客户端上传收据:
Bundle.main.appStoreReceiptURL获取加密的收据数据。服务器端验证逻辑:
environment字段是否为"Sandbox"。苹果服务器验证:
import requestsdef validate_receipt(receipt_data, is_sandbox=False):url = "https://sandbox.itunes.apple.com/verifyReceipt" if is_sandbox else "https://buy.itunes.apple.com/verifyReceipt"response = requests.post(url, json={"receipt-data": receipt_data})return response.json()
21007表示需切换至生产环境验证。receipt.in_app数组中的product_id和transaction_id是否匹配。transaction_id至数据库,防止同一收据重复验证。original_purchase_date和purchase_date,防止篡改时间。| 错误代码 | 原因 | 解决方案 |
|---|---|---|
| 21002 | 收据数据无效 | 检查客户端收据上传逻辑 |
| 21004 | 共享密钥不匹配 | 确认App专用共享密钥配置 |
| 21005 | 收据服务器不可用 | 实现重试机制并提示用户稍后再试 |
com.example.app.starterpack),提供更高性价比。通过系统化的商品配置、严谨的代码实现与安全的服务器验证,开发者可高效构建稳定的非订阅型商品充值流程,最终提升应用收入与用户满意度。