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

StoreKit 2 API购买成功后沙箱环境本地收据缺失问题咨询

解决StoreKit 2购买后本地收据未更新的问题

在沙箱环境下,使用StoreKit 2完成购买并验证交易后,本地收据可能不会立即同步更新——这是因为系统的收据同步机制存在延迟。要确保能获取到包含最新购买记录的收据,你需要主动触发收据刷新操作,而非直接读取本地文件。

核心解决方案

  • 不要在调用await transaction.finish()前直接读取收据,先发起收据刷新请求,等待刷新完成后再读取收据数据。
  • 使用SKReceiptRefreshRequest主动请求App Store更新本地收据,该请求会强制系统同步最新的购买记录到本地收据文件中。

调整后的代码实现

首先封装一个异步的收据刷新工具函数:

func refreshReceipt() async throws {
    try await withCheckedThrowingContinuation { continuation in
        let refreshRequest = SKReceiptRefreshRequest()
        let delegate = ReceiptRefreshDelegate(continuation: continuation)
        refreshRequest.delegate = delegate
        refreshRequest.start()
        // 持有请求避免提前释放
        delegate.request = refreshRequest
    }
}

class ReceiptRefreshDelegate: NSObject, SKRequestDelegate {
    private let continuation: CheckedContinuation<Void, Error>
    weak var request: SKRequest?
    
    init(continuation: CheckedContinuation<Void, Error>) {
        self.continuation = continuation
        super.init()
    }
    
    func requestDidFinish(_ request: SKRequest) {
        continuation.resume()
        self.request = nil
    }
    
    func request(_ request: SKRequest, didFailWithError error: Error) {
        continuation.resume(throwing: error)
        self.request = nil
    }
}

然后在购买流程中集成刷新逻辑:

let purchaseResult = try await product.purchase(options: purchaseOptions)

switch purchaseResult {
case .success(let verification):
    let transaction = try checkVerified(verification)
    
    // 主动刷新收据,确保获取最新记录
    try await refreshReceipt()
    
    // 读取更新后的收据数据
    guard let receiptURL = Bundle.main.appStoreReceiptURL,
          FileManager.default.fileExists(atPath: receiptURL.path) else {
        throw Error.missingReceipt
    }
    
    let receiptData = try Data(contentsOf: receiptURL)
    let receiptString = receiptData.base64EncodedString(options: .endLineWithLineFeed)
    
    // 执行服务器端校验逻辑
    ...
    
    // 最后完成交易
    await transaction.finish()
case .userCancelled:
    // 处理用户取消操作
    break
case .pending:
    // 处理待确认交易(如家庭共享、家长验证场景)
    break
@unknown default:
    break
}

注意事项

  • 刷新收据需要网络连接,确保App已配置网络权限(沙箱环境允许HTTP,正式环境需使用HTTPS)。
  • 沙箱环境下偶尔会出现刷新延迟,建议添加重试逻辑(最多重试2次,每次间隔1-2秒),避免临时网络问题导致失败。
  • 务必在调用transaction.finish()前完成收据刷新和读取,交易完成后同步收据的准确性可能受影响。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 09:53:17