activemerchant 1.119.0 → 1.120.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.
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'] = {}