activemerchant 1.119.0 → 1.120.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +75 -1
  3. data/README.md +3 -1
  4. data/lib/active_merchant/billing/check.rb +10 -0
  5. data/lib/active_merchant/billing/credit_card_methods.rb +9 -3
  6. data/lib/active_merchant/billing/gateways/adyen.rb +20 -6
  7. data/lib/active_merchant/billing/gateways/authorize_net.rb +9 -3
  8. data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +3 -0
  9. data/lib/active_merchant/billing/gateways/braintree_blue.rb +47 -7
  10. data/lib/active_merchant/billing/gateways/cashnet.rb +7 -2
  11. data/lib/active_merchant/billing/gateways/checkout_v2.rb +21 -0
  12. data/lib/active_merchant/billing/gateways/credorax.rb +13 -8
  13. data/lib/active_merchant/billing/gateways/cyber_source.rb +23 -3
  14. data/lib/active_merchant/billing/gateways/d_local.rb +1 -1
  15. data/lib/active_merchant/billing/gateways/elavon.rb +11 -1
  16. data/lib/active_merchant/billing/gateways/forte.rb +12 -0
  17. data/lib/active_merchant/billing/gateways/hps.rb +55 -1
  18. data/lib/active_merchant/billing/gateways/litle.rb +1 -1
  19. data/lib/active_merchant/billing/gateways/mercado_pago.rb +2 -2
  20. data/lib/active_merchant/billing/gateways/netbanx.rb +26 -2
  21. data/lib/active_merchant/billing/gateways/orbital.rb +62 -53
  22. data/lib/active_merchant/billing/gateways/payeezy.rb +30 -6
  23. data/lib/active_merchant/billing/gateways/payment_express.rb +5 -5
  24. data/lib/active_merchant/billing/gateways/payway_dot_com.rb +253 -0
  25. data/lib/active_merchant/billing/gateways/qvalent.rb +23 -9
  26. data/lib/active_merchant/billing/gateways/redsys.rb +19 -4
  27. data/lib/active_merchant/billing/gateways/safe_charge.rb +18 -11
  28. data/lib/active_merchant/billing/gateways/stripe.rb +8 -8
  29. data/lib/active_merchant/billing/gateways/stripe_payment_intents.rb +61 -25
  30. data/lib/active_merchant/billing/gateways/vpos.rb +172 -0
  31. data/lib/active_merchant/billing/gateways/worldpay.rb +24 -11
  32. data/lib/active_merchant/version.rb +1 -1
  33. data/lib/certs/cacert.pem +1582 -2431
  34. metadata +5 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 93f6306f4daee82e8458586cf10ba23a4b1cfa085c912430821bf583c789aded
4
- data.tar.gz: a943a31836368d69faf7c731dbc4c81d8b1a302b0fddd5cb4960c6714a88f11a
3
+ metadata.gz: 649ffe0485eeee7fba63fb57ee6f2ccee8ae113d8ad7ec42fb26d7895f5e8c03
4
+ data.tar.gz: 24dcf747601a2be45ca1938919e0626428be6ea19a22834666166772c8773035
5
5
  SHA512:
6
- metadata.gz: cb33c86a0b9f3be8186a69fe170656684a98f74dcd9597df7f70792e23050235a9774c4192f25a1700110315dd6a98afa4ef0c3b74e8ea495814146594c2746a
7
- data.tar.gz: 68729586be8247575dd96b6351db94f5b726338b92229cb49ddb82d6652ed93300049dd1edc18929a01850ec161cbe7574b0ceda0f1f233941019b7dfbca74f4
6
+ metadata.gz: 72e799731ef457d0f5c9d9995591c692e268265562465ba91023e87dad7fde4b25db3754920a51e24180d052d59ce7ecc33a7b2f2fc80b1e127984c5550122f9
7
+ data.tar.gz: 6dcc6c4f22b351497233ebd2ef9fc6354113921c75a4279909050e73e509570d6d97b698c9aa98199b7996019a53fb4dbb2daaa8ba1f85732d0af748033022ff
data/CHANGELOG CHANGED
@@ -2,11 +2,84 @@
2
2
 
3
3
  == HEAD
4
4
 
