killbill-cybersource 4.0.7 → 4.0.8
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 +2 -2
- data/NEWS +6 -0
- data/README.md +2 -0
- data/VERSION +1 -1
- data/lib/cybersource/api.rb +32 -0
- data/lib/cybersource/ext/active_merchant/active_merchant.rb +62 -2
- data/lib/cybersource/models/response.rb +1 -0
- data/pom.xml +1 -1
- data/spec/cybersource/base_plugin_spec.rb +147 -16
- data/spec/cybersource/remote/integration_spec.rb +52 -0
- 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: e5e9dc0988edff5c4623bbe0b78fff943f7deeca
|
4
|
+
data.tar.gz: 8021eb5f7e6a7ad4c8132ecf7f7d7a2f96fc4523
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8c8240aff2da9f916e0dad419b4ca2a335a38850ec4628046819d858dc5fead9fbccda182e22cee2340f655a54a5d21449e440e9b5a2cbc9c6985239ca1d6b50
|
7
|
+
data.tar.gz: 25bf63b13df3da99c28903e0534398dedd6e24ae3c80b4e6799f6d0e62e78d4aa8b236fa3a713ee0373d33cdeed5b5c7fc12b5bf16ff021b5481b75c34919847
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
killbill-cybersource (4.0.
|
4
|
+
killbill-cybersource (4.0.8)
|
5
5
|
actionpack (~> 4.1.0)
|
6
6
|
actionview (~> 4.1.0)
|
7
7
|
activemerchant (~> 1.48.0)
|
@@ -78,7 +78,7 @@ GEM
|
|
78
78
|
ruby-maven (~> 3.3, >= 3.3.3)
|
79
79
|
jdbc-mariadb (1.2.3)
|
80
80
|
jdbc-sqlite3 (3.8.11.2)
|
81
|
-
jruby-openssl (0.9.
|
81
|
+
jruby-openssl (0.9.17-java)
|
82
82
|
json (1.8.3-java)
|
83
83
|
killbill (7.0.6)
|
84
84
|
rack (>= 1.5.2)
|
data/NEWS
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
4.0.8
|
2
|
+
Add Android Pay support
|
3
|
+
Add support for merchant descriptors
|
4
|
+
Return processor response in PaymentTransactionInfoPlugin
|
5
|
+
Update jruby-openssl to 0.9.17 (see jruby/jruby-openssl#94)
|
6
|
+
|
1
7
|
4.0.7
|
2
8
|
Fix auth reversal in non-USD
|
3
9
|
Cancel old UNDEFINED transactions that cannot be found in CyberSource
|
data/README.md
CHANGED
@@ -157,5 +157,7 @@ Plugin properties
|
|
157
157
|
| payment_instrument_name | ApplePay tokenization attribute |
|
158
158
|
| payment_network | ApplePay tokenization attribute |
|
159
159
|
| transaction_identifier | ApplePay tokenization attribute |
|
160
|
+
| source | androidpay for AndroidPay |
|
160
161
|
| force_validation | If true, trigger a non-$0 auth to validate cards not supporting $0 auth |
|
161
162
|
| force_validation_amount | Amount to use when force_validation is set |
|
163
|
+
| merchant_descriptor | Merchant descriptor as `{"name":"Merchant Name","contact":"8888888888"}`|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
4.0.
|
1
|
+
4.0.8
|
data/lib/cybersource/api.rb
CHANGED
@@ -30,6 +30,7 @@ module Killbill #:nodoc:
|
|
30
30
|
options = {}
|
31
31
|
|
32
32
|
add_required_options(kb_account_id, properties, options, context)
|
33
|
+
add_merchant_descriptor(:AUTHORIZE, properties, options)
|
33
34
|
|
34
35
|
properties = merge_properties(properties, options)
|
35
36
|
auth_response = super(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
|
@@ -51,6 +52,7 @@ module Killbill #:nodoc:
|
|
51
52
|
options = {}
|
52
53
|
|
53
54
|
add_required_options(kb_account_id, properties, options, context)
|
55
|
+
add_merchant_descriptor(:CAPTURE, properties, options)
|
54
56
|
|
55
57
|
properties = merge_properties(properties, options)
|
56
58
|
super(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
|
@@ -96,6 +98,7 @@ module Killbill #:nodoc:
|
|
96
98
|
options = {}
|
97
99
|
|
98
100
|
add_required_options(kb_account_id, properties, options, context)
|
101
|
+
add_merchant_descriptor(:REFUND, properties, options)
|
99
102
|
|
100
103
|
properties = merge_properties(properties, options)
|
101
104
|
super(kb_account_id, kb_payment_id, kb_payment_transaction_id, kb_payment_method_id, amount, currency, properties, context)
|
@@ -276,6 +279,19 @@ module Killbill #:nodoc:
|
|
276
279
|
(now - transaction.created_at) >= threshold
|
277
280
|
end
|
278
281
|
|
282
|
+
def before_gateways(kb_transaction, last_transaction, payment_source, amount_in_cents, currency, options, context = nil)
|
283
|
+
# Provide necessary information for merchant descriptor
|
284
|
+
if options[:merchant_descriptor].present? &&
|
285
|
+
options[:merchant_descriptor][:card_type].nil? &&
|
286
|
+
payment_source.present? &&
|
287
|
+
payment_source.respond_to?(:brand)
|
288
|
+
|
289
|
+
options[:merchant_descriptor][:card_type] = payment_source.brand
|
290
|
+
end
|
291
|
+
|
292
|
+
super
|
293
|
+
end
|
294
|
+
|
279
295
|
# Make calls idempotent
|
280
296
|
def before_gateway(gateway, kb_transaction, last_transaction, payment_source, amount_in_cents, currency, options, context)
|
281
297
|
super
|
@@ -336,6 +352,22 @@ module Killbill #:nodoc:
|
|
336
352
|
::Killbill::Plugin::ActiveMerchant::Utils.normalize_property(properties, 'ignore_cvv')
|
337
353
|
end
|
338
354
|
|
355
|
+
def add_merchant_descriptor(transaction_type, properties, options)
|
356
|
+
merchant_descriptor = find_value_from_properties(properties, 'merchant_descriptor')
|
357
|
+
return unless merchant_descriptor.present?
|
358
|
+
|
359
|
+
merchant_descriptor_hash = JSON.parse(merchant_descriptor) rescue nil
|
360
|
+
return unless merchant_descriptor_hash.present? && merchant_descriptor_hash.is_a?(Hash)
|
361
|
+
|
362
|
+
merchant_descriptor_hash = merchant_descriptor_hash.with_indifferent_access
|
363
|
+
|
364
|
+
merchant_descriptor_hash[:transaction_type] = transaction_type
|
365
|
+
if merchant_descriptor_hash[:card_type].nil?
|
366
|
+
merchant_descriptor_hash[:card_type] = ::Killbill::Plugin::ActiveMerchant::Utils.normalized(properties_to_hash(properties), :cc_type)
|
367
|
+
end
|
368
|
+
options[:merchant_descriptor] = merchant_descriptor_hash
|
369
|
+
end
|
370
|
+
|
339
371
|
def get_report_api(options, context)
|
340
372
|
return nil if options[:skip_gw] || options[:bypass_duplicate_check]
|
341
373
|
cybersource_config = config(context.tenant_id)[:cybersource]
|
@@ -48,7 +48,7 @@ module ActiveMerchant
|
|
48
48
|
when :visa
|
49
49
|
xml.tag! 'ccAuthService', {'run' => 'true'} do
|
50
50
|
xml.tag!("cavv", payment_method.payment_cryptogram)
|
51
|
-
xml.tag!("commerceIndicator", options[:commerce_indicator] ||
|
51
|
+
xml.tag!("commerceIndicator", options[:commerce_indicator] || (is_android_pay(payment_method, options) ? 'internet' : 'vbv'))
|
52
52
|
xml.tag!("xid", payment_method.payment_cryptogram)
|
53
53
|
end
|
54
54
|
when :master
|
@@ -69,9 +69,22 @@ module ActiveMerchant
|
|
69
69
|
end
|
70
70
|
end
|
71
71
|
|
72
|
+
# Changes:
|
73
|
+
# * http://apps.cybersource.com/library/documentation/dev_guides/Android_Pay_SO_API/html/wwhelp/wwhimpl/js/html/wwhelp.htm#href=ch_soAPI.html
|
74
|
+
# * add paymentSolution tag to support Android Pay
|
75
|
+
def add_payment_solution(xml, payment_method, options)
|
76
|
+
if is_android_pay(payment_method, options)
|
77
|
+
xml.tag!('paymentSolution', '006')
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def is_android_pay(payment_method, options)
|
82
|
+
(payment_method.respond_to?(:source) && payment_method.source == :android_pay) || options[:source] == 'androidpay'
|
83
|
+
end
|
84
|
+
|
72
85
|
# Changes:
|
73
86
|
# * Enable business rules for Apple Pay
|
74
|
-
# * Set paymentNetworkToken if needed (a bit of a hack to do it here, but it avoids having to override too much code)
|
87
|
+
# * Set paymentNetworkToken and paymentSolution if needed (a bit of a hack to do it here, but it avoids having to override too much code)
|
75
88
|
def add_business_rules_data(xml, payment_method, options)
|
76
89
|
prioritized_options = [options, @options]
|
77
90
|
|
@@ -84,6 +97,8 @@ module ActiveMerchant
|
|
84
97
|
xml.tag! 'paymentNetworkToken' do
|
85
98
|
xml.tag!('transactionType', "1")
|
86
99
|
end
|
100
|
+
|
101
|
+
add_payment_solution(xml, payment_method, options)
|
87
102
|
end
|
88
103
|
end
|
89
104
|
|
@@ -129,6 +144,31 @@ module ActiveMerchant
|
|
129
144
|
xml.tag! 'clientLibrary' ,'Kill Bill'
|
130
145
|
xml.tag! 'clientLibraryVersion', KB_PLUGIN_VERSION
|
131
146
|
xml.tag! 'clientEnvironment' , RUBY_PLATFORM
|
147
|
+
add_invoice_header(xml, options) # Merchant soft descriptor
|
148
|
+
end
|
149
|
+
|
150
|
+
def add_invoice_header(xml, options)
|
151
|
+
merchant_descriptor = options[:merchant_descriptor]
|
152
|
+
if merchant_descriptor.present? &&
|
153
|
+
merchant_descriptor.is_a?(Hash) &&
|
154
|
+
!merchant_descriptor['card_type'].nil? &&
|
155
|
+
!merchant_descriptor['transaction_type'].nil?
|
156
|
+
name = merchant_descriptor['name']
|
157
|
+
contact = merchant_descriptor['contact']
|
158
|
+
if merchant_descriptor['card_type'].to_s == 'american_express'
|
159
|
+
unless merchant_descriptor['transaction_type'] == :AUTHORIZE # Amex only supports capture and refund
|
160
|
+
xml.tag! 'invoiceHeader' do
|
161
|
+
xml.tag! 'amexDataTAA1', format_string(name, 40)
|
162
|
+
xml.tag! 'amexDataTAA2', format_string(contact, 40)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
else
|
166
|
+
xml.tag! 'invoiceHeader' do
|
167
|
+
xml.tag! 'merchantDescriptor', format_name(name)
|
168
|
+
xml.tag! 'merchantDescriptorContact', format_contact(contact)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
132
172
|
end
|
133
173
|
|
134
174
|
def parse_element(reply, node)
|
@@ -147,6 +187,26 @@ module ActiveMerchant
|
|
147
187
|
end
|
148
188
|
return reply
|
149
189
|
end
|
190
|
+
|
191
|
+
def format_string(str, max_length)
|
192
|
+
return '' if str.nil?
|
193
|
+
str.first(max_length)
|
194
|
+
end
|
195
|
+
|
196
|
+
def format_contact(contact)
|
197
|
+
contact ||= ''
|
198
|
+
contact = contact.gsub(/\D/, '').ljust(10, '0')
|
199
|
+
[contact[0..2],contact[3..5],contact[6..9]].join('-')
|
200
|
+
end
|
201
|
+
|
202
|
+
def format_name(name)
|
203
|
+
name ||= ''
|
204
|
+
if name.index('*') != nil
|
205
|
+
subnames = name.split('*')
|
206
|
+
name = subnames[0].ljust(12)[0..11] + '*' + subnames[1]
|
207
|
+
end
|
208
|
+
name.ljust(22)[0..21]
|
209
|
+
end
|
150
210
|
end
|
151
211
|
end
|
152
212
|
end
|
@@ -121,6 +121,7 @@ module Killbill #:nodoc:
|
|
121
121
|
t_info_plugin = super(transaction)
|
122
122
|
|
123
123
|
t_info_plugin.properties << create_plugin_property('cybersourceResponseId', id)
|
124
|
+
t_info_plugin.properties << create_plugin_property('processorResponse', params_processor_response)
|
124
125
|
|
125
126
|
set_correct_status(t_info_plugin)
|
126
127
|
|
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>4.0.
|
28
|
+
<version>4.0.8</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>
|
@@ -196,6 +196,82 @@ describe Killbill::Cybersource::PaymentPlugin do
|
|
196
196
|
end
|
197
197
|
end
|
198
198
|
|
199
|
+
def stub_gateway_for_invoice_header(invoice_match_status)
|
200
|
+
::ActiveMerchant::Billing::CyberSourceGateway.any_instance.stub(:ssl_post) do |host, request_body|
|
201
|
+
case(invoice_match_status)
|
202
|
+
when :none
|
203
|
+
request_body.should_not match('<invoiceHeader>')
|
204
|
+
when :all
|
205
|
+
request_body.should match('<invoiceHeader>\n <merchantDescriptor>Ray Qiu </merchantDescriptor>\n <merchantDescriptorContact>650-888-3161</merchantDescriptorContact>\n </invoiceHeader>')
|
206
|
+
when :except_authorize
|
207
|
+
if request_body.index('ccAuthService').present?
|
208
|
+
request_body.should_not match('<invoiceHeader>\n <amexDataTAA1>Ray Qiu</amexDataTAA1>\n <amexDataTAA2>6508883161</amexDataTAA2>')
|
209
|
+
else
|
210
|
+
request_body.should match('<invoiceHeader>\n <amexDataTAA1>Ray Qiu</amexDataTAA1>\n <amexDataTAA2>6508883161</amexDataTAA2>')
|
211
|
+
end
|
212
|
+
end
|
213
|
+
successful_purchase_response
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
shared_examples 'full payment' do
|
218
|
+
before do
|
219
|
+
send(add_payment_properties, txn_properties, card_type)
|
220
|
+
stub_gateway_for_invoice_header(invoice_match_status)
|
221
|
+
end
|
222
|
+
|
223
|
+
it 'should met expectations' do
|
224
|
+
auth_responses = create_transaction(card_type, :authorize, nil, :PROCESSED, txn_properties, expected_successful_params)
|
225
|
+
capture_responses = create_transaction(card_type, :capture, auth_responses, :PROCESSED, txn_properties, expected_successful_params)
|
226
|
+
create_transaction(card_type, :refund, capture_responses, :PROCESSED, txn_properties, expected_successful_params)
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
shared_examples 'invoice header example' do
|
231
|
+
let(:card_type){ :visa }
|
232
|
+
let(:txn_properties){ [] }
|
233
|
+
|
234
|
+
context 'while no descriptor provided' do
|
235
|
+
let(:invoice_match_status){ :none }
|
236
|
+
|
237
|
+
context 'visa' do
|
238
|
+
it_behaves_like 'full payment'
|
239
|
+
end
|
240
|
+
|
241
|
+
context 'amex' do
|
242
|
+
let(:card_type){ :amex }
|
243
|
+
it_behaves_like 'full payment'
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
context 'while descriptor provided' do
|
248
|
+
before{ txn_properties << build_property('merchant_descriptor', {"name"=>"Ray Qiu", "contact"=>"6508883161"}.to_json) }
|
249
|
+
|
250
|
+
context 'visa' do
|
251
|
+
let(:invoice_match_status){ :all }
|
252
|
+
it_behaves_like 'full payment'
|
253
|
+
end
|
254
|
+
|
255
|
+
context 'amex' do
|
256
|
+
let(:card_type){ :amex }
|
257
|
+
let(:invoice_match_status){ :except_authorize }
|
258
|
+
it_behaves_like 'full payment'
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
context 'Invoice Header' do
|
264
|
+
context 'payments with card' do
|
265
|
+
let(:add_payment_properties){ :add_card_property }
|
266
|
+
it_behaves_like 'invoice header example'
|
267
|
+
end
|
268
|
+
|
269
|
+
context 'payments with network tokenization' do
|
270
|
+
let(:add_payment_properties){ :add_network_tokenization_properties }
|
271
|
+
it_behaves_like 'invoice header example'
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
199
275
|
private
|
200
276
|
|
201
277
|
def with_transaction(kb_payment_id, transaction_type, created_at, context)
|
@@ -215,43 +291,98 @@ describe Killbill::Cybersource::PaymentPlugin do
|
|
215
291
|
t.destroy! unless t.nil?
|
216
292
|
end
|
217
293
|
|
218
|
-
def
|
294
|
+
def add_card_property(properties, card_type = :visa)
|
219
295
|
properties << build_property('email', 'foo@bar.com')
|
220
|
-
|
221
|
-
|
222
|
-
|
296
|
+
if card_type == :amex
|
297
|
+
properties << build_property('cc_number', '378282246310005')
|
298
|
+
else
|
299
|
+
properties << build_property('cc_number', '4111111111111111')
|
300
|
+
end
|
223
301
|
end
|
224
302
|
|
225
|
-
def
|
303
|
+
def add_token_property(properties)
|
226
304
|
properties << build_property('email', 'foo@bar.com')
|
227
305
|
properties << build_property('token', '1234')
|
228
|
-
|
229
|
-
purchase(expected_status, properties, expected_params)
|
230
306
|
end
|
231
307
|
|
232
|
-
def
|
308
|
+
def add_network_tokenization_properties(properties, card_type = :visa)
|
309
|
+
if card_type == :amex
|
310
|
+
properties << build_property('cc_number', '378282246310005')
|
311
|
+
properties << build_property('brand', 'american_express')
|
312
|
+
properties << build_property('payment_cryptogram', Base64.encode64('111111111100cryptogram'))
|
313
|
+
else
|
314
|
+
properties << build_property('cc_number', '4111111111111111')
|
315
|
+
properties << build_property('brand', 'visa')
|
316
|
+
properties << build_property('payment_cryptogram', '111111111100cryptogram')
|
317
|
+
end
|
233
318
|
properties << build_property('email', 'foo@bar.com')
|
234
|
-
properties << build_property('cc_number', '4111111111111111')
|
235
|
-
properties << build_property('brand', 'visa')
|
236
319
|
properties << build_property('eci', '05')
|
237
|
-
|
320
|
+
end
|
238
321
|
|
322
|
+
def purchase_with_card(expected_status = :PROCESSED, properties = [], expected_params = {})
|
323
|
+
add_card_property(properties)
|
239
324
|
purchase(expected_status, properties, expected_params)
|
240
325
|
end
|
241
326
|
|
242
|
-
def
|
243
|
-
|
244
|
-
|
245
|
-
|
327
|
+
def purchase_with_token(expected_status = :PROCESSED, properties = [], expected_params = {})
|
328
|
+
add_token_property(properties)
|
329
|
+
purchase(expected_status, properties, expected_params)
|
330
|
+
end
|
246
331
|
|
247
|
-
|
332
|
+
def purchase_with_network_tokenization(expected_status = :PROCESSED, properties = [], expected_params = {})
|
333
|
+
add_network_tokenization_properties(properties)
|
334
|
+
purchase(expected_status, properties, expected_params)
|
335
|
+
end
|
336
|
+
|
337
|
+
def verify_response(payment_response, expected_status, expected_params)
|
248
338
|
payment_response.status.should eq(expected_status), payment_response.gateway_error
|
249
339
|
|
250
340
|
gw_response = Killbill::Cybersource::CybersourceResponse.last
|
251
341
|
expected_params.each do |k, v|
|
252
342
|
gw_response.send(k.to_sym).should == v
|
253
343
|
end
|
344
|
+
end
|
254
345
|
|
346
|
+
def create_transaction(card_type = :visa, txn_type = :authorize, previous_response = nil, expected_status = :PROCESSED, properties = [], expected_params = {})
|
347
|
+
if txn_type == :authorize
|
348
|
+
authorize(expected_status, properties, expected_params)
|
349
|
+
else
|
350
|
+
previous_response.shift
|
351
|
+
send(txn_type, *previous_response, expected_status, properties, expected_params)
|
352
|
+
end
|
353
|
+
end
|
354
|
+
|
355
|
+
def authorize(expected_status = :PROCESSED, properties = [], expected_params = {})
|
356
|
+
kb_account_id = SecureRandom.uuid
|
357
|
+
kb_payment_method_id = SecureRandom.uuid
|
358
|
+
kb_payment_id = SecureRandom.uuid
|
359
|
+
kb_payment = @plugin.kb_apis.proxied_services[:payment_api].add_payment(kb_payment_id)
|
360
|
+
kb_transaction_id = kb_payment.transactions[0].id
|
361
|
+
|
362
|
+
payment_response = @plugin.authorize_payment(kb_account_id, kb_payment_id, kb_transaction_id, kb_payment_method_id, BigDecimal.new('100'), 'USD', properties, build_call_context)
|
363
|
+
verify_response(payment_response, expected_status, expected_params)
|
364
|
+
return payment_response, kb_account_id, kb_payment_id, kb_transaction_id, kb_payment_method_id
|
365
|
+
end
|
366
|
+
|
367
|
+
def capture(kb_account_id, kb_payment_id, kb_transaction_id, kb_payment_method_id, expected_status = :PROCESSED, properties = [], expected_params = {})
|
368
|
+
payment_response = @plugin.capture_payment(kb_account_id, kb_payment_id, kb_transaction_id, kb_payment_method_id, BigDecimal.new('100'), 'USD', properties, build_call_context)
|
369
|
+
verify_response(payment_response, expected_status, expected_params)
|
370
|
+
return payment_response, kb_account_id, kb_payment_id, kb_transaction_id, kb_payment_method_id
|
371
|
+
end
|
372
|
+
|
373
|
+
def refund(kb_account_id, kb_payment_id, kb_transaction_id, kb_payment_method_id, expected_status = :PROCESSED, properties = [], expected_params = {})
|
374
|
+
payment_response = @plugin.refund_payment(kb_account_id, kb_payment_id, kb_transaction_id, kb_payment_method_id, BigDecimal.new('100'), 'USD', properties, build_call_context)
|
375
|
+
verify_response(payment_response, expected_status, expected_params)
|
376
|
+
return payment_response, kb_account_id, kb_payment_id, kb_transaction_id, kb_payment_method_id
|
377
|
+
end
|
378
|
+
|
379
|
+
def purchase(expected_status = :PROCESSED, properties = [], expected_params = {})
|
380
|
+
kb_payment_id = SecureRandom.uuid
|
381
|
+
kb_payment = @plugin.kb_apis.proxied_services[:payment_api].add_payment(kb_payment_id)
|
382
|
+
kb_transaction_id = kb_payment.transactions[0].id
|
383
|
+
|
384
|
+
payment_response = @plugin.purchase_payment(SecureRandom.uuid, kb_payment_id, kb_transaction_id, SecureRandom.uuid, BigDecimal.new('100'), 'USD', properties, build_call_context)
|
385
|
+
verify_response(payment_response, expected_status, expected_params)
|
255
386
|
payment_response
|
256
387
|
end
|
257
388
|
|
@@ -184,6 +184,22 @@ describe Killbill::Cybersource::PaymentPlugin do
|
|
184
184
|
check_response(payment_response, @amount, :PURCHASE, :PROCESSED, 'Successful transaction', '100')
|
185
185
|
end
|
186
186
|
|
187
|
+
it 'should be able to pay with Android Pay' do
|
188
|
+
properties = build_pm_properties(nil,
|
189
|
+
{
|
190
|
+
:cc_number => 4895370012003478,
|
191
|
+
:cc_type => 'visa',
|
192
|
+
:payment_cryptogram => 'AgAAAAAABk4DWZ4C28yUQAAAAAA=',
|
193
|
+
:ignore_avs => true,
|
194
|
+
:ignore_cvv => true
|
195
|
+
})
|
196
|
+
properties << build_property('source', 'androidpay')
|
197
|
+
|
198
|
+
kb_payment = setup_kb_payment
|
199
|
+
payment_response = @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)
|
200
|
+
check_response(payment_response, @amount, :AUTHORIZE, :PROCESSED, 'Successful transaction', '100')
|
201
|
+
end
|
202
|
+
|
187
203
|
it 'should be able to fix UNDEFINED payments' do
|
188
204
|
payment_response = @plugin.purchase_payment(@pm.kb_account_id, @kb_payment.id, @kb_payment.transactions[0].id, @pm.kb_payment_method_id, @amount, @currency, @properties, @call_context)
|
189
205
|
check_response(payment_response, @amount, :PURCHASE, :PROCESSED, 'Successful transaction', '100')
|
@@ -545,6 +561,42 @@ describe Killbill::Cybersource::PaymentPlugin do
|
|
545
561
|
end
|
546
562
|
end
|
547
563
|
|
564
|
+
shared_examples 'success_auth_capture_and_refund' do
|
565
|
+
it 'should be able to auth, capture and refund with descriptors' do
|
566
|
+
@pm = create_payment_method(::Killbill::Cybersource::CybersourcePaymentMethod, nil, @call_context.tenant_id, @properties)
|
567
|
+
|
568
|
+
payment_response = @plugin.authorize_payment(@pm.kb_account_id, payment_id, SecureRandom.uuid, @pm.kb_payment_method_id, @amount, @currency, @properties, @call_context)
|
569
|
+
check_response(payment_response, @amount, :AUTHORIZE, :PROCESSED, 'Successful transaction', '100')
|
570
|
+
|
571
|
+
# Try a capture
|
572
|
+
payment_response = @plugin.capture_payment(@pm.kb_account_id, payment_id, SecureRandom.uuid, @pm.kb_payment_method_id, @amount, @currency, @properties, @call_context)
|
573
|
+
check_response(payment_response, @amount, :CAPTURE, :PROCESSED, 'Successful transaction', '100')
|
574
|
+
|
575
|
+
# Try a refund
|
576
|
+
refund_response = @plugin.refund_payment(@pm.kb_account_id, payment_id, SecureRandom.uuid, @pm.kb_payment_method_id, @amount, @currency, @properties, @call_context)
|
577
|
+
check_response(refund_response, @amount, :REFUND, :PROCESSED, 'Successful transaction', '100')
|
578
|
+
end
|
579
|
+
end
|
580
|
+
|
581
|
+
describe 'with merchant descriptor' do
|
582
|
+
before do
|
583
|
+
@properties << build_property('merchant_descriptor', {"name"=>"Ray Qiu", "contact"=>"6508883161"}.to_json)
|
584
|
+
end
|
585
|
+
let(:payment_id){ SecureRandom.uuid }
|
586
|
+
|
587
|
+
context 'using cybersource token' do
|
588
|
+
it_behaves_like 'success_auth_capture_and_refund'
|
589
|
+
end
|
590
|
+
|
591
|
+
context 'using credit card' do
|
592
|
+
before do
|
593
|
+
@properties << build_property('email', 'foo@bar.com')
|
594
|
+
@properties << build_property('cc_number', '4111111111111111')
|
595
|
+
end
|
596
|
+
it_behaves_like 'success_auth_capture_and_refund'
|
597
|
+
end
|
598
|
+
end
|
599
|
+
|
548
600
|
private
|
549
601
|
|
550
602
|
def check_response(payment_response, amount, transaction_type, expected_status, expected_error, expected_error_code, expected_processor_response = nil)
|
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: 4.0.
|
4
|
+
version: 4.0.8
|
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: 2016-
|
11
|
+
date: 2016-08-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: killbill
|