Class: Payment::StrategyResolver

Inherits:
BaseService show all
Defined in:
app/services/payment/strategy_resolver.rb

Defined Under Namespace

Classes: CaptureOptions, Deadline, ReauthResult, Result

Constant Summary collapse

REAUTH_BUFFER_DAYS =
2
LEGACY_AUTH_WINDOW_DAYS =
6
EXTENDED_AUTH_WINDOW_DAYS =
28
PAYPAL_AUTH_WINDOW_DAYS =
3

Instance Method Summary collapse

Methods inherited from BaseService

#log_debug, #log_error, #log_info, #log_warning, #logger, #options, #process, #tagged_logger

Constructor Details

#initialize(payment) ⇒ StrategyResolver

Returns a new instance of StrategyResolver.



23
24
25
# File 'app/services/payment/strategy_resolver.rb', line 23

def initialize(payment)
  @payment = payment
end

Instance Method Details

#authorization_deadlineObject



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'app/services/payment/strategy_resolver.rb', line 85

def authorization_deadline
  if @payment.capture_before.present?
    remaining = ((@payment.capture_before - Time.current) / 1.day).ceil
    source = paypal? ? :paypal_api : :stripe_api
    Deadline.new(capture_before: @payment.capture_before, days_remaining: remaining, source: source)
  else
    fallback_days = if paypal?
                      PAYPAL_AUTH_WINDOW_DAYS
                    elsif supports_extended_authorization?
                      EXTENDED_AUTH_WINDOW_DAYS
                    else
                      LEGACY_AUTH_WINDOW_DAYS
                    end
    fallback = @payment.created_at + fallback_days.days
    remaining = ((fallback - Time.current) / 1.day).ceil
    Deadline.new(capture_before: fallback, days_remaining: remaining, source: :heuristic)
  end
end

#capture_options(order:) ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'app/services/payment/strategy_resolver.rb', line 39

def capture_options(order:)
  unless credit_card? || paypal?
    return CaptureOptions.new(final_capture: true, reason: 'non-gateway payment')
  end

  if credit_card? && !supports_multicapture?
    return CaptureOptions.new(final_capture: true, reason: 'multicapture not available')
  end

  if cross_order_siblings_pending?
    return CaptureOptions.new(final_capture: false, reason: 'cross-order siblings still authorized')
  end

  unshipped = order.deliveries.select { |d| !d.shipped? && !d.invoiced? }
  if unshipped.size > 1
    CaptureOptions.new(final_capture: false, reason: "#{unshipped.size} deliveries still pending")
  else
    CaptureOptions.new(final_capture: true, reason: 'last or only delivery')
  end
end

#increase_strategy(new_amount) ⇒ Object



60
61
62
63
64
65
66
67
68
69
70
71
# File 'app/services/payment/strategy_resolver.rb', line 60

def increase_strategy(new_amount)
  return Result.new(strategy: :new_payment, reason: 'not a credit card') unless credit_card?

  if supports_incremental_authorization? && @payment.authorized? && @payment.stripe_payment_intent_id.present?
    Result.new(strategy: :increment, payment: @payment, reason: 'incremental authorization available')
  elsif @payment.credit_card_vault.present?
    Result.new(strategy: :void_and_reauth, payment: @payment, vault: @payment.credit_card_vault,
               reason: 'no incremental auth; vault available for void+reauth')
  else
    Result.new(strategy: :new_payment, reason: 'no incremental auth and no vault')
  end
end

#needs_reauthorization?Boolean

Returns:

  • (Boolean)


73
74
75
76
77
78
79
80
81
82
83
# File 'app/services/payment/strategy_resolver.rb', line 73

def needs_reauthorization?
  return ReauthResult.new(reauth_needed: false, reason: 'not authorized') unless @payment.authorized?
  return ReauthResult.new(reauth_needed: false, reason: 'not a credit card') unless credit_card?

  deadline = authorization_deadline
  if deadline.capture_before.present? && deadline.days_remaining <= REAUTH_BUFFER_DAYS
    ReauthResult.new(reauth_needed: true, reason: "capture_before in #{deadline.days_remaining} days (#{deadline.source})")
  else
    ReauthResult.new(reauth_needed: false, reason: "#{deadline.days_remaining} days remaining (#{deadline.source})")
  end
end

#supports_extended_authorization?Boolean

Returns:

  • (Boolean)


35
36
37
# File 'app/services/payment/strategy_resolver.rb', line 35

def supports_extended_authorization?
  credit_card? && capability_value(:extended_authorization) == 'enabled'
end

#supports_incremental_authorization?Boolean

Returns:

  • (Boolean)


31
32
33
# File 'app/services/payment/strategy_resolver.rb', line 31

def supports_incremental_authorization?
  credit_card? && capability_value(:incremental_authorization) == 'available'
end

#supports_multicapture?Boolean

Returns:

  • (Boolean)


27
28
29
# File 'app/services/payment/strategy_resolver.rb', line 27

def supports_multicapture?
  credit_card? && capability_value(:multicapture) == 'available'
end