Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,10 @@ public class PaywallViewController: UIViewController, LoadingDelegate {
/// Tracks whether explicit stripe_checkout_abandon was already received for this checkout flow.
private var didReceiveStripeCheckoutAbandonMessage = false

/// The product ID from the most recent stripe_checkout_start message, used as a fallback
/// when the user swipe-dismisses the checkout sheet before stripe_checkout_abandon fires.
private var lastStripeCheckoutProductId: String?

/// Ensures Stripe checkout callbacks are forwarded to WebEntitlementRedeemer in order.
private var previousStripeCheckoutTask: Task<Void, Never>?

Expand Down Expand Up @@ -1126,12 +1130,13 @@ extension PaywallViewController: UIAdaptivePresentationControllerDelegate {

// MARK: - PaywallMessageHandlerDelegate
extension PaywallViewController: PaywallMessageHandlerDelegate {
func openPaymentSheet(_ url: URL) {
func openPaymentSheet(_ url: URL, productId: String?) {
#if !os(visionOS)
// Reset flags when opening checkout
didRedeemSucceedDuringCheckout = false
isCheckoutDismissedProgrammatically = false
didReceiveStripeCheckoutAbandonMessage = false
lastStripeCheckoutProductId = productId
transactionAbandonWorkItem?.cancel()
transactionAbandonWorkItem = nil

Expand All @@ -1155,11 +1160,12 @@ extension PaywallViewController: PaywallMessageHandlerDelegate {
if !self.didRedeemSucceedDuringCheckout,
!self.isCheckoutDismissedProgrammatically,
!self.didReceiveStripeCheckoutAbandonMessage {
let abandonProductId = self.lastStripeCheckoutProductId ?? ""
let workItem = DispatchWorkItem { [weak self] in
guard let self = self else { return }
Task {
let event = InternalSuperwallEvent.Transaction(
state: .abandon(StoreProduct.blank()),
state: .abandon(StoreProduct.blank(productIdentifier: abandonProductId)),
paywallInfo: self.info,
product: nil,
transaction: nil,
Expand All @@ -1178,6 +1184,7 @@ extension PaywallViewController: PaywallMessageHandlerDelegate {
self.didRedeemSucceedDuringCheckout = false
self.isCheckoutDismissedProgrammatically = false
self.didReceiveStripeCheckoutAbandonMessage = false
self.lastStripeCheckoutProductId = nil
}

checkoutVC.modalPresentationStyle = .pageSheet
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ enum PaywallMessage: Decodable, Equatable {
case restore
case openUrl(_ url: URL)
case openUrlInSafari(_ url: URL)
case openPaymentSheet(_ url: URL)
case openPaymentSheet(_ url: URL, productId: String?)
case openDeepLink(url: URL)
case purchase(productId: String, shouldDismiss: Bool)
case custom(data: String)
Expand Down Expand Up @@ -184,7 +184,12 @@ enum PaywallMessage: Decodable, Equatable {
// On visionOS, always use openUrl instead of payment sheet
self = .openUrl(url)
#else
self = browserType == "payment_sheet" ? .openPaymentSheet(url) : .openUrl(url)
if browserType == "payment_sheet" {
let productId = try? values.decode(String.self, forKey: .productId)
self = .openPaymentSheet(url, productId: productId)
} else {
self = .openUrl(url)
}
#endif
return
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
func presentSafariInApp(_ url: URL)
func presentSafariExternal(_ url: URL)
func requestReview(type: ReviewType)
func openPaymentSheet(_ url: URL)
func openPaymentSheet(_ url: URL, productId: String?)
func handleStripeCheckoutSubmit(checkoutContextId: String, productId: String)
func handleStripeCheckoutComplete(
checkoutContextId: String,
Expand Down Expand Up @@ -176,8 +176,8 @@
openUrl(url)
case .openUrlInSafari(let url):
openUrlInSafari(url)
case .openPaymentSheet(let url):
openPaymentSheet(url)
case let .openPaymentSheet(url, productId):
openPaymentSheet(url, productId: productId)
case .openDeepLink(let url):
openDeepLink(url)
case .restore:
Expand Down Expand Up @@ -414,7 +414,7 @@
// block selection
let selectionString =
// swiftlint:disable:next line_length
"var css = '*{-webkit-touch-callout:none;-webkit-user-select:none} .w-webflow-badge { display: none !important; }'; "

Check warning on line 417 in Sources/SuperwallKit/Paywall/View Controller/Web View/Message Handling/PaywallMessageHandler.swift

View workflow job for this annotation

GitHub Actions / Package-SwiftLint

Superfluous Disable Command Violation: SwiftLint rule 'line_length' did not trigger a violation in the disabled region; remove the disable command (superfluous_disable_command)
+ "var head = document.head || document.getElementsByTagName('head')[0]; "
+ "var style = document.createElement('style'); style.type = 'text/css'; "
+ "style.appendChild(document.createTextNode(css)); head.appendChild(style); "
Expand Down Expand Up @@ -474,13 +474,13 @@
delegate?.presentSafariExternal(url)
}

private func openPaymentSheet(_ url: URL) {
private func openPaymentSheet(_ url: URL, productId: String?) {
detectHiddenPaywallEvent(
"openPaymentSheet",
userInfo: ["url": url]
)
hapticFeedback()
delegate?.openPaymentSheet(url)
delegate?.openPaymentSheet(url, productId: productId)
}

private func openDeepLink(_ url: URL) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,11 @@ final class PaywallMessageHandlerDelegateMock: PaywallMessageHandlerDelegate {
didRequestReview = true
}

func openPaymentSheet(_ url: URL) {
var openPaymentSheetProductId: String?

func openPaymentSheet(_ url: URL, productId: String?) {
didOpenPaymentSheet = true
openPaymentSheetProductId = productId
}

func handleStripeCheckoutSubmit(checkoutContextId: String, productId: String) {
Expand Down
Loading