@@ -333,33 +333,15 @@ private extension CollectOrderPaymentUseCase {
333333
334334 trackPaymentFailure ( with: error)
335335
336- // Inform about the error
337- alertsPresenter. present (
338- viewModel: paymentAlerts. error ( error: error,
339- tryAgain: { [ weak self] in
340-
341- // Cancel current payment
342- self ? . paymentOrchestrator. cancelPayment { [ weak self] result in
343- guard let self = self else { return }
344-
345- switch result {
346- case . success:
347- // Retry payment
348- self . attemptPayment ( alertProvider: paymentAlerts,
349- onCompletion: onCompletion)
350-
351- case . failure( let cancelError) :
352- // Inform that payment can't be retried.
353- self . alertsPresenter. present (
354- viewModel: paymentAlerts. nonRetryableError ( error: cancelError) {
355- onCompletion ( . failure( error) )
356- } )
357- }
358- }
359- } , dismissCompletion: {
360- onCompletion ( . failure( error) )
361- } )
362- )
336+ if canRetryPayment ( with: error) {
337+ presentRetryableError ( error: error,
338+ paymentAlerts: paymentAlerts,
339+ onCompletion: onCompletion)
340+ } else {
341+ presentNonRetryableError ( error: error,
342+ paymentAlerts: paymentAlerts,
343+ onCompletion: onCompletion)
344+ }
363345 }
364346
365347 private func trackPaymentFailure( with error: Error ) {
@@ -370,6 +352,72 @@ private extension CollectOrderPaymentUseCase {
370352 cardReaderModel: connectedReader? . readerType. model) )
371353 }
372354
355+ private func canRetryPayment( with error: Error ) -> Bool {
356+ guard let serviceError = error as? CardReaderServiceError else {
357+ return true
358+ }
359+ switch serviceError {
360+ case . paymentMethodCollection( let underlyingError) ,
361+ . paymentCapture( let underlyingError) ,
362+ . paymentCancellation( let underlyingError) :
363+ return canRetryPayment ( underlyingError: underlyingError)
364+ default :
365+ return true
366+ }
367+ }
368+
369+ private func canRetryPayment( underlyingError: UnderlyingError ) -> Bool {
370+ switch underlyingError {
371+ case . notConnectedToReader,
372+ . commandNotAllowedDuringCall,
373+ . featureNotAvailableWithConnectedReader:
374+ return false
375+ default :
376+ return true
377+ }
378+ }
379+
380+ private func presentRetryableError( error: Error ,
381+ paymentAlerts: CardReaderTransactionAlertsProviding ,
382+ onCompletion: @escaping ( Result < CardPresentCapturedPaymentData , Error > ) -> ( ) ) {
383+ alertsPresenter. present (
384+ viewModel: paymentAlerts. error ( error: error,
385+ tryAgain: { [ weak self] in
386+
387+ // Cancel current payment
388+ self ? . paymentOrchestrator. cancelPayment { [ weak self] result in
389+ guard let self = self else { return }
390+
391+ switch result {
392+ case . success:
393+ // Retry payment
394+ self . attemptPayment ( alertProvider: paymentAlerts,
395+ onCompletion: onCompletion)
396+
397+ case . failure( let cancelError) :
398+ // Inform that payment can't be retried.
399+ self . alertsPresenter. present (
400+ viewModel: paymentAlerts. nonRetryableError ( error: cancelError) {
401+ onCompletion ( . failure( error) )
402+ } )
403+ }
404+ }
405+ } , dismissCompletion: {
406+ onCompletion ( . failure( error) )
407+ } )
408+ )
409+ }
410+
411+ private func presentNonRetryableError( error: Error ,
412+ paymentAlerts: CardReaderTransactionAlertsProviding ,
413+ onCompletion: @escaping ( Result < CardPresentCapturedPaymentData , Error > ) -> ( ) ) {
414+ alertsPresenter. present (
415+ viewModel: paymentAlerts. nonRetryableError ( error: error,
416+ dismissCompletion: {
417+ onCompletion ( . failure( error) )
418+ } ) )
419+ }
420+
373421 /// Cancels payment and record analytics.
374422 ///
375423 func cancelPayment( onCompleted: @escaping ( ) -> ( ) ) {
0 commit comments