From 25155cab188ebf1c593ffc4c27f8ed0d516f177b Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Wed, 15 Jul 2020 17:13:46 +1000 Subject: [PATCH 1/3] Provide credit card brand to Pin Payments Spree replaced the Ruby code providing the credit card brand with a jquery plugin providing it on the checkout screen. I re-added Ruby code because it's easier and more robust than updating the user interface with new Javascript. --- app/services/checkout/form_data_adapter.rb | 14 +++++++++++++ .../checkout/form_data_adapter_spec.rb | 20 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/app/services/checkout/form_data_adapter.rb b/app/services/checkout/form_data_adapter.rb index a374444637..60bb9257c5 100644 --- a/app/services/checkout/form_data_adapter.rb +++ b/app/services/checkout/form_data_adapter.rb @@ -12,6 +12,8 @@ module Checkout move_payment_source_to_payment_attributes! + fill_in_card_type + set_amount_in_payments_attributes construct_saved_card_attributes if @params[:order][:existing_card_id] @@ -31,6 +33,18 @@ module Checkout @params[:order][:payments_attributes].first[:source_attributes] = payment_source_params end + def fill_in_card_type + payment = params[:order][:payments_attributes]&.first&.dig(:source_attributes) + + return if payment&.dig(:number).blank? + + payment[:cc_type] ||= card_brand(payment[:number]) + end + + def card_brand(number) + ActiveMerchant::Billing::CreditCard.brand?(number) + end + def delete_payment_source_params! @params.delete(:payment_source)[ @params[:order][:payments_attributes].first[:payment_method_id].underscore diff --git a/spec/services/checkout/form_data_adapter_spec.rb b/spec/services/checkout/form_data_adapter_spec.rb index be248a2af0..e2b3c38a94 100644 --- a/spec/services/checkout/form_data_adapter_spec.rb +++ b/spec/services/checkout/form_data_adapter_spec.rb @@ -36,6 +36,26 @@ describe Checkout::FormDataAdapter do end end + describe "and a credit card is provided" do + before do + params[:order][:payments_attributes].first[:source_attributes] = {number: "4444333322221111"} + end + + it "fills in missing credit card brand" do + expect(adapter.params[:order][:payments_attributes].first[:source_attributes][:cc_type]).to eq "visa" + end + + it "leaves an existing credit card brand" do + params[:order][:payments_attributes].first[:source_attributes][:cc_type] = "test" + expect(adapter.params[:order][:payments_attributes].first[:source_attributes][:cc_type]).to eq "test" + end + + it "doesn't touch the credit card brand without a number" do + params[:order][:payments_attributes].first[:source_attributes][:number] = "" + expect(adapter.params[:order][:payments_attributes].first[:source_attributes].key?(:cc_type)).to eq false + end + end + describe "and existing credit card is provided" do before { params[:order][:existing_card_id] = credit_card.id } From 31e072179b5cfaf90744af929fe202326b689faa Mon Sep 17 00:00:00 2001 From: Luis Ramos Date: Wed, 15 Jul 2020 15:19:16 +0100 Subject: [PATCH 2/3] Make method a little simple by extracting method --- app/services/checkout/form_data_adapter.rb | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/app/services/checkout/form_data_adapter.rb b/app/services/checkout/form_data_adapter.rb index 60bb9257c5..273a978a55 100644 --- a/app/services/checkout/form_data_adapter.rb +++ b/app/services/checkout/form_data_adapter.rb @@ -34,11 +34,16 @@ module Checkout end def fill_in_card_type - payment = params[:order][:payments_attributes]&.first&.dig(:source_attributes) + return unless payment_source_attributes - return if payment&.dig(:number).blank? + return if payment_source_attributes.dig(:number).blank? - payment[:cc_type] ||= card_brand(payment[:number]) + payment_source_attributes[:cc_type] ||= card_brand(payment_source_attributes[:number]) + end + + def payment_source_attributes + @payment_source_attributes ||= + params[:order][:payments_attributes]&.first&.dig(:source_attributes) end def card_brand(number) From 4e00c45782ac9ffee3bb0e3d8a7e3df5bf74d99b Mon Sep 17 00:00:00 2001 From: Pau Perez Date: Wed, 15 Jul 2020 16:46:09 +0200 Subject: [PATCH 3/3] Doc defensive coding needed by pin payments [skip ci] --- app/services/checkout/form_data_adapter.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/services/checkout/form_data_adapter.rb b/app/services/checkout/form_data_adapter.rb index 273a978a55..1333ed5dbd 100644 --- a/app/services/checkout/form_data_adapter.rb +++ b/app/services/checkout/form_data_adapter.rb @@ -33,6 +33,11 @@ module Checkout @params[:order][:payments_attributes].first[:source_attributes] = payment_source_params end + # Ensures cc_type is always passed to the model by inferring the type when + # the frontend didn't provide it. This fixes Pin Payments specifically + # although it might be useful for future payment gateways. + # + # More details: app/assets/javascripts/darkswarm/services/checkout.js.coffee#L70-L98 def fill_in_card_type return unless payment_source_attributes