Skip to content

Commit

Permalink
Stores the latest transaction for SK2 as fallback
Browse files Browse the repository at this point in the history
  • Loading branch information
yusuftor committed Jan 16, 2025
1 parent c7169c2 commit e1fc16d
Show file tree
Hide file tree
Showing 7 changed files with 26 additions and 12 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ The changelog for `SuperwallKit`. Also see the [releases](https://github.com/sup

- Renames `PaywallView(event:)` to `PaywallView(placement:)`.

### Fixes

- Adds extra check to get StoreKit 2 transaction data on `transaction_complete`.

## 4.0.0-beta.2

### Fixes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ The `Superwall` class is used to access all the features of the SDK. Before usin
- `PaywallViewController`
- `PaywallViewControllerDelegate`
- `PaywallViewControllerDelegateObjc`
- `PaywallView`

### Handling Purchases

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ final class PurchaseManager: Purchasing {
identityManager: identityManager,
receiptManager: receiptManager,
storage: storage,
coordinator: coordinator,
factory: factory
)
_sk2TransactionListener = SK2TransactionListener(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,20 +137,21 @@ actor PurchasingCoordinator {
result: PurchaseResult
) async {
let transaction = await factory.makeStoreTransaction(from: transaction)
completePurchase(of: transaction, result: result)
storeTransaction(transaction, result: result)
completion?(result)
}

@available(iOS 15.0, *)
func completePurchase(
of transaction: SK2Transaction,
func storeTransaction(
_ transaction: SK2Transaction,
result: PurchaseResult
) async {
let transaction = await factory.makeStoreTransaction(from: transaction)
completePurchase(of: transaction, result: result)
storeTransaction(transaction, result: result)
}

private func completePurchase(
of transaction: StoreTransaction,
private func storeTransaction(
_ transaction: StoreTransaction,
result: PurchaseResult
) {
if result == .purchased {
Expand All @@ -170,7 +171,6 @@ actor PurchasingCoordinator {
}
}
lastInternalTransaction = transaction
completion?(result)
}

func reset() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ extension ProductPurchaserSK1: SKPaymentTransactionObserver {
)
if !isExistingTransaction {
let transactionManager = factory.makeTransactionManager()
await transactionManager.observeTransaction(for: skTransaction.payment.productIdentifier)
await transactionManager.observeSK1Transaction(for: skTransaction.payment.productIdentifier)
storedIds.insert(skTransaction.payment.productIdentifier)
storage.save(storedIds, forType: PurchasingProductIds.self)
}
Expand Down Expand Up @@ -262,7 +262,8 @@ extension ProductPurchaserSK1: SKPaymentTransactionObserver {
}
await coordinator.completePurchase(
of: skTransaction,
result: .failed(error))
result: .failed(error)
)
}
case .deferred:
finishTransaction(skTransaction)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import StoreKit
final class ProductPurchaserSK2: Purchasing {
private unowned let identityManager: IdentityManager
private unowned let receiptManager: ReceiptManager
private let coordinator: PurchasingCoordinator
private unowned let factory: Factory
typealias Factory = HasExternalPurchaseControllerFactory
& OptionsFactory
Expand All @@ -30,10 +31,12 @@ final class ProductPurchaserSK2: Purchasing {
identityManager: IdentityManager,
receiptManager: ReceiptManager,
storage: Storage,
coordinator: PurchasingCoordinator,
factory: Factory
) {
self.identityManager = identityManager
self.receiptManager = receiptManager
self.coordinator = coordinator
self.factory = factory

if #available(iOS 17.2, *) {
Expand Down Expand Up @@ -105,10 +108,14 @@ final class ProductPurchaserSK2: Purchasing {
case let .success(.verified(transaction)):
await transaction.finish()
await receiptManager.loadPurchasedProducts()
return .purchased
let result = PurchaseResult.purchased
await coordinator.storeTransaction(transaction, result: result)
return result
case let .success(.unverified(transaction, error)):
await transaction.finish()
return .failed(error)
let result = PurchaseResult.failed(error)
await coordinator.storeTransaction(transaction, result: result)
return result
case .userCancelled:
return .cancelled
case .pending:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ final class TransactionManager {
}
}

func observeTransaction(for productId: String) async {
func observeSK1Transaction(for productId: String) async {
guard
let storeProduct = try? await productsManager.products(
identifiers: [productId],
Expand Down

0 comments on commit e1fc16d

Please sign in to comment.