Skip to content
Draft
Show file tree
Hide file tree
Changes from 53 commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
16e6383
Track customer center purchases
facumenzella Oct 21, 2025
05b03df
simplified logic
facumenzella Oct 22, 2025
5205282
add spiinternal
facumenzella Oct 22, 2025
37e9ddd
Merge branch 'main' into feat/paywall-source
facumenzella Oct 22, 2025
f6aef6d
fixed tests
facumenzella Oct 22, 2025
a9885c2
pod lib lint
facumenzella Oct 22, 2025
ba5e231
Add PaywallSource.swift to RevenueCatUI target
ajpallares Mar 2, 2026
61a4904
Remove unnecessary `@_spi(Internal)` attributes
ajpallares Mar 2, 2026
eaf2a30
Simplified Customer Center paywall source to `customer_center`
ajpallares Mar 2, 2026
75fa191
Remove redundant `source` parameter from `track` method
ajpallares Mar 2, 2026
aa70dc4
Update snapshot files
ajpallares Mar 2, 2026
fd1c9a6
Move PaywallSource to RevenueCat module as @_spi(Internal) enum
ajpallares Mar 2, 2026
3cb71dd
Fix: pass `paywallSource` to `PaywallEvent` creation
ajpallares Mar 2, 2026
a73b3e3
Cleanup unnecessary diff
ajpallares Mar 2, 2026
7bb804f
Revert changes to Examples/rc-maestro/rc-maestro/Resources/StoreKit/S…
ajpallares Mar 2, 2026
225d51f
Remove redundant source parameter from trackPaywallImpression
ajpallares Mar 2, 2026
f296de3
Undo changes to RevenueCatUI/Purchasing/MockPurchases.swift
ajpallares Mar 2, 2026
a1e3649
Undo changes to RevenueCatUI/Purchasing/PurchaseHandler.swift
ajpallares Mar 2, 2026
35f2098
Remove presentedOfferingSource from receipt posting
ajpallares Mar 2, 2026
c19f27d
Remove trailing newlines from snapshot JSON files
ajpallares Mar 2, 2026
d6cc5eb
Simplification
ajpallares Mar 2, 2026
b27f274
Remove trailing newlines from OfferingContext snapshot files
ajpallares Mar 2, 2026
09734f4
Change Paywall.source type from String? to PaywallSource?
ajpallares Mar 2, 2026
7505fa6
Revert cosmetic changes to PurchaseHandler+TestData.swift
ajpallares Mar 2, 2026
db71ef5
Change EventsRequest.PaywallEvent.source type from String? to Paywall…
ajpallares Mar 2, 2026
a3c02c3
Cleanup
ajpallares Mar 2, 2026
274efe2
Revert cosmetic changes in AsyncPurchaseHandler init
ajpallares Mar 2, 2026
52370ce
Add snapshot test for PaywallEvent source serialization
ajpallares Mar 2, 2026
58b2931
Merge remote-tracking branch 'origin/main' into feat/paywall-source
ajpallares Mar 2, 2026
c4efa7f
Update deprecation messages for PaywallEvent.Data inits
ajpallares Mar 2, 2026
8cd9955
Fix compilation error, add source: nil test coverage, fix snapshot ne…
ajpallares Mar 2, 2026
fe45b30
Fix snapshot test trailing newlines causing test failures
ajpallares Mar 2, 2026
bf43308
Fix exhaustive switch on PaywallEvent in PurchaseHandlerTests
ajpallares Mar 2, 2026
71593a0
Add presentedOfferingSource to receipt posting
ajpallares Mar 2, 2026
377f9ac
Add PurchaseSource tracking for non-paywall purchases
ajpallares Mar 2, 2026
2a9f152
Use typed PurchaseSource in CachedPurchaseSource and PurchasedTransac…
ajpallares Mar 2, 2026
03bcbff
Persist presentedOfferingSource in LocalTransactionMetadata
ajpallares Mar 3, 2026
e2a9926
[skip ci] Generating new test snapshots (#6377)
RCGitBot Mar 3, 2026
bbbd391
[skip ci] Generating new test snapshots (#6378)
RCGitBot Mar 3, 2026
3e61256
[skip ci] Generating new test snapshots (#6381)
RCGitBot Mar 3, 2026
e39605c
[skip ci] Generating new test snapshots (#6385)
RCGitBot Mar 3, 2026
f733110
[skip ci] Generating new test snapshots (#6384)
RCGitBot Mar 3, 2026
744cdee
[skip ci] Generating new test snapshots (#6382)
RCGitBot Mar 3, 2026
c2ecdbc
[skip ci] Generating new test snapshots (#6383)
RCGitBot Mar 3, 2026
4988cdd
[skip ci] Generating new test snapshots (#6379)
RCGitBot Mar 3, 2026
125310e
Merge branch 'main' into feat/paywall-source
ajpallares Mar 3, 2026
213d58e
Merge branch 'feat/paywall-source' into pallares/presented-offering-s…
ajpallares Mar 3, 2026
6b5e41c
Add missing `cachePurchaseSource` call
ajpallares Mar 3, 2026
f9e5d15
Generating new test snapshots for `pallares/presented-offering-source…
RCGitBot Mar 3, 2026
d119a2e
Merge branch 'main' into feat/paywall-source
ajpallares Mar 3, 2026
919b581
Merge branch 'feat/paywall-source' into pallares/presented-offering-s…
ajpallares Mar 3, 2026
2a906a2
Merge branch 'main' into feat/paywall-source
ajpallares Mar 3, 2026
84c0a8e
Merge branch 'feat/paywall-source' into pallares/presented-offering-s…
ajpallares Mar 3, 2026
a03e43c
Rename presentedOfferingSource to purchaseSource
ajpallares Mar 3, 2026
84c30a1
Fix lint and snapshot test failures
ajpallares Mar 3, 2026
7cd3856
Merge branch 'main' into feat/paywall-source
ajpallares Mar 4, 2026
6b0f5c9
Merge branch 'feat/paywall-source' into pallares/presented-offering-s…
ajpallares Mar 4, 2026
1e98533
Cache purchase source for Customer Center change plans flow
ajpallares Mar 4, 2026
a63a4f6
Fix PaywallSource being dropped by withPurchaseInfo
ajpallares Mar 4, 2026
133977f
Merge branch 'feat/paywall-source' into pallares/presented-offering-s…
ajpallares Mar 4, 2026
cc0ac0c
Merge branch 'main' into feat/paywall-source
ajpallares Mar 5, 2026
7cbd17a
fix: Add missing `source` parameter to PaywallEvent.Data init in tests
ajpallares Mar 5, 2026
c432e4b
Merge branch 'main' into feat/paywall-source
ajpallares Mar 5, 2026
16cd10b
Merge branch 'main' into feat/paywall-source
ajpallares Mar 6, 2026
39e5e77
Merge branch 'feat/paywall-source' into pallares/presented-offering-s…
ajpallares Mar 6, 2026
ee5fc2a
Merge remote-tracking branch 'origin/main' into pallares/presented-of…
ajpallares Mar 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions RevenueCat.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -835,6 +835,7 @@
57ACB12528174B9F000DCC9F /* CustomerInfo+TestExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57ACB12328174B9F000DCC9F /* CustomerInfo+TestExtensions.swift */; };
57ACB13728184CF1000DCC9F /* DecoderExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57ACB13628184CF1000DCC9F /* DecoderExtensionTests.swift */; };
57B0E8802DFAC2C900EB5FE1 /* PurchaseCardViewBadgeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57B0E87F2DFAC2C400EB5FE1 /* PurchaseCardViewBadgeTests.swift */; };
57B1D7B22F2A1F1800A77E21 /* PaywallSourceEnvironment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57B1D7B12F2A1F1800A77E21 /* PaywallSourceEnvironment.swift */; };
57BA943128330ACA00CD5FC5 /* ConfigurationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57BA943028330ACA00CD5FC5 /* ConfigurationTests.swift */; };
57BB070E28D27A2B007F5DF0 /* CachingProductsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57BB070D28D27A2B007F5DF0 /* CachingProductsManager.swift */; };
57BB071628D282A4007F5DF0 /* CachingProductsManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57BB071528D282A4007F5DF0 /* CachingProductsManagerTests.swift */; };
Expand Down Expand Up @@ -952,6 +953,8 @@
755C26A42E310B19006DD0AE /* WebBillingProductsResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 755C26A32E310B19006DD0AE /* WebBillingProductsResponse.swift */; };
755C26A62E310B7B006DD0AE /* BackendGetWebBillingProductsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 755C26A52E310B7B006DD0AE /* BackendGetWebBillingProductsTests.swift */; };
756AE8352D8816CD00BA2E39 /* PurchasesDiagnosticsTrackingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 756AE8342D8816CD00BA2E39 /* PurchasesDiagnosticsTrackingTests.swift */; };
986C48FD2F55A58C00D8CEA5 /* PaywallSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57B1D7B32F2A213800A77E21 /* PaywallSource.swift */; };
54AA9CA4EE764557A8EABD84 /* PurchaseSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CF9C1D90C944B8BBBE07749 /* PurchaseSource.swift */; };
7571BE9F2D672B2C00A2C8B6 /* TrialOrIntroPriceEligibilityCheckerUIPreviewModeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7571BE9E2D672B2C00A2C8B6 /* TrialOrIntroPriceEligibilityCheckerUIPreviewModeTests.swift */; };
757E73CE2F0FE2410066DCDC /* LocalTransactionMetadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = 757E73CC2F0FE2410066DCDC /* LocalTransactionMetadata.swift */; };
757E73D12F0FE26A0066DCDC /* TransactionMetadataStrings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 757E73D02F0FE26A0066DCDC /* TransactionMetadataStrings.swift */; };
Expand Down Expand Up @@ -2413,6 +2416,9 @@
57ACB12328174B9F000DCC9F /* CustomerInfo+TestExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CustomerInfo+TestExtensions.swift"; sourceTree = "<group>"; };
57ACB13628184CF1000DCC9F /* DecoderExtensionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DecoderExtensionTests.swift; sourceTree = "<group>"; };
57B0E87F2DFAC2C400EB5FE1 /* PurchaseCardViewBadgeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PurchaseCardViewBadgeTests.swift; sourceTree = "<group>"; };
57B1D7B12F2A1F1800A77E21 /* PaywallSourceEnvironment.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PaywallSourceEnvironment.swift; sourceTree = "<group>"; };
57B1D7B32F2A213800A77E21 /* PaywallSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaywallSource.swift; sourceTree = "<group>"; };
0CF9C1D90C944B8BBBE07749 /* PurchaseSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PurchaseSource.swift; sourceTree = "<group>"; };
57B530E52858F3FD00FA4E37 /* SwiftStyleGuide.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = SwiftStyleGuide.swift; path = Contributing/SwiftStyleGuide.swift; sourceTree = "<group>"; };
57BA943028330ACA00CD5FC5 /* ConfigurationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigurationTests.swift; sourceTree = "<group>"; };
57BB070D28D27A2B007F5DF0 /* CachingProductsManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CachingProductsManager.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -4391,6 +4397,7 @@
37E35C7060D7E486F5958BED /* ProductsManager.swift */,
37E35E8DCF998D9DB63850F8 /* ProductsRequestFactory.swift */,
B3DDB55826854865008CCF23 /* PurchaseOwnershipType.swift */,
0CF9C1D90C944B8BBBE07749 /* PurchaseSource.swift */,
80E80EF026970DC3008F245A /* ReceiptFetcher.swift */,
F5BE423F26962ACF00254A30 /* ReceiptRefreshPolicy.swift */,
3597020F24BF6A710010506E /* TransactionsFactory.swift */,
Expand Down Expand Up @@ -4779,6 +4786,7 @@
1621701B2EBE5581008ACFE9 /* Locale+Comparison.swift */,
4F062D312A85A11600A8A613 /* PaywallData+Localization.swift */,
4F6ABC772A81595900250E63 /* PaywallCacheWarming.swift */,
57B1D7B32F2A213800A77E21 /* PaywallSource.swift */,
4F89A55C2A6ABADF008A411E /* PaywallViewMode.swift */,
65279ABC122869A50AEB8A27 /* ExitOffer.swift */,
);
Expand Down Expand Up @@ -5466,6 +5474,7 @@
887A5FD92C1D037000E1A461 /* TemplateViewConfiguration+Images.swift */,
887A5FDA2C1D037000E1A461 /* TestData.swift */,
887A5FDB2C1D037000E1A461 /* UserInterfaceIdiom.swift */,
57B1D7B12F2A1F1800A77E21 /* PaywallSourceEnvironment.swift */,
887A5FDC2C1D037000E1A461 /* Variables.swift */,
93B46553B99148F3A60B8BFB /* CustomPaywallVariables.swift */,
);
Expand Down Expand Up @@ -7254,6 +7263,8 @@
57D5414227F656D9004CC35C /* NetworkError.swift in Sources */,
B3781568285A79FC000A7B93 /* IdentityAPI.swift in Sources */,
B325543C2825C81800DA62EA /* Configuration.swift in Sources */,
986C48FD2F55A58C00D8CEA5 /* PaywallSource.swift in Sources */,
54AA9CA4EE764557A8EABD84 /* PurchaseSource.swift in Sources */,
4F89A55D2A6ABADF008A411E /* PaywallViewMode.swift in Sources */,
4F1428A42A4A132C006CD196 /* TestStoreProductDiscount.swift in Sources */,
53A8DCC32E0EA4FF00FEABEA /* HealthReportAvailabilityResponse.swift in Sources */,
Expand Down Expand Up @@ -7932,6 +7943,7 @@
887A608B2C1D037000E1A461 /* PurchaseHandler+TestData.swift in Sources */,
887A60682C1D037000E1A461 /* TemplateError.swift in Sources */,
887A60792C1D037000E1A461 /* UserInterfaceIdiom.swift in Sources */,
57B1D7B22F2A1F1800A77E21 /* PaywallSourceEnvironment.swift in Sources */,
03C06FCC2D479C7C00600693 /* CarouselComponentViewModel.swift in Sources */,
1699BC382EEB4EFA002001FB /* AppStyleExtractor.swift in Sources */,
887A60742C1D037000E1A461 /* Strings.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ final class CustomerCenterPurchases: CustomerCenterPurchasesType {
product: StoreProduct,
promotionalOffer: PromotionalOffer?
) async throws -> PurchaseResultData {
Purchases.shared.cachePurchaseSource(.customerCenter, productIdentifier: product.productIdentifier)

if let promotionalOffer = promotionalOffer {
return try await Purchases.shared.purchase(
product: product,
Expand All @@ -71,6 +73,8 @@ final class CustomerCenterPurchases: CustomerCenterPurchasesType {
}

func purchase(package: Package) async throws -> PurchaseResultData {
Purchases.shared.cachePurchaseSource(.customerCenter,
productIdentifier: package.storeProduct.productIdentifier)
return try await Purchases.shared.purchase(package: package)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ struct NoSubscriptionsCardView: View {
performRestore: viewModel.performRestore)
)
)
.paywallSource(.customerCenter)
})
.onAppear {
viewModel.refreshOffering()
Expand Down
44 changes: 44 additions & 0 deletions RevenueCatUI/Data/PaywallSourceEnvironment.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//
// PaywallSourceEnvironment.swift
//
//
// Created by RevenueCat on 2/26/25.
//

#if canImport(SwiftUI)

@_spi(Internal) import RevenueCat
import SwiftUI

#if !os(tvOS)

@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)
private struct PaywallSourceKey: EnvironmentKey {

static let defaultValue: PaywallSource? = nil

}

@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)
extension EnvironmentValues {

/// The optional paywall source available in the current environment.
var paywallSource: PaywallSource? {
get { self[PaywallSourceKey.self] }
set { self[PaywallSourceKey.self] = newValue }
}
}

@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)
extension View {

/// Associates the provided paywall source with this view hierarchy so downstream paywall presentations can read it.
func paywallSource(_ source: PaywallSource?) -> some View {
self.environment(\.paywallSource, source)
}

}

#endif

#endif
6 changes: 5 additions & 1 deletion RevenueCatUI/PaywallView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,9 @@ struct LoadedOfferingPaywallView: View {
@Environment(\.dismiss)
private var dismiss

@Environment(\.paywallSource)
private var paywallSource

init(
offering: Offering,
activelySubscribedProductIdentifiers: Set<String>,
Expand Down Expand Up @@ -631,7 +634,8 @@ struct LoadedOfferingPaywallView: View {
sessionID: .init(),
displayMode: self.mode,
locale: .current,
darkMode: self.colorScheme == .dark
darkMode: self.colorScheme == .dark,
source: self.paywallSource
)
}

Expand Down
6 changes: 5 additions & 1 deletion RevenueCatUI/Templates/V2/PaywallsV2View.swift
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ struct PaywallsV2View: View {
@Environment(\.colorScheme)
private var colorScheme

@Environment(\.paywallSource)
private var paywallSource

@StateObject
private var introOfferEligibilityContext: IntroOfferEligibilityContext

Expand Down Expand Up @@ -285,7 +288,8 @@ struct PaywallsV2View: View {
sessionID: .init(),
displayMode: .fullScreen,
locale: .current,
darkMode: self.colorScheme == .dark
darkMode: self.colorScheme == .dark,
source: self.paywallSource
)
}

Expand Down
12 changes: 10 additions & 2 deletions Sources/Networking/Operations/PostReceiptDataOperation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,12 @@ final class PostReceiptDataOperation: CacheableNetworkOperation {
/// - `subscriberAttributesByKey`
/// - `sdkOriginated`
/// - `transactionId` (only if there is attribution data, to always post receipts with attribution data)
let presentedOfferingSource = postData.presentedOfferingSource ?? ""
let cacheKey =
"""
\(configuration.appUserID)-\(postData.isRestore)-\(postData.receipt.hash)
-\(postData.productData?.cacheKey ?? "")
-\(postData.presentedOfferingIdentifier ?? "")-\(postData.observerMode)
-\(postData.presentedOfferingIdentifier ?? "")-\(presentedOfferingSource)-\(postData.observerMode)
-\(postData.subscriberAttributesByKey?.individualizedCacheKeyPart ?? "")
-\(postData.sdkOriginated)
-\(postData.containsAttributionData ? (postData.transactionId ?? "") : "")
Expand Down Expand Up @@ -138,6 +139,7 @@ extension PostReceiptDataOperation {
let productData: ProductRequestData?
let presentedOfferingIdentifier: String?
let presentedPlacementIdentifier: String?
let presentedOfferingSource: String?
let appliedTargetingRule: AppliedTargetingRule?
let paywall: Paywall?

Expand Down Expand Up @@ -171,6 +173,7 @@ extension PostReceiptDataOperation {
var displayMode: PaywallViewMode
var darkMode: Bool
var localeIdentifier: String
var source: PaywallSource?

}

Expand Down Expand Up @@ -206,6 +209,7 @@ extension PostReceiptDataOperation.PostData {
productData: productData,
presentedOfferingIdentifier: data.presentedOfferingContext?.offeringIdentifier,
presentedPlacementIdentifier: data.presentedOfferingContext?.placementIdentifier,
presentedOfferingSource: data.presentedOfferingSource?.rawValue,
appliedTargetingRule: data.presentedOfferingContext?.targetingContext.flatMap {
.init(revision: $0.revision, ruleId: $0.ruleId)
},
Expand Down Expand Up @@ -235,7 +239,8 @@ private extension PurchasedTransactionData {
revision: paywall.data.paywallRevision,
displayMode: paywall.data.displayMode,
darkMode: paywall.data.darkMode,
localeIdentifier: paywall.data.localeIdentifier)
localeIdentifier: paywall.data.localeIdentifier,
source: paywall.data.source)
}
}

Expand Down Expand Up @@ -301,6 +306,7 @@ extension PostReceiptDataOperation.PostData: Encodable {
case presentedPlacementIdentifier
case appliedTargetingRule
case paywall
case presentedOfferingSource = "presented_offering_source"
case testReceiptIdentifier = "test_receipt_identifier"
case appTransaction = "app_transaction"
case transactionId = "transaction_id"
Expand Down Expand Up @@ -332,6 +338,7 @@ extension PostReceiptDataOperation.PostData: Encodable {
try container.encodeIfPresent(self.appliedTargetingRule, forKey: .appliedTargetingRule)
try container.encodeIfPresent(self.paywall, forKey: .paywall)
try container.encodeIfPresent(self.purchaseCompletedBy?.name, forKey: .purchaseCompletedBy)
try container.encodeIfPresent(self.presentedOfferingSource, forKey: .presentedOfferingSource)

try container.encodeIfPresent(
self.subscriberAttributesByKey
Expand All @@ -357,6 +364,7 @@ extension PostReceiptDataOperation.Paywall: Codable {
case displayMode
case darkMode
case localeIdentifier = "locale"
case source

}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ extension FeatureEventsRequest {
var displayMode: PaywallViewMode
var darkMode: Bool
var localeIdentifier: String
var source: PaywallSource?
var exitOfferType: ExitOfferType?
var exitOfferingID: String?
var packageId: String?
Expand Down Expand Up @@ -79,6 +80,7 @@ extension FeatureEventsRequest.PaywallEvent {
displayMode: data.displayMode,
darkMode: data.darkMode,
localeIdentifier: data.localeIdentifier,
source: data.source,
exitOfferType: exitOfferData?.exitOfferType,
exitOfferingID: exitOfferData?.exitOfferingIdentifier,
packageId: data.packageId,
Expand Down Expand Up @@ -133,6 +135,7 @@ extension FeatureEventsRequest.PaywallEvent: Encodable {
case displayMode
case darkMode
case localeIdentifier = "locale"
case source
case exitOfferType
case exitOfferingID = "exitOfferingId"
case packageId = "packageId"
Expand Down
49 changes: 49 additions & 0 deletions Sources/Paywalls/Events/PaywallEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -109,13 +109,15 @@ extension PaywallEvent {
public var displayMode: PaywallViewMode
public var localeIdentifier: String
public var darkMode: Bool
@_spi(Internal) public var source: PaywallSource?
var packageId: String?
var productId: String?
var errorCode: Int?
var errorMessage: String?

#if !os(tvOS) // For Paywalls V2
@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)
@available(*, deprecated, message: "This initializer will be removed in a future version.")
public init(
offering: Offering,
paywallComponentsData: PaywallComponentsData,
Expand All @@ -134,9 +136,32 @@ extension PaywallEvent {
darkMode: darkMode
)
}

@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)
@_spi(Internal) public init(
offering: Offering,
paywallComponentsData: PaywallComponentsData,
sessionID: SessionID,
displayMode: PaywallViewMode,
locale: Locale,
darkMode: Bool,
source: PaywallSource?
) {
self.init(
paywallIdentifier: paywallComponentsData.id,
offeringIdentifier: offering.identifier,
paywallRevision: paywallComponentsData.revision,
sessionID: sessionID,
displayMode: displayMode,
localeIdentifier: locale.identifier,
darkMode: darkMode,
source: source
)
}
#endif

@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)
@available(*, deprecated, message: "This initializer will be removed in a future version.")
public init(
offering: Offering,
paywall: PaywallData,
Expand All @@ -155,6 +180,28 @@ extension PaywallEvent {
darkMode: darkMode
)
}

@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)
@_spi(Internal) public init(
offering: Offering,
paywall: PaywallData,
sessionID: SessionID,
displayMode: PaywallViewMode,
locale: Locale,
darkMode: Bool,
source: PaywallSource?
) {
self.init(
paywallIdentifier: paywall.id,
offeringIdentifier: offering.identifier,
paywallRevision: paywall.revision,
sessionID: sessionID,
displayMode: displayMode,
localeIdentifier: locale.identifier,
darkMode: darkMode,
source: source
)
}
// swiftlint:enable missing_docs

init(
Expand All @@ -165,6 +212,7 @@ extension PaywallEvent {
displayMode: PaywallViewMode,
localeIdentifier: String,
darkMode: Bool,
source: PaywallSource? = nil,
packageId: String? = nil,
productId: String? = nil,
errorCode: Int? = nil,
Expand All @@ -177,6 +225,7 @@ extension PaywallEvent {
self.displayMode = displayMode
self.localeIdentifier = localeIdentifier
self.darkMode = darkMode
self.source = source
self.packageId = packageId
self.productId = productId
self.errorCode = errorCode
Expand Down
22 changes: 22 additions & 0 deletions Sources/Paywalls/PaywallSource.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//
// Copyright RevenueCat Inc. All Rights Reserved.
//
// Licensed under the MIT License (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://opensource.org/licenses/MIT
//
// PaywallSource.swift
//
// Created by RevenueCat on 2/26/25.

import Foundation

/// Identifies where a paywall was presented from so that backend analytics can classify the event.
@_spi(Internal) public enum PaywallSource: String, Sendable, Codable {

/// The paywall was presented from Customer Center.
case customerCenter = "customer_center"

}
Loading