Skip to content

Conversation

ajpallares
Copy link
Member

This PR integrates the (fake) purchase UI for Test Store products (under the TEST_STORE compiler flag).

Screenshots

iOS

image

macOS

image

tvOS

image

visionOS

image

watchOS

image

@ajpallares ajpallares requested a review from a team July 21, 2025 16:22
Copy link

emerge-tools bot commented Jul 21, 2025

📸 Snapshot Test

705 unchanged

Name Added Removed Modified Renamed Unchanged Errored Approval
RevenueCat
com.revenuecat.PaywallsTester
0 0 0 0 235 0 N/A
RevenueCat
com.revenuecat.PaywallsTester.mac-catalyst-optimized-for-mac
0 0 0 0 235 0 N/A
RevenueCat
com.revenuecat.PaywallsTester.mac-catalyst-scaled-to-match-ipad
0 0 0 0 235 0 N/A

🛸 Powered by Emerge Tools

Copy link
Member

@JayShortway JayShortway left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice!

Comment on lines 186 to 187
var message = "⚠️ This is a test purchase and should be tested with real products using " +
"an Apple API key from RevenueCat.\n\n"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is slightly confusing imo. How about something like:

This is a test purchase and should only be used during development. In production, use an Apple API key from RevenueCat.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like it! It may be worth changing this copy also in react-native-purchases @tonidero?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup! Will update my branch!

Copy link
Contributor

@tonidero tonidero left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great to me! Nice job!!


private extension PurchasesOrchestrator {

func handlePurchase(testStoreProduct: TestStoreProduct, completion: @escaping PurchaseCompletedBlock) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see we created a TestStorePurchaseHandler. Would it make sense to also move all this logic there? Mostly want to avoid increasing the size of the orchestrator too much... and this all seems like it could live there?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think that's a good point. I intend to add the whole after-purchase logic in a separate PR so I'll take this into account to add all the logic in the TestStorePurchaseHandler. I agree it's better to keep PurchasesOrchestrator as dedicated as possible to the "real" purchases logic.
Thanks for the suggestion!

if userConfirmed {
// WIP: Implement actual test purchase completion logic
// For now, we'll simulate a successful purchase
completion(nil, nil, nil, false)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to return the CustomerInfo for this? Though I'm ok adding that later once we add the actual implementation I think

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, exactly. We need to return the CustomerInfo here. Right now, confirming the purchase crashes due to it not containing the CustomerInfo. I could return the same mocked CustomerInfo that I used for UI preview mode. It will only contain minimum hardcoded information, but I think it's better than a crash. WDYT?
It's not a big deal as this is all under the TEST_STORE flag, but perhaps it's better a hardcoded response than a crash anyway.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah... either that or just fetching the latest customer info... but that's probably harder, and not something we will need to do anyway, so I think a hardcoded version is ok for now!

@ajpallares ajpallares force-pushed the test-store/test-purchase-ui branch from 1f9948b to cc50f53 Compare July 22, 2025 10:27
@ajpallares
Copy link
Member Author

@RCGitBot please test

Since the minimum supported versions of the SDK are iOS 13 and tvOS 13
Comment on lines +106 to +111
if #available(iOS 15.0, macCatalyst 15.0, *) {
window = nil
} else {
// Fallback to legacy approach on OSs where UIApplication's `windows` property is not deprecated
window = application.windows.first(where: { $0.isKeyWindow })
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UIApplication's windows property is deprecated since iOS 15, visionOS 1, so this was triggering a warning that was making CI fail. I've tested with visionOS 1, iOS 15 and tvOS and it works properly (the window is taken from application.currentWindowScene above

@ajpallares
Copy link
Member Author

I did some cleanup and added small changes based on the review comments and also to remove some deprecation warnings.
I will add unit tests in a future PR when I implement the complete Test Store Product purchase flow.

Copy link
Contributor

@tonidero tonidero left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great!

@ajpallares ajpallares merged commit 02cccca into main Jul 28, 2025
12 checks passed
@ajpallares ajpallares deleted the test-store/test-purchase-ui branch July 28, 2025 17:11
This was referenced Jul 30, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants