Skip to content

Commit

Permalink
Added internal `NonSubscriptionTransaction.storeTransactionIdentifi…
Browse files Browse the repository at this point in the history
…er` (#3009)

This will be used for #2841.
  • Loading branch information
NachoSoto authored and MarkVillacampa committed Sep 6, 2023
1 parent 6868946 commit 534107a
Show file tree
Hide file tree
Showing 10 changed files with 53 additions and 13 deletions.
5 changes: 5 additions & 0 deletions Sources/Networking/Responses/CustomerInfoResponse.swift
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ extension CustomerInfoResponse {
var purchaseDate: Date?
var originalPurchaseDate: Date?
var transactionIdentifier: String?
var storeTransactionIdentifier: String?
@IgnoreDecodeErrors<Store>
var store: Store
var isSandbox: Bool
Expand Down Expand Up @@ -118,6 +119,7 @@ extension CustomerInfoResponse.Transaction: Codable, Hashable {
case purchaseDate
case originalPurchaseDate
case transactionIdentifier = "id"
case storeTransactionIdentifier = "storeTransactionId"
case store
case isSandbox

Expand Down Expand Up @@ -174,12 +176,14 @@ extension CustomerInfoResponse.Transaction {
purchaseDate: Date?,
originalPurchaseDate: Date?,
transactionIdentifier: String?,
storeTransactionIdentifier: String?,
store: Store,
isSandbox: Bool
) {
self.purchaseDate = purchaseDate
self.originalPurchaseDate = originalPurchaseDate
self.transactionIdentifier = transactionIdentifier
self.storeTransactionIdentifier = storeTransactionIdentifier
self.store = store
self.isSandbox = isSandbox
}
Expand Down Expand Up @@ -221,6 +225,7 @@ extension CustomerInfoResponse.Subscription {
return .init(purchaseDate: self.purchaseDate,
originalPurchaseDate: self.originalPurchaseDate,
transactionIdentifier: nil,
storeTransactionIdentifier: nil,
store: self.store,
isSandbox: self.isSandbox)
}
Expand Down
18 changes: 17 additions & 1 deletion Sources/Purchasing/NonSubscriptionTransaction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,38 @@ public final class NonSubscriptionTransaction: NSObject {
/// The date that App Store charged the user’s account.
@objc public let purchaseDate: Date

/// The unique identifier for the transaction.
/// The unique identifier for the transaction created by RevenueCat.
@objc public let transactionIdentifier: String

/// The unique identifier for the transaction created by the Store.
@objc internal let storeTransactionIdentifier: String

init?(with transaction: CustomerInfoResponse.Transaction, productID: String) {
guard let transactionIdentifier = transaction.transactionIdentifier,
let storeTransactionIdentifier = transaction.storeTransactionIdentifier,
let purchaseDate = transaction.purchaseDate else {
Logger.error("Couldn't initialize NonSubscriptionTransaction. " +
"Reason: missing data: \(transaction).")
return nil
}

self.transactionIdentifier = transactionIdentifier
self.storeTransactionIdentifier = storeTransactionIdentifier
self.purchaseDate = purchaseDate
self.productIdentifier = productID
}

public override var description: String {
return """
<\(String(describing: NonSubscriptionTransaction.self)):
productIdentifier=\(self.productIdentifier)
purchaseDate=\(self.purchaseDate)
transactionIdentifier=\(self.transactionIdentifier)
storeTransactionIdentifier=\(self.storeTransactionIdentifier)
>
"""
}

}

#if swift(>=5.7)
Expand Down
7 changes: 6 additions & 1 deletion Tests/BackendIntegrationTests/StoreKitIntegrationTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,13 @@ class StoreKit1IntegrationTests: BaseStoreKitIntegrationTests {
}

func testCanPurchaseConsumable() async throws {
let info = try await self.purchaseConsumablePackage().customerInfo
let result = try await self.purchaseConsumablePackage()
let info = result.customerInfo
let transaction = try XCTUnwrap(result.transaction)
let nonSubscription = try XCTUnwrap(info.nonSubscriptions.onlyElement)

expect(nonSubscription.productIdentifier) == Self.consumable10Coins
expect(nonSubscription.storeTransactionIdentifier) == transaction.transactionIdentifier
expect(info.allPurchasedProductIdentifiers).to(contain(Self.consumable10Coins))
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ class CustomerInfoDecodingTests: BaseHTTPResponseTest {
expect(transaction.purchaseDate) == dateFormatter.date(from: "2022-02-11T00:03:28Z")
expect(transaction.originalPurchaseDate) == dateFormatter.date(from: "2022-03-10T00:04:28Z")
expect(transaction.transactionIdentifier) == "17459f5ff7"
expect(transaction.storeTransactionIdentifier) == "340001090153249"
expect(transaction.store) == .appStore
expect(transaction.isSandbox) == false
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"purchase_date": "2022-02-11T00:03:28Z",
"original_purchase_date": "2022-03-10T00:04:28Z",
"id": "17459f5ff7",
"store_transaction_id": "340001090153249",
"store": "app_store",
"is_sandbox": false
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
"is_sandbox" : false,
"original_purchase_date" : 668563468,
"purchase_date" : 666230608,
"store" : "app_store"
"store" : "app_store",
"store_transaction_id" : "340001090153249"
}
]
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
"is_sandbox" : false,
"original_purchase_date" : 668563468,
"purchase_date" : 666230608,
"store" : "app_store"
"store" : "app_store",
"store_transaction_id" : "340001090153249"
}
]
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
"is_sandbox" : false,
"original_purchase_date" : 668563468,
"purchase_date" : 666230608,
"store" : "app_store"
"store" : "app_store",
"store_transaction_id" : "340001090153249"
}
]
},
Expand Down
2 changes: 2 additions & 0 deletions Tests/UnitTests/Purchasing/CustomerInfoTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class BasicCustomerInfoTests: TestCase {
"onetime_purchase": [
[
"id": "d6c007ba74",
"store_transaction_id": "340001090153249",
"is_sandbox": true,
"original_purchase_date": "1990-08-30T02:40:36Z",
"purchase_date": "1990-08-30T02:40:36Z",
Expand Down Expand Up @@ -153,6 +154,7 @@ class BasicCustomerInfoTests: TestCase {
expect(transaction.productIdentifier) == "onetime_purchase"
expect(transaction.purchaseDate) == ISO8601DateFormatter.default.date(from: "1990-08-30T02:40:36Z")
expect(transaction.transactionIdentifier) == "d6c007ba74"
expect(transaction.storeTransactionIdentifier) == "340001090153249"
}

@available(*, deprecated) // Ignore deprecation warnings
Expand Down
23 changes: 15 additions & 8 deletions Tests/UnitTests/Purchasing/TransactionsFactoryTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,22 @@ class TransactionsFactoryTests: TestCase {
let nonSubscriptionTransactions = try TransactionsFactory.nonSubscriptionTransactions(
withSubscriptionsData: Self.sampleTransactions
)
expect(nonSubscriptionTransactions.count) == 5
expect(nonSubscriptionTransactions).to(haveCount(5))

try Self.sampleTransactions.forEach { productId, transactionsData in
for (productId, transactionsData) in Self.sampleTransactions {
let filteredTransactions = nonSubscriptionTransactions
.filter { $0.productIdentifier == productId }

expect(filteredTransactions.count) == transactionsData.count
expect(filteredTransactions).to(haveCount(transactionsData.count))

try transactionsData.forEach { dictionary in
let transactionId = try XCTUnwrap(dictionary["id"] as? String)
let containsTransaction = filteredTransactions
.contains { $0.transactionIdentifier == transactionId }
for dictionary in transactionsData {
let revenueCatTransactionID = try XCTUnwrap(dictionary["id"] as? String)
let storeTransactionID = try XCTUnwrap(dictionary["store_transaction_id"] as? String)

expect(containsTransaction) == true
expect(filteredTransactions).to(containElementSatisfying {
$0.transactionIdentifier == revenueCatTransactionID &&
$0.storeTransactionIdentifier == storeTransactionID
})
}
}

Expand All @@ -48,13 +50,15 @@ private extension TransactionsFactoryTests {
"100_coins": [
[
"id": "72c26cc69c",
"store_transaction_id": "1",
"is_sandbox": true,
"original_purchase_date": "1990-08-30T02:40:36Z",
"purchase_date": "2019-07-11T18:36:20Z",
"store": "app_store"
],
[
"id": "6229b0bef1",
"store_transaction_id": "2",
"is_sandbox": true,
"original_purchase_date": "2019-11-06T03:26:15Z",
"purchase_date": "2019-11-06T03:26:15Z",
Expand All @@ -64,13 +68,15 @@ private extension TransactionsFactoryTests {
"500_coins": [
[
"id": "d6c007ba74",
"store_transaction_id": "3",
"is_sandbox": true,
"original_purchase_date": "2019-07-11T18:36:20Z",
"purchase_date": "2019-07-11T18:36:20Z",
"store": "play_store"
],
[
"id": "5b9ba226bc",
"store_transaction_id": "4",
"is_sandbox": true,
"original_purchase_date": "2019-07-26T22:10:27Z",
"purchase_date": "2019-07-26T22:10:27Z",
Expand All @@ -80,6 +86,7 @@ private extension TransactionsFactoryTests {
"lifetime_access": [
[
"id": "d6c097ba74",
"store_transaction_id": "5",
"is_sandbox": true,
"original_purchase_date": "2018-07-11T18:36:20Z",
"purchase_date": "2018-07-11T18:36:20Z",
Expand Down

0 comments on commit 534107a

Please sign in to comment.