5
+
6
+ == Version 1.120.0 (May 28th, 2021)
7
+ * Braintree: Bump required braintree gem version to 3.0.1
8
+ * Stripe PI: ensure `setup_future_sage` and `off_session` work when using SetupIntents.
9
+ * Orbital: Update commit to accept retry_logic in params [jessiagee] #3890
10
+ * Orbital: Update remote 3DS tests [jessiagee] #3892
11
+ * Mercado Pago: support Creditel card type [therufs] #3893
12
+ * Payeezy: Update error mapping [meagabeth] #3896
13
+ * HPS: Add support for stored_credential [cdmackeyfree] #3894
14
+ * Orbital: Ensure payment_detail sends for ECP [jessiagee] #3899
15
+ * Payeezy: Update `error_code_from` method [meagabeth] #3900
16
+ * Worldpay: Add support for `statementNarrative` field [meagabeth] #3901
17
+ * Mercado Pago: Give ability to pass capture option in authorize txn field [naashton] #3897
18
+ * Orbital: Ensure correct fields sent in refund [jessiagee] #3903
19
+ * WorldPay: remove some defaults in billing address [carrigan] #3902
20
+ * Adyen: Support for General Credit [naashton] #3904
21
+ * Worldpay: reintroduce address1 and city defaults [carrigan] #3905
22
+ * Stripe: ensure potentially nested data is scrubbed #3907
23
+ * Stripe PI: Send Validate on Payment Method Attach [tatsianaclifton] #3909
24
+ * Adyen: Update handling of authorization returned from gateway [meagabeth] #3910
25
+ * Update gateway templates for Rubocop compliance [therufs] #3912 #3895
26
+ * Orbital: Send AVSname for all eCheck transactions [jessiagee] #3911
27
+ * Litle: update support of customerId field [cdmackeyfree] #3913
28
+ * Payment Express: fix signature for `verify` [therufs] #3914
29
+ * Forte: Send xdata fields [dsmcclain] #3915
30
+ * PaywayDotCom: Add New Gateway [DanAtPayway] #3898
31
+ * Orbital: Remove unnecessary requirements [jessiagee] #3917
32
+ * SafeCharge (Nuvei): Add network tokenization support [DStoyanoff] #3847
33
+ * Stripe PI: Enhance testing of SetupIntents API #3908
34
+ * SafeCharge (Nuvei): Fix NT related bug [jimilpatel24] #3921
35
+ * Worldpay: Only override cardholdername for 3ds tests [curiousepic] #3918
36
+ * Orbital: Add support for general credit [meagabeth] #3922
37
+ * Banco Sabadell: Ensure sca_exemption field is used #3923
38
+ * Redsys: Refactor XML character escape logic #3925
39
+ * HPS: Strip zip codes of non-alphanumeric characters [dsmcclain] #3926
40
+ * Orbital: $0 PreNote using authorize for eCheck force_capture [jessiagee] #3927
41
+ * Worldpay: synchronous response changes [naashton] #3928
42
+ * PaywayDotCom: Add more thorough scrubbing [tatsianaclifton] #3929
43
+ * Remove CONTRIBUTING.md and update README.md to reflect new repository wiki [dsmcclain] #3930
44
+ * Qvalent: Add customer_reference_number [fredo-] #3931
45
+ * Orbital: Add 'ND' ECPActionCode to $0 Prenote Check [jessiagee] #3935
46
+ * Checkout: Add support for stored_credential [meagabeth] #3934
47
+ * Credorax: Add support for 3ds_reqchallengeind [dsmcclain] #3936
48
+ * Adyen: cancelOrRefund endpoint when passed as option [naashton] #3937
49
+ * Qvalent: Add customer reference number FIX [fredo-] #3939
50
+ * Orbital: Pass line_items in capture [jessiagee] #3941
51
+ * BraintreeBlue: Add support for $0 auth verification [meagabeth] #3944
52
+ * JCB: Add additional BIN ranges [dsmcclain] #3946
53
+ * vPOS: Support new gateway type [therufs] #3906
54
+ * Braintree: Add support for AVS and CVV results in $0 credit card verification transactions [meagabeth] #3951
55
+ * Braintree: Return cvv_code and avs_code in response [meagabeth] #3952
56
+ * vPOS: Stringify values [therufs] #3954
57
+ * Payeezy: Send level2 fields [dsmcclain] #3953
58
+ * Credorax: adjust logic for sending 3ds shipping address fields [dsmcclain] #3959
59
+ * Orbital: Ensure ECP always sends AVSName [jessiagee] #3963
60
+ * Orbital: Add middle name to EWSMiddleName for ECP [jessiagee] #3962
61
+ * Support Canadian Bank Accounts [naashton] #3964
62
+ * Windcave/Payment Express: Add support for AvsAction and EnableAVSData fields [meagabeth] #3967
63
+ * CyberSource: Update XML tag for merchantDefinedData [meagabeth] #3969
64
+ * Elavon: Send ssl_vendor_id field [dsmcclain] #3972
65
+ * Credorax: Add support for `echo` field [meagabeth] #3973
66
+ * Worldpay: support cancelOrRefund via options [therufs] #3975
67
+ * Payeezy: support general credit [cdmackeyfree] #3977
68
+ * Ripley and Hipercard: Add BIN ranges [naashton] #3978
69
+ * Adyen: Default card holder name for credit cards [shasum] #3980
70
+ * PaywayDotCom: make `source_id` a required field [dsmcclain] # 3981
71
+ * Qvalent: remove `pem_password` from required credentials [dsmcclain] #3982
72
+ * Authorize.net: Fix stored credentials [tatsianaclifton] #3971
73
+ * CyberSource: Add support for multiple new fields [dsmcclain] #3984
74
+ * CASHNet: Update gateway adapter [dsmcclain] #3986
75
+ * Elavon: Send `ssl_vendor_id` field via options on gateway initialization [dsmcclain] #3989
76
+
5
77
  == Version 1.119.0 (February 9th, 2021)
