最近向苹果商店发布了一个应用程序(几个小时前)。应用程序内购买会显示成功消息。但是,它不会要求用户提供付款信息,也不向用户收费。这是购买流程:
在沙盒模式下,会发生相同的流程,但是,它表示您不会因处于沙盒模式而被收费。
在生产中,它只是不向用户收费。
该产品已在 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)
}
}
显然,苹果这边向客户收费有5个小时的延迟。不确定这是否是由于新应用程序造成的,或者情况总是如此。然而,所有购买都在大约 5 小时后完成。