Class: GbPrimepay::CheckStatus

Inherits:
Object
  • Object
show all
Defined in:
app/my_lib/gb_primepay/check_status.rb

Defined Under Namespace

Classes: RateLimitError

Constant Summary collapse

RATE_LIMIT_STATUS_CODES =

Rate limiting status codes and response patterns

[429, 1015].freeze
RATE_LIMIT_PATTERNS =
[
  /rate limit/i,
  /error.*1015/i,
  /ddos protection/i,
  /too many requests/i,
].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeCheckStatus

Returns a new instance of CheckStatus.



26
27
28
29
30
# File 'app/my_lib/gb_primepay/check_status.rb', line 26

def initialize
  @errors = []
  @invalid_card = false
  @rate_limited = false
end

Instance Attribute Details

#dataObject

Returns the value of attribute data.



5
6
7
# File 'app/my_lib/gb_primepay/check_status.rb', line 5

def data
  @data
end

#errorsObject

Returns the value of attribute errors.



5
6
7
# File 'app/my_lib/gb_primepay/check_status.rb', line 5

def errors
  @errors
end

#invalid_cardObject

Returns the value of attribute invalid_card.



5
6
7
# File 'app/my_lib/gb_primepay/check_status.rb', line 5

def invalid_card
  @invalid_card
end

#rate_limitedObject

Returns the value of attribute rate_limited.



5
6
7
# File 'app/my_lib/gb_primepay/check_status.rb', line 5

def rate_limited
  @rate_limited
end

Instance Method Details

#check(reference_no) ⇒ Object



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'app/my_lib/gb_primepay/check_status.rb', line 32

def check(reference_no)
  payload = { referenceNo: reference_no }.to_json
  url = 'v1/check_status_txn'
  reservation = Reservation.find_by(id: reference_no.to_s.split('_').first)

  if reservation.present?
    BUSINESS_LOGGER.set_business_context({
                                           reference_no: reference_no,
                                           reservation_id: reservation&.id,
                                         })
  end

  # Use Retriable gem to handle rate limiting and other transient errors
  Retriable.retriable(
    on: [RateLimitError, Faraday::ConnectionFailed, Faraday::TimeoutError, Errno::ECONNRESET],
    tries: 3,
    base_interval: 10,
    multiplier: 2,
    rand_factor: 0.5,
    on_retry: proc do |exception, _try_number, _elapsed_time, _next_interval|
      @rate_limited = true if exception.is_a?(RateLimitError)
    end,
  ) do
    perform_api_call(url, payload, reservation, reference_no)
  end
rescue RateLimitError => e
  @rate_limited = true
  APMErrorHandler.report('GbPrimepay::CheckStatus rate limited - max retries exceeded', {
                           reservation_id: reservation&.id,
                           reference_no: reference_no,
                           response_status: e.response&.status,
                           response_headers: e.response&.headers&.to_h,
                         })

  errors << 'Payment gateway is temporarily unavailable due to rate limiting. Please try again later.'
  nil
rescue StandardError => e
  APMErrorHandler.report('GbPrimepay::CheckStatus unexpected error', {
                           exception: e,
                           reservation_id: reservation&.id,
                           reference_no: reference_no,
                         })

  errors << "Payment gateway error: #{e.message}"
  nil
end

#error_messagesObject



79
80
81
# File 'app/my_lib/gb_primepay/check_status.rb', line 79

def error_messages
  errors.join(',')
end

#invalid_card?Boolean

Returns:

  • (Boolean)


87
88
89
# File 'app/my_lib/gb_primepay/check_status.rb', line 87

def invalid_card?
  invalid_card
end

#rate_limited?Boolean

Returns:

  • (Boolean)


91
92
93
# File 'app/my_lib/gb_primepay/check_status.rb', line 91

def rate_limited?
  rate_limited
end

#success?Boolean

Returns:

  • (Boolean)


83
84
85
# File 'app/my_lib/gb_primepay/check_status.rb', line 83

def success?
  errors.empty?
end