From 9020331484c0c8deb62f900879e278c28abe1248 Mon Sep 17 00:00:00 2001 From: Luuk Veenis Date: Tue, 25 Apr 2017 11:31:09 -0700 Subject: [PATCH] Handle processor and gateway error responses The existing code here will only return error messages if they come from Braintree. In the case that the transaction is rejected by the gateway or the processor, we'll return an error response with a blank message. For these cases, the `errors` array will be empty, and we need to look at the gateway rejection status or processor response codes as per the documentation here: https://developers.braintreepayments.com/reference/response/transaction/ruby#result-object --- .../solidus_paypal_braintree/response.rb | 14 +++++- .../solidus_paypal_braintree/response_spec.rb | 46 +++++++++++++++++-- 2 files changed, 53 insertions(+), 7 deletions(-) diff --git a/app/models/solidus_paypal_braintree/response.rb b/app/models/solidus_paypal_braintree/response.rb index baf228f2..f9e4b9e5 100644 --- a/app/models/solidus_paypal_braintree/response.rb +++ b/app/models/solidus_paypal_braintree/response.rb @@ -34,8 +34,18 @@ def build_success(result) end def build_failure(result) - msg = result.errors.map { |e| "#{e.message} (#{e.code})" }.join(" ") - new(false, msg) + new(false, error_message(result)) + end + + def error_message(result) + if result.errors.any? + result.errors.map { |e| "#{e.message} (#{e.code})" }.join(" ") + else + [result.transaction.status, + result.transaction.gateway_rejection_reason, + result.transaction.processor_settlement_response_code, + result.transaction.processor_settlement_response_text].compact.join(" ") + end end end end diff --git a/spec/models/solidus_paypal_braintree/response_spec.rb b/spec/models/solidus_paypal_braintree/response_spec.rb index 484ad513..6970a285 100644 --- a/spec/models/solidus_paypal_braintree/response_spec.rb +++ b/spec/models/solidus_paypal_braintree/response_spec.rb @@ -1,17 +1,20 @@ require 'spec_helper' RSpec.describe SolidusPaypalBraintree::Response do - let(:error_result) do - error = instance_double( + let(:failed_transaction) { nil } + let(:error) do + instance_double( 'Braintree::ValidationError', code: '12345', message: "Cannot refund a transaction unless it is settled." ) - + end + let(:error_result) do instance_double( 'Braintree::ErrorResult', success?: false, - errors: [error] + errors: [error], + transaction: failed_transaction ) end @@ -61,7 +64,40 @@ context "with an error response" do subject { error_response.message } - it { is_expected.to eq "Cannot refund a transaction unless it is settled. (12345)" } + + context "with a Braintree error" do + it { is_expected.to eq "Cannot refund a transaction unless it is settled. (12345)" } + end + + context "with a processor error" do + let(:error) { nil } + let(:failed_transaction) do + instance_double( + 'Braintree::Transaction', + status: "settlement_declined", + gateway_rejection_reason: nil, + processor_settlement_response_code: "4001", + processor_settlement_response_text: "Settlement Declined" + ) + end + + it { is_expected.to eq "settlement_declined 4001 Settlement Declined" } + end + + context "with a gateway error" do + let(:error) { nil } + let(:failed_transaction) do + instance_double( + 'Braintree::Transaction', + status: "gateway_rejected", + gateway_rejection_reason: "cvv", + processor_settlement_response_code: nil, + processor_settlement_response_text: nil + ) + end + + it { is_expected.to eq "gateway_rejected cvv" } + end end end