killbill-orbital 0.1.8 → 0.1.9

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 79c94a1e5cf3ddacf63444b693a0b576353b3c7b
4
- data.tar.gz: ccf210b4dd5e6e76047552eccfc00898ac27bc82
3
+ metadata.gz: cec1cf6adeb886d2e658647977c87cc258505954
4
+ data.tar.gz: a0f94ccdb83a09e44bafd3546f0c19aed32a256f
5
5
  SHA512:
6
- metadata.gz: 0bfef0b4ec28065a2b8dba0acd47a8c2e8491cb85b2920dcb602c4c2e3d3356ed64a7f9a964aebeb04277a97569f3950ad6c3904d5ae68fd13c5fea0592dc823
7
- data.tar.gz: 754d60b264e0d33e0dc58abcc4f76e8c316c3ce43bdcd602e709f1877a034983e12a78876e311e46b624e3f9c2468ce27ccbdab679d3a8b4abd9686d6f328650
6
+ metadata.gz: 36f2b52df194d8469e5c4957b2bded12f6d4d8a5dd7c67d3fe8d7ef03452163d8b4bd78a2bc6945381ce1211fa45f8f3bbe50366bee739a04d14b649dbef6448
7
+ data.tar.gz: 19170d1876ada2aa6d01ac59cf19682329bf1860518d4f4048625864856b32ec9a32318adb4dcf8b6fec8b5b2607309839f850c42fb33d867e147f6555eb2360
data/lib/orbital/api.rb CHANGED
@@ -1,6 +1,8 @@
1
1
  module Killbill #:nodoc:
2
2
  module Orbital #:nodoc:
3
3
  class PaymentPlugin < ::Killbill::Plugin::ActiveMerchant::PaymentPlugin
4
+ FIVE_MINUTES_AGO = (5 * 60)
5
+ ONE_HOUR_AGO = (1 * 3600)
4
6
 
5
7
  def initialize
6
8
  gateway_builder = Proc.new do |config|
@@ -30,7 +32,7 @@ module Killbill #:nodoc:
30
32
  options = {}
31
33
 
32
34
  properties = merge_properties(properties, options)
