iOS: 购买成功后如何获取交易id或收据数据Swift

iOS: How to get transaction id or receipt data after successful in app purchase Swift

我想知道在成功购买后如何获得交易 ID 或收据信息,以便我可以发送到我的服务器并用于购买验证。 同样在同一主题上,我想知道如果由于某种原因连接在我将购买信息发送到我的服务器之前中断,那么我将如何将通知链接到购买订阅的用户?

谢谢

所以我想在下面开关的.purchased部分做我的处理

import Foundation
import StoreKit

class StoreManager: NSObject, ObservableObject, SKProductsRequestDelegate, SKPaymentTransactionObserver {
    
    //FETCH PRODUCTS
    var request: SKProductsRequest!
    
    @Published var myProducts = [SKProduct]()
    
    func getProducts(productIDs: [String]) {
        print("Start requesting products ...")
        let request = SKProductsRequest(productIdentifiers: Set(productIDs))
        request.delegate = self
        request.start()
    }
    
    func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
        print("Did receive response")
        
        if !response.products.isEmpty {
            for fetchedProduct in response.products {
                DispatchQueue.main.async {
                    self.myProducts.append(fetchedProduct)
                }
            }
        }
        
        for invalidIdentifier in response.invalidProductIdentifiers {
            print("Invalid identifiers found: \(invalidIdentifier)")
        }
    }
    
    func request(_ request: SKRequest, didFailWithError error: Error) {
        print("Request did fail: \(error)")
    }
    
    //HANDLE TRANSACTIONS
    @Published var transactionState: SKPaymentTransactionState?
    
    func purchaseProduct(product: SKProduct) {
        if SKPaymentQueue.canMakePayments() {
            let payment = SKPayment(product: product)
            SKPaymentQueue.default().add(payment)
        } else {
            print("User can't make payment.")
        }
    }
    
    func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
        for transaction in transactions {
            switch transaction.transactionState {
            case .purchasing:
                transactionState = .purchasing
            case .purchased:
                UserDefaults.standard.setValue(true, forKey: transaction.payment.productIdentifier)
                queue.finishTransaction(transaction)
                transactionState = .purchased
            case .restored:
                UserDefaults.standard.setValue(true, forKey: transaction.payment.productIdentifier)
                queue.finishTransaction(transaction)
                transactionState = .restored
            case .failed, .deferred:
                print("Payment Queue Error: \(String(describing: transaction.error))")
                queue.finishTransaction(transaction)
                transactionState = .failed
            default:
                queue.finishTransaction(transaction)
            }
        }
    }
    
    func restoreProducts() {
        print("Restoring products ...")
        SKPaymentQueue.default().restoreCompletedTransactions()
    }
}

你可以试试这个-

if let url = Bundle.main.appStoreReceiptURL, 
   let data = try? Data(contentsOf: url) {
      let receiptBase64 = data.base64EncodedString()
      // Send to server
}

更新

Wondering what your would recommend if eg the connection is interrupted before the receipt strings is sent to my server and for some reason the user deletes the app or something before I can process it.

  1. 在 UserDefaults 中为名为 needsToSendPurchaseReceiptToServer 的变量存储一个 true 值。
  2. 成功完成 API 调用后,将其更新为 false
  3. 如果 api 调用失败,请不要更新 UserDefaults 值。
  4. 下次您的应用程序启动/或从后台恢复 appDidBecomeActive 回调时,您检查此标志,如果它仍然 true,请尝试再次将收据发送到服务器。
  5. 不需要向用户提供任何通知。
  6. 如果多次失败,用户应该仍然可以通过 Restore Purchase 选项手动触发。