6
78
  * Payment Express: support verify/validate [therufs] #3874
7
79
  * GlobalCollect: Truncate address fields [meagabeth] #3878
8
80
  * Litle: Truncate address fields [meagabeth] #3877
9
81
  * Netbanx: Add-customer-information(name,email,IP)-to-a-transaction [rockyhakjoong] #3754
82
+ * Netbanx: Adjust the avs and cvv return code in shopify [rockyhakjoong] #3833
10
83
  * Decidir: Improve error mapping [meagabeth] #3875
11
84
  * Worldpay: support `skip_capture` [therufs] #3879
12
85
  * Redsys: Add new response code text [britth] #3880
@@ -15,8 +88,9 @@
15
88
  * HPS: Update Add support for general credit [naashton] #3885
16
89
  * Elavon: Fix issue with encoding data sent in the request [naashton] #3865
17
90
  * Orbital: Update ECP to use EWS verification [jessiagee] #3886
18
- * Eway: Add 3ds field when do direct payment [GavinSun9527] #3860
91
+ * Eway: Add 3ds field when do direct payment [GavinSun9527] #3860
19
92
  * Support Creditel cardtype [therufs] #3883
93
+ * Elavon: Remove ampersand char from fields [naashton] #3891
20
94
 
21
95
  == Version 1.118.0 (January 22nd, 2021)
22
96
  * Worldpay: Add support for challengeWindowSize [carrigan] #3823
data/README.md CHANGED
@@ -17,7 +17,7 @@ from an ever-growing set of contributors.
17
17
  See [GettingStarted.md](GettingStarted.md) if you want to learn more about using Active Merchant in your
18
18
  applications.
19
19
 
20
- If you'd like to contribute to Active Merchant, please start with our [contribution guide](CONTRIBUTING.md).
20
+ If you'd like to contribute to Active Merchant, please start with our [Contribution Guide](https://github.com/activemerchant/active_merchant/wiki/Contributing).
21
21
 
22
22
  ## Installation
23
23
 
@@ -81,6 +81,8 @@ if credit_card.validate.empty?
81
81
  end
