Stripe PaymentSheet with async/await as a call anywhere UIKit extension
By Ryan Romanchuk
On
On
import UIKit
import class Stripe.PaymentSheet
import enum Stripe.PaymentSheetResult
extension UIViewController {
func showStripePaymentSheet() async throws -> PaymentSheetResult {
guard let customerId = await currentUser()?.stripe_customer_id else {
throwFatal("Missing required customer account.")
}
let setupIntent = try await BillingService.createSetupIntent()
let ephemeralKey = try await StripeUserService.fetchEphemeralKey()
var configuration = PaymentSheet.Configuration()
configuration.allowsDelayedPaymentMethods = true
configuration.customer = .init(id: customerId, ephemeralKeySecret: ephemeralKey.secret)
configuration.returnURL = C.Stripe.config.return_url
let paymentSheet = PaymentSheet(setupIntentClientSecret: setupIntent.client_secret, configuration: configuration)
let result: PaymentSheetResult = await withCheckedContinuation { continuation in
paymentSheet.present(from: self) { paymentResult in
continuation.resume(returning: paymentResult)
}
}
switch result {
case .completed:
break
case .canceled, .failed:
async let _ = try? await BillingService.cancelSetupIntent(setupIntent.id)
}
return result
}
}
Usage
class MyViewController: UIViewController {
func updateCard() {
Task {
do {
let result = try await showStripePaymentSheet()
switch result {
case .completed:
// showSuccess()
default:
break
}
} catch {
log.error(error)
}
}
}
}