#commander-apollo-z_api
1 messages Β· Page 1 of 1 (latest)
π Welcome to your new thread!
β²οΈ We'll be here soon! Typically we respond in a few minutes, but sometimes we might take a bit longer if the server is busy or if you have a particularly tricky question.
β±οΈ We close idle threads, which makes them read-only. Once a thread is closed it won't be reopened, but you can always start a new thread if you have another question.
π This thread will always be available, even after it's closed. You can find it again using Discord's search, or you can save this link: https://discord.com/channels/841573134531821608/1354535151161577482
π Have more to share? Add more details, code, screenshots, videos, etc. below.
Hi π can we start by aligning on what you're doing, because if you're using the Payment Sheet then I'm surprised to hear you're also using an in-app browser for any part of the payment process.
Hi! I'm using the payment sheet, correct. With the iDEAL payment method. This opens a browser view inside the app where I can either confirm or decline the payment.
Hm, okay. And that page is being opened automatically by the Payment Sheet? Or are you directing your customers to that page yourself?
When you say you open this with Safari, is that using the buttom near the bottom of that view to open that same page in Safari?
The Payment Sheet is opening it automatically. And yes, it works when I authorize it that way. But when I click the Safari icon, the page opens in Safari, I can still confirm, and the payment goes through. But the returnURL is not being handled by the function anymore. The Payment Sheet still shows me that I should pay. When I do, I get the error that the paymentIntent is already being used, and the payment paid.
I would expect that once I return back to the app through the returnURL, that the PaymentSheet would react the same as when using the in app browser.
Hm, I'm not sure that is expected to behave the same, let me see if I can find a teammte more familiar with these iOS flows.
Okay thanks π
π not deeply familiar here with iOS but have a bit of experience -- our mobile dev expert isn't available right now unfortunately.
That said, when you "click the Safari" icon can you clarify exactly what you mean by that?
Hi! In the second image I sent, the screenshot from the in app browser, there is a small Safari icon on the bottom right corner, next to the sharing icon. When you click this icon, the page is being opened in a regular (not in app) Safari window (or whichever browser is set as the system default).
I use the paymentSheet convenience wrapper, which I assume internally uses the Flow Controller.
The FlowController is one variation of using PaymentSheet
Can you show me your relevant client-side code snippets here?
Here is the UI part:
struct PaymentSheetViewSimple<Content: View>: View {
private let paymentSheet: PaymentSheet
private let onCompletion: (PaymentSheetResult) -> Void
private let content: Content
@State private var showingPaymentSheet: Bool = false
/// Initialize a `PaymentButton` with required parameters.
public init(
paymentSheet: PaymentSheet,
onCompletion: @escaping (PaymentSheetResult) -> Void,
@ViewBuilder content: () -> Content
) {
self.paymentSheet = paymentSheet
self.onCompletion = onCompletion
self.content = content()
}
var body: some View {
content
.paymentSheet(
isPresented: $showingPaymentSheet,
paymentSheet: paymentSheet,
onCompletion: onCompletion
)
.onAppear {
showingPaymentSheet = true
}
}
}
The payment model:
@Observable
public class PaymentModel {
public init() {}
let apiPath = "/payment-sheet"
let returnURL = "xxxx://stripe-redirect"
public private(set) var paymentSheet: PaymentSheet?
public private(set) var paymentResult: PaymentSheetResult?
public var showPaymentSheet: Bool = false
public func preparePaymentSheet(customerId: String, orderId: String) async throws {
let requestBody = PrepareStripePaymentRequestBodySchema(
customerId: customerId,
amount: 10.00,
currency: "eur"
)
let responseBody = try await LambdaQuery.shared.prepareStripePayment(requestBody)
STPAPIClient.shared.publishableKey = responseBody.publishableKey
await MainActor.run {
var configuration = PaymentSheet.Configuration()
configuration.returnURL = returnURL
configuration.merchantDisplayName = "Xxxx.xx"
configuration.billingDetailsCollectionConfiguration.address = .never
configuration.billingDetailsCollectionConfiguration.email = .never
configuration.billingDetailsCollectionConfiguration.name = .never
configuration.billingDetailsCollectionConfiguration.phone = .never
configuration.customer = PaymentSheet.CustomerConfiguration(
id: responseBody.customerId,
ephemeralKeySecret: responseBody.ephemeralKeySecret
)
configuration.allowsDelayedPaymentMethods = true
self.paymentSheet = PaymentSheet(paymentIntentClientSecret: responseBody.paymentIntentClientSecret, configuration: configuration)
self.showPaymentSheet = true
}
}
public func onPaymentCompletion(result: PaymentSheetResult) {
self.paymentResult = result
}
}
And the handling of the returnUrl (which does work from within the in app browser):
var body: some Scene {
WindowGroup {
AppContentView()
.preferredColorScheme(.dark)
.onOpenURL {
if StripeAPI.handleURLCallback(with: $0) {
Log.checkout.debug("Stripe url: \($0.debugDescription)")
} else {
Log.debug.debug("Other url: \($0.debugDescription)")
}
}
}
Okay so doesn't look like you are using FlowController
So you never handle confirming the PaymentIntent yourself, correct?
No, I only create the intent through my backend, everything else is handled by the paymentSheet Stripe provides
Okay one minute
Okay π
If you just use your custom URL scheme directly from Safari does it open your App?
Yes it does, also the Stripe page where I can confirm or decline a payment does open the app from Safari, and the log Log.debug.debug("Other url: \($0.debugDescription)") does log the URL
The URL it logs looks like this:xxxx://stripe-redirect?payment_intent=pi_xxxxxxxxxxx&payment_intent_client_secret=pi_xxxxxxxxxx_secret_xxxxxxxxx&redirect_status=succeeded
Oh I'm sorry, I thought you weren't being redirected to your app at all in this case.
The deep link itself works fine, but the state of the PaymentIntent is broken?
Ahh no, it's basically this function that does not return true: StripeAPI.handleURLCallback(with: $0)
Ah ah it just recognizes that it is a different URL as opposed to the Stripe redirect.
Okay I gotcha now
Curious
Looks to be a bug since you have no control here.
I'll file a ticket to get this looked at by our Eng team.
Okay perfect. Thanks! π
Hello @wicked pagoda, we have sent you a direct message, please check it at https://discord.com/channels/@me/1354559486337220780
- πThe message has instructions on how to open a direct support case with our Developer Support team, in order to help you more effectively.
Go ahead and follow the instructions in the DM you just received and then we can follow up our email after our Eng team has had a look.
Let me know when you submitted that flow.
Sounds good! I'll let you know once I'm done with it, might be a moment though. π