Skip to content

Commit

Permalink
PurchaseOrchestrator: fix incorrect InitiationSource for SK1 queu…
Browse files Browse the repository at this point in the history
…e transactions
  • Loading branch information
NachoSoto committed Apr 21, 2023
1 parent f4a6888 commit fc064d5
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 21 deletions.
47 changes: 36 additions & 11 deletions Sources/Purchasing/Purchases/PurchasesOrchestrator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -570,9 +570,14 @@ extension PurchasesOrchestrator: StoreKit1WrapperDelegate {
let storeTransaction = StoreTransaction(sk1Transaction: transaction)

switch transaction.transactionState {
case .restored, // for observer mode
.purchased:
self.handlePurchasedTransaction(storeTransaction, storefront: storeKit1Wrapper.currentStorefront)
case .restored: // for observer mode
self.handlePurchasedTransaction(storeTransaction,
storefront: storeKit1Wrapper.currentStorefront,
restored: true)
case .purchased:
self.handlePurchasedTransaction(storeTransaction,
storefront: storeKit1Wrapper.currentStorefront,
restored: false)
case .purchasing:
break
case .failed:
Expand Down Expand Up @@ -708,15 +713,19 @@ extension PurchasesOrchestrator: @unchecked Sendable {}
private extension PurchasesOrchestrator {

func handlePurchasedTransaction(_ transaction: StoreTransaction,
storefront: StorefrontType?) {
storefront: StorefrontType?,
restored: Bool) {
self.receiptFetcher.receiptData(
refreshPolicy: self.refreshRequestPolicy(forProductIdentifier: transaction.productIdentifier)
) { receiptData in
if let receiptData = receiptData, !receiptData.isEmpty {
self.fetchProductsAndPostReceipt(withTransaction: transaction,
receiptData: receiptData,
initiationSource: .purchase,
storefront: storefront)
self.fetchProductsAndPostReceipt(
withTransaction: transaction,
receiptData: receiptData,
initiationSource: self.initiationSource(for: transaction.productIdentifier,
restored: restored),
storefront: storefront
)
} else {
self.handleReceiptPost(withTransaction: transaction,
result: .failure(.missingReceiptFile()),
Expand Down Expand Up @@ -799,6 +808,20 @@ private extension PurchasesOrchestrator {
#endif
}
}

private func initiationSource(
for productIdentifier: String,
restored: Bool
) -> ProductRequestData.InitiationSource {
let hasPurchaseCallback = self.purchaseCompleteCallbacksByProductID.value.keys.contains(productIdentifier)

switch (hasPurchaseCallback, restored) {
case (true, false): return .purchase
case (true, true): return .restore
case (false, _): return .queue
}
}

}

@available(iOS 15.0, tvOS 15.0, macOS 12.0, watchOS 8.0, *)
Expand Down Expand Up @@ -919,8 +942,8 @@ private extension PurchasesOrchestrator {
let unsyncedAttributes = self.unsyncedAttributes

self.backend.post(receiptData: receiptData,
appUserID: appUserID,
isRestore: allowSharingAppStoreAccount,
appUserID: self.appUserID,
isRestore: self.allowSharingAppStoreAccount,
productData: productData,
presentedOfferingIdentifier: presentedOfferingID,
observerMode: self.observerMode,
Expand Down Expand Up @@ -1177,7 +1200,9 @@ extension PurchasesOrchestrator {
}
)

self.handlePurchasedTransaction(transaction, storefront: storefront)
self.handlePurchasedTransaction(transaction,
storefront: storefront,
restored: false)
}
}

Expand Down
4 changes: 4 additions & 0 deletions Tests/StoreKitUnitTests/PurchasesOrchestratorTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ class PurchasesOrchestratorTests: StoreKitConfigTestCase {
expect(self.backend.invokedPostReceiptDataCount) == 1
expect(self.backend.invokedPostReceiptDataParameters?.productData).toNot(beNil())
expect(self.backend.invokedPostReceiptDataParameters?.offeringIdentifier) == "offering"
expect(self.backend.invokedPostReceiptDataParameters?.initiationSource) == .purchase
}

func testSK1PurchaseDoesNotAlwaysRefreshReceiptInProduction() async throws {
Expand Down Expand Up @@ -436,6 +437,7 @@ class PurchasesOrchestratorTests: StoreKitConfigTestCase {
expect(self.backend.invokedPostReceiptDataCount) == 1
expect(self.backend.invokedPostReceiptDataParameters?.productData).toNot(beNil())
expect(self.backend.invokedPostReceiptDataParameters?.offeringIdentifier).to(beNil())
expect(self.backend.invokedPostReceiptDataParameters?.initiationSource) == .purchase
}

@available(iOS 15.0, tvOS 15.0, watchOS 8.0, macOS 12.0, *)
Expand Down Expand Up @@ -639,6 +641,7 @@ class PurchasesOrchestratorTests: StoreKitConfigTestCase {
expect(transaction.finishInvoked) == true
expect(self.backend.invokedPostReceiptData) == true
expect(self.backend.invokedPostReceiptDataParameters?.isRestore) == false
expect(self.backend.invokedPostReceiptDataParameters?.initiationSource) == .queue
}

@available(iOS 15.0, tvOS 15.0, watchOS 8.0, macOS 12.0, *)
Expand Down Expand Up @@ -722,6 +725,7 @@ class PurchasesOrchestratorTests: StoreKitConfigTestCase {
expect(transaction.finishInvoked) == false
expect(self.backend.invokedPostReceiptData) == true
expect(self.backend.invokedPostReceiptDataParameters?.isRestore) == true
expect(self.backend.invokedPostReceiptDataParameters?.initiationSource) == .queue
}

@available(iOS 15.0, tvOS 15.0, watchOS 8.0, macOS 12.0, *)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,15 @@ class PurchasesPurchasingTests: BasePurchasesTests {
let transaction = MockTransaction()
transaction.mockPayment = try XCTUnwrap(self.storeKit1Wrapper.payment)

transaction.mockState = SKPaymentTransactionState.purchasing
transaction.mockState = .purchasing
self.storeKit1Wrapper.delegate?.storeKit1Wrapper(self.storeKit1Wrapper, updatedTransaction: transaction)

transaction.mockState = SKPaymentTransactionState.purchased
transaction.mockState = .purchased
self.storeKit1Wrapper.delegate?.storeKit1Wrapper(self.storeKit1Wrapper, updatedTransaction: transaction)

expect(self.backend.postReceiptDataCalled) == true
expect(self.backend.postedIsRestore) == false
expect(self.backend.postedInitiationSource) == .purchase
expect(self.purchasesDelegate.customerInfoReceivedCount).toEventually(equal(1))
}

Expand Down Expand Up @@ -68,13 +69,14 @@ class PurchasesPurchasingTests: BasePurchasesTests {
let transaction = MockTransaction()
transaction.mockPayment = try XCTUnwrap(self.storeKit1Wrapper.payment)

transaction.mockState = SKPaymentTransactionState.purchasing
transaction.mockState = .purchasing
self.storeKit1Wrapper.delegate?.storeKit1Wrapper(self.storeKit1Wrapper, updatedTransaction: transaction)

transaction.mockState = SKPaymentTransactionState.purchased
transaction.mockState = .purchased
self.storeKit1Wrapper.delegate?.storeKit1Wrapper(self.storeKit1Wrapper, updatedTransaction: transaction)

expect(self.backend.postReceiptDataCalled) == true
expect(self.backend.postedInitiationSource) == .purchase
expect(self.backend.postedIsRestore) == false
}

Expand All @@ -86,11 +88,11 @@ class PurchasesPurchasingTests: BasePurchasesTests {

let transaction = MockTransaction()
transaction.mockPayment = try XCTUnwrap(self.storeKit1Wrapper.payment)
transaction.mockState = .purchasing

transaction.mockState = SKPaymentTransactionState.purchasing
self.storeKit1Wrapper.delegate?.storeKit1Wrapper(self.storeKit1Wrapper, updatedTransaction: transaction)

transaction.mockState = SKPaymentTransactionState.purchased
transaction.mockState = .purchased
self.storeKit1Wrapper.delegate?.storeKit1Wrapper(self.storeKit1Wrapper, updatedTransaction: transaction)

expect(self.backend.postReceiptDataCalled) == true
Expand Down Expand Up @@ -944,10 +946,10 @@ class PurchasesPurchasingCustomSetupTests: BasePurchasesTests {
let transaction = MockTransaction()
transaction.mockPayment = try XCTUnwrap(self.storeKit1Wrapper.payment)

transaction.mockState = SKPaymentTransactionState.purchasing
transaction.mockState = .purchasing
self.storeKit1Wrapper.delegate?.storeKit1Wrapper(self.storeKit1Wrapper, updatedTransaction: transaction)

transaction.mockState = SKPaymentTransactionState.purchased
transaction.mockState = .purchased
self.storeKit1Wrapper.delegate?.storeKit1Wrapper(self.storeKit1Wrapper, updatedTransaction: transaction)

expect(self.backend.postReceiptDataCalled) == true
Expand All @@ -963,10 +965,11 @@ class PurchasesPurchasingCustomSetupTests: BasePurchasesTests {
let transaction = MockTransaction()
transaction.mockPayment = try XCTUnwrap(self.storeKit1Wrapper.payment)

transaction.mockState = SKPaymentTransactionState.restored
transaction.mockState = .restored
self.storeKit1Wrapper.delegate?.storeKit1Wrapper(self.storeKit1Wrapper, updatedTransaction: transaction)

expect(self.backend.postReceiptDataCalled) == true
expect(self.backend.postedInitiationSource) == .restore
expect(self.storeKit1Wrapper.finishCalled).toEventually(beFalse())
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,8 @@ class PurchasesTransactionHandlingTests: BasePurchasesTests {
transaction.mockState = .purchased
try self.delegate.storeKit1Wrapper(self.storeKit1Wrapper, updatedTransaction: transaction)

expect(self.backend.postReceiptDataCalled).to(beTrue())
expect(self.backend.postReceiptDataCalled) == true
expect(self.backend.postedInitiationSource) == .queue
expect(self.purchasesDelegate.customerInfoReceivedCount).toEventually(equal(2))
}

Expand Down

0 comments on commit fc064d5

Please sign in to comment.