Merge pull request #5233 from luisramos0/stripe_sca_bo

[StripeSCA] Fix card payments in the Backoffice
This commit is contained in:
Luis Ramos
2020-04-27 13:00:24 +01:00
committed by GitHub
3 changed files with 128 additions and 15 deletions

View File

@@ -155,7 +155,6 @@ Layout/LineLength:
- spec/controllers/spree/admin/orders/customer_details_controller_spec.rb
- spec/controllers/spree/admin/orders_controller_spec.rb
- spec/controllers/spree/admin/payment_methods_controller_spec.rb
- spec/controllers/spree/admin/payments_controller_spec.rb
- spec/controllers/spree/admin/products_controller_spec.rb
- spec/controllers/spree/admin/reports_controller_spec.rb
- spec/controllers/spree/admin/variants_controller_spec.rb

View File

@@ -29,6 +29,8 @@ module Spree
return
end
authorize_stripe_sca_payment
if @order.completed?
@payment.process!
flash[:success] = flash_message_for(@payment, :successfully_created)
@@ -93,7 +95,7 @@ module Spree
available(:back_end).
select{ |pm| pm.has_distributor? @order.distributor }
@payment_method = if @payment && @payment.payment_method
@payment_method = if @payment&.payment_method
@payment.payment_method
else
@payment_methods.first
@@ -124,6 +126,13 @@ module Spree
def load_payment
@payment = Payment.find(params[:id])
end
def authorize_stripe_sca_payment
return unless @payment.payment_method.class == Spree::Gateway::StripeSCA
@payment.authorize!
raise Spree::Core::GatewayError, I18n.t('authorization_failure') unless @payment.pending?
end
end
end
end

View File

