#DevonAllary

1 messages · Page 1 of 1 (latest)

odd oysterBOT
frank badge
#

HI 👋 apologies for the oversight. The server was really busy and we missed your question. Are you still with us?

whole pike
#

no problem, yes I'm still here

#

I'm currently on a work call though so I might not be very quick to respond

frank badge
#

Okay, taking a look at your question now

whole pike
#

thanks!

frank badge
#

So is the issue that you don't want to create a Payment Intent up front?

whole pike
#

Yeah, I don't want to create a payment intent on the view loading, but only when the user clicks a button ("Buy"), then I have a call to the server to create the payment intent. However, the payment sheet won't present after this

frank badge
#

I don't think that is possible, as Payment Intents are not optional. I would recommend gathering product data and presenting that, then creating the Payment Intent and rendering the Payment Sheet after they select one of the products

whole pike
#

Gotcha, I might just need to change my UI. Is there somewhere I could request this as a feature update? The same issue is causing a bit of unusual behaviour in my app. For example, I have another view where I create a "Setup Intent" so that my users can manage their payment methods, but because I have to load the Setup Intent before the view loads, it leads to that page of my app having a very long load time even before the user "commits" to changing their payment method

frank badge
whole pike
#

thanks for your help!

whole pike
#

However, I want to do this all in the same view without having to navigate to a second "Product Detail" page or something

frank badge
#

I'm not sure I understand. That seems doable and relatively simple to set up. Is there a question?

whole pike
#

I have a list of products, as you described, and a button for each product. When the button is clicked, my app calls the server to retrieve a payment intent for that product. However, it doesn't render this onto the view as a bottom sheet.

#

I'd like help figuring out why it won't render

#

I have a link to the code in my first message

frank badge
#

Can you repost the code that you're using to create the Payment Intent before redirecting?

whole pike
#

import SwiftUI
import Stripe
import FirebaseFunctions

class ItemCheckoutViewModel: ObservableObject {
@Published var paymentSheet: PaymentSheet?
@Published var paymentResult: PaymentSheetResult?
@Published var showPaymentSheet = false
var stripePublishableKey = "[Redacted]"
lazy var functions = Functions.functions()

@MainActor
func preparePaymentSheet(for item: ProductItem) async {
    do {
        let result = try await functions.httpsCallable("getStripeIntent").call([
            "itemId": item.id
        ])
        if let data = result.data as? [String: Any] {
            guard
                let customerId = data["customer"] as? String,
                let customerEphemeralKeySecret = data["ephemeralKey"] as? String,
                let paymentIntentClientSecret = data["paymentIntent"] as? String
            else {
                return
            }
            STPAPIClient.shared.publishableKey = stripePublishableKey
            var configuration = PaymentSheet.Configuration()
            configuration.merchantDisplayName = "Test"
            configuration.customer = .init(id: customerId, ephemeralKeySecret: customerEphemeralKeySecret)
            configuration.allowsDelayedPaymentMethods = true
            self.paymentSheet = PaymentSheet(paymentIntentClientSecret: paymentIntentClientSecret, configuration: configuration)
            self.showPaymentSheet = true
        }
        
    } catch {
        print(error)
    }
}
func handlePaymentCompletion(result: PaymentSheetResult) {
    //
}

}

#

struct ProductItem: Identifiable, Codable {
var id: String
var title: String
var amount: Int
}

struct PaymentSheetView: View {
@StateObject var viewModel = ItemCheckoutViewModel()
var items: [ProductItem]

@ViewBuilder func itemRowView(item: ProductItem) -> some View {
    HStack {
        Text(item.title)
        Spacer()
        Button {
            Task {
                await viewModel.preparePaymentSheet(for: item)
            }
        } label: {
            Text("Pay \(String(format: "$%.2f", item.amount/100))")
        }
    }
}
var body: some View {
    List(items) { item in
        itemRowView(item: item)
    }

// This is the problem here... it won't render this view
if let paymentSheet = viewModel.paymentSheet {
EmptyView()
.paymentSheet(isPresented: $viewModel.showPaymentSheet,
paymentSheet: paymentSheet,
onCompletion: viewModel.handlePaymentCompletion)
}
}
}

glossy bronze
#

Hey @whole pike ! I'm sorry but none of the people around on my team know enough about this to help I'm sorry. I think the best option here will be to ask for support directly to our support team via https://support.stripe.com/contact/email. Make it clear what you are trying to do, share detailed/exact code, screenshots of what you are trying to achieve, reference the doc(s) you are following and that you spoke to us on Discord and someone will be able to help you with this

whole pike
#

got it, thanks!