- <% if payment.source.address %>
- <%= render partial: 'spree/admin/shared/address', locals: {address: payment.source.address} %>
- <% end %>
diff --git a/core/README.md b/core/README.md
index d625b2fd92e..5442b660404 100644
--- a/core/README.md
+++ b/core/README.md
@@ -40,7 +40,6 @@ source (e.g. `Spree::CreditCard`) using a specific payment method (e.g
`Solidus::Gateway::Braintree`).
* `Spree::PaymentMethod` - A base class which is used for implementing payment methods.
* `Spree::PaymentMethod::CreditCard` - An implementation of a `Spree::PaymentMethod` for credit card payments.
-See https://github.com/solidusio/solidus_gateway/ for officially supported payment method implementations.
* `Spree::CreditCard` - The `source` of a `Spree::Payment` using `Spree::PaymentMethod::CreditCard` as payment method.
## Inventory sub-system
diff --git a/core/app/models/spree/payment.rb b/core/app/models/spree/payment.rb
index 0cdce2c1b9f..07aba3ef6b9 100644
--- a/core/app/models/spree/payment.rb
+++ b/core/app/models/spree/payment.rb
@@ -54,7 +54,7 @@ class Payment < Spree::Base
scope :processing, -> { with_state('processing') }
scope :failed, -> { with_state('failed') }
- scope :risky, -> { where("avs_response IN (?) OR (cvv_response_code IS NOT NULL and cvv_response_code != 'M') OR state = 'failed'", RISKY_AVS_CODES) }
+ scope :risky, -> { failed.or(where(avs_response: RISKY_AVS_CODES)).or(where.not(cvv_response_code: [nil, '', 'M'])) }
scope :valid, -> { where.not(state: %w(failed invalid void)) }
scope :store_credits, -> { where(source_type: Spree::StoreCredit.to_s) }
@@ -127,6 +127,11 @@ def payment_source
res || payment_method
end
+ # @return [Boolean] true when this payment is risky
+ def risky?
+ is_avs_risky? || is_cvv_risky? || state == 'failed'
+ end
+
# @return [Boolean] true when this payment is risky based on address
def is_avs_risky?
return false if avs_response.blank? || NON_RISKY_AVS_CODES.include?(avs_response)
@@ -137,7 +142,6 @@ def is_avs_risky?
def is_cvv_risky?
return false if cvv_response_code == "M"
return false if cvv_response_code.nil?
- return false if cvv_response_message.present?
true
end
diff --git a/core/app/models/spree/payment_method/credit_card.rb b/core/app/models/spree/payment_method/credit_card.rb
index 78e6d2c069a..6e268cf1664 100644
--- a/core/app/models/spree/payment_method/credit_card.rb
+++ b/core/app/models/spree/payment_method/credit_card.rb
@@ -4,10 +4,6 @@ module Spree
# An implementation of a `Spree::PaymentMethod` for credit card payments.
#
# It's a good candidate as base class for other credit card based payment methods.
- #
- # See https://github.com/solidusio/solidus_gateway/ for
- # officially supported payment method implementations.
- #
class PaymentMethod::CreditCard < PaymentMethod
def payment_source_class
Spree::CreditCard
diff --git a/core/spec/models/spree/payment_spec.rb b/core/spec/models/spree/payment_spec.rb
index e38a7a832ff..fc1c1b8a45f 100644
--- a/core/spec/models/spree/payment_spec.rb
+++ b/core/spec/models/spree/payment_spec.rb
@@ -46,14 +46,29 @@
)
end
- context '.risky' do
+ context 'risk analysis' do
let!(:payment_1) { create(:payment, avs_response: 'Y', cvv_response_code: 'M', cvv_response_message: 'Match') }
let!(:payment_2) { create(:payment, avs_response: 'Y', cvv_response_code: 'M', cvv_response_message: '') }
let!(:payment_3) { create(:payment, avs_response: 'A', cvv_response_code: 'M', cvv_response_message: 'Match') }
let!(:payment_4) { create(:payment, avs_response: 'Y', cvv_response_code: 'N', cvv_response_message: 'No Match') }
+ let!(:payment_5) { create(:payment, avs_response: 'Y', cvv_response_code: 'M', cvv_response_message: '', state: 'failed') }
- it 'should not return successful responses' do
- expect(subject.class.risky.to_a).to match_array([payment_3, payment_4])
+ describe '.risky' do
+ it 'fetches only risky payments' do
+ expect(subject.class.risky.to_a).to match_array([payment_3, payment_4, payment_5])
+ end
+ end
+
+ context '#risky?' do
+ it 'is true for risky payments' do
+ aggregate_failures do
+ expect(payment_1).not_to be_risky
+ expect(payment_2).not_to be_risky
+ expect(payment_3).to be_risky
+ expect(payment_4).to be_risky
+ expect(payment_5).to be_risky
+ end
+ end
end
end
@@ -1207,7 +1222,7 @@
end
end
- describe "is_avs_risky?" do
+ describe "#is_avs_risky?" do
it "returns false if avs_response included in NON_RISKY_AVS_CODES" do
('A'..'Z').reject{ |x| subject.class::RISKY_AVS_CODES.include?(x) }.to_a.each do |char|
payment.update_attribute(:avs_response, char)
@@ -1231,26 +1246,17 @@
end
end
- describe "is_cvv_risky?" do
- it "returns false if cvv_response_code == 'M'" do
- payment.update_attribute(:cvv_response_code, "M")
- expect(payment.is_cvv_risky?).to eq(false)
- end
-
- it "returns false if cvv_response_code == nil" do
- payment.update_attribute(:cvv_response_code, nil)
- expect(payment.is_cvv_risky?).to eq(false)
- end
-
- it "returns false if cvv_response_message == ''" do
- payment.update_attribute(:cvv_response_message, '')
- expect(payment.is_cvv_risky?).to eq(false)
+ describe "#is_cvv_risky?" do
+ ['M', nil].each do |char|
+ it "returns false if cvv_response_code is #{char.inspect}" do
+ payment.cvv_response_code = char
+ expect(payment.is_cvv_risky?).to eq(false)
+ end
end
- it "returns true if cvv_response_code == [A-Z], omitting D" do
- # should use cvv_response_code helper
- (%w{N P S U} << "").each do |char|
- payment.update_attribute(:cvv_response_code, char)
+ ['', *('A'...'M'), *('N'..'Z')].each do |char|
+ it "returns true if cvv_response_code is #{char.inspect} (not 'M' or nil)" do
+ payment.cvv_response_code = char
expect(payment.is_cvv_risky?).to eq(true)
end
end