@@ -12,16 +12,114 @@ describe Spree::Admin::PaymentsController, type: :controller do
context "#create" do
let!(:payment_method) { create(:payment_method, distributors: [shop]) }
let!(:order) do
create(:order_with_totals_and_distribution, distributor: shop, state: "payment")
end
let(:params) { { amount: order.total, payment_method_id: payment_method.id } }
it "advances the order state" do
expect {
spree_post :create, payment: params, order_id: order.number
}.to change { order.reload.state }.from("payment").to("complete")
context "order is not complete" do
let!(:order) do
create(:order_with_totals_and_distribution, distributor: shop, state: "payment")
end
it "advances the order state" do
expect {
spree_post :create, payment: params, order_id: order.number
}.to change { order.reload.state }.from("payment").to("complete")
end
end
context "order is complete" do
let!(:order) do
create(:order_with_totals_and_distribution, distributor: shop,
state: "complete",
completed_at: Time.zone.now)
end
context "with Check payment (payment.process! does nothing)" do
it "redirects to list of payments with success flash" do
spree_post :create, payment: params, order_id: order.number
redirects_to_list_of_payments_with_success_flash
expect(order.reload.payments.last.state).to eq "checkout"
end
end
context "with Stripe payment where payment.process! errors out" do
let!(:payment_method) { create(:stripe_payment_method, distributors: [shop]) }
before do
allow_any_instance_of(Spree::Payment).
to receive(:process!).
and_raise(Spree::Core::GatewayError.new("Payment Gateway Error"))
end
it "redirects to new payment page with flash error" do
spree_post :create, payment: params, order_id: order.number
redirects_to_new_payment_page_with_flash_error("Payment Gateway Error")
expect(order.reload.payments.last.state).to eq "checkout"
end
end
context "with StripeSCA payment" do
let!(:payment_method) { create(:stripe_sca_payment_method, distributors: [shop]) }
context "where payment.authorize! raises GatewayError" do
before do
allow_any_instance_of(Spree::Payment).
to receive(:authorize!).
and_raise(Spree::Core::GatewayError.new("Stripe Authorization Failure"))
end
it "redirects to new payment page with flash error" do
spree_post :create, payment: params, order_id: order.number
redirects_to_new_payment_page_with_flash_error("Stripe Authorization Failure")
expect(order.reload.payments.last.state).to eq "checkout"
end
end
context "where payment.authorize! does not move payment to pending state" do
before do
allow_any_instance_of(Spree::Payment).to receive(:authorize!).and_return(true)
end
it "redirects to new payment page with flash error" do
spree_post :create, payment: params, order_id: order.number
redirects_to_new_payment_page_with_flash_error("Authorization Failure")
expect(order.reload.payments.last.state).to eq "checkout"
end
end
context "where both payment.process! and payment.authorize! work" do
before do
allow_any_instance_of(Spree::Payment).to receive(:authorize!) do |payment|
payment.update_attribute :state, "pending"
end
allow_any_instance_of(Spree::Payment).to receive(:process!).and_return(true)
end
it "redirects to list of payments with success flash" do
spree_post :create, payment: params, order_id: order.number
redirects_to_list_of_payments_with_success_flash
expect(order.reload.payments.last.state).to eq "pending"
end
end
end
def redirects_to_list_of_payments_with_success_flash
expect_redirect_to spree.admin_order_payments_url(order)
expect(flash[:success]).to eq "Payment has been successfully created!"
end
def redirects_to_new_payment_page_with_flash_error(flash_error)
expect_redirect_to spree.new_admin_order_payment_url(order)
expect(flash[:error]).to eq flash_error
end
def expect_redirect_to(path)
expect(response.status).to eq 302
expect(response.location).to eq path
end
end
end
@@ -38,8 +136,10 @@ describe Spree::Admin::PaymentsController, type: :controller do
context "that was processed by stripe" do
let!(:payment_method) { create(:stripe_payment_method, distributors: [shop]) }
# let!(:credit_card) { create(:credit_card, gateway_customer_profile_id: "cus_1", gateway_payment_profile_id: 'card_2') }
let!(:payment) { create(:payment, order: order, state: 'completed', payment_method: payment_method, response_code: 'ch_1a2b3c', amount: order.total) }
let!(:payment) do
create(:payment, order: order, state: 'completed', payment_method: payment_method,
response_code: 'ch_1a2b3c', amount: order.total)
end
before do
allow(Stripe).to receive(:api_key) { "sk_test_12345" }
@@ -49,7 +149,8 @@ describe Spree::Admin::PaymentsController, type: :controller do
before do
stub_request(:post, "https://api.stripe.com/v1/charges/ch_1a2b3c/refunds").
with(basic_auth: ["sk_test_12345", ""]).
to_return(status: 200, body: JSON.generate(id: 're_123', object: 'refund', status: 'succeeded') )
to_return(status: 200,
body: JSON.generate(id: 're_123', object: 'refund', status: 'succeeded') )
end
it "voids the payment" do
@@ -94,7 +195,10 @@ describe Spree::Admin::PaymentsController, type: :controller do
context "that was processed by stripe" do
let!(:payment_method) { create(:stripe_payment_method, distributors: [shop]) }
let!(:payment) { create(:payment, order: order, state: 'completed', payment_method: payment_method, response_code: 'ch_1a2b3c', amount: order.total + 5) }
let!(:payment) do
create(:payment, order: order, state: 'completed', payment_method: payment_method,
response_code: 'ch_1a2b3c', amount: order.total + 5)
end
before do
allow(Stripe).to receive(:api_key) { "sk_test_12345" }
@@ -104,7 +208,8 @@ describe Spree::Admin::PaymentsController, type: :controller do
before do
stub_request(:post, "https://api.stripe.com/v1/charges/ch_1a2b3c/refunds").
with(basic_auth: ["sk_test_12345", ""]).
to_return(status: 200, body: JSON.generate(id: 're_123', object: 'refund', status: 'succeeded') )
to_return(status: 200,
body: JSON.generate(id: 're_123', object: 'refund', status: 'succeeded') )
end
it "partially refunds the payment" do