82
82
  ```
83
83
 
84
+ ## Contributing
85
+
84
86
  For more in-depth documentation and tutorials, see [GettingStarted.md](GettingStarted.md) and the
85
87
  [API documentation](http://www.rubydoc.info/github/activemerchant/active_merchant/).
86
88
 
@@ -13,6 +13,14 @@ module ActiveMerchant #:nodoc:
13
13
  # Used for Canadian bank accounts
14
14
  attr_accessor :institution_number, :transit_number
15
15
 
16
+ # Canadian Institution Numbers
17
+ # Found here: https://en.wikipedia.org/wiki/Routing_number_(Canada)
18
+ INSTITUTION_NUMBERS = %w(
19
+ 001 002 003 004 006 010 016 030 039 117 127 177 219 245 260 269 270 308
20
+ 309 310 315 320 338 340 509 540 608 614 623 809 815 819 828 829 837 839
21
+ 865 879 889 899
22
+ )
23
+
16
24
  def name
17
25
  @name ||= "#{first_name} #{last_name}".strip
18
26
  end
@@ -67,6 +75,8 @@ module ActiveMerchant #:nodoc:
67
75
  else
68
76
  false
69
77
  end
78
+ when 8
79
+ true if INSTITUTION_NUMBERS.include?(routing_number[0..2].to_s)
70
80
  else
71
81
  false
72
82
  end
@@ -11,7 +11,7 @@ module ActiveMerchant #:nodoc:
11
11
  'american_express' => ->(num) { num =~ /^3[47]\d{13}$/ },
12
12
  'naranja' => ->(num) { num&.size == 16 && in_bin_range?(num.slice(0, 6), NARANJA_RANGES) },
13
13
  'diners_club' => ->(num) { num =~ /^3(0[0-5]|[68]\d)\d{11,16}$/ },
14
- 'jcb' => ->(num) { num =~ /^35(28|29|[3-8]\d)\d{12}$/ },
14
+ 'jcb' => ->(num) { num =~ /^(35(28|29|[3-8]\d)\d{12}|308800\d{10})$/ },
15
15
  'dankort' => ->(num) { num =~ /^5019\d{12}$/ },
16
16
  'maestro' => lambda { |num|
17
17
  (12..19).cover?(num&.size) && (
@@ -71,6 +71,12 @@ module ActiveMerchant #:nodoc:
71
71
  MASTERCARD_RANGES = [
72
72
  (222100..272099),
73
73
  (510000..559999),
74
+ [605272],
75
+ [606282],
76
+ [637095],
77
+ [637568],
78
+ (637599..637600),
79
+ [637609],
74
80
  ]
75
81
 
76
82
  MAESTRO_BINS = Set.new(
@@ -105,7 +111,7 @@ module ActiveMerchant #:nodoc:
105
111
  606126
106
112
  636380 636422 636502 636639
107
113
  637046 637756
108
- 639130
114
+ 639130 639229
109
115
  690032]
110
116
  )
111
117
 
@@ -198,7 +204,7 @@ module ActiveMerchant #:nodoc:
198
204
  def self.in_bin_range?(number, ranges)
199
205
  bin = number.to_i
200
206
  ranges.any? do |range|
201
- range.cover?(bin)
207
+ range.include?(bin)
202
208
  end
203
209
  end
204
210
 
@@ -78,10 +78,19 @@ module ActiveMerchant #:nodoc:
78
78
  commit('refund', post, options)
79
79
  end
80
80
 
81
+ def credit(money, payment, options = {})
82
+ post = init_post(options)
83
+ add_invoice(post, money, options)
84
+ add_payment(post, payment, options)
85
+ add_shopper_reference(post, options)
86
+ commit('refundWithData', post, options)
87
+ end
88
+
81
89
  def void(authorization, options = {})
82
90
  post = init_post(options)
91
+ endpoint = options[:cancel_or_refund] ? 'cancelOrRefund' : 'cancel'
83
92
  add_reference(post, authorization, options)
84
- commit('cancel', post, options)
93
+ commit(endpoint, post, options)
85
94
  end
86
95
 
87
96
  def adjust(money, authorization, options = {})
@@ -374,7 +383,7 @@ module ActiveMerchant #:nodoc:
374
383
  }
375
384
 
376
385
  card.delete_if { |_k, v| v.blank? }
377
- card[:holderName] ||= 'Not Provided' if credit_card.is_a?(NetworkTokenizationCreditCard)
386
+ card[:holderName] ||= 'Not Provided'
378
387
  requires!(card, :expiryMonth, :expiryYear, :holderName, :number)
379
388
  post[:card] = card
380
389
  end
@@ -391,7 +400,11 @@ module ActiveMerchant #:nodoc:
391
400
  end
392
401
 
393
402
  def add_original_reference(post, authorization, options = {})
394
- original_psp_reference, = authorization.split('#')
403
+ if authorization.start_with?('#')
404
+ _, original_psp_reference, = authorization.split('#')
405
+ else
406
+ original_psp_reference, = authorization.split('#')
407
+ end
395
408
  post[:originalReference] = single_reference(authorization) || original_psp_reference
396
409
  end
397
410
 
@@ -552,11 +565,10 @@ module ActiveMerchant #:nodoc:
552
565
  response['refusalReason'] = 'Received unexpected 3DS authentication response. Use the execute_threed and/or threed_dynamic options to initiate a proper 3DS flow.'
553
566
  return false
554
567
  end
555
-
556
568
  case action.to_s
557
569
  when 'authorise', 'authorise3d'
558
570
  %w[Authorised Received RedirectShopper].include?(response['resultCode'])
559
- when 'capture', 'refund', 'cancel'
571
+ when 'capture', 'refund', 'cancel', 'cancelOrRefund'
560
572
  response['response'] == "[#{action}-received]"
561
573
  when 'adjustAuthorisation'
562
574
  response['response'] == 'Authorised' || response['response'] == '[adjustAuthorisation-received]'
@@ -564,6 +576,8 @@ module ActiveMerchant #:nodoc:
564
576
  response['result'] == 'Success'
565
577
  when 'disable'
566
578
  response['response'] == '[detail-successfully-disabled]'
579
+ when 'refundWithData'
580
+ response['resultCode'] == 'Received'
567
581
  else
568
582
  false
569
583
  end
@@ -572,7 +586,7 @@ module ActiveMerchant #:nodoc:
572
586
  def message_from(action, response)
573
587
  return authorize_message_from(response) if %w(authorise authorise3d authorise3ds2).include?(action.to_s)
574
588
 
575
- response['response'] || response['message'] || response['result']
589
+ response['response'] || response['message'] || response['result'] || response['resultCode']
576
590
  end
577
591
 
578
592
  def authorize_message_from(response)
@@ -708,9 +708,10 @@ module ActiveMerchant
708
708
  return unless options[:stored_credential]
709
709
 
710
710
  xml.processingOptions do
711
- if options[:stored_credential][:initial_transaction]
711
+ if options[:stored_credential][:initial_transaction] && options[:stored_credential][:reason_type] == 'recurring'
712
+ xml.isFirstRecurringPayment 'true'
713
+ elsif options[:stored_credential][:initial_transaction]
712
714
  xml.isFirstSubsequentAuth 'true'
713
- # xml.isFirstRecurringPayment 'true' if options[:stored_credential][:reason_type] == 'recurring'
714
715
  elsif options[:stored_credential][:initiator] == 'cardholder'
715
716
  xml.isStoredCredentials 'true'
716
717
  else
@@ -720,7 +721,7 @@ module ActiveMerchant
720
721
  end
721
722
 
722
723
  def add_subsequent_auth_information(xml, options)
723
- return unless options.dig(:stored_credential, :reason_type) == 'unscheduled'
724
+ return unless options.dig(:stored_credential, :initiator) == 'merchant'
724
725
 
725
726
  xml.subsequentAuthInformation do
726
727
  xml.reason options[:stored_credential_reason_type_override] if options[:stored_credential_reason_type_override]
@@ -934,6 +935,11 @@ module ActiveMerchant
934
935
  empty?(element.content) ? nil : element.content
935
936
  end
936
937
 
938
+ response[:network_trans_id] =
939
+ if element = doc.at_xpath('//networkTransId')
940
+ empty?(element.content) ? nil : element.content
941
+ end
942
+
937
943
  response
938
944
  end
939
945
 
@@ -563,6 +563,8 @@ module ActiveMerchant #:nodoc:
563
563
 
564
564
  def build_get_customer_profile_request(xml, options)
565
565
  xml.tag!('customerProfileId', options[:customer_profile_id])
566
+ xml.tag!('unmaskExpirationDate', options[:unmask_expiration_date]) if options[:unmask_expiration_date]
567
+ xml.tag!('includeIssuerInfo', options[:include_issuer_info]) if options[:include_issuer_info]
566
568
  xml.target!
567
569
  end
568
570
 
@@ -574,6 +576,7 @@ module ActiveMerchant #:nodoc:
574
576
  xml.tag!('customerProfileId', options[:customer_profile_id])
575
577
  xml.tag!('customerPaymentProfileId', options[:customer_payment_profile_id])
576
578
  xml.tag!('unmaskExpirationDate', options[:unmask_expiration_date]) if options[:unmask_expiration_date]
579
+ xml.tag!('includeIssuerInfo', options[:include_issuer_info]) if options[:include_issuer_info]
577
580
  xml.target!
578
581
  end
579
582
 
@@ -7,7 +7,7 @@ rescue LoadError
7
7
  raise 'Could not load the braintree gem. Use `gem install braintree` to install it.'
8
8
  end
9
9
 
10
- raise "Need braintree gem >= 2.78.0. Run `gem install braintree --version '~>2.78'` to get the correct version." unless Braintree::Version::Major == 2 && Braintree::Version::Minor >= 78
10
+ raise "Need braintree gem >= 3.0.0. Run `gem install braintree --version '~>3.0.0'` to get the correct version." unless Braintree::Version::Major == 3 && Braintree::Version::Minor == 0
11
11
 
12
12
  module ActiveMerchant #:nodoc:
13
13
  module Billing #:nodoc:
@@ -115,10 +115,36 @@ module ActiveMerchant #:nodoc:
115
115
  end
116
116
  end
117
117
 
118
- def verify(credit_card, options = {})
119
- MultiResponse.run(:use_first_response) do |r|
120
- r.process { authorize(100, credit_card, options) }
121
- r.process(:ignore_result) { void(r.authorization, options) }
118
+ def verify(creditcard, options = {})
119
+ if options[:allow_card_verification] == true
120
+ options.delete(:allow_card_verification)
121
+ exp_month = creditcard.month.to_s
122
+ exp_year = creditcard.year.to_s
123
+ expiration = "#{exp_month}/#{exp_year}"
124
+ payload = {
125
+ credit_card: {
126
+ number: creditcard.number,
127
+ expiration_date: expiration,
128
+ cvv: creditcard.verification_value,
129
+ billing_address: {
130
+ postal_code: options[:billing_address][:zip]
131
+ }
132
+ }
133
+ }
134
+ commit do
135
+ result = @braintree_gateway.verification.create(payload)
136
+ response = Response.new(result.success?, message_from_transaction_result(result), response_options(result))
137
+ response.cvv_result['message'] = ''
138
+ response.cvv_result['code'] = response.params['cvv_result']
139
+ response.avs_result['code'] = response.params['avs_result'][:code]
140
+ response
141
+ end
142
+
143
+ else
144
+ MultiResponse.run(:use_first_response) do |r|
145
+ r.process { authorize(100, creditcard, options) }
146
+ r.process(:ignore_result) { void(r.authorization, options) }
147
+ end
122
148
  end
123
149
  end
124
150
 
@@ -368,7 +394,11 @@ module ActiveMerchant #:nodoc:
368
394
 
369
395
  def response_options(result)
370
396
  options = {}
371
- if result.transaction
397
+ if result.credit_card_verification
398
+ options[:authorization] = result.credit_card_verification.id
399
+ options[:avs_result] = { code: avs_code_from(result.credit_card_verification) }
400
+ options[:cvv_result] = result.credit_card_verification.cvv_response_code
401
+ elsif result.transaction
372
402
  options[:authorization] = result.transaction.id
373
403
  options[:avs_result] = { code: avs_code_from(result.transaction) }
374
404
  options[:cvv_result] = result.transaction.cvv_response_code
@@ -592,6 +622,7 @@ module ActiveMerchant #:nodoc:
592
622
  add_addresses(parameters, options)
593
623
 
594
624
  add_descriptor(parameters, options)
625
+ add_risk_data(parameters, options)
595
626
  add_travel_data(parameters, options) if options[:travel_data]
596
627
  add_lodging_data(parameters, options) if options[:lodging_data]
597
628
  add_channel(parameters, options)
@@ -652,6 +683,15 @@ module ActiveMerchant #:nodoc:
652
683
  }
653
684
  end
654
685
 
686
+ def add_risk_data(parameters, options)
687
+ return unless options[:risk_data]
688
+
689
+ parameters[:risk_data] = {
690
+ customer_browser: options[:risk_data][:customer_browser],
691
+ customer_ip: options[:risk_data][:customer_ip]
692
+ }
693
+ end
694
+
655
695
  def add_level_2_data(parameters, options)
656
696
  parameters[:tax_amount] = options[:tax_amount] if options[:tax_amount]
657
697
  parameters[:tax_exempt] = options[:tax_exempt] if options[:tax_exempt]
@@ -761,7 +801,7 @@ module ActiveMerchant #:nodoc:
761
801
  eci_indicator: credit_card_or_vault_id.eci
762
802
  }
763
803
  elsif credit_card_or_vault_id.source == :android_pay || credit_card_or_vault_id.source == :google_pay
764
- parameters[:android_pay_card] = {
804
+ parameters[:google_pay_card] = {
765
805
  number: credit_card_or_vault_id.number,
766
806
  cryptogram: credit_card_or_vault_id.payment_cryptogram,
767
807
  expiration_month: credit_card_or_vault_id.month.to_s.rjust(2, '0'),
@@ -8,7 +8,7 @@ module ActiveMerchant #:nodoc:
8
8
 
9
9
  self.supported_countries = ['US']
10
10
  self.supported_cardtypes = %i[visa master american_express discover diners_club jcb]
11
- self.homepage_url = 'http://www.higherone.com/'
11
+ self.homepage_url = 'https://transactcampus.com'
12
12
  self.display_name = 'Cashnet'
13
13
  self.money_format = :dollars
14
14
  self.max_retries = 0
@@ -76,7 +76,7 @@ module ActiveMerchant #:nodoc:
76
76
 
77
77
  return unparsable_response(raw_response) unless parsed_response
78
78
 
79
- success = (parsed_response[:result] == '0')
79
+ success = success?(parsed_response)
80
80
  Response.new(
81
81
  success,
82
82
  CASHNET_CODES[parsed_response[:result]],
@@ -86,6 +86,10 @@ module ActiveMerchant #:nodoc:
86
86
  )
87
87
  end
88
88
 
89
+ def success?(response)
90
+ response[:result] == '0'
91
+ end
92
+
89
93
  def post_data(action, parameters = {})
90
94
  post = {}
91
95
  post[:command] = action
@@ -191,6 +195,7 @@ module ActiveMerchant #:nodoc:
191
195
  '215' => 'Old PIN does not validate ',
192
196
  '221' => 'Invalid credit card processor type specified in location or payment code',
193
197
  '222' => 'Credit card processor error',
198
+ '230' => 'Host Error (USE VOID OR REVERSAL TO REFUND UNSETTLED TRANSACTIONS)',
194
199
  '280' => 'SmartPay transaction not posted',
195
200
  '301' => 'Original transaction not found for this customer',
196
201
  '302' => 'Amount to refund exceeds original payment amount or is missing',
@@ -79,6 +79,7 @@ module ActiveMerchant #:nodoc:
79
79
  add_invoice(post, amount, options)
80
80
  add_payment_method(post, payment_method, options)
81
81
  add_customer_data(post, options)
82
+ add_stored_credential_options(post, options)
82
83
  add_transaction_data(post, options)
83
84
  add_3ds(post, options)
84
85
  end
@@ -138,6 +139,26 @@ module ActiveMerchant #:nodoc:
138
139
  post[:previous_payment_id] = options[:previous_charge_id] if options[:previous_charge_id]
139
140
  end
140
141
 
142
+ def add_stored_credential_options(post, options = {})
143
+ return unless options[:stored_credential]
144
+
145
+ case options[:stored_credential][:initial_transaction]
146
+ when true
147
+ post[:merchant_initiated] = false
148
+ when false
149
+ post[:'source.stored'] = true
150
+ post[:previous_payment_id] = options[:stored_credential][:network_transaction_id] if options[:stored_credential][:network_transaction_id]
151
+ post[:merchant_initiated] = true
152
+ end
153
+
154
+ case options[:stored_credential][:reason_type]
155
+ when 'recurring' || 'installment'
156
+ post[:payment_type] = 'Recurring'
157
+ when 'unscheduled'
158
+ return
159
+ end
160
+ end
161
+
141
162
  def add_3ds(post, options)
142
163
  if options[:three_d_secure] || options[:execute_threed]
143
164
  post[:'3ds'] = {}