IOS IAP成功但不向用户收费

问题描述 投票:0回答:1

最近向苹果商店发布了一个应用程序(几个小时前)。应用程序内购买会显示成功消息。但是,它不会要求用户提供付款信息,也不向用户收费。这是购买流程:

  1. 用户点击产品
  2. Apple storekit 显示一条包含定价和购买选项的消息
  3. apple 要求登录才能完成购买
  4. 苹果显示购买成功信息

在沙盒模式下,会发生相同的流程,但是,它表示您不会因处于沙盒模式而被收费。

在生产中,它只是不向用户收费。

该产品已在 App Store Connect 中获得批准

IAP代码是:

import Foundation
import StoreKit

public struct InAppPurchasesCallbacks {
    var onFetchCompleted: (([SKProduct]) -> Void)?
    var onProductsNotFound: (([String]?) -> Void)?
    var onPurchaseSucceeded: ((SKProduct, SKPaymentTransaction) -> Void)?
    var onPurchaseFailed: ((SKProduct, Error?) -> Void)?
    var onRestoreCompleted: (([SKPaymentTransaction]) -> Void)?
    var onRestoreFailed: ((Error?) -> Void)?
    
    public init(onFetchCompleted: (([SKProduct]) -> Void)? = nil, onProductsNotFound: (([String]?) -> Void)? = nil, onPurchaseSucceeded: ((SKProduct, SKPaymentTransaction) -> Void)? = nil, onPurchaseFailed: ((SKProduct, Error?) -> Void)? = nil, onRestoreCompleted: (([SKPaymentTransaction]) -> Void)? = nil, onRestoreFailed: ( (Error?) -> Void)? = nil) {
        self.onFetchCompleted = onFetchCompleted
        self.onProductsNotFound = onProductsNotFound
        self.onPurchaseSucceeded = onPurchaseSucceeded
        self.onPurchaseFailed = onPurchaseFailed
        self.onRestoreCompleted = onRestoreCompleted
        self.onRestoreFailed = onRestoreFailed
    }
}

public class InAppPurchaseWrapper: NSObject, SKProductsRequestDelegate, SKPaymentTransactionObserver {
    private var products = [SKProduct]()
    private var callbacks: InAppPurchasesCallbacks
    private var productIdentifiers: Set<String>
    
    public init(productIdentifiers: Set<String>, callbacks: InAppPurchasesCallbacks) {
        self.productIdentifiers = productIdentifiers
        self.callbacks = callbacks
        super.init()
        SKPaymentQueue.default().add(self)
        fetchProductInfo()
    }
    
    private func fetchProductInfo() {
        let request = SKProductsRequest(productIdentifiers: productIdentifiers)
        request.delegate = self
        request.start()
    }
    
    public func purchaseProduct(_ product: SKProduct) {
        let payment = SKPayment(product: product)
        SKPaymentQueue.default().add(payment)
    }
    
    public func restorePurchases() {
        SKPaymentQueue.default().restoreCompletedTransactions()
    }
    
    private func validateTransaction(transaction: SKPaymentTransaction, product: SKProduct) {
       // some backend server verification calls, removed for security here.
    }
}

// MARK: - Delegate methods
extension InAppPurchaseWrapper {
    
    public func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
        products = response.products
        let unrecognized = response.invalidProductIdentifiers
        
        if products.count == 0 {
            if unrecognized.count > 0 {
                callbacks.onProductsNotFound?(unrecognized)
            } else {
                callbacks.onProductsNotFound?(nil)
            }
        } else {
            callbacks.onFetchCompleted?(products)
            
            if unrecognized.count > 0{
                callbacks.onProductsNotFound?(unrecognized)
            }
        }
    }
    
    public func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
        for transaction in transactions {
            switch transaction.transactionState {
            case .purchasing:
                break
            case .purchased:
                let product = products.first {
                    $0.productIdentifier == transaction.payment.productIdentifier
                }
                
                if let p = product {
                    validateTransaction(transaction: transaction, product: p)
                    callbacks.onPurchaseSucceeded?(p, transaction)
                } else {
                    callbacks.onProductsNotFound?(nil)
                    queue.finishTransaction(transaction)
                }
            case .failed:
                let product = products.first {
                    $0.productIdentifier == transaction.payment.productIdentifier
                }
                
                if let p = product, let e = transaction.error {
                    callbacks.onPurchaseFailed?(p, e)
                } else {
                    callbacks.onProductsNotFound?(nil)
                }
                queue.finishTransaction(transaction)
            case .restored:
                let product = products.first {
                    $0.productIdentifier == transaction.original?.payment.productIdentifier
                }
                if let p = product {
                    callbacks.onPurchaseSucceeded?(p, transaction)
                } else {
                    callbacks.onProductsNotFound?(nil)
                }
                queue.finishTransaction(transaction)
            case .deferred:
                break
            @unknown default:
                break
            }
        }
    }
    
    public func paymentQueue(_ queue: SKPaymentQueue, restoreCompletedTransactionsFailedWithError error: Error) {
        callbacks.onRestoreFailed?(error)
    }
    
    public func paymentQueueRestoreCompletedTransactionsFinished(_ queue: SKPaymentQueue) {
        callbacks.onRestoreCompleted?(queue.transactions)
    }
}

ios in-app-purchase app-store-connect
1个回答
0
投票

显然,苹果这边向客户收费有5个小时的延迟。不确定这是否是由于新应用程序造成的,或者情况总是如此。然而,所有购买都在大约 5 小时后完成。

© www.soinside.com 2019 - 2024. All rights reserved.