killbill-cybersource 5.1.0 → 5.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/VERSION +1 -1
- data/lib/cybersource/api.rb +8 -1
- data/lib/cybersource/cyber_source_on_demand.rb +4 -0
- data/pom.xml +1 -1
- data/spec/cybersource/remote/integration_spec.rb +69 -10
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0156e88d591e65a124e91d54707a6c35058e7cf4
|
4
|
+
data.tar.gz: 69163de4f9aa3c74d5325a6c561abab2f8e9efc3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c505cfb2f367215a4ec6b42fcc8edb5d33da5732cb9392bb5d862eb45b6f841e648c68fc572bff89b216c52ae169da79efeef80935d4d5b7763e7b2b4b05709c
|
7
|
+
data.tar.gz: 8d502c587dfc6a4fd41d28813e92bcc35875d85e68e7ffd8a545df043a0a51aa696716414dd51e4a8bdeee30dd1b49bac8968598671bdf1d7a844257fada10ad
|
data/Gemfile.lock
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
5.
|
1
|
+
5.2.0
|
data/lib/cybersource/api.rb
CHANGED
@@ -134,6 +134,8 @@ module Killbill #:nodoc:
|
|
134
134
|
# authorization is very likely nil, as we didn't get an answer from the gateway in the first place
|
135
135
|
order_id ||= authorization.split(';')[0] unless authorization.nil?
|
136
136
|
|
137
|
+
existing_request_ids = transaction_info_plugins.map{|trx_info| trx_info.first_payment_reference_id}.compact
|
138
|
+
|
137
139
|
stale = false
|
138
140
|
transaction_info_plugins.each do |transaction_info_plugin|
|
139
141
|
# We only need to fix the UNDEFINED ones
|
@@ -171,7 +173,7 @@ module Killbill #:nodoc:
|
|
171
173
|
|
172
174
|
threshold = (Killbill::Plugin::ActiveMerchant::Utils.normalized(options, :cancel_threshold) || ONE_DAY_AGO).to_i
|
173
175
|
should_cancel_payment = delay_since_transaction >= threshold
|
174
|
-
if report.empty? && !should_cancel_payment
|
176
|
+
if (report.empty? || report_not_match(report, transaction_info_plugin.first_payment_reference_id, existing_request_ids)) && !should_cancel_payment
|
175
177
|
# We'll retry later
|
176
178
|
logger.info("Unable to fix UNDEFINED kb_transaction_id='#{transaction_info_plugin.kb_transaction_payment_id}' (not found in CyberSource)")
|
177
179
|
next
|
@@ -445,6 +447,11 @@ module Killbill #:nodoc:
|
|
445
447
|
# We might want a 'util' function to make the conversion Joda DateTime to a Ruby Time object
|
446
448
|
Time.parse(@clock.get_clock.get_utc_now.to_s)
|
447
449
|
end
|
450
|
+
|
451
|
+
def report_not_match(report, request_id, existing_request_ids)
|
452
|
+
# Check if the response's request id is the request_id of a previous request. If so, then this report does not match.
|
453
|
+
report.request_id.nil? || (request_id != report.request_id && existing_request_ids.include?(report.request_id))
|
454
|
+
end
|
448
455
|
end
|
449
456
|
end
|
450
457
|
end
|
data/pom.xml
CHANGED
@@ -25,7 +25,7 @@
|
|
25
25
|
<groupId>org.kill-bill.billing.plugin.ruby</groupId>
|
26
26
|
<artifactId>cybersource-plugin</artifactId>
|
27
27
|
<packaging>pom</packaging>
|
28
|
-
<version>5.
|
28
|
+
<version>5.2.0</version>
|
29
29
|
<name>cybersource-plugin</name>
|
30
30
|
<url>http://github.com/killbill/killbill-cybersource-plugin</url>
|
31
31
|
<description>Plugin for accessing Cybersource as a payment gateway</description>
|
@@ -266,7 +266,7 @@ describe Killbill::Cybersource::PaymentPlugin do
|
|
266
266
|
fix_transaction(0) if with_report_api
|
267
267
|
|
268
268
|
# Compare the state of the old and new response
|
269
|
-
check_old_new_response(response, :PURCHASE, 0, initial_auth)
|
269
|
+
check_old_new_response(response, :PURCHASE, 0, initial_auth, payment_response.first_payment_reference_id)
|
270
270
|
|
271
271
|
break unless with_report_api
|
272
272
|
|
@@ -280,14 +280,72 @@ describe Killbill::Cybersource::PaymentPlugin do
|
|
280
280
|
fix_transaction(1)
|
281
281
|
|
282
282
|
# Compare the state of the old and new response
|
283
|
-
check_old_new_response(response, :REFUND, 1, initial_auth)
|
283
|
+
check_old_new_response(response, :REFUND, 1, initial_auth, refund_response.first_payment_reference_id)
|
284
|
+
end
|
285
|
+
|
286
|
+
it 'should fix UNDEFINED captures' do
|
287
|
+
@plugin.authorize_payment(@pm.kb_account_id, @kb_payment.id, @kb_payment.transactions[0].id, @pm.kb_payment_method_id, @amount, @currency, @properties, @call_context)
|
288
|
+
payment_response = @plugin.capture_payment(@pm.kb_account_id, @kb_payment.id, @kb_payment.transactions[1].id, @pm.kb_payment_method_id, @amount, @currency, @properties, @call_context)
|
289
|
+
check_response(payment_response, @amount, :CAPTURE, :PROCESSED, 'Successful transaction', '100')
|
290
|
+
|
291
|
+
# Force a transition to :UNDEFINED
|
292
|
+
response, initial_auth = transition_last_response_to_UNDEFINED(2)
|
293
|
+
|
294
|
+
# Skip if the report API isn't configured
|
295
|
+
fix_transaction(1) if with_report_api
|
296
|
+
|
297
|
+
# Compare the state of the old and new response
|
298
|
+
check_old_new_response(response, :CAPTURE, 1, initial_auth, payment_response.first_payment_reference_id)
|
299
|
+
|
300
|
+
break unless with_report_api
|
301
|
+
|
302
|
+
# Try a full refund
|
303
|
+
refund_response = @plugin.refund_payment(@pm.kb_account_id, @kb_payment.id, @kb_payment.transactions[1].id, @pm.kb_payment_method_id, @amount, @currency, @properties, @call_context)
|
304
|
+
check_response(refund_response, @amount, :REFUND, :PROCESSED, 'Successful transaction', '100')
|
305
|
+
end
|
306
|
+
|
307
|
+
it 'should not fix UNDEFINED captures if the report only covers the previous request' do
|
308
|
+
@plugin.authorize_payment(@pm.kb_account_id, @kb_payment.id, @kb_payment.transactions[0].id, @pm.kb_payment_method_id, @amount, @currency, @properties, @call_context)
|
309
|
+
|
310
|
+
# Skip gw call so that on_demand report api won't return a record for this call
|
311
|
+
skip_gw = Killbill::Plugin::Model::PluginProperty.new
|
312
|
+
skip_gw.key = 'skip_gw'
|
313
|
+
skip_gw.value = 'true'
|
314
|
+
properties_with_skip_gw = @properties.clone
|
315
|
+
properties_with_skip_gw << skip_gw
|
316
|
+
@plugin.capture_payment(@pm.kb_account_id, @kb_payment.id, @kb_payment.transactions[1].id, @pm.kb_payment_method_id, @amount, @currency, properties_with_skip_gw, @call_context)
|
317
|
+
|
318
|
+
# Force a transition to :UNDEFINED
|
319
|
+
transition_last_response_to_UNDEFINED(2)
|
320
|
+
|
321
|
+
# Shouldn't be able to fix the capture because it skipped the gateway call
|
322
|
+
fix_transaction(1, :UNDEFINED) if with_report_api
|
323
|
+
end
|
324
|
+
|
325
|
+
it 'should not fix UNDEFINED refunds if the report only covers the previous requests' do
|
326
|
+
@plugin.authorize_payment(@pm.kb_account_id, @kb_payment.id, @kb_payment.transactions[0].id, @pm.kb_payment_method_id, @amount, @currency, @properties, @call_context)
|
327
|
+
@plugin.capture_payment(@pm.kb_account_id, @kb_payment.id, @kb_payment.transactions[1].id, @pm.kb_payment_method_id, @amount, @currency, @properties, @call_context)
|
328
|
+
|
329
|
+
# Skip gw call so that on_demand report api won't return a record for this call
|
330
|
+
skip_gw = Killbill::Plugin::Model::PluginProperty.new
|
331
|
+
skip_gw.key = 'skip_gw'
|
332
|
+
skip_gw.value = 'true'
|
333
|
+
properties_with_skip_gw = @properties.clone
|
334
|
+
properties_with_skip_gw << skip_gw
|
335
|
+
@plugin.refund_payment(@pm.kb_account_id, @kb_payment.id, @kb_payment.transactions[1].id, @pm.kb_payment_method_id, @amount, @currency, properties_with_skip_gw, @call_context)
|
336
|
+
|
337
|
+
# Force a transition to :UNDEFINED
|
338
|
+
transition_last_response_to_UNDEFINED(3)
|
339
|
+
|
340
|
+
# Shouldn't be able to fix the capture because it skipped the gateway call
|
341
|
+
fix_transaction(2, :UNDEFINED) if with_report_api
|
284
342
|
end
|
285
343
|
|
286
344
|
def transition_last_response_to_UNDEFINED(expected_nb_transactions)
|
287
345
|
Killbill::Cybersource::CybersourceTransaction.last.delete
|
288
346
|
response = Killbill::Cybersource::CybersourceResponse.last
|
289
347
|
initial_auth = response.authorization
|
290
|
-
response.update(:authorization => nil, :message => {:payment_plugin_status => 'UNDEFINED'}.to_json)
|
348
|
+
response.update(:authorization => nil, :params_request_id => nil, :message => {:payment_plugin_status => 'UNDEFINED'}.to_json)
|
291
349
|
|
292
350
|
skip_gw = Killbill::Plugin::Model::PluginProperty.new
|
293
351
|
skip_gw.key = 'skip_gw'
|
@@ -303,7 +361,7 @@ describe Killbill::Cybersource::PaymentPlugin do
|
|
303
361
|
[response, initial_auth]
|
304
362
|
end
|
305
363
|
|
306
|
-
def fix_transaction(transaction_nb)
|
364
|
+
def fix_transaction(transaction_nb, expected_state=:PROCESSED)
|
307
365
|
# The report API can be delayed
|
308
366
|
await do
|
309
367
|
!@plugin.get_single_transaction_report(report_api, @kb_payment.transactions[0].id, Time.now.utc).empty? ||
|
@@ -323,7 +381,7 @@ describe Killbill::Cybersource::PaymentPlugin do
|
|
323
381
|
properties_with_janitor_delay_threshold << janitor_delay_threshold
|
324
382
|
transaction_info_plugins = @plugin.get_payment_info(@pm.kb_account_id, @kb_payment.id, properties_with_janitor_delay_threshold, @call_context)
|
325
383
|
transaction_info_plugins.size.should == transaction_nb + 1
|
326
|
-
transaction_info_plugins.last.status.should eq(
|
384
|
+
transaction_info_plugins.last.status.should eq(expected_state)
|
327
385
|
|
328
386
|
# Set skip_gw=true, to check the local state
|
329
387
|
skip_gw = Killbill::Plugin::Model::PluginProperty.new
|
@@ -333,10 +391,10 @@ describe Killbill::Cybersource::PaymentPlugin do
|
|
333
391
|
properties_with_skip_gw << skip_gw
|
334
392
|
transaction_info_plugins = @plugin.get_payment_info(@pm.kb_account_id, @kb_payment.id, properties_with_skip_gw, @call_context)
|
335
393
|
transaction_info_plugins.size.should == transaction_nb + 1
|
336
|
-
transaction_info_plugins.last.status.should eq(
|
394
|
+
transaction_info_plugins.last.status.should eq(expected_state)
|
337
395
|
end
|
338
396
|
|
339
|
-
def check_old_new_response(response, transaction_type, transaction_nb, initial_auth)
|
397
|
+
def check_old_new_response(response, transaction_type, transaction_nb, initial_auth, request_id)
|
340
398
|
new_response = Killbill::Cybersource::CybersourceResponse.last
|
341
399
|
new_response.id.should == response.id
|
342
400
|
new_response.api_call.should == transaction_type.to_s.downcase
|
@@ -354,12 +412,13 @@ describe Killbill::Cybersource::PaymentPlugin do
|
|
354
412
|
new_response.params_request_token.should == response.params_request_token
|
355
413
|
new_response.params_currency.should == response.params_currency
|
356
414
|
new_response.params_amount.should == response.params_amount
|
357
|
-
new_response.params_authorization_code.should == response.params_authorization_code
|
358
|
-
new_response.params_avs_code.should == response.params_avs_code
|
359
|
-
new_response.params_avs_code_raw.should == response.params_avs_code_raw
|
415
|
+
new_response.params_authorization_code.should == response.params_authorization_code unless response.params_authorization_code.nil?
|
416
|
+
new_response.params_avs_code.should == response.params_avs_code unless response.params_avs_code.nil?
|
417
|
+
new_response.params_avs_code_raw.should == response.params_avs_code_raw unless response.params_avs_code.nil?
|
360
418
|
new_response.params_reconciliation_id.should == response.params_reconciliation_id
|
361
419
|
new_response.success.should be_true
|
362
420
|
new_response.message.should == (with_report_api ? 'Request was processed successfully.' : '{"payment_plugin_status":"UNDEFINED"}')
|
421
|
+
new_response.params_request_id.should == request_id if with_report_api
|
363
422
|
end
|
364
423
|
end
|
365
424
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: killbill-cybersource
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.2.0
|
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-04-
|
11
|
+
date: 2017-04-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|