You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Superwall中配置applicationUsername(AppTokenId)以验证IAP的问题咨询

在Superwall中配置applicationUsername实现IAP服务器验证

你的代码存在几个关键问题,导致applicationUsername无法被正确设置,甚至支付逻辑根本无法执行:

  1. 你用了闭包回调式的网络请求,但Superwall的purchase是async/await异步函数,直接返回.cancelled会让Superwall判定购买已取消,后续支付代码完全不会被触发
  2. 成功回调里第一行就写了return,直接终止了后续创建支付请求的逻辑
  3. 异步流程处理错误,网络请求的结果无法同步到purchase函数的返回值中

修正后的实现代码

首先需要把你的ApiGenerator.request改成支持async/await的版本(如果原封装不支持,可通过withCheckedThrowingContinuation封装),再调整purchase函数的逻辑:

class SubscriptionController: PurchaseController {
    var orderPresenter = OrderPresenter()
    
    func purchase(product: SKProduct) async -> SuperwallKit.PurchaseResult {
        let productID = product.productIdentifier
        let data = ["productId": productID]
        
        do {
            // 改用异步请求获取AppTokenId
            let response = try await ApiGenerator.request(
                targetApi: OrderService.Init(data: data),
                responseModel: SuccessModel_str.self
            )
            
            guard response.response.statusCode == 200, let appTokenId = response.body?.id else {
                return .failed(error: NSError(domain: "YourAppDomain", code: -1, userInfo: [NSLocalizedDescriptionKey: "获取AppTokenId失败"]))
            }
            
            guard SKPaymentQueue.canMakePayments() else {
                return .failed(error: NSError(domain: "YourAppDomain", code: -2, userInfo: [NSLocalizedDescriptionKey: "无法发起支付,请检查系统设置"]))
            }
            
            // 创建支付请求并设置applicationUsername
            let paymentRequest = SKMutablePayment(product: product)
            paymentRequest.applicationUsername = appTokenId
            SKPaymentQueue.default().add(paymentRequest)
            
            // 根据实际流程返回结果:发起支付后可返回.pending,若需等待支付完成则结合SKPaymentQueue监听处理
            return .pending
        } catch {
            print("请求错误:\(error)")
            return .failed(error: error)
        }
    }
    
    func restorePurchases() async -> SuperwallKit.RestorationResult {
        // 此处需实现实际的恢复购买逻辑,不要直接返回.restored
        do {
            // 调用恢复购买接口或处理StoreKit恢复流程
            return .restored
        } catch {
            return .failed(error: error)
        }
    }
}

关键说明

  • 异步请求适配:必须将网络请求改为async/await形式,才能在purchase这个async函数中等待请求结果,避免提前返回错误的PurchaseResult
  • 移除无效return:删掉原成功回调里的提前return,确保支付请求代码能执行
  • 正确设置applicationUsername:创建SKMutablePayment时,直接将请求返回的response.body?.id赋值给paymentRequest.applicationUsername,这个值会被包含在IAP交易凭证中,后续自有服务器验证时可通过它做用户关联
  • PurchaseResult返回逻辑:根据实际业务流程返回对应结果,比如发起支付后返回.pending,若需等待支付完成再返回结果,需结合SKPaymentQueue的交易监听实现

内容的提问来源于stack exchange,提问作者Am1rFT

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 11:48:13