diff --git a/Signal/src/ViewControllers/Donations/DonationPaymentDetailsViewController+MonthlyDonation.swift b/Signal/src/ViewControllers/Donations/DonationPaymentDetailsViewController+MonthlyDonation.swift index d5f6cb3238..7baf9f0dba 100644 --- a/Signal/src/ViewControllers/Donations/DonationPaymentDetailsViewController+MonthlyDonation.swift +++ b/Signal/src/ViewControllers/Donations/DonationPaymentDetailsViewController+MonthlyDonation.swift @@ -21,83 +21,64 @@ extension DonationPaymentDetailsViewController { Logger.info("[Donations] Starting monthly donation") - Promise.wrapAsync { - try await DonationViewsUtil.wrapInProgressView( - from: self, - operation: firstly(on: DispatchQueue.sharedUserInitiated) { () -> Promise in - if let existingSubscriberId { - Logger.info("[Donations] Cancelling existing subscription") - - return Promise.wrapAsync { + Task { + do { + try await DonationViewsUtil.wrapInProgressView( + from: self, + operation: { + if let existingSubscriberId { + Logger.info("[Donations] Cancelling existing subscription") try await DonationSubscriptionManager.cancelSubscription(for: existingSubscriberId) + } else { + Logger.info("[Donations] No existing subscription to cancel") } - } else { - Logger.info("[Donations] No existing subscription to cancel") - return Promise.value(()) - } - }.then(on: DispatchQueue.sharedUserInitiated) { () -> Promise in - Logger.info("[Donations] Preparing new monthly subscription") + Logger.info("[Donations] Preparing new monthly subscription") + let subscriberId = try await DonationSubscriptionManager.prepareNewSubscription(currencyCode: currencyCode) - return Promise.wrapAsync { - try await DonationSubscriptionManager.prepareNewSubscription(currencyCode: currencyCode) - } - }.then(on: DispatchQueue.sharedUserInitiated) { subscriberId -> Promise<(Data, DonationSubscriptionManager.RecurringSubscriptionPaymentType)> in - Promise.wrapAsync { () -> String in Logger.info("[Donations] Creating Signal payment method for new monthly subscription") - return try await Stripe.createSignalPaymentMethodForSubscription(subscriberId: subscriberId) - }.then(on: DispatchQueue.sharedUserInitiated) { clientSecret -> Promise in - Logger.info("[Donations] Authorizing payment for new monthly subscription") + let clientSecret = try await Stripe.createSignalPaymentMethodForSubscription(subscriberId: subscriberId) - return Promise.wrapAsync { - return try await Stripe.setupNewSubscription( - clientSecret: clientSecret, - paymentMethod: validForm.stripePaymentMethod - ) - }.then(on: DispatchQueue.sharedUserInitiated) { confirmedIntent -> Promise in - if let redirectToUrl = confirmedIntent.redirectToUrl { - if case .ideal = validForm.donationPaymentMethod { - Logger.info("[Donations] Subscription requires iDEAL authentication. Presenting...") - let confirmedDonation = PendingMonthlyIDEALDonation( - subscriberId: subscriberId, - clientSecret: clientSecret, - setupIntentId: confirmedIntent.setupIntentId, - newSubscriptionLevel: newSubscriptionLevel, - oldSubscriptionLevel: priorSubscriptionLevel, - amount: self.donationAmount - ) - SSKEnvironment.shared.databaseStorageRef.write { tx in - do { - try donationStore.setPendingSubscription(donation: confirmedDonation, tx: tx) - } catch { - owsFailDebug("[Donations] Failed to persist pending iDEAL subscription.") - } + Logger.info("[Donations] Authorizing payment for new monthly subscription") + let confirmedIntent = try await Stripe.setupNewSubscription( + clientSecret: clientSecret, + paymentMethod: validForm.stripePaymentMethod + ) + + if let redirectToUrl = confirmedIntent.redirectToUrl { + if case .ideal = validForm.donationPaymentMethod { + Logger.info("[Donations] Subscription requires iDEAL authentication. Presenting...") + let confirmedDonation = PendingMonthlyIDEALDonation( + subscriberId: subscriberId, + clientSecret: clientSecret, + setupIntentId: confirmedIntent.setupIntentId, + newSubscriptionLevel: newSubscriptionLevel, + oldSubscriptionLevel: priorSubscriptionLevel, + amount: self.donationAmount + ) + await SSKEnvironment.shared.databaseStorageRef.awaitableWrite { tx in + do { + try donationStore.setPendingSubscription(donation: confirmedDonation, tx: tx) + } catch { + owsFailDebug("[Donations] Failed to persist pending iDEAL subscription.") } - } else { - Logger.info("[Donations] Subscription requires 3DS authentication. Presenting...") } - return self.show3DS(for: redirectToUrl) - .map(on: DispatchQueue.sharedUserInitiated) { _ in - return confirmedIntent - } } else { - return Promise.value(confirmedIntent) - } - }.map { confirmedIntent in - switch validForm { - case .card: - return .creditOrDebitCard(paymentMethodId: confirmedIntent.paymentMethodId) - case .sepa: - return .sepa(paymentMethodId: confirmedIntent.paymentMethodId) - case .ideal: - return .ideal(setupIntentId: confirmedIntent.setupIntentId) + Logger.info("[Donations] Subscription requires 3DS authentication. Presenting...") } + _ = try await self.show3DS(for: redirectToUrl).awaitable() } - }.map(on: DispatchQueue.sharedUserInitiated) { paymentType -> (Data, DonationSubscriptionManager.RecurringSubscriptionPaymentType) in - (subscriberId, paymentType) - } - }.then(on: DispatchQueue.sharedUserInitiated) { (subscriberId, paymentType) in - return Promise.wrapAsync { + + let paymentType: DonationSubscriptionManager.RecurringSubscriptionPaymentType + switch validForm { + case .card: + paymentType = .creditOrDebitCard(paymentMethodId: confirmedIntent.paymentMethodId) + case .sepa: + paymentType = .sepa(paymentMethodId: confirmedIntent.paymentMethodId) + case .ideal: + paymentType = .ideal(setupIntentId: confirmedIntent.setupIntentId) + } + try await DonationViewsUtil.completeMonthlyDonations( subscriberId: subscriberId, paymentType: paymentType, @@ -107,14 +88,13 @@ extension DonationPaymentDetailsViewController { databaseStorage: SSKEnvironment.shared.databaseStorageRef ) } - }.awaitable - ) - }.done(on: DispatchQueue.main) { [weak self] in - Logger.info("[Donations] Monthly donation finished") - self?.onFinished(nil) - }.catch(on: DispatchQueue.main) { [weak self] error in - Logger.info("[Donations] Monthly donation UX dismissing w/error (might not be fatal)") - self?.onFinished(error) + ) + Logger.info("[Donations] Monthly donation finished") + self.onFinished(nil) + } catch { + Logger.info("[Donations] Monthly donation UX dismissing w/error (might not be fatal)") + self.onFinished(error) + } } } }