killbill-cybersource 4.0.7 → 4.0.8
Sign up to get free protection for your applications and to get access to all the features.
- 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
|