Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] Allow passing additional completion on PaymentButton initialization for button action (User taps button to start checkout) #3215

Open
rromanchuk opened this issue Jan 26, 2024 · 1 comment
Labels
kind:improvement triaged Issue has been reviewed by Stripe and is being tracked internally

Comments

@rromanchuk
Copy link

Is your feature request related to a problem? Please describe.

Using PaymentSheet.PaymentButton there is not an obvious way to react to the button press, the action completion, Button(action:{}, label: {}) is wrapped.

Describe the solution you'd like

I'd like to be able to pass an additional optional block, something like onTap: (() -> Void)? = nil that yields on the actual button press.

Why? That user intent is an important event in standard ecomm funnel: add_to_cart -> view_cart -> begin_checkout -> purchase.

Describe alternatives you've considered

I guess tacking on an .onTapGesture, but that seems like a super smelly as a modifier on a Button

Additional context

extension PaymentSheet {
    /// A button which presents a sheet for a customer to complete their payment.
    /// This is a convenience wrapper for the .paymentSheet() ViewModifier.
    /// - Parameter paymentSheet: A PaymentSheet to present.
    /// - Parameter onCompletion: Called with the result of the payment after the payment sheet is dismissed.
    /// - Parameter onTap: Called when user 
    ///    taps button to launch the payment sheet, aka initiates the checkout
    /// - Parameter content: The content of the view.
    public struct PaymentButton<Content: View>: View {
        private let paymentSheet: PaymentSheet
        private let onCompletion: (PaymentSheetResult) -> Void
        private let content: Content

        @State private var showingPaymentSheet = false

        /// Initialize a `PaymentButton` with required parameters.
        public init(
            paymentSheet: PaymentSheet,
            onCompletion: @escaping (PaymentSheetResult) -> Void, // <---- this is *after* checkout was initiated 
            onTap: @escaping (() -> Void)? = nil, // <-- completion on button tap
            @ViewBuilder content: () -> Content
        ) {
            self.paymentSheet = paymentSheet
            self.onCompletion = onCompletion
            self.content = content()
        }

        public var body: some View {
            Button(action: {
                onTap?() // <----- Yield here so I can Analytics.logEvent(AnalyticsEventBeginCheckout)
                showingPaymentSheet = true
            }) {
                content
            }.paymentSheet(
                isPresented: $showingPaymentSheet,
                paymentSheet: paymentSheet,
                onCompletion: onCompletion)
        }
    }
}
@porter-stripe
Copy link
Collaborator

Hi 👋 @rromanchuk this is something on our roadmap to implement but we don't have a specific timeline to share. I'll keep this issue open and circle back once we have more details.

@porter-stripe porter-stripe added the triaged Issue has been reviewed by Stripe and is being tracked internally label Apr 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind:improvement triaged Issue has been reviewed by Stripe and is being tracked internally
Projects
None yet
Development

No branches or pull requests

2 participants