33
- super(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
35
+ super(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context, with_trace_num_and_order_id(properties))
34
36
  end
35
37
 
36
38
  def capture_payment(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
@@ -43,7 +45,7 @@ module Killbill #:nodoc:
43
45
  options[:prior_auth_id] = last_auth_response.params_auth_code
44
46
  purchase_payment(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, hash_to_properties(options), context)
45
47
  else
46
- super(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
48
+ super(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context, with_trace_num_and_order_id(properties))
47
49
  end
48
50
  end
49
51
 
@@ -52,7 +54,7 @@ module Killbill #:nodoc:
52
54
  options = {}
53
55
 
54
56
  properties = merge_properties(properties, options)
55
- super(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
57
+ super(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context, with_trace_num_and_order_id(properties))
56
58
  end
57
59
 
58
60
  def void_payment(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, properties, context)
@@ -60,7 +62,7 @@ module Killbill #:nodoc:
60
62
  options = {}
61
63
 
62
64
  properties = merge_properties(properties, options)
63
- super(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, properties, context)
65
+ super(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, properties, context, with_trace_num_and_order_id(properties))
64
66
  end
65
67
 
66
68
  def credit_payment(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
@@ -68,7 +70,7 @@ module Killbill #:nodoc:
68
70
  options = {}
69
71
 
70
72
  properties = merge_properties(properties, options)
71
- super(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
73
+ super(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context, with_trace_num_and_order_id(properties))
72
74
  end
73
75
 
74
76
  def refund_payment(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
@@ -76,15 +78,15 @@ module Killbill #:nodoc:
76
78
  options = {}
77
79
 
78
80
  properties = merge_properties(properties, options)
79
- super(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
81
+ super(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context, with_trace_num_and_order_id(properties))
80
82
  end
81
83
 
82
84
  def get_payment_info(kb_account_id, kb_payment_id, properties, context)
83
- # Pass extra parameters for the gateway here
84
- options = {}
85
+ options = properties_to_hash(properties)
85
86
 
86
- properties = merge_properties(properties, options)
87
- super(kb_account_id, kb_payment_id, properties, context)
87
+ plugin_trxs_info = super(kb_account_id, kb_payment_id, properties, context)
88
+ return super(kb_account_id, kb_payment_id, properties, context) if try_fix_undefined_trxs(plugin_trxs_info, options, context)
89
+ plugin_trxs_info
88
90
  end
89
91
 
90
92
  def search_payments(search_key, offset, limit, properties, context)
@@ -142,6 +144,82 @@ module Killbill #:nodoc:
142
144
  def reset_payment_methods(kb_account_id, payment_methods, properties, context)
143
145
  super
144
146
  end
147
+
148
+ private
149
+
150
+ def try_fix_undefined_trxs(plugin_trxs_info, options, context)
151
+ stale = false
152
+ plugin_trxs_info.each do |plugin_trx_info|
153
+ next unless should_try_to_fix_trx plugin_trx_info, options
154
+ stale = true if fix_undefined_trx plugin_trx_info, context, options
155
+ end
156
+ stale
157
+ end
158
+
159
+ def should_try_to_fix_trx(plugin_trx_info, options)
160
+ plugin_trx_info.status == :UNDEFINED && pass_delay_time(plugin_trx_info, options)
161
+ end
162
+
163
+ def fix_undefined_trx(plugin_trx_info, context, options)
164
+ inquiry_response = inquiry(plugin_trx_info, context)
165
+ update_response_if_needed plugin_trx_info, inquiry_response, options
166
+ end
167
+
168
+ def update_response_if_needed(plugin_trx_info, inquiry_response, options)
169
+ response_id = find_value_from_properties(plugin_trx_info.properties, 'orbital_response_id')
170
+ response = OrbitalResponse.find_by(:id => response_id)
171
+ updated = false
172
+ if should_update_response inquiry_response, plugin_trx_info
173
+ logger.info("Fixing UNDEFINED kb_transaction_id='#{plugin_trx_info.kb_transaction_payment_id}', success='#{inquiry_response.success?}'")
174
+ response.update_and_create_transaction(inquiry_response)
175
+ updated = true
176
+ elsif should_cancel_payment plugin_trx_info, options
177
+ @logger.info("Canceling UNDEFINED kb_transaction_id='#{plugin_trx_info.kb_transaction_payment_id}'")
178
+ response.cancel
179
+ updated = true
180
+ end
181
+ updated
182
+ end
183
+
184
+ def should_update_response(inquiry_response, plugin_trx_info)
185
+ !inquiry_response.nil? && !inquiry_response.params.nil? && inquiry_response.params['order_id'] == plugin_trx_info.second_payment_reference_id
186
+ end
187
+
188
+ def should_cancel_payment(plugin_trx_info, options)
189
+ threshold = (Killbill::Plugin::ActiveMerchant::Utils.normalized(options, :cancel_threshold) || ONE_HOUR_AGO).to_i
190
+ delay_since_trx(plugin_trx_info) >= threshold
191
+ end
192
+
193
+ def pass_delay_time(plugin_trx_info, options)
194
+ janitor_delay_threshold = (Killbill::Plugin::ActiveMerchant::Utils.normalized(options, :janitor_delay_threshold) || FIVE_MINUTES_AGO).to_i
195
+ delay_since_trx(plugin_trx_info) >= janitor_delay_threshold
196
+ end
197
+
198
+ def delay_since_trx(plugin_trx_info)
199
+ delay_since_transaction = now - plugin_trx_info.created_date
200
+ delay_since_transaction < 0 ? 0 : delay_since_transaction
201
+ end
202
+
203
+ def now
204
+ Time.parse(@clock.get_clock.get_utc_now.to_s)
205
+ end
206
+
207
+ def inquiry(plugin_trx_info, context)
208
+ payment_processor_account_id = find_value_from_properties(plugin_trx_info.properties, 'payment_processor_account_id')
209
+ trace_number = find_value_from_properties(plugin_trx_info.properties, 'trace_number')
210
+ orbital_order_id = plugin_trx_info.second_payment_reference_id
211
+
212
+ return nil if trace_number.nil? || orbital_order_id.nil? || payment_processor_account_id.nil?
213
+
214
+ gateway = lookup_gateway(payment_processor_account_id, context.tenant_id)
215
+ gateway.inquiry(orbital_order_id, trace_number)
216
+ end
217
+
218
+ def with_trace_num_and_order_id(properties)
219
+ {:params_trace_number => find_value_from_properties(properties, :trace_number),
220
+ :params_order_id => find_value_from_properties(properties, :order_id)}.delete_if{|_, value| value.blank?}
221
+ end
222
+
145
223
  end
146
224
  end
147
225
  end
@@ -42,7 +42,7 @@ module ActiveMerchant
42
42
  'Content-Type' => 'application/PTI70')
43
43
  headers['X-Request-Id'] = x_r_id unless x_r_id.blank?
44
44
  headers.merge!('Trace-number' => trace_number.to_s,
45
- 'Merchant-Id' => @options[:merchant_id]) if @options[:retry_logic] && trace_number
45
+ 'Merchant-Id' => @options[:merchant_id]) if trace_number
46
46
  request = lambda { |url| parse(ssl_post(url, order, headers)) }
47
47
 
48
48
  # Failover URL will be attempted in the event of a connection error
@@ -59,7 +59,7 @@ module ActiveMerchant
59
59
  :authorization => authorization_string(response[:tx_ref_num], response[:order_id]),
60
60
  :test => self.test?,
61
61
  :avs_result => OrbitalGateway::AVSResult.new(response[:avs_resp_code]),
62
- :cvv_result => OrbitalGateway::CVVResult.new(response[:cvv2_resp_code])
62
+ :cvv_result => OrbitalGateway::CVVResult.new(response[:cvv2_resp_code]),
63
63
  })
64
64
  end
65
65
 
@@ -139,6 +139,24 @@ module ActiveMerchant
139
139
  commit(order, :credit, options[:trace_number])
140
140
  end
141
141
 
142
+ def inquiry(order_id, retry_num)
143
+ query = build_inquiry_request(order_id, retry_num, options)
144
+ commit(query, :inquiry, options[:trace_number])
145
+ end
146
+
147
+ def build_inquiry_request(order_id, retry_num, options)
148
+ xml = xml_envelope
149
+ xml.tag! :Request do
150
+ xml.tag! :Inquiry do
151
+ add_xml_credentials(xml)
152
+ add_bin_merchant_and_terminal(xml, options)
153
+ xml.tag! :OrderID, order_id
154
+ xml.tag! :InquiryRetryNumber, retry_num
155
+ end
156
+ end
157
+ xml.target!
158
+ end
159
+
142
160
  def build_new_order_xml_with_cc(operation, money, creditcard, options)
143
161
  build_new_order_xml(operation, money, options.merge(:creditcard=>creditcard)) do |xml|
144
162
  add_creditcard(xml, creditcard, options)
@@ -88,6 +88,69 @@ module Killbill #:nodoc:
88
88
  params_order_id
89
89
  end
90
90
 
91
+ def cancel
92
+ begin
93
+ error_details = JSON.parse(message)
94
+ original_message = nil
95
+ rescue
96
+ error_details = {}
97
+ original_message = message
98
+ end
99
+ error_details['original_message'] = original_message unless original_message.blank?
100
+ error_details['payment_plugin_status'] = 'CANCELED'
101
+
102
+ updated_attributes = {
103
+ :message => error_details.to_json,
104
+ :success => false,
105
+ :updated_at => Time.now.utc
106
+ }
107
+
108
+ # Update the response row
109
+ update!(updated_attributes)
110
+ end
111
+
112
+ def update_and_create_transaction(gw_response)
113
+ updated_attributes = {
114
+ :message => gw_response.message,
115
+ :authorization => gw_response.authorization,
116
+ :fraud_review => gw_response.fraud_review?,
117
+ :test => gw_response.test?,
118
+ :avs_result_code => gw_response.avs_result.kind_of?(::ActiveMerchant::Billing::AVSResult) ? gw_response.avs_result.code : gw_response.avs_result['code'],
119
+ :avs_result_message => gw_response.avs_result.kind_of?(::ActiveMerchant::Billing::AVSResult) ? gw_response.avs_result.message : gw_response.avs_result['message'],
120
+ :avs_result_street_match => gw_response.avs_result.kind_of?(::ActiveMerchant::Billing::AVSResult) ? gw_response.avs_result.street_match : gw_response.avs_result['street_match'],
121
+ :avs_result_postal_match => gw_response.avs_result.kind_of?(::ActiveMerchant::Billing::AVSResult) ? gw_response.avs_result.postal_match : gw_response.avs_result['postal_match'],
122
+ :cvv_result_code => gw_response.cvv_result.kind_of?(::ActiveMerchant::Billing::CVVResult) ? gw_response.cvv_result.code : gw_response.cvv_result['code'],
123
+ :cvv_result_message => gw_response.cvv_result.kind_of?(::ActiveMerchant::Billing::CVVResult) ? gw_response.cvv_result.message : gw_response.cvv_result['message'],
124
+ :success => gw_response.success?,
125
+ :updated_at => Time.now.utc
126
+ }.merge(OrbitalResponse.orbital_response_params(gw_response))
127
+
128
+ # Keep original values as much as possible
129
+ updated_attributes.delete_if { |k, v| v.blank? }
130
+
131
+ # Update the response row
132
+ update!(updated_attributes)
133
+
134
+ # Create the transaction row if needed (cannot have been created before or the state wouldn't have been UNDEFINED)
135
+ if gw_response.success?
136
+ amount = gw_response.params['amount']
137
+ currency = gw_response.params['currency']
138
+ amount_in_cents = amount.nil? ? nil : ::Monetize.from_numeric(amount.to_f, currency).cents.to_i
139
+ build_orbital_transaction(:kb_account_id => kb_account_id,
140
+ :kb_tenant_id => kb_tenant_id,
141
+ :amount_in_cents => amount_in_cents,
142
+ :currency => currency,
143
+ :api_call => api_call,
144
+ :kb_payment_id => kb_payment_id,
145
+ :kb_payment_transaction_id => kb_payment_transaction_id,
146
+ :transaction_type => transaction_type,
147
+ :payment_processor_account_id => payment_processor_account_id,
148
+ :txn_id => txn_id,
149
+ :created_at => updated_at,
150
+ :updated_at => updated_at).save!
151
+ end
152
+ end
153
+
91
154
  def self.auth_responses_from_kb_payment_id(kb_payment_id, kb_tenant_id)
92
155
  where(:kb_payment_id => kb_payment_id, :kb_tenant_id => kb_tenant_id, :api_call => 'authorize').order(:created_at)
93
156
  end
@@ -99,8 +162,8 @@ module Killbill #:nodoc:
99
162
  def to_transaction_info_plugin(transaction=nil)
100
163
  t_info_plugin = super(transaction)
101
164
  t_info_plugin.properties << create_plugin_property('processorResponse', params_host_resp_code)
102
-
103
- t_info_plugin.status = :CANCELED if t_info_plugin.status == :UNDEFINED
165
+ t_info_plugin.properties << create_plugin_property('orbital_response_id', id)
166
+ t_info_plugin.properties << create_plugin_property('trace_number', params_trace_number)
104
167
  t_info_plugin
105
168
  end
106
169
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: killbill-orbital
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.8
4
+ version: 0.1.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kill Bill core team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-10-26 00:00:00.000000000 Z
11
+ date: 2018